Edited at

SSHのプロトコルについてまとめてみた 第一弾

More than 1 year has passed since last update.


はじめに


SSHについて


  • 皆さん, SSH使っていますか? ほとんどすべてのエンジニアがSSHを使用していると思います。

  • インフラエンジニアでなくても, デプロイや設定, gitでSSHを使用しているので, SSHを使わなければいけないシーンがあるのではないでしょうか。

  • 日常的に使っているSSHとはそもそもなんなのか, どのように盗聴されていない・改ざんされていないことを担保するのかについて再度学習してみました。

  • 今回はSSHのプロトコルについて, 実際に接続した際の流れをまとめてみました。

  • 今回はパスワード認証ではなく, 公開鍵暗号化方式を使用したSSHということですすめていきたいと思います。


SSH Protocol2における接続時のシーケンス図


  • TeraTermのマニュアルページに参考になるシーケンス図がございましたので, こちら使用させていただいております。

TeraTerm Reference Figure1

段階を追って説明していきます!


SSHでリモートに接続した際の流れ


1. バージョンの相互確認


  • 相互のバージョンに応じて, アルゴリズムを利用するようにする。


    • 相手のバージョンについては, 以下のようにnetcatやtelnetで確認する事ができます。



$ telnet hogehoge.com 22

# サーバーの対応するバージョンを返してくる
SSH-2.0-OpenSSH_6.6.1p1-RHEL7-6.6.1p1-25

# クライアントのバージョンを入力する
SSH-2.0-OpenSSH_7.4

# サーバーがアルゴリズムを提案してくる
ތfurve25519-sha256@libssh.org,ecdh-sha2-nistp256,....



  • ssh -vで確認するところの次の出力に当たります。

# protocol2を選択する

debug1: Enabling compatibility mode for protocol 2.0

# ローカルのOpenSSHバージョン
debug1: Local version string SSH-2.0-OpenSSH_7.4

# リモートのOpenSSHバージョン
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1-RHEL7-6.6.1p1-25

# 以下のバージョンのプロトコルでやる
debug1: match: OpenSSH_6.6.1p1-RHEL7-6.6.1p1-25 pat OpenSSH_6.6.1* compat 0x04000000


2. 共通鍵の交換


  • Diffie-Hellman鍵交換法で共通鍵暗号化方式の共通鍵を交換する。


    • 公開鍵暗号化方式では, 暗号化に時間がかかり一方向の暗号化しか行うことが出来ないため公開鍵暗号化方式で共通鍵の受け渡しを行う。



debug1: Authenticating to hogehoge.com:22 as 'remote-hoge'

debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received

# 鍵交換のアルゴリズムを決定する
debug1: kex: algorithm: curve25519-sha256@libssh.org
debug1: kex: host key algorithm: ecdsa-sha2-nistp256

# サーバーから共通鍵としてAES 256bit CTRモードを提案
# メッセージ認証符号(MAC)の方式を決定;改ざん検知に使用する
debug1: kex: server->client cipher: aes256-ctr MAC: umac-64-etm@openssh.com compression: zlib@openssh.com

# クライアントから共通鍵としてAES 256bit CTRモードを提案
debug1: kex: client->server cipher: aes256-ctr MAC: umac-64-etm@openssh.com compression: zlib@openssh.com


3. リモートホストの確認


  • リモートホストが悪意を持ったサーバーになりすましを受けていないかを確認する。


    • 相手のサーバーが保有しているのは公開鍵なので, 漏れた公開鍵を利用しなりすましを受ける可能性はある。

    • ローカルのknown_hostsに初回接続時にFingerprintを残し, 毎回の接続時にFingerprintを照合する。



  • もし, 自分の操作でマシンを切り替えて, かつIPアドレスに変化のない場合は該当するFingerprintを削除し再度登録することで警告を出さなくなる。

debug1: expecting SSH2_MSG_KEX_ECDH_REPLY

debug1: Server host key: ecdsa-sha2-nistp256 SHA256:l1AGSlrOJX/k1Uu7ih4VscJkbzckOSwHtS8Pu0O50mU

# known_hostsと/etc/ssh/ssh_host_rsa_key.pubの照合
debug1: Host '[hogehoge.com]:22' is known and matches the ECDSA host key.
debug1: Found key in /Users/local-hoge/.ssh/known_hosts:10


  • Finderprintは/etc/ssh/ssh_host_rsa_key.pubに存在し, OpenSSHのインストール時に作成しているようです。


    • これで持って, ホストを識別しています。

    • 例えば, AMIやrsync等でまるっと中身をコピーしたサーバーを複数台立てると/etc/ssh/ssh_host_rsa_key.pubがコピーされるのでFinderprintが同じホストが複数できることになります。

    • またIPアドレスや, IPアドレスから逆引きした際に得られたホスト名も合わせて照合しているようです。




まとめ


  • 調べてみると, ものすごい奥が深くすべて調べきりませんでした...



    • known_hostsはどのように生成されているのか。


      • ホスト固有の情報を使っているのか。



    • 暗号利用モードとは?

    • パスワード認証ではどのようにパスワードがやりとりされているのか。


      • ハッシュ化されたパスワードをサーバー側で照合しているのか。





  • デファクトなSSH実装であるOpenSSHがつい最近リリースされたバージョン(7.4)では, SSH Protocol 1のサーバーサポートを打ち切ったようです。https://mag.osdn.jp/16/12/20/160000

  • サーバーもしくはクライアントのバージョンが古いと, 強度の弱いarcfourやMD5が使用されることがあるので脆弱性のある暗号化方式・ハッシュを選択しないように設定・アップデートを行う必要がある。


    • たしかに共通鍵暗号化方式はaesよりarcfourの方がscpsftpでファイルを転送したときに早いので, インターネットに通信が出ないSSHであればarcfourを選択するのもありだと思います。



  • 私自身も含めてセキュリティに関して興味を持つきっかけになればなと思います。


次回について


  • いったん, ここまでとさせていただきます。間に合わなかった。

  • 続きの第二弾をご期待下さい!



    • 実用SSHを読んでおかないとまずいです...




Disclaimer


  • 今回のこの記事は私自信の勉強も兼ねさせております。


    • そのため正確性に関しては保証いたしかねます。参考程度にしていただけると幸いです。



  • もし正しくない点等ございましたら, 以下コメント欄からご指摘いただけると大変ありがたいです。


最後に


参考URL

http://ttssh2.osdn.jp/manual/ja/reference/sourcecode.html#ttssh

http://bie.inf.kyushu-u.ac.jp/~yosinori/ssh/protocol-j.html

http://www.unixuser.org/~euske/doc/openssh/book/chap3.html