業務の一環でNW機器のsshdのアルゴリズムを調べていたんですが、
そういえばSSHのセッション確立のフローについてちゃんと説明出来ないなと思ったのでおさらいします。
アルゴリズムの中身を書いていくときりがないので、どのタイミングで何をしているのかを整理したいと思います。
仕組み自体もそうですが、アルゴリズムの種類も多いので用語で混乱してしまいますね。
SSHで出てくる用語
アルゴリズム
鍵
SSHの動作 コネクション
大まかな流れ
- TCPコネクション確立
- サーバ使用できるバージョンを応答
- サーバの公開ホストキーの提供
- 公開鍵認証でサーバのFinger printを確認して認証
- 各アルゴリズムのネゴシエーション
- Diffie Hellman関数で鍵交換
- ここで暗号化、複合化用の共通鍵が交換される
- 共通鍵を使って以後の通信をやりとり
認証
以下のどちらかでユーザを認証する
- パスワード認証
- 公開鍵認証
- 公開鍵、秘密鍵はここで使われる
なぜ説明できなかったのか、勘違いしていたところ
対象鍵暗号、非対称鍵暗号アルゴリズムがごっちゃになっていた
- 対象鍵暗号
- DES、AES等
- 鍵の交換は別のアルゴリズムを使用する(Diffie-Hellman等)
- 非対称鍵暗号
- RSA、ECDSA等
各アルゴリズムの用語は覚えていましたが、何の鍵暗号化の紐づけが忘れてしまっていました。
ホストキーと公開鍵がごっちゃになっていた
公開ホストキーと書かれている場合が多いので公開鍵と間違えていました。
- 公開ホストキーはSSHコネクション時に確認される
- known_hostsファイルに保存される。情報が無い場合はユーザ認証前に確認される
- 公開鍵はユーザ認証のみで使う
- 認証キーペアはクライアント側で作成してサーバに配置する
これですっきり。
ファイル、コマンド系
サーバ側
- 公開ホストキー
ホストキはssh_host_XXX_key.pubとアルゴリズムごとにありますが、私の経験ではecdsaがよく使われています。
/etc/ssh/ssh_host_ecdsa_key.pub # 接続するとclientのknown_hostsに書かれる
- ホストキー確認コマンド
ssh-keygen -lv -f /etc/ssh/ssh_host_ecdsa_key.pub
クライアント側
Windowsだとソフトによりけりなので一般的なLinuxで書きます。
- 各sshサーバのホストキー
$HOME/.ssh/known_hosts
- 認証鍵ペア
$HOME/.ssh/id_rsa $HOME/.ssh/id_rsa.pub # こっちをサーバのauthrized_keyに書く。またはssh-copy-id
残課題 ホストキーについて
- ホストの認証とは何なのか?どう行っているのか?
SSHコネクションを行う際に公開ホストキーでサーバの識別を行いますが、ecdsaの鍵が使われておりこれも公開鍵認証を行っていそうです。
ユーザではなくサーバ認証用のキーペアがありそうですが、この周りの資料が出てこなかったのでこの分は今回保留とします。
サーバ側でホストキーファイルを確認したら公開鍵と秘密鍵のペアっぽいものがありました。
masashi@PC-ubuntu:~$ ls -l /etc/ssh/ssh_host_* -rw------- 1 root root 227 8月 17 2019 /etc/ssh/ssh_host_ecdsa_key -rw-r--r-- 1 root root 176 8月 17 2019 /etc/ssh/ssh_host_ecdsa_key.pub -rw------- 1 root root 411 8月 17 2019 /etc/ssh/ssh_host_ed25519_key -rw-r--r-- 1 root root 96 8月 17 2019 /etc/ssh/ssh_host_ed25519_key.pub -rw------- 1 root root 1675 8月 17 2019 /etc/ssh/ssh_host_rsa_key -rw-r--r-- 1 root root 396 8月 17 2019 /etc/ssh/ssh_host_rsa_key.pub
公開鍵を確認。
masashi@PC-ubuntu:~$ cat /etc/ssh/ssh_host_ecdsa_key.pub ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIYnhbqvzAS0J/yUr7jCGLx88zBL9GqPlrZZLobdBmdkKdLEDIQ2VUCcMdfsZ1IZA0kqStnq61o5s9OGQ0sbzN0= root@PC-ubuntu
クライアント側と比較してみます。
環境の都合でWindowsでの確認ですが、同じですね。
最近のビルドではPowershellにsshが付いているので便利です。
PS C:\Users\masashi> cat .\.ssh\known_hosts 192.168.0.10 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIYnhbqvzAS0J/yUr7jCGLx88zBL9GqPlrZZLobdBmdkKdLEDIQ2VUCcMdfsZ1IZA0kqStnq61o5s9OGQ0sbzN0=
ということはサーバ接続時も公開鍵認証でクライアントがサーバを認証していてアルゴリズムはecdsaを使用しているということになりますね。
で、サーバの公開鍵がクライアントのknown_hostsに書かれると。
パスワード認証の場合でも一回は公開鍵認証をしているということですね。
まとめ
普段使っているSSHですが、意外と説明に困ったので今回まとめてみました。
技術的な説明は何もできていませんが、とりあえずはフローの整理ができたので良しとします。
SSHが詳しく書かれている本って意外と無いんですよね。
O'Reilly本を読むのとRFCを読まないとですね。
参考サイト
Understanding the SSH Encryption and Connection Process | DigitalOcean