SSHの基礎を調べるよ

背景・経緯
なんか久しぶりに古いノートPCを起動して、git pull
を打つと変なエラーを受けとった。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s.
Please contact your system administrator.
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
Host key for github.com has changed and you have requested strict checking.
Host key verification failed.
GitHubがRSAホストキーを更新したことが原因らしい。
さて、手順通りやれば問題なくgit pull
が打てるようになったが、こういう時にちょこちょこ出てくるfingerprint
やknown_hosts
ファイルなど、SSH周りのことを理解していないなーと思ったので調べる。

やっていき。色々再確認していく。
ssh-keygenコマンド
authentication keys for ssh
を生成したり管理したりするコマンド。
基本的な方法でコマンドを実行すると、知っての通り2種類のファイルが生成される。
拡張子なしファイルとpubファイル
拡張子なしファイルはいわゆる「秘密鍵」
.pub
拡張子のファイルはいわゆる「公開鍵」

ホスト認証とユーザ認証
SSHの仕組みは2種類の認証が存在する。
なんか適当に手順通りやっているだけでは、ユーザ認証しか意識しないことになってしまってSSHを理解できなくなる()
- ホスト認証
- 今からSSHで接続する先(ホスト)が本当に正しいかどうかを確認する
- ユーザ認証
- 今からSSHで接続する先(ホスト)にログインできるユーザかどうかを確認する

ユーザ認証の仕組み(簡易版)
- 公開鍵を予めサーバに登録する
- ローカル(クライアント)には秘密鍵がある。公開鍵・秘密鍵の特性上、秘密鍵で公開鍵の暗号を解くことができるので、ユーザの判定(認証)ができる。ログインも許可する。
※詳細の流れは後ほど学ぶ。
まぁこれはなんとなく知っている話。このときの、ローカル(クライアント)側に秘密鍵がある鍵ペアのことをユーザーキー
と呼んだりする。ユーザーキーとか言いながらペアのことを指すので注意。
で、もちろん秘密鍵が漏れたら終わり。
これが一般的だが、一応パスワード認証方式もある。まさにホスト側にあるログインユーザのパスワードを入れることで認証する。パスワードが分かれば誰でも入れるので基本使用しない。

ホスト認証の仕組み(簡易版)
こっちも公開鍵暗号方式を使っている。
鍵ペアはクライアント側だけにありそうなイメージ(GitHubとかを意識せずにセッティングしているとそう見えがち)だが、サーバ側にも鍵ペアが存在する。
- 接続の確立前に、サーバは公開鍵をクライアントに返す
- クライアント側は、
known_hosts
の中と送られてきた公開鍵を見比べて、サーバが確かに正しいことを確認する
※これだけだと偽サーバが真サーバの公開鍵を偽装して返せば終わりじゃん、と思われるが、この後SSH確立の過程で暗号・復号を実際に行う際に結局秘密鍵がない偽サーバはバレる。
known_hosts
に記載がない初回は特殊な過程がある。
比較ができないため、代わりにfingerprint
と呼ばれるものをユーザに提示する。
fingerprint
はホスト公開鍵をハッシュ化したもので、ホスト側は信頼できる方法でこれを予めユーザに伝えておく。(ただしWebサイトで適当に公開しているのが普通。)
fingerprintがおかしい場合は、変なサーバに接続しようとしている(中間者攻撃に遭っている)可能性がある。
でも偽サーバにはユーザの公開鍵が配置されていないから、結局SSHを確立できなくて安全では?
偽サーバにユーザの公開鍵が本当に無いのであれば、確かにSSHを確立できないので問題ない。
…本当に無いのであれば。
- もし何らかの方法で偽サーバがユーザ公開鍵を入手していたら…?
↑これを考えるのが妥当だろう。

authorized_keysファイルとは
これはサーバ側に用意するファイル。
クライアントの公開鍵が書かれてある。ここに載っていないとSSHを確立できない。