nmapつかおうねという話。
前ふり: ssh の暗号化方式
sshは沢山の暗号化方式を扱います。
- 通信をはじめる前のDH鍵交換 (KexAlgorithms)
- ホストを確認するためのホスト鍵や個人を確認するための鍵 (HostKeyAlgorithms, PubkeyAcceptedAlgorithms)
- 通信の暗号化 (Ciphers)
- 暗号化されたメッセージの認証 (MACs)
- などなど
暗号化方式の中には既に危険なもの、十分安全ではないものがあるので、設定によりそれらを排除します。
sshdの設定を外部から確認するには、 nmapを利用して以下のようにします。
$ nmap --script ssh2-enum-algos -sV -p 22 127.0.0.1
`Starting Nmap 7.92 ( https://nmap.org ) at 2025-02-07 09:12 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00021s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.8 (protocol 2.0)
| ssh2-enum-algos:
| kex_algorithms: (11)
| curve25519-sha256
| curve25519-sha256@libssh.org
| ecdh-sha2-nistp256
| ecdh-sha2-nistp384
| ecdh-sha2-nistp521
| diffie-hellman-group-exchange-sha256
| diffie-hellman-group14-sha256
| diffie-hellman-group16-sha512
| diffie-hellman-group18-sha512
| ext-info-s
| kex-strict-s-v00@openssh.com
| server_host_key_algorithms: (4)
| rsa-sha2-512
| rsa-sha2-256
| ecdsa-sha2-nistp256
| ssh-ed25519
| encryption_algorithms: (5)
| aes256-gcm@openssh.com
| chacha20-poly1305@openssh.com
| aes256-ctr
| aes128-gcm@openssh.com
| aes128-ctr
| mac_algorithms: (8)
| hmac-sha2-256-etm@openssh.com
| hmac-sha1-etm@openssh.com
| umac-128-etm@openssh.com
| hmac-sha2-512-etm@openssh.com
| hmac-sha2-256
| hmac-sha1
| umac-128@openssh.com
| hmac-sha2-512
| compression_algorithms: (2)
| none
|_ zlib@openssh.com
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.30 seconds
縛りプレイ: nmap禁止
ssh の通信では、サーバとクライアントがそれぞれ自分の使える暗号化方式の一覧を相手に宣言して、
そのANDをとって採用する暗号化方式をきめます。
デバッグ出力をみると、利用する暗号化方式のやりとりを観察できます。
メッセージがどうなるかはバージョン依存です。手元のfedoraだとこんなかんじ。。。
$ ssh -vv localhost
OpenSSH_9.8p1, OpenSSL 3.2.2 4 Jun 2024
debug1: Reading configuration data /home/moriwaka/.ssh/config
(設定読み込み略)
(1) TCP接続して
debug2: resolving "localhost" port 22
debug1: Connecting to localhost [::1] port 22.
debug1: Connection established.
(private key略)
(2) 互いのバージョン確認、認証しよう
debug1: Local version string SSH-2.0-OpenSSH_9.8
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.8
debug1: compat_banner: match: OpenSSH_9.8 pat OpenSSH* compat 0x04000000
debug2: fd 3 setting O_NONBLOCK
debug1: Authenticating to localhost:22 as 'moriwaka'
(private key略)
(3) 鍵交換しよう! クライアント側の 扱える暗号化はこう
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ext-info-c,kex-strict-c-v00@openssh.com
debug2: host key algorithms: ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
debug2: ciphers ctos: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: ciphers stoc: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: MACs ctos: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: MACs stoc: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: compression ctos: none,zlib@openssh.com,zlib
debug2: compression stoc: none,zlib@openssh.com,zlib
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
(4) サーバから鍵交換の返事きた。サーバ側の扱える暗号化方式はこう。
冒頭のnmapのスクリプトはサーバと通信して、ここに相当する処理をして結果を出力しています。
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ext-info-s,kex-strict-s-v00@openssh.com
debug2: host key algorithms: rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
debug2: ciphers ctos: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: ciphers stoc: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: MACs ctos: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: MACs stoc: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: compression ctos: none,zlib@openssh.com
debug2: compression stoc: none,zlib@openssh.com
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
(5)プロフィール交換したんで実際kexやるよ
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: aes256-gcm@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: aes256-gcm@openssh.com MAC: <implicit> compression: none
debug1: kex: curve25519-sha256 need=32 dh_need=32
debug1: kex: curve25519-sha256 need=32 dh_need=32
(6) 返事きてkex成功したね
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
(以下略)
サーバ設定の確認
(4)の箇所から確認します。なんとなく読めますが……。
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ext-info-s,kex-strict-s-v00@openssh.com
→ ext-info-s はサーバ側であることを示しています。kex-strict-s-v00@openssh.com は実際の暗号化方式ではなくダミーで、鍵交換方式のバリエーションを示します。
debug2: host key algorithms: rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
→ ホスト鍵で利用できるアルゴリズム一覧です。対応するホスト鍵がない場合もあります。
debug2: ciphers ctos: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: ciphers stoc: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
debug2: MACs ctos: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: MACs stoc: hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512
debug2: compression ctos: none,zlib@openssh.com
debug2: compression stoc: none,zlib@openssh.com
debug2: languages ctos:
debug2: languages stoc:
→ 'ctos', 'stoc'はclientから送信するとき、serverから送信するときの通信方向に対応します。
暗号化方式だけでなく圧縮方式などのやりとりもしています。
結論: nmapをつかおう
サーバ側の設定を追加ツールなしでも読みとれることがわかりました。ただし「できること」と「やるべきこと」は違います。運用においては nmap や他のツールを使いましょう。
- (3)と(4)を見比べるとわかりますが、字面で全く同じであっても登場する場所によりクライアント側の話か、サーバ側の話かが違います。人間による読解は間違いがあるので第一の選択肢ではありません。
- ログメッセージは規格でもなんでもないので、バージョンが違えば表示有無、ログレベル、テキスト表記等が変わるようなことは当然発生します。デバッグログをテキスト処理することはそれらの変化に追従するメンテナンスコストが必要な、まずい選択肢です。
- sshの規格を知らないと意味がわからない
ext-info-s や openssh の独自拡張があり、「暗号化方式のリスト」に単純に一致するわけではありません。
- 利用するツールを nmap に限定する必要はないですが、まともなツールを使えば上記の問題は全て避けられます。