このブログを検索

ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2021/09/23

古いASAにASDMでアクセスできないのはTLSバージョンのせい

私はCisco ASA5505を持っている。

ヤフオクで入手した中古品だ。


ASAはASDMというJavaで動く管理用のGUIツールを使って設定する。

CLIでも設定できるが見やすかったり設定しやすかったりするのでだいたいASDMを使う。


久しぶりに引っ張り出してASDMでアクセスしたら、こんなエラーになった。


ログインダイアログ右下にあるJavaコンソール(コーヒーカップのアイコン)を開いてアクセスすると、以下のようなエラーが記録されている。

javax.net.ssl.SSLHandshakeException: The server selected protocol version TLS10 is not accepted by client preferences [TLS12]


Javaのバージョンは 1.8.0_301-b09
ASAは9.2(4)33

コントロールパネルの「プログラム」にあるJavaコントロールパネルを起動し、
詳細タブを見ると、「高度なセキュリティ設定」のところの「TLS1.0を使用する」のチェックがはずれている。


ASAにconsoleかsshでログインしてみると

# show ssl
Accept connections using SSLv2, SSLv3 or TLSv1 and negotiate to SSLv3 or TLSv1
Start connections using TLSv1 and negotiate to TLSv1
Enabled cipher order: dhe-aes256-sha1 dhe-aes128-sha1 aes256-sha1 aes128-sha1
Disabled ciphers: 3des-sha1 des-sha1 rc4-md5 rc4-sha1 null-sha1
SSL trust-points:
  outside VPNLB interface: ASDM_Launcher_Access_TrustPoint_0
  outside interface: ASDM_Launcher_Access_TrustPoint_0
Certificate authentication is not enabled


TLS1しかサポートしていない。

ASAはTLS1、JavaはTLS1.1以上だったため、接続できないのだ。

接続できるようにするには、ASAがTLS1.1以上を使うか、JavaがTLS1.0を使うようにすればよい。

が、結論から言うとどっちもできなかった。
ASAには ssl server-versionというコマンドがあるのだがtlsv1より上を設定できない。

そしてJavaコンソールでTLS1.0をチェックしても、上記のエラーは変わらない。
ここの設定を変えてもTLS1.2で接続しようとするようなのだ。

家にJavaがインストールされていない古いパソコンがあったので、
そこに 1.7.0_80-b15 を入れてみた。

Javaコンソールを開くと「TLS1.0を使用する」がチェックされており、1.1と1.2はチェックされていない。

この状態だとASDMで接続できた。


OSをあげれば、と思ったが、
5505は販売終了製品で、9.2(4)33が2018年にリリースされた後新しいバージョンはリリースされていない。

JavaコンソールでTLS1.0をチェックしてもダメな理由がわからず、
どこか別の設定を変えればいけるのかもしれないが使用が推奨されない古いプロトコルを使うことをあまり深追いするのもアレなので。

2020/01/18

TCPまたはUDPパケットを送信する。javaで。

UDPかTCPを指定できるようにした。 Clientx.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.io.DataOutputStream;
import java.net.Socket;


public class Clientx {
 public static void main(String[] args) throws IOException{
  String sendData = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";

  String Host = args[0];
  Integer DstPort = Integer.parseInt(args[1]);
  int count = Integer.parseInt(args[2]);
  String Proto = args[3];
 
  System.out.println(Proto);

  if (Proto.equals("U")) {
   UDPsend(sendData,Host,DstPort,count);
  }else{
   TCPsend(sendData,Host,DstPort,count);
  }
 }

 public static void UDPsend(String sdata, String host, int dstPort, int count) throws IOException{
  byte[] bdata = sdata.getBytes("UTF-8");
  DatagramSocket sock = new DatagramSocket();
  DatagramPacket packet 
  = new DatagramPacket(bdata, bdata.length, new InetSocketAddress(host,dstPort));


  for(int i=1; i<=count; i++) {  
   sock.send(packet);
   System.out.println("Sent UDP data  "+host+":"+dstPort);
    try{
    Thread.sleep(1000);
   }catch(InterruptedException e){}
  }
  sock.close();//
 }

 public static void TCPsend(String sdata, String host, int dstPort, int count) {
  try{

   for(int i=1; i<=count; i++) {  
    Socket sock = new Socket(host,dstPort);
    DataOutputStream out = new DataOutputStream(sock.getOutputStream());
    out.writeUTF(sdata);
    System.out.println("Sent TCP data  "+host+":"+dstPort);

    out.close();
    sock.close();
     try{
     Thread.sleep(1000);
    }catch(InterruptedException e){}
   }

  }catch(IOException e){
   e.printStackTrace();
  }

 }
}
------------- 

 使い方 

 TCP12345のパケットを5個送信 

java Clientx localhost 12345 5 T 

 UDP12345のパケットを5個送信 

java Clientx localhost 12345 5 U 

 実際は4番目の引数が"U"ならUDP、それ以外だとTCPになる。 

4番目の引数がないと動かない。 

UDPの場合はport unreachableが返ってきてもとりあえず送信はするが、 
TCPの場合受信者がいないと(指定したTCPポートをリッスンしていない)と、 
1回送ってExceptionを吐いて終了してしまう。 

 TCPのサーバも作った。 TCPのサーバ 

 ServerT.java
import java.io.IOException;
import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerT {
 public static void main(String[] args) {
  try{
   while(true){
    ServerSocket svSock = new ServerSocket(12345);
    Socket sock = svSock.accept();
    DataInputStream in = new DataInputStream(sock.getInputStream());
    String strData = in.readUTF();
    System.out.println("Received TCP : "+strData);
    in.close();
    svSock.close();
   }
  }catch(IOException e){
   e.printStackTrace();
  }

 }
}
UDP/TCPどっちでも受信できるようにするのはまた今度。

任意のパケットを送信する。javaで。UDP編

たとえばFirewallのポリシーの設定確認のときに、任意のパケットを送信したいことがある。 UDP 1234とか、TCP 5678とか。

ICMPならpingを打てばよいし、HTTP、HTTPS、SSH、TELNETなどならブラウザやteratermで実際にアクセスしてみればいい。TCPならtelnetでポート指定すればよいが、UDPの特定のポートの通信を発生させるためにはツールを使っていた。ipsendwinとか、iperfとか。 ixiaのトラフィックジェネレータを使ったこともある。

最近もipsendwinを使ったのだが、もう古いソフトで、Vectorのダウンロード画面ではサポートOSに「Windows XP/Me/2000/NT/98/95」と書いてある。 そしてあるPCでは「winpcap.dllがない」と表示され、コピーするもまた違うdllがない、エントリポイントが見つからない、などどいうことで実行するのをあきらめた。

そして、このご時世、いろんなアプリやスクリプトがあるし、「UDP 1234のパケットを特定のIPアドレスに10個ほど送信する」なんてことは簡単にできるんじゃないのかと思った。

pythonとかjavascriptとかさらっと調べたが、結局javaでやった。

java。 ちょっと、今更java?みたいな感じがした。 javaで簡単なプログラムを書いたことはあり、 簡単に書けて「ネットワークプログラミングならjavaだな」と思った。

しかし、javaは当然インストールされているだろうと思って普段仕事でつかっているPCのコントロールパネルを見たがjavaがインストールされていない。 たしかコントロールパネルにjavaのアイコンがあったはず.... もう最近はjavaが使われなくなりつつあるのか?

というわけでjavaのインストールから始める。 「java ダウンロード」などで検索するとダウンロードページがすぐ出てくるが、 32ビット版をインストールするように導かれる。 今なら、Version 8 Update 241 64ビット版もあるようだがどういうことだろうと少し調べたら、 ブラウザが32ビット版がデフォルトなのでjavaも32ビット版を使え、ということだった。

https://java.com/ja/download/faq/java_win64bit.xml

普段はクロームを使っているが64ビット版である。 が、たしかクロームでjavaが使えなくなったんじゃなかったっけ...?

IEはたしかに32ビット版のようである。使っていないが。 javaのランタイムは32ビット版のインストールページが検索すると上位に表示されるが、 開発環境、jdkだと13.0.2の64ビット版が出てくる。

32ビット版のランタイムがインストールされているところに64ビット版のjdkをインストールすると、実行時にエラーになる。 ランタイムは入れず、入っていたらアンインストールし、64ビット版のjdkをインストールする。 インストールしたら、binフォルダへのpathを登録する。

C:\Program Files\Java\jdk-13.0.2\bin

pathを登録したらコマンドプロンプトを開いてバージョンを確認してみる。

C:\WINDOWS\system32>javac -version
javac 13.0.2

HelloWorld.java を作る。

public class HelloWorld{
   public static void main(String[] args){
     System.out.println("Hello World!!");
   }
}
javac HelloWorld.java

でコンパイル。 HelloWorld.class ができる。

 実行。

C:\WINDOWS\system32>java HelloWorld
Hello World!!

では、UDPの任意のパケットを送信するプログラムを書こう。

 Client.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class Client {
 public static void main(String[] args) throws IOException {
  String sendData = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
  byte[] data = sendData.getBytes("UTF-8");
  DatagramSocket sock = new DatagramSocket();
   int count = Integer.parseInt(args[2]);
  String Host = args[0];
  Integer DestPort = Integer.parseInt(args[1]);
   for(int i=1; i<=count; i++) {  
   DatagramPacket packet 
   = new DatagramPacket(data, data.length, new InetSocketAddress(Host,DestPort));
   sock.send(packet);
   System.out.println("Sent UDP data  "+Host+":"+DestPort);
    try{
    Thread.sleep(1000);
   }catch(InterruptedException e){}
   }  
   sock.close();//
 }
}

使い方
java Client 宛先 ポート番号 パケット数

たとえば

java Client 192.168.1.1 12345 5

192.168.1.1宛に、UDP の宛先ポート12345のパケットを5個送信する。
間隔は1秒

送るだけならこれで終わり。 もし指定したIPアドレスのホストが存在しないと、arp解決されずパケットが送信されないだろう。 指定したIPアドレスのホストが存在すればパケットが送信されるが、 テキトーなポート宛に送っているので、port unreachableが返ってくるだろう。 送ったパケットを受信しそれを確認したい場合は受信側で下記を実行する。

Server.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;
public class Server {
        public static void main(String[] args) throws IOException {
                Integer Port = Integer.parseInt(args[0]);
                while (true) {
                        DatagramSocket sock = new DatagramSocket(Port);
                        byte[] data = new byte[1024];
                        DatagramPacket packet = new DatagramPacket(data, data.length);
                        sock.receive(packet);
                        System.out.println("Received :"+new String(Arrays.copyOf(packet.getData(),packet.getLength()),"UTF-8"));
                        sock.close();
                }
        }
}

動作確認 Client.javaとServer.javaをコンパイルしたら、 コマンドプロンプトを二つ起動して、 Client.classとServer.classがあるフォルダに移動し、片側でサーバを起動するこのときポート番号を指定する。

C:\Users\sam\udp_data_send>java Server 12345

もう一方でクライアントを起動する。
C:\Users\sam\udp_data_send>java Client localhost 12345 10
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
Sent UDP data  localhost:12345
C:\Users\sam\udp_data_send>java Server 12345
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Received :0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TCPはまた今度。

2013/01/26

Java

ちょっとjavaを使ってみる。

server - clientのサンプルがあって、1台のパソコンで両方動かしてみたことがあるが、

それをさくらのVPSのサーバとWindows7間でやってみたい。

まずWin7にJDKを入れる。

JDKでいいんだっけ?

JavaはもうSunではなくORACLEのものになっている。

インストールして、Pathを追加して、helloworld的なものを動かしてみる。

さくらの方は、rpmファイルをPCに落としてftpであげようとしたら遅くて待てないので、wgetしようとしたら失敗する。どうも、WEBでLicense Agreementに同意してダウンロードしないとダメらしいので、PCからアップロードすることにする・・・あと80分とかいう表示・・・待てない。

さくらのvpsにX WindowsとGNOMEを入れて、VNCでつなぎ、firefoxをいれて、ORACLEのダウンロードページへ行って落とす。

けっこう時間はかかったが、今後もこういうことがあるかもしれないからね。

というわけでWin7とCentOS6の両方でjavaのHelloWorldを動かした。



2011/10/24

javamail入門

javamail入門という面白そうな本があったので、ちょっとやってみる。 javamailとかJAFとかを入れてみるがちゃんと動かない。 いつ入れたのか定かでないSDKを消して、入れなおす。
www.oracle.com/technetwork/java/javase/downloads/jdk-7u1-download-513651.html

インストーラが起動する。 デフォルトではデモをインストールしないようになっているが、インストールする。 インストール後、ユーザー登録画面が出てくる。 ついでなので登録しておく。

pathの登録が必要。

F:\Program Files\Java\jdk1.7.0_01\bin


言い忘れたけど Windows XPです。 昔書いたhello,world的なサンプルをコンパイルしてみる。

エラーになる。 ファイル名とクラス名が同じでないといけないのを思い出して、ちゃんと同じになっているものをコンパイルして動くことを確認する。

javamailは解凍したフォルダを program files\java に移しておき、 環境変数を登録する。 CLASSPATHのところに、mail.jarのフルパスを書く。

F:\Program Files\Java¥javamail-1.4.4\mail.jar;


ファイル名まで書かなければならない。 ということはjarを入れるたびに常にclasspathを書き換える必要があるのか?メンドクサイ・・・ と思うがそれはおいておく。

demoの msgshow.javaをコンパイルする。 classpathがうまく登録されていなかったり反映していないと、エラーが大量に出る。

ちなみに、WindowsXPの環境変数の変更は、 Program Files のように間にスペースがあっても""で囲んだりする必要はない。 コマンドプロンプトを起動していた場合は、そのままでは反映しない。(setをやってみるとわかる)。 コマンドプロンプトをいったん閉じて起動し直すと反映する。ログオフや再起動の必要はない。

実行してみた。

F:\Program Files\Java\javamail-1.4.4\demo>java msgshow -T pop3 -H example.com -U hoge -P xxxxxxx
--------------------------
MESSAGE #1:
This is the message envelope
---------------------------
FROM: John Lennon <john@example.com>
REPLY TO: John Lennon <john@example.com>
TO: hoge@example.com
SUBJECT: test
SendDate: Mon Oct 24 16:10:05 JST 2011
FLAGS:
X-Mailer NOT available

F:\Program Files\Java\javamail-1.4.4\demo>


感動。

じゃあ送信をやってみようと思ったら、うまくいかない。サーバはさくらのVPSを使っていたのだが、25番ポートがどうしても開かなかった。しかたがないので587番に変えた。ところがデモは25番を使っていて、ポートの指定はできなかった。さっそく改変の必要が生じた。しかしこんなのは簡単で、argvを格納しているところに新しい引数と変数を作り、

if (port != null)
props.put("mail.smtp.port", port);


とするだけでOKだった。ちなみにいじったのは msgsend.java である。