21.5. 公開鍵を使用したユーザー認証

SSH では、サーバーの公開鍵を使用したホスト認証が行われますが、ユーザー認証では通常のパスワード認証をそのまま使用しています。つまり、ログインプロンプトで入力するユーザー名とパスワードによって認証が行われます。これでも、平文でデータを送信する telnet などと比較すれば、通信は暗号化されていますのでパスワードが盗聴される危険性は低いといえますが、総当り(ブルートフォース攻撃)でパスワードを探り当てられる可能性は残ります。

SSH では、ユーザー認証においても公開鍵暗号方式を利用することで、本当に正しいユーザーがログインしようとしているのかを確認することができます。そのためには、事前の準備が必要です。ユーザーは自分の公開鍵と秘密鍵のペアを作成し、作成した公開鍵を接続するリモートホストへ事前に登録しておかなければなりません。リモートホスト側では、ユーザーが登録した公開鍵を使用して暗号化したデータをクライアントへ送信します。クライアントはそのデータをユーザーの秘密鍵で復号化し、サーバーへ送り返します。このとき、暗号化されたデータを復合化できるのは、公開鍵とペアの秘密鍵を持っているユーザーだけです。暗号化する前のデータとクライアントから返されたデータが一致していれば、ユーザーの認証は成立します。ここでは、ユーザーが鍵のペアを作成する方法とリモートホストへ公開鍵を登録する手順を解説します。

ユーザー鍵の生成

ユーザーが自分の秘密鍵と公開鍵のペアを作成するには、ssh-keygen コマンドを使用します。例えば、SSH v2 用の RSA 秘密鍵と RSA 公開鍵を生成するには、以下のように ssh-keygen コマンドに -t rsa オプションを指定して実行します。

ティップ

SSH v2 用の DSA 秘密鍵と公開鍵を生成するには、-t dsa オプションを指定します。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/taro/.ssh/id_rsa):

生成した鍵を保存するファイル名を問われますので、そのまま[Enter]キーを押します。次にパスフレーズの入力を要求されます。

Enter passphrase (empty for no passphrase): ←パスフレーズを入力
Enter same passphrase again: ←パスフレーズを再入力
Your identification has been saved in /home/taro/.ssh/id_rsa.
Your public key has been saved in /home/taro/.ssh/id_rsa.pub.
The key fingerprint is:
e2:57:0d:f5:d8:df:e1:ca:7e:f8:8e:7b:78:1f:12:b8 taro@server1.example.com

パスフレーズとはパスワードのようなものですが、パスワードより長い文字列を入力できます。スペースやその他の特殊文字も使用できるため、他人には分かりづらい文章などを入力するのもよいでしょう。また、たとえ秘密鍵が盗まれたとしても、パスフレーズを知らなければ秘密鍵を使用することはできません。つまり、秘密鍵自体もこのパスフレーズにより暗号化されています。

ティップ

そのまま[Enter]キーを押すと、暗号化されない秘密鍵が作成されますが、このように作成した秘密鍵はセキュリティ上問題がない用途でのみ使用するべきです。特別な事情がない限りは,必ずパスフレーズを入力してください。

パスフレーズを入力すると、ユーザーのホームディレクトリに .ssh ディレクトリが作成され、その中に 2 つのファイルが保存されます。id_rsa ファイルが SSH v2 用の RSA 秘密鍵であり、id_rsa.pub ファイルが公開鍵となります。なお、SSH v2 用の DSA 秘密鍵と公開鍵を生成した場合は、id_dsa が秘密鍵、id_dsa.pub が公開鍵となります。

公開鍵の登録

ssh-keygen コマンドで作成した公開鍵をリモートホストの ~/.ssh/authorized_keys ファイルへ登録します。~/.ssh/authorized_keys は、ユーザーの公開鍵を登録するための設定ファイルです。登録する鍵は公開鍵なので、どのような方法で登録しても構いません。以下の手順では、作成した SSH v2 用の RSA 公開鍵 ~/.ssh/id_rsa.pub を scp コマンドでリモートホストへコピーし、その後に cat コマンドで ~/.ssh/authorized_keys ファイルへ追記しています。scp については、項21.6 を参照してください。

リモートホスト sshsvr のホームディレクトリに .ssh ディレクトリが存在しない場合は作成しておきます。

$ ssh sshsvr 'mkdir ~/.ssh'

~/.ssh/id_rsa.pub をリモートホストの ~/.ssh ディレクトリに id_rsa.pub.client1 のファイル名でコピーします。

$ scp ~/.ssh/id_rsa.pub sshsvr:~/.ssh/id_rsa.pub.client1

~/.ssh/authorized_keys ファイルに公開鍵を追記します。

$ ssh sshsvr 'cat ~/.ssh/id_rsa.pub.client1 >> ~/.ssh/authorized_keys'

注意

~/.ssh/authorized_keys には他のクライアントで作成した公開鍵を登録している可能性もありますので、ファイルを上書きしてはいけません。

公開鍵によるログイン

公開鍵の登録完了後、ssh クライアントでリモートログインしてみます。

$ ssh sshsrv
Enter passphrase for key '/home/taro/.ssh/id_rsa': ← パスフレーズを入力

パスフレーズを要求されますので、鍵を生成したときに入力したパスフレーズを入力します。パスフレーズが正しければ、リモートホストへログインすることができます。

パスフレーズの記憶

頻繁にログインするリモートホストが存在する場合、ログインの度にパスフレーズを入力する手間を省きたいと考えるでしょう。ssh-agent と ssh-add コマンドを使用すると入力したパスフレーズをシェルに記憶させて、次回のログイン時から入力の手間を省くことができます。

はじめに、以下のコマンドを実行します。

$ ssh-agant $SHELL

次に、ssh-add コマンドを実行し、パスフレーズを記憶させます。

$ ssh-add
Enter passphrase for /home/taro/.ssh/id_rsa:
Identity added: /home/taro/.ssh/id_rsa (/home/taro/.ssh/id_rsa)

パスフレーズを要求されますので、パスフレーズを入力します。これで、次回のログイン時からパスフレーズを入力せずにリモートホストへログインすることができます。なお、記憶しているのは、このシェルだけです。シェルを終了すれば、再びパスフレーズの入力が必要です。