Last Updated at $Date: 2005/06/08 15:51:00 $.
SSH (Secure SHell) は, rsh/rlogin/rcp などの r 系コマンドを代替するために作られたプログラムです. 広く知られているように, r 系コマンドは認証手段が非常に貧弱なので,クラッカーの格好の標的となってしまいます. 対して,SSH は,公開鍵暗号に基づく強力な認証手段と通信路の暗号化により, 信用できないネットワーク上で安全な通信を行う方法を提供します.
2005年5月26日に OpenSSH 4.1 が公開されました.
セキュリティ上の理由から, アクセスを受け付けるホストを制限しているメールサーバーやニュースサーバーが増えています. このようなサーバーに接続する場合,SSH の Port Forwarding の機能を利用することによって, 特定のホストから通信しているように見せかけることができます. また,SSH は Port Forwarding の対象となるネットワーク接続を暗号化しますから, 様々な通信を安全に行うことが出来るようにもなります.
この方法の具体例については, FAQ の『4.8 ftp や POP などのサービスを安全にするために ssh が使えますか?』が大変参考になります.
portfwd.el
を使うと,Emacs 上で動作するプログラムの通信を
Port Forwarding によって中継することができます.
ただし,SSH によって作成された Port Forwarding 用の通信経路は, クライアント上の全ての local process から接続することができます. したがって,「クライアント上の全ての local user が信用できる」という環境でなければ, Port Forwarding の利用はセキュリティ上の危険を増加させる可能性があります.
fetchmail を使っている場合,~/.fetchmailrc
に以下のように記述すると,Port Forwarding を利用してメールを取得できます.
poll server via localhost port 8236 protocol apop preconnect 'ssh -f -P -C -L 8236:server:110 -l username server sleep 15 </dev/null >/dev/null 2>&1' username "username" password "password"
しかし,この方法では,
指定されたポート 8236 番が何らかの理由で使用中の場合にうまく接続できません.
遠隔サーバーに connect
がインストールされていれば,以下のような別の方法も利用できます.
poll server protocol apop plugin "ssh -C -l username %h connect localhost %p" username "username" password "password"
普段使っているコマンドなのに,SSH 経由で実行すると, 以下のようにエラーメッセージが出力されて実行できないことがあります.
[client:~]% ssh server command Command not found
この問題は,ログイン先のホストでシェルが実行されているかどうかの違いに原因があります.
あるホストにログインして対話的に利用する場合には,
通常のシェル初期化ファイル(~/.bashrc や ~/.cshrc
など)が読み込まれるので,環境変数 PATH は普段通りに設定されます.
しかし,この例のように単にコマンドを実行するだけの場合は,
ログイン先のホストではシェルは呼び出されないため,環境変数 PATH が設定されません.
その結果,普段使っているコマンドなのに見つからない,ということが起こります.
SSH はコマンド実行時の環境変数を ~/.ssh/environment
というファイルから読み込むようになっています.したがって,以下のコマンドを実行して,
~/.ssh/environment を用意しておくと,
普段通りの環境変数が設定されるようになり,コマンドもきちんと見つかるようになります.
[client:~]% ssh server [server:~]% printenv | egrep '^PATH=' > ~/.ssh/environment
しかし,NFS などでホームディレクトリを共有している異種混在環境にログインする場合には,
上述のような静的な手法では対処できません.最近の OpenSSH であれば,
~/.ssh/rc というファイルにシェルスクリプトを記述することができ,
そのような環境でも対応することができます.
以下は,私の使っている ~/.ssh/rc です.
if [ -d /var/lib/dpkg ]; then
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
else
PATH=/usr/local/bin/X11:/usr/local/bin:/usr/bin:/bin:/usr/ccs/bin:/usr/ucb
fi
if read proto cookie && [ -n "$DISPLAY" ]; then
if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
echo add unix:`echo $DISPLAY | cut -c11-` $proto $cookie
else
echo add $DISPLAY $proto $cookie
fi | xauth -q -
fi
なお,上記スクリプトの後半部分は,X11転送を処理するためのスクリプトです. 詳しくは sshd のマニュアルを参照してください.
OpenSSH には,単体で SOCKS 経由の通信を行う機能はありません. その代わりに,ProxyCommand というオプションを利用して, SOCKS サーバーに接続する外部プログラムを呼び出すことによって通信を行います.
ProxyCommand には,指定されたホスト・ポートに対する通信を標準入出力に
redirect するコマンドを指定します.そのようなコマンドとして,後藤さんによって作られた
connect
を利用することができます.具体的には,以下のように ~/.ssh/config
に設定します.
Host * ProxyCommand connect -S socks-server %h %p
防火壁よりも外のマシンに防火壁の中からログインする場合には,
一旦,防火壁のマシン(firewall.example.net)にログインしなければならない,
という状況は珍しくありません.そういう場合には,ssh と
connect
の組み合わせを ProxyCommand として利用すると,簡単に防火壁を越えることができます.
具体的には,以下のように ~/.ssh/config に設定します.
Host *.example.net ProxyCommand none Host *.* ProxyCommand ssh -C -x -e none firewall.example.net connect %h %p
逆に,防火壁よりも外のマシンから防火壁の中にログインする場合には,
以下のように ~/.ssh/config に設定します.
Host firewall.example.net ProxyCommand none Host *.example.net ProxyCommand ssh -C -x -e none firewall.example.net connect %h %p
防火壁のマシンに connect が正式にインストールされていない場合でも,
個人のホームディレクトリ以下にインストールして適切に環境設定すれば,
利用できます.
Hostbased 認証とは,登録済みのクライアントから接続があった場合は, そのクライアント上でのユーザー情報を信用して接続を許可する認証方式です. 多くのクライアントとサーバーが稼働しているサイトで適切に利用すると, ユーザーのパスワード入力の手間を減らすことができます. 設定手順は以下の通りです.
Hostbased 認証は,クライアントのホスト鍵,特に秘密鍵の秘匿性に基づいて認証を行っています. したがって,秘密鍵のファイル([client:~]# ssh-keygen -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key)の読み取り許可属性が適切に設定されていることを確認しておく必要があります.
[client:~]$ ls -l /etc/ssh/ssh_host_rsa_key -rw------- 1 root root 883 2002-01-01 12:00 /etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_config
に以下の設定を追加して,server に対して通信を行う時は
Hostbased 認証を利用するように指定します.
Host server HostbasedAuthentication yes
/etc/ssh/sshd_config
に以下の設定を追加して,Hostbased 認証を受け付けるように指定します.
以下は Hostbased 認証と直接の関係はありませんが,一般ユーザーによる Hostbased 認証の乱用を禁止するために設定しておくべき項目です.HostbasedAuthentication yes
IgnoreRhosts yes IgnoreUserKnownHosts yes RhostsAuthentication no RhostsRSAAuthentication no
[server:~]# ssh-keyscan -t rsa client,address >> /etc/ssh/ssh_known_hosts
[server:~]# echo client >> /etc/ssh/shosts.equiv
これで,クライアントからサーバーに対してパスワード入力を省略して ssh 経由でログインすることができるようになっているはず‥‥でしたが, 私は以下のような問題で苦労しました.
OpenSSH-3.4p1 はバグのために,Hostbased 認証が正常に機能しないようです. パッチを適用する必要があります.
ProxyCommand と Hostbased 認証は共存できません. ProxyCommand が設定されている状態で Hostbased 認証を行おうとすると,以下のようなエラーメッセージが表示されます.
% ssh server userauth_hostbased: cannot get local ipaddr/name
OpenSSH-3.6p1 以降は ProxyCommand の設定を無効化することができるらしいので, Hostbased 認証を行うホストを対象として ProxyCommand を無効化するという設定を試してみたのですが,手元では正しく動作しませんでした. したがって,現在のところ簡単な解決策はなく, ProxyCommand を利用するホストを小まめに指定するしかないようです.
Hostbased 認証には,クライアントの秘密鍵の情報が必要です.
通常,秘密鍵は root 以外は読み出せないようになっていますから,
OpenSSH は ssh-keysign という setuid root
された補助プログラムを利用して認証を行っています.
補助プログラムが setuid root されていないと, 以下のようなエラーメッセージが表示されました.
% ssh server could not open any host key ssh_keysign: no reply key_sign failed
Debian の場合は,dpkg-recongfigure ssh というコマンドを実行して, "Do you want /usr/lib/ssh-keysign to be installed SUID root?" という質問に「Yes」と答えると,適切な実行許可属性に設定されます. それ以外の環境では,以下のコマンドで修正できるでしょう.
# chmod u+s /usr/lib/ssh-keysign
久しぶりに,OpenSSH ではなく商用の SSH がインストールされている環境を使うことになったのですが, 公開鍵認証によるログインがうまくいかずに,かなり悩みました.
ssh-keygen -x -f ~/.ssh/id_rsa.pub > ~/id_rsa.pub
~/.ssh/authorized_keys に,全ての公開鍵を直接書き込みます.
公開鍵は全て個別に保存(例えば,~/.ssh2/id_rsa.pub)し,
そのファイルの場所を ~/.ssh2/authorization に書き込みます.
key id_rsa.pub
より詳しい情報は, 「OpenSSH と SSH の相互運用」や 「相互運用のための鍵管理」を参照してください.
クライアント側の設定に問題があると考えられる場合は, -v オプションを指定してクライアントを実行した結果を調べると原因が分かることがあります.
% ssh -v server
サーバー側の設定に問題があると考えられる場合は, -d -d -d オプションを指定してサーバーを実行した結果が有用です.
# /etc/init.d/ssh stop # /usr/sbin/sshd -d -d -d
SSH 対応版 impost は,最早,メンテナンスされていません.
メール/ニュースを送信する時の通信を, Port Forwarding を利用して中継できるように改造した impost です.
なお,impost は既に開発が終了しています. 後継版は imput と名前が変更され IM の一部となっています.
SSH 対応版 impost では,3つのオプションが拡張されています.
たとえば,次のようにオプションを指定すると,
-SMTPServer mail.example.net:8025 -NNTPServer news.example.net/6119:8119 -Clientname firewall.example.net
メールの場合は,
ssh -n -x -o BatchMode yes -L8025:mail.example.net:25 firewall.example.net
というコマンドを先に実行しておき,その上で localhost の8025番ポートにアクセスします.
そうすると,mail.example.net からみると,
この通信はあたかも firewall.example.net からの通信のように見えます.
同様に,ニュースの場合は,
ssh -n -x -o BatchMode yes -L8119:news.example.net:6119 firewall.example.net
となります.
localhost 上で使用するポート番号については,なるべく他のプログラムによって使用されないようなポートを指定してください. なお,指定されたポートが使用中の場合は,ポート番号を1つずつ順に増やして,未使用のポートを検索します.
SSH は,通信路を暗号化すると同時に,その通信路を経由する通信を圧縮する機能を持っています.
~/.ssh/config に以下の設定を加えておくと,常に圧縮されるようになります.
Host * Compression yes CompressionLevel 9
Gnus と impost を組合わせて使用する場合は,以下のように設定してください.
(setq news-inews-program (expand-file-name "~/bin/impost")
sendmail-program (expand-file-name "~/bin/impost"))
なお,~/.impostrc は,次のように設定しています.
mnews と impost の組合わせを利用する場合は,mnews によって付加された Path: ヘッダがおかしいというエラーメッセージが出力されて,送信できない場合があります. その場合は,このパッチを試してみてください. また,mnews と impost を組合わせて利用する方法について, 大塚さんが解説されています.
[Top] / [SSH について]