SSHでサーバーに接続した際、以下のような表示(フィンガープリント)がされ、サーバーへ本当に接続して良いか確認されることがあります。
本記事では、どうしてそのような表示がされるのか、またどのようにフィンガープリントを活用すべきなのかを解説します。
$ ssh -p 2222 vagrant@127.0.0.1
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is SHA256:1pOx1qnpCf9UfJQPVaMRfJV/6LZkHWQXljHwwYGlN1g.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
フィンガープリントとは
SSH接続におけるフィンガープリントとは、サーバー(接続先)の公開鍵から計算されたハッシュ値
です。
これはフィンガープリントという名の通り、サーバーの指紋となります。
SSH接続ではその過程でホスト認証というものが行われますが、フィンガープリントはその際に使用されます。
ホスト認証とは
ホスト認証とは、sshでクライアントがサーバーに接続する際に、そのサーバーが本当に接続したいサーバーかを確認する技術のことです。
要するに、ホスト認証とはサーバーのなりすましを防ぐためのしくみです。
ホスト認証には公開鍵が使われます。
クライアントがSSHでサーバーに接続すると、まずそのサーバーの公開鍵が送られてきます。
クライアントは事前にサーバーから入手した公開鍵を、この鍵と同じであるかを比較し、相手のサーバーが接続したいサーバーであるか確認を行います。
ここで事前にサーバーから公開鍵を入手すると述べましたが、その際にフィンガープリントを使用します。
フィンガープリントの使われ方については、次章で解説します。
公開鍵の比較後、同じものと確認できればクライアントはランダムなデータを生成し、それをサーバーの公開鍵を使って暗号化したうえでサーバーに送信します。
なぜこのような処理をするかというと、公開鍵の突き合わせだけではまだ本物のサーバーかどうか判断しきれないからです。
公開鍵というのは誰でも入手できる鍵なので、偽物のサーバーが本物のサーバーの公開鍵を送りつけている可能性があります。
そこで接続先サーバーにある秘密鍵を使って、本当に本物のサーバーであるかを確認します。
公開鍵で暗号化したデータはそれに紐づく秘密鍵でしか復号できません。
秘密鍵というのは盗まれたり、意図的に複製しない限りはどこにも公開されず、その持ち主のサーバーにのみ存在します。
その性質を利用して、公開鍵で暗号化したデータをサーバーへ送信し、そのデータをサーバーに秘密鍵で復号させ、復号した結果を再びクライアントに送付することでサーバーが本物であるかを確認します。(正確にいえば復号したデータのハッシュ値を求め、そのハッシュ値をクライアントに送ります)
クライアントは、サーバーから送られてきたデータが暗号化前のデータと同じであれば本物のサーバーであると判断し、通信を開始します。
フィンガープリントが使われるタイミング
上記ホスト認証の解説で、クライアントは事前にサーバーの公開鍵を入手しておきという解説をしましたが、事前に公開鍵を入手していない場合どのようになるのでしょうか?
ここでフィンガープリントの出番です。
接続先のサーバーの公開鍵が未入手の状態でSSH接続を行うと、冒頭で紹介したようなメッセージがコンソールに表示されます。
$ ssh -p 2222 vagrant@127.0.0.1
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is SHA256:1pOx1qnpCf9UfJQPVaMRfJV/6LZkHWQXljHwwYGlN1g.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
フィンガープリントとは接続先サーバーの公開鍵のハッシュ値です。
このハッシュ値をサーバーで事前に確認しておくことで、公開鍵が未入手の状態でも相手のサーバーが本物であると確認できる仕組みが、SSH接続におけるフィンガープリントの役割です。
フィンガープリントは人間が目検できるように比較的短い文字列になっています。
サーバー上でフィンガープリントを確認する
サーバーの公開鍵はCentOS 8の場合、/etc/ssh
に保存されています。
秘密鍵がssh_host_rsa_key
、公開鍵がssh_host_rsa_key.pub
です。
[root@centos8 ssh]# ls /etc/ssh
moduli sshd_config ssh_host_rsa_key
ssh_config ssh_config.d ssh_host_rsa_key.pub
サーバーに配置されている公開鍵に対して、次のコマンドを実行すると公開鍵のハッシュ値(フィンガープリント)を確認できます。
[root@centos8 ssh]# ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
3072 SHA256:1pOx1qnpCf9UfJQPVaMRfJV/6LZkHWQXljHwwYGlN1g no comment (RSA)
先ほどクライアントからSSHコマンドを実行した際に表示されたフィンガープリントが次のものです。同じハッシュ値となっていますね。
$ ssh -p 2222 vagrant@127.0.0.1
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is SHA256:1pOx1qnpCf9UfJQPVaMRfJV/6LZkHWQXljHwwYGlN1g.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
上記画面でyes
と入力し、enterを押すとサーバーの公開鍵がクライアントに保存され、次回からは上記のような質問がされずSSH接続を行うことができます。
$ ssh -p 2222 vagrant@127.0.0.1
vagrant@127.0.0.1's password:
Last login: Sat Aug 21 19:33:19 2021 from 10.0.2.2
[vagrant@centos8 ~]$
サーバーの公開鍵は、MacやLinuxの場合、~/.ssh/known_hosts
に保存されます。
cat /Users/hogeuser/.ssh/known_hosts
[127.0.0.1]:2222 ssh-rsa AAAAB3NzaC1yc2EXXXXDAQABAAABgQCnPfWMvfuCx7NmQqBMUkCE/BXo1yOBg2GETYb9Z938xxufMomNQaTlslG+gHwtpVwqtSCNt9UgulwM0BdoEA9Iy0Y11bmLs3njfDhky+EbZd8tj7FkTNLKi36jWeOeFUuDakTeawnLPPk15JdDR0cADEKL08zK7Kf0jinEvPm0roPBewEgFFeZ98WLXXxx3N0qA8ihKL23YPLdIY6wNuXlSG7ZpuwjLStMutzUlsW4AdK3MsA4scGOPhv0nRpXnRTWANTa1reAXZgNxFxxxxXOFCSP458cQF8/tvMe6/djOB4oSLslE+knLF7DDfPb9IisJ45A/+rQp2q0VOwdhPdWD/wXgUfzzVLECJT6T3PwXqTZ8iYOpVsQdZ0SYPgT99qazWFtaXsWocp492HxECModVIsxWiOrGsABsVdbqneqzKNxfIGGlDoadIyv+C4DBZgu/kR5r4itIbuyKYDYKL2rGf47QrtpL3fXoQynwxx4IiPY9pBNqnlUB3VG1Va+BE=
サーバーの鍵が変更された場合
初回接続以降にサーバーの公開鍵が変更された場合、sshコマンド実行時に警告が表示されます。
試しにサーバーの公開鍵を変更してみましょう。
まず、現在の公開鍵のフィンガープリントを確認します。
[root@centos8 ssh]# ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
3072 SHA256:1pOx1qnpCf9UfJQPVaMRfJV/6LZkHWQXljHwwYGlN1g no comment (RSA)
次に公開鍵を変更します。
公開鍵を変更するには、サーバーから秘密鍵と公開鍵を削除して、sshd再起動します。
[root@centos8 ssh]# rm -f /etc/ssh/ssh_host_rsa_key
[root@centos8 ssh]# rm -f /etc/ssh/ssh_host_rsa_key.pub
[root@centos8 ssh]# service sshd restart
再びフィンガープリントを確認すると、公開鍵が再作成されたため内容が変更されていることを確認できます。
[root@centos8 ssh]# ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
3072 SHA256:1Cj2czt6gXJtQHCxY99LUnZ88FQ3XFsJRXN6DtOmfCg no comment (RSA)
この状態でクライアントからSSH接続を行うと次のような警告が表示されます。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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:1Cj2czt6gXJtQHCxY99LUnZ88FQ3XFsJRXN6DtOmfCg.
Please contact your system administrator.
Add correct host key in /Users/hogeuser/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/hogeuser/.ssh/known_hosts:21
RSA host key for [127.0.0.1]:2222 has changed and you have requested strict checking.
Host key verification failed.
(base) mbp:.ssh hogeuser$
このようなメッセージが初回接続以降に表示された場合は、サーバーの公開鍵が変更されたか、あるいはサーバーのなりすましの可能性があるので、どうして公開鍵が変更されたのかをよく確認しましょう。
今回のように、サーバーの公開鍵を意図的に修正したとわかっている場合は、ローカル端末の~/.ssh/known_hosts
から、変更前のサーバーの公開鍵を削除することでサーバーに再接続できます。
$ vi known_hosts
# ↓接続先サーバーのIPアドレス(とポート)が記載されている行を削除する
[127.0.0.1]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCnPfWMvfuCx7NmQqBMUkCE/BXo1yOBg2GETYb9Z938xxufMomNQaTlslG+gHwtpVwqtSCNt9UgulwM0BdoEA9Iy0Y11bmLs3njfDhky+EbZd8tj7FkTNLKi36jWeOeFUuDakTeawnLPPk15JdDR0cADEKL08zK7Kf0jinEvPm0roPBewEgFFeZ98WLDGgw3N0qA8ihKL23YPLdIY6wNuXlSG7ZpuwjLStMutzUlsW4AdK3MsA4scGOPhv0nRpXnRTWANTa1reAXZgNxF002kmOFCSP458cQF8/tvMe6/djOB4oSLslE+knLF7DDfPb9IisJ45A/+rQp2q0VOwdhPdWD/wXgUfzzVLECJT6T3PwXqTZ8iYOpVsQdZ0SYPgT99qazWFtaXsWocp492HxECModVIsxWiOrGsABsVdbqneqzKNxfIGGlDoadIyv+C4DBZgu/kR5r4itIbuyKYDYKL2rGf47QrtpL3fXoQynwxx4IiPY9pBNqnlUB3VG1Va+BE=
対象行を削除してsshコマンドを実行すると、初回接続時と同じメッセージが表示されるのでyesと答えます。
ssh -p 2222 vagrant@127.0.0.1
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is SHA256:1Cj2czt6gXJtQHCxY99LUnZ88FQ3XFsJRXN6DtOmfCg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
そうすると新しい公開鍵がknown_hosts
に保存されるため、次回以降はこの質問が表示されなくなります。
$ ssh -p 2222 vagrant@127.0.0.1
vagrant@127.0.0.1's password:
Last login: Sat Aug 21 19:34:40 2021 from 10.0.2.2
[vagrant@centos8 ~]$