OpenSSHの公開鍵認証時の正常異常ログ比較の続編です。
前の記事では、SSHクライアントには秘密鍵"id_rsa_test"のみを配置して動作を確認しました。今回は、秘密鍵"id_rsa_test"と同フォルダに公開鍵"id_rsa_test.pub"を配置した状態で動作を確認してみます。
この記事には、以下の"会社で聞かれて答えたこと"のエッセンスが含まれています。
- 関連会社から送ってもらった鍵ファイルの、拡張子とファイル形式が合っていないようなので見てほしい
- どの形式のファイルを、どのアプリケーションが使えるのか
公開鍵ファイルがある場合とない場合の動作の違い
"秘密鍵ファイルだけを使った場合"と"秘密鍵ファイルと公開鍵ファイルの両方を使った場合"のログの、違いのある部分を抜粋します。大まかな違いを確認するため、デバッグレベル1で比較しています。
認証失敗パターンを使うと、違いが分かりやすいです。ここで試した認証失敗パターンは、サーバーの"authorized_keys"が読み込みできない状態&パスワード認証不可となっています。
ログの中で行頭に■を付けてある行が、差異のある行です。
"秘密鍵ファイルだけを使った場合"のログ
C:\Tmp>ssh -v -p 10022 -i id_rsa_test linuser@127.0.0.1 echo OK
:
debug1: Connecting to 127.0.0.1 [127.0.0.1] port 10022.
debug1: Connection established.
■ debug1: key_load_public: No such file or directory
■ debug1: identity file id_rsa_test type -1
debug1: key_load_public: No such file or directory
debug1: identity file id_rsa_test-cert type -1
:
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
■ debug1: Trying private key: id_rsa_test
■ debug1: read_passphrase: can't open /dev/tty: No such file or directory
■ Enter passphrase for key 'id_rsa_test':
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
linuser@127.0.0.1: Permission denied (publickey).
:
C:\Tmp>
"秘密鍵ファイルと公開鍵ファイルの両方を使った場合"のログ
C:\Tmp>ssh -v -v -p 10022 -i id_rsa_test linuser@127.0.0.1 echo OK
:
debug1: Connecting to 127.0.0.1 [127.0.0.1] port 10022.
debug1: Connection established.
■ debug1: identity file id_rsa_test type 0
debug1: key_load_public: No such file or directory
debug1: identity file id_rsa_test-cert type -1
:
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
■ debug1: Offering public key: RSA SHA256:shv7i4Upls8ekTl1bGFiZ/1o9P0zHRSKDgMvQznCxSU id_rsa_test
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
linuser@127.0.0.1: Permission denied (publickey).
:
C:\Tmp>
ログの違いの解説
前者のログに"Enter passphrase for key 'id_rsa_test':"と表示されていることに気が付くでしょう。これはパスフレーズの入力です。そして、後者ではパスフレーズの入力がありません。これが一番大きな違いです。
このタイミングで何が起こっているのでしょうか。
公開鍵認証の大まかな仕組みは、過去の記事で紹介したUnixUserの過去記事に記されています。公開鍵認証部分を抜粋すると、以下のような仕組みになっています。
- クライアントは、公開鍵を指定し、"指定した公開鍵に対応する秘密鍵"を持っていることをサーバーに通知する。
- サーバーは、指定された公開鍵を持っているかどうかを確認する。
- 持っていない場合は、指定された公開鍵を持っていないことをクライアントに通知する。
- この場合、クライアントはこの鍵ペアに対する処理を終了する。
- サーバーは、"指定された公開鍵に対応する秘密鍵を持っていることを証明して"とクライアントに促す。
- これが"チャレンジ"と呼ばれるもの
- クライアントは、"秘密鍵を持っていること"を証明するための情報を送る。
- これが"レスポンス"と呼ばれるもの
- サーバーは、クライアントからのレスポンスが正しいかどうかを判定する。
- レスポンスが正しい場合、"クライアントは正しい秘密鍵を持っている"と判断して、ログイン許可をクライアントに通知する。
- レスポンスが正しくない場合、ログイン許可できないことをクライアントに通知する。
- この場合、クライアントはこの鍵ペアに対する処理を終了する。
このうち、最初の処理でクライアントが準備すべきものは公開鍵です。
秘密鍵ファイル"id_rsa_test"に対する公開鍵ファイル"id_rsa_test.pub"が同じフォルダに置いてある場合、その公開鍵ファイル"id_rsa_test.pub"をそのまま公開鍵として使うことができます。
秘密鍵ファイル"id_rsa_test"に対する公開鍵ファイル"id_rsa_test.pub"が同じフォルダに置いてない場合、公開鍵を秘密鍵ファイル"id_rsa_test"から取り出す必要があります。この秘密鍵はパスフレーズ付きです。そのため、秘密鍵から公開鍵を取り出すためにはパスフレーズ入力が必要です。
公開鍵ファイル"id_rsa_test.pub"がある場合は、パスフレーズを入力しなくとも公開鍵を使用できます。対して、公開鍵ファイル"id_rsa_test.pub"がない場合は、パスフレーズを入力しないと公開鍵を使用できません。これがパスフレーズ入力有無の違いとなって表れているわけです。
鍵ファイルの形式
上の動きに密接に関連しているのが、前の記事でいただいたコメントで紹介されている記事"PuTTYの秘密鍵が独自形式な理由"およびそこから紹介されている"PuTTY wish key-formats-natively"です。
前の記事と紹介記事"PuTTYの秘密鍵が独自形式な理由"に記されている鍵ファイルのうち、よく見かけるファイル形式を列記してみます。
ファイル形式を見分けるための情報を先に記載します。その後、個々の形式を少しだけ掘り下げて説明します。
ファイル形式の見分け方
- OpenSSH秘密鍵ファイル(旧型式):OpenSSL-PEM形式
- 拡張子はなし
- ファイル冒頭に"BEGIN RSA PRIVATE KEY"と書かれた秘密鍵ファイル
- OpenSSH秘密鍵ファイル(新形式)
- 拡張子はなし
- ファイルの冒頭に"BEGIN OPENSSH PRIVATE KEY"と書かれた秘密鍵ファイル
- OpenSSH公開鍵ファイル
- 拡張子は".pub"
- "ssh-~"で始まる1行形式の公開鍵ファイル
- Putty秘密鍵ファイル:PPK形式
- 拡張子は".ppk"
- ファイル冒頭に"PuTTY-User-Key-File"と書かれた秘密鍵および公開鍵の鍵ペアファイル
訂正:ここに記載されていた"RFC4716形式"という記載は除去しました。
訂正:ここに記載されていた"Putty公開鍵ファイル"は除去しました。それに伴い、サブ節も除去しました。
Putty秘密鍵ファイル
Puttyの秘密鍵ファイルは、実際は"秘密鍵"と"公開鍵"がまとまっているファイルです。上のテストで使用したファイルをPPK形式に変換したものは、以下のようになっています。
C:\Tmp>type id_rsa_test.ppk
PuTTY-User-Key-File-2: ssh-rsa
Encryption: aes256-cbc
Comment: imported-openssh-key
Public-Lines: 6
AAAAB3NzaC1yc2EAAAADAQABAAABAQDQCWJn07n7TzKAoRcJvZ+QnV99Pc5NVbcB
:
4/iLYgX4GPq9LSjKuM0NgFCUK7kGS3XuGOJNSwLQcxvfoKTOtoIJ
Private-Lines: 14
fm7UYN2IWHW/pgKAa8hse9iyx9is8T9/60fPGcdQ0PqYMl/rXfvA7J4E+nIULxwL
:
woTdftnHEkLDqZUHktHMBJcjHnXn+p7l8dZdJyTdqfEJDRRO6fzoEVbLnkjkiFZG
Private-MAC: 59d4a5873be28c86b015f5a59f32326a6ead7ef8
C:\Tmp>
"Public-Lines:"で始まる部分が公開鍵、"Private-Lines:"で始まる秘密鍵、これらが同じファイルにまとまっています。そのため、パスフレーズ付きの鍵であっても公開鍵をパスフレーズ入力なしに取り出すことができます。試してみましょう。
Putty-GDIを使って接続したときのログは、以下のようになっています。
2020-04-24 10:08:37 Connecting to 127.0.0.1 port 10022
2020-04-24 10:08:37 We claim version: SSH-2.0-PuTTY_Unidentified_Local_Build
2020-04-24 10:08:37 Server version: SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2
2020-04-24 10:08:37 Using SSH protocol version 2
2020-04-24 10:08:37 Doing ECDH key exchange with curve Curve25519 and hash SHA-256
2020-04-24 10:08:38 Server also has ecdsa-sha2-nistp256/ssh-rsa host keys, but we don't know any of them
2020-04-24 10:08:38 Host key fingerprint is:
2020-04-24 10:08:38 ssh-ed25519 256 21:20:26:6e:01:58:31:06:87:63:c9:8e:21:e1:17:25
2020-04-24 10:08:38 Initialised AES-256 SDCTR client->server encryption
2020-04-24 10:08:38 Initialised HMAC-SHA-256 client->server MAC algorithm
2020-04-24 10:08:38 Initialised AES-256 SDCTR server->client encryption
2020-04-24 10:08:38 Initialised HMAC-SHA-256 server->client MAC algorithm
2020-04-24 10:08:38 Reading key file "D:\Tmp\id_rsa_test.ppk"
2020-04-24 10:08:38 Offered public key
2020-04-24 10:08:38 Server refused our key
2020-04-24 10:08:38 Disconnected: No supported authentication methods available (server sent: publickey)
秘密鍵ファイルの"D:\Tmp\id_rsa_test.ppk"を読み込んだ後、公開鍵を送信したことを表すログ"Offered public key"が表示されています。このとき、パスフレーズを入力していません。
この動きが、紹介記事"PuTTYの秘密鍵が独自形式な理由"にある"Puttyの秘密鍵の優位性"の一つです。
OpenSSH秘密鍵ファイル
OpenSSHの7.6以前の形式は"OpenSSL-PEM形式"(以下単にPEM形式)、OpenSSHの7.7以降は別の独自形式となっています。
前回の記事で使用していた形式は"PEM形式"でした。CentOS 7.7を使用していたためです。CentOS 7に"yum install"されるOpenSSHは7.4です。そのため、旧型式の秘密鍵となっています。
この鍵を新形式に変換してみます。
[linuser@localhost tmp] $docker run -itd --name tmp centos:8
f1390bf25a3ff9e12a7218afc67c7dc1c234e90ff53d2edf5d7d2358f2a55ff9
[linuser@localhost tmp] $docker exec tmp yum -y install openssh-clients > /dev/null 2>&1
[linuser@localhost tmp] $docker exec tmp ssh -V
OpenSSH_8.0p1, OpenSSL 1.1.1c FIPS 28 May 2019
[linuser@localhost tmp] $cat id_rsa_test
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,824850D9B060D4CD6FB1A9AB0AC7ABB0
DzmmOEGVleY76yfLLbbx1gEG7EHabHWxoVWipPVpbJOpOAAlqw1PgRi3DCJJNuIE
:
H8twA2qLWzeneSmqSrHBheV/o1aMHwxmyksBau5qPfDXEio2U8Tni3AQhUxMRbks
-----END RSA PRIVATE KEY-----
[linuser@localhost tmp] $docker cp id_rsa_test tmp:/tmp/id_rsa_test
[linuser@localhost tmp] $docker exec -it tmp ssh-keygen -p -f /tmp/id_rsa_test -N ABCDEFG
Enter old passphrase:
Your identification has been saved with the new passphrase.
[linuser@localhost tmp] $docker cp tmp:/tmp/id_rsa_test id_rsa_test_new
[linuser@localhost tmp] $cat id_rsa_test_new
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAji9Pn5q
:
iCkeiisg==
-----END OPENSSH PRIVATE KEY-----
[linuser@localhost tmp] $docker stop tmp
tmp
[linuser@localhost tmp] $docker rm tmp
tmp
[linuser@localhost tmp] $
鍵ファイルの冒頭に"BEGIN OPENSSH PRIVATE KEY"と書かれています。これで新形式となりました。
但し、新形式でも同じフォルダに公開鍵ファイル"id_rsa_new.pub"ファイルがない場合の動きは、旧型式の場合と同じです。実験結果は全く同じなので省略します。
アプリケーションの対応
秘密鍵ファイルの、アプリケーションの対応状況を記します。
アプリケーション | OpenSSH旧型式 | OpenSSH新形式 | Putty形式 | 備考 |
---|---|---|---|---|
OpenSSH-7.6以前 | ○ | ○ | - | 但し新形式への対応は6.5以降 |
OpenSSH-7.7以降 | ○ | ○ | - | |
Putty-GDI-20191001 | - | - | ○ | PuTTYgenの対応状況ではない |
WinSCP-5.7.2 | - | - | ○ | |
RLogin-2.25.0 | ○ | ○ | ○ |
あまりに古いアプリケーションは、OpenSSH新形式には対応していないと考えていいでしょう。ED25519などへの対応も同様です。もっとも、セキュリティ関連のアプリケーションを古いまま使うこと自体がどうなのかという話はあります。
まとめ
今回は、以下のことを説明しました。
- "ssh -i"で秘密鍵を読み込むとき、同じフォルダに公開鍵があるかどうかで、どのように動作が変わるか
- Puttyだとどのように動作するのか
- OpenSSHとPuttyで秘密鍵はどのように違うのか、なぜPuttyはOpenSSHと異なる形式を用いているのか
- アプリケーションの秘密鍵形式への対応