Open6

SSHの基礎を調べるよ

takamin55takamin55

背景・経緯

なんか久しぶりに古いノート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ホストキーを更新したことが原因らしい。

https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/

さて、手順通りやれば問題なくgit pullが打てるようになったが、こういう時にちょこちょこ出てくるfingerprintknown_hostsファイルなど、SSH周りのことを理解していないなーと思ったので調べる。

takamin55takamin55

やっていき。色々再確認していく。

ssh-keygenコマンド

https://www.man7.org/linux/man-pages/man1/ssh-keygen.1.html

authentication keys for sshを生成したり管理したりするコマンド。
基本的な方法でコマンドを実行すると、知っての通り2種類のファイルが生成される。

拡張子なしファイルとpubファイル

拡張子なしファイルはいわゆる「秘密鍵」
.pub拡張子のファイルはいわゆる「公開鍵」

takamin55takamin55

ホスト認証とユーザ認証

SSHの仕組みは2種類の認証が存在する。
なんか適当に手順通りやっているだけでは、ユーザ認証しか意識しないことになってしまってSSHを理解できなくなる()

  • ホスト認証
    • 今からSSHで接続する先(ホスト)が本当に正しいかどうかを確認する
  • ユーザ認証
    • 今からSSHで接続する先(ホスト)にログインできるユーザかどうかを確認する
takamin55takamin55

ユーザ認証の仕組み(簡易版)

  1. 公開鍵を予めサーバに登録する
  2. ローカル(クライアント)には秘密鍵がある。公開鍵・秘密鍵の特性上、秘密鍵で公開鍵の暗号を解くことができるので、ユーザの判定(認証)ができる。ログインも許可する。

※詳細の流れは後ほど学ぶ。

まぁこれはなんとなく知っている話。このときの、ローカル(クライアント)側に秘密鍵がある鍵ペアのことをユーザーキーと呼んだりする。ユーザーキーとか言いながらペアのことを指すので注意。

で、もちろん秘密鍵が漏れたら終わり。

これが一般的だが、一応パスワード認証方式もある。まさにホスト側にあるログインユーザのパスワードを入れることで認証する。パスワードが分かれば誰でも入れるので基本使用しない。

takamin55takamin55

ホスト認証の仕組み(簡易版)

こっちも公開鍵暗号方式を使っている。
鍵ペアはクライアント側だけにありそうなイメージ(GitHubとかを意識せずにセッティングしているとそう見えがち)だが、サーバ側にも鍵ペアが存在する。

  1. 接続の確立前に、サーバは公開鍵をクライアントに返す
  2. クライアント側は、known_hostsの中と送られてきた公開鍵を見比べて、サーバが確かに正しいことを確認する

※これだけだと偽サーバが真サーバの公開鍵を偽装して返せば終わりじゃん、と思われるが、この後SSH確立の過程で暗号・復号を実際に行う際に結局秘密鍵がない偽サーバはバレる。

known_hostsに記載がない初回は特殊な過程がある。

比較ができないため、代わりにfingerprintと呼ばれるものをユーザに提示する。
fingerprintはホスト公開鍵をハッシュ化したもので、ホスト側は信頼できる方法でこれを予めユーザに伝えておく。(ただしWebサイトで適当に公開しているのが普通。)

fingerprintがおかしい場合は、変なサーバに接続しようとしている(中間者攻撃に遭っている)可能性がある。

でも偽サーバにはユーザの公開鍵が配置されていないから、結局SSHを確立できなくて安全では?

偽サーバにユーザの公開鍵が本当に無いのであれば、確かにSSHを確立できないので問題ない。
…本当に無いのであれば。

  • もし何らかの方法で偽サーバがユーザ公開鍵を入手していたら…?

↑これを考えるのが妥当だろう。

takamin55takamin55

authorized_keysファイルとは

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