Q. ssh, slogin, scp, sftp を使うたびに、毎回パスワード/パスフレーズを
入力するのが面倒なのですが、省略することは出来ませんか?
A. 面倒な作業を楽にするためには、何らかの形でマシンに接続情報を残すことに
なります。そのマシンがクラックされた場合、いもづる式に他のマシンも
クラックの対象になってしまいます。セキュリティに対して責任を持てる場合
以外は楽をするべきではありません。このことを認識したうえでお読み下さい。
なお、この QandA の内容は OpenSSH のバージョン 2.9 以降に基づいています。
(OpenSSH2.9 は FreeBSD 4.5-RELEASE および 4.6-RELEASE に付属しています。)
古いバージョンの OpenSSH や、他の SSH の実装 (ports の security/ssh 等)
では、一部の機能が使えなかったり、設定方法が異なる場合があります。
SSH で使われる認証方法を分類すると以下のようになります。
A. パスワード認証
PasswordAuthentication (SSH1, SSH2)
B. 公開鍵認証
PubkeyAuthentication (SSH2)
RSAAuthentication (SSH1)
C. ホストベース認証
HostbasedAuthentication (SSH2)
RhostsRSAAuthentication (SSH1)
D. その他
このうち、公開鍵認証やホストベース認証を使っている場合は
パスワード/パスフレーズの入力を省略することができます。
[公開鍵認証の場合]
公開鍵認証を行なうためには、まず認証鍵の作成が必要です。
[管理番号 1948] [管理番号 1949] を読んで認証鍵の設定をして下さい。
秘密鍵は絶対に洩れてはいけない情報ですので、ファイルに記録される際は
安全性を考えて鍵作成時に入力したパスフレーズによって暗号化されています。
ssh 接続時にパスフレーズの入力を求められるのは、認証を行なうために
暗号化された秘密鍵を復号する必要があるからです。
そこで、あらかじめ復号済みの秘密鍵を記憶しておくことで
接続のたびにパスフレーズを入力する手間を省いてくれる
ssh-agent というコマンドが用意されています。
もちろん、復号済みの秘密鍵は ssh-agent プロセスのメモリ内だけに
記憶されているので、メモリの内容を直接覗かれたりしない限り
秘密鍵が洩れる心配はありません。
ssh-agent を利用するには以下の 2 つの手順が必要です。
1. ssh-agent を起動する。
2. ssh-add を使って、秘密鍵を復号し ssh-agent に登録する。
1. ssh-agent を起動する。
ssh-agent の起動方法は 2 つあります。
ひとつは
% ssh-agent tcsh
として新しいシェルを起動する方法です。
この場合、新しく起動したシェルの中からだけ ssh-agent の機能を
利用することができます。シェルが終了すると ssh-agent も
自動的に終了します。
もうひとつは
% eval `ssh-agent -c`
% ...(ssh-add, ssh, scp 等の利用)...
% eval `ssh-agent -c -k`
として、現在のシェルに対し ssh-agent の情報を eval によって
伝える方法です。この場合は、ssh-agent は自動的には終了しないので
eval `ssh-agent -c -k` で終了させるのを忘れないようにして下さい。
また、bash や zsh など sh 系のシェルを使っている場合は
ssh-agent -c の代わりに ssh-agent -s と指定して下さい。
2. ssh-add を使って、秘密鍵を復号し ssh-agent に登録する。
ssh-agent が起動できたら、続いて認証鍵の登録を行ないます。
引数に秘密鍵のファイル名を指定して ssh-add を実行して下さい。
% ssh-add ~/.ssh/identity
パスフレーズを入力してやれば鍵の登録は完了です。
また、X を使用している場合は
% ssh-add ~/.ssh/identity < /dev/null
とすることで GUI のパスフレーズ入力ウインドウを開くことができます。
ただし、あらかじめ port/package から security/openssh-askpass を
インストールしておく必要があります。
ssh-agent の起動と認証鍵の登録が終れば、パスフレーズを入力することなく
ssh, scp 等が利用できるようになります。
上記の手順をさらに自動化する方法も紹介します。
a. pam_ssh を使う。
4.6-RELEASE からは、pam_ssh module を使うことが出来ます。
/etc/pam.conf を適切に設定してやれば、
ログイン時に ssh-agent の起動や認証鍵の登録を、
ログアウト時に ssh-agent の終了を自動で行なってくれるようになります。
/etc/pam.conf の xdm 部分の設定例は次のようになります。
xdm auth required pam_unix.so
xdm auth optional pam_ssh.so use_first_pass
xdm account required pam_unix.so
xdm session optional pam_ssh.so
xdm session required pam_permit.so
xdm password required pam_deny.so
このように設定し、UNIX パスワードと同じパスフレーズで
SSH の秘密鍵を作成しておくと、ログイン時に自動で
ssh-agent が起動し、その秘密鍵が登録されるようになります。
また、起動した ssh-agent はログアウト時に自動的に終了します。
詳しくは、pam_ssh(8), pam.conf(5) を参照して下さい。
b. スタートアップスクリプトで ssh-agent を起動させる。
pam_ssh を使わない場合は、~/.login 等のスタートアップスクリプトで
ssh-agent を起動する方法があります。
コンソールからログインしている人は、~/.login の最後に
eval `ssh-agent -c`
としておいて、~/.logout に
eval `ssh-agent -c -k`
と書いておくとよいでしょう。
xdm を使用している人は ~/.xsession に
-----------
#!/bin/sh
eval `ssh-agent -s`
twm & # ウィンドウマネージャを起動
PID=$!
...(kterm などの起動)...
wait $PID # ウィンドウマネージャの終了を待ち
eval `ssh-agent -s -k` # ssh-agent を kill
-----------
と書いたり、
-----------
#!/bin/sh
xrdb .Xresources
exec ssh-agent fvwm # ウィンドウマネージャを ssh-agent の制御下で起動
-----------
と書いておくとよいでしょう。
次に、ssh-add でパスフレーズを入力しなければいけませんが
-----------
#!/bin/sh
if [ -z "${SSH_IDENT}" ]; then
SSH_IDENT="${HOME}/.ssh/identity"
fi
if [ -n "${SSH_AUTH_SOCK}" -a -z "${SSH_CLIENT}" -a -f "${SSH_IDENT}" -a -f "${SSH_IDENT}.pub" ]; then
FINGERPRINT=`ssh-keygen -l -f "${SSH_IDENT}.pub" | awk '{print $2}'`
if ! ssh-add -l | grep "${FINGERPRINT}" >/dev/null; then
if [ -z "${DISPLAY}" -o -z "${SSH_ASKPASS}" ]; then
ssh-add "${SSH_IDENT}"
else
ssh-add "${SSH_IDENT}" </dev/null
fi
fi
fi
exec "/usr/bin/${0##*/}" "$@"
-----------
というスクリプトを ~/bin/{ssh,slogin,scp,sftp} に置いておけば
(PATH の先頭に ~/bin を加えておく)、初回のみ自動的に
パスフレーズを聞いてきて ssh-add で鍵を登録してくれるように
なります。
また、X を使用している場合は、スタートアップスクリプト内で
ssh-add < /dev/null も実行させるのもよいでしょう。
[ホストベース認証の場合]
ホストベース認証とは、リモートマシンの ~/.shosts に、
パスワード無しでのログインを許可するホスト名とユーザ名を
指定する方法です。
rsh(1) や rlogin(1) とよく似ていますが、通信路を暗号化したり、
ホスト鍵を用いた認証でなりすましを防止したりするので、
安全な接続を行なうことができます。
ホストベース認証はデフォルトでは無効になっているので、
利用するにはあらかじめ設定を変更しておく必要があります。
まず、リモートマシンの /etc/ssh/sshd_config に以下のように記述し、
sshd を再起動させます。
-----------
# SSH2 プロトコルを使用する場合
HostbasedAuthentication yes
# SSH1 プロトコルを使用する場合
RhostsRSAAuthentication yes
# これは安全でない認証方法なので yes にしてはいけない
RhostsAuthentication no
# ~/.shosts および ~/.rhosts を有効にするために必要
IgnoreRhosts no
-----------
次に、ローカルマシンの /etc/ssh/ssh_config に以下のように記述します。
-----------
# SSH2 プロトコルを使用する場合
HostbasedAuthentication yes
PreferredAuthentications hostbased,publickey,password
# SSH1 プロトコルを使用する場合
RhostsRSAAuthentication yes
-----------
さらに、ホストベース認証を利用するにはローカルマシンの ssh の
バイナリが root に setuid されていなければなりません。
root になって以下のコマンドを実行して下さい。
# chmod 4555 /usr/bin/ssh
OpenSSH 3.3 以降で SSH2 を利用している場合は、特権が必要な処理が
ssh-keysign というコマンドへ分離されたので、ssh の代わりに
こちらを setuid します。
# chmod 4511 /usr/libexec/ssh-keysign
以上でホストベース認証自体の有効化は終わりですので、次に
各ユーザ毎に必要な手順を説明します。
まず、リモートマシンの ~/.shosts にログインを許可する
ホスト名とユーザ名をスペースで区切って記述します。
ユーザ名は省略可能で、その場合はリモートマシンと同じ名前の
ユーザを許可することになります。
たとえば、~hoge/.shosts に以下のように記述したとすると
local.example.ne.jp のユーザ hoge と somewhere.example.ne.jp の
ユーザ fuga に対してログインを許可することになります。
-----------
local.example.ne.jp
somewhere.example.ne.jp fuga
-----------
最後に、~/.ssh/known_hosts(known_hosts2) にログインを許可したホストの
ホスト鍵を登録します。この作業は、リモートマシンからローカルマシンへ
ssh で一度ログインすれば自動的に行なうことができます。
以上の設定が完了すると、パスワードを入力することなく ssh 等を
利用できるようになります。
グループ名: ssh