OpenSSH のような複雑なソフトウェアで問題が発生した場合、 その原因をつきとめるのは時に多くの労力を要することがあります。 本章では OpenSSH のインストールから運用に至るまでの さまざまな状況に対して、原因の追及と対策を考えていきます。
本節では OpenSSH をソースコードからコンパイルしたときに発生する症状とその解決方法を説明します。
OpenSSH は暗号化のために OpenSSL ライブラリを使用しています。
ソースコードから OpenSSH をコンパイルする場合、このライブラリは必要不可欠です。
./configure
スクリプトを実行中に、
以下のようなエラーが出た場合、OpenSSL がインストールされていない可能性があります:
またはconfigure: error: OpenSSL version header not found.
configure: error: *** Can't find recent OpenSSL libcrypto (see config.log for details) ***
このような場合は OpenSSL 公式サイト [脚注: http://www.openssl.org/ ] からダウンロードして インストールしてください。
ライブラリをインストールしたにもかかわらず、以下のようなエラー
が表示された場合は、複数個の OpenSSL がシステムの別々の場所にインストールされていてconfigure: error: Your OpenSSL headers do not match your library.
./configure
スクリプトがお互いに異なるバージョン用の
ライブラリファイルとインクルードファイルを発見したことが原因だと思われます。
このような場合 --with-ssl-dir
オプションでパスを指定してください。
なお、ディストリビューションによっては最初から OpenSSL のインクルードファイルと
ライブラリファイルのバージョンが違っていることがあり、
このような場合には OpenSSL をインストールしなおす必要があります。
./configure
スクリプトを実行中に、
次のようなエラーが表示されることがあります。
configure: error: *** zlib too old - check config.log *** Your reported zlib version has known security problems. It's possible your vendor has fixed these problems without changing the version number. If you are sure this is the case, you can disable the check by running "./configure --without-zlib-version-check". If you are in doubt, upgrade zlib to version 1.2.3 or greater. See http://www.gzip.org/zlib/ for details.
通常 configure
はシステムにインストールされている zlib のバージョンを検査し、
それが脆弱性のあるバージョン (1.2.2
以前) の場合は続行を拒否します。
しかし多くのシステムではセキュリティ・アップデートにより zlib の脆弱性が回避されたあとも、
互換性を保つために zlib のバージョン番号を変更せず以前のままにしておく傾向があります。
このような場合、オペレーティングシステムのベンダーなどが配布する最新のセキュリティ・アップデートを適用して
システムの zlib に脆弱性がないことを確信できるのであれば、
--without-zlib-version-check
オプションをつけて警告を回避してください。
configure
の --with-xxx
オプションで
特定の機能を有効化する指定を行なった場合、通常はその機能を組みこむために必要なライブラリがないとエラーが発生します。
しかし configure
では未知の --with-xxx
オプションがあっても
エラーを出さないため、 --with-xxx
オプションをタイプミスすると
そのオプションは単に無視され、最後に表示されるメッセージで指定したはずの機能が yes にならないことがあります。
このような場合は configure
に与えるオプションに間違いがないかどうか確認してください。
sshd
サーバデーモンは起動時に致命的なエラーが発生すると
すぐに終了します。このエラーは標準エラー出力に表示されることもあり、
ログファイルに残されることもあります。たいていの場合は、標準エラー出力の内容や、
/var/log/messages
または /var/log/syslog
などに記録されている
ログに残されたメッセージを見ることで原因が判明します。
ログファイルの例:
Mar 25 21:47:53 server sshd[43656]: error: Bind to port xxxx on 0.0.0.0 failed: Address already in use. Mar 25 21:47:53 server sshd[43656]: fatal: Cannot bind any address.
以下のようなメッセージが表示される場合は、sshd_config
設定ファイルに
文法上の誤りがあります。このような場合は表示された行を確認してください。
/etc/ssh/sshd_config: line 120: Bad configuration option: asswordAuthentication
代表的なメッセージ:
Bad configuration option
garbage at end of line
#
' 記号を使ってください。
Unsupported option
UsePAM
設定項目を指定するとこのエラーが発生します。
Bad yes/no argument
yes
あるいは no
を
指定すべきところでそれ以外の文字列が指定されています。
missing file name
missing port number
などほかにも数種類あります。
sshd
の初期化に関するエラーCould not load host key
(ホスト鍵が読み込めない)sshd
が起動するには、最低ひとつのホスト秘密鍵ファイルが必要です。
通常 sshd
の設定ファイル用ディレクトリには、
SSH1 プロトコル用の秘密鍵・公開鍵ペアが一組と、SSH2 プロトコル用の
秘密鍵・公開鍵ペアが二組 (RSA 用と DSA 用それぞれ一組ずつ) 格納されているはずです (2.2.2. 設定ファイルのファイル構成を調べる 参照)。
sshd_config
の HostKey
設定項目を確認してください。
なお、sshd_config
で HostKey
設定項目をまったく指定しない場合は
ホスト秘密鍵ファイルのデフォルトのパス名が検索されますが、
HostKey
設定項目をひとつでも指定した場合、これらデフォルトのパス名は
すべて無視されますので注意してください。
また、sshd
はホスト秘密鍵がひとつでも見つかれば
動作を開始しますが、特定のプロトコル (SSH1 あるいは SSH2) 用の
ホスト秘密鍵が見つからない場合、そのプロトコルの使用は禁止されます。
sshd re-exec requires execution with an absolute path
(sshd の実行には絶対パス名の指定が必要)sshd
をコマンドラインから実行する場合に、
/usr/sbin/sshd
などと絶対パス名を指定しなかった場合に発生します。
絶対パス名は、sshd
プロセスに SIGHUP シグナルを送って再起動する際に
sshd
プロセスが自分自身を再実行するために必要です。
PRNG is not seeded
(乱数源が初期化されていない)sshd
が乱数を生成するために使用する
/dev/urandom
ファイルが存在していない場合に発生します。
sshd
を chroot環境で実行している場合は、このデバイスファイルを作成してください。
Privilege separation user sshd does not exist
(特権分離用のユーザ sshd が存在していない)sshd
はクライアントからの接続時に特権分離 (privilege separation) された
子プロセスを fork します。このとき子プロセスの sshd
は "sshd
" というユーザ名の
権限で実行されますが、このユーザ名が /etc/passwd
ファイル中に存在しない場合にこのエラーが発生します。
通常、このユーザは FreeBSD や Mac OS X ではデフォルトで含まれており、
Red Hat や Solaris では OpenSSH をパッケージからインストールするさいに自動的に作成されます。
なんらかの理由で作成されない場合はソースコード中の README.privsep
ファイルを
参照してユーザ sshd
を作成してください。
Missing privilege separation directory: /var/empty/sshd
(特権分離用のディレクトリが存在していない)/var/empty/sshd
ディレクトリは、特権分離された子プロセスが動作するのに必要です。
通常、このディレクトリは OpenSSH のインストール時に自動的に作成されます。
Bind to port xxx on 0.0.0.0 failed: Address already in use.
(指定されたポート番号が使用できない)Cannot bind any address.
(どのアドレスも使用できない)sshd
デーモンが同じポート番号で動いていないか確認してください。
また、ユーザ権限で sshd
を実行している場合は 1023番以下のポートは利用できませんので、
sshd_config
の Port
設定項目を書き換えてください。
OpenSSH のクライアントやサーバが期待どおりの動作をしない場合は、
できるだけ多くの情報を集めることが必要です。 OpenSSH に含まれている
ssh
や sshd
などのコマンドにはデバッグ用の
オプションが用意されているので、これらのオプションを与えて実行してみてください。
ssh
をデバッグモードで実行する
ssh
を、コマンドラインから実行するさいに
-v
オプションを与えるとデバッグ出力を表示できます。
-v
オプションを繰り返し指定すると、指定回数に比例して詳細な出力を得ることができます。
最高 3つまでの -v
オプションがサポートされています。
ssh をデバッグモードで実行する |
---|
$ ssh [-v [-v [-v]]] [オプション] 引数1 引数2 ... |
実行例:
$ ssh -v yusuke@server.example.com OpenSSH_4.3p2, OpenSSL 0.9.7e-p1 25 Oct 2004 debug1: Reading configuration data /home/yusuke/.ssh/config debug1: Applying options for server.example.com debug1: Applying options for * debug1: Reading configuration data /etc/ssh/ssh_config debug1: Connecting to server.example.com [xx.xx.xx.xx] port xx. debug1: Connection established. debug1: identity file /home/yusuke/.ssh/id_rsa type 1 debug1: Remote protocol version 1.99, remote software version OpenSSH_4.3 debug1: match: OpenSSH_4.3 pat OpenSSH* debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_4.3 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received ...
ssh
コマンドでデバッグ出力を表示した場合、
以下のようにサーバ側からのデバッグ情報が表示されることがあります。
ここに含まれる「debug1: Remote: X11 forwarding disabled in user configuration file.
Remote:
」という文字列は、
これがリモートホストからの情報であることを示しています。
このような情報は原因の追及に役立ちますが、一般的に OpenSSH ではセキュリティ向上のため
サーバ側がクライアント側に情報を渡すことはほとんどありません。
したがって、ログインできない場合はおもに
サーバ側のログを見て原因を追及する必要があります。
sshd
をデバッグモードで実行する
sshd
サーバデーモンは、
コマンドラインから -d
オプションを与えて直接実行することにより
デバッグモードで実行できます。-d
オプションを与えられると、サーバはバックグラウンドに移行せず、
標準エラー出力にデバッグ出力を表示します。
最高 3つまでの -d
オプションがサポートされています。
また sshd はデバッグモードではクライアントからの接続を一度だけしか受けつけず、
クライアントの接続が切れるとすぐに終了します。
なお sshd
サーバデーモンの起動時には必ずフルパス名を指定する必要があります。
すでに sshd
が動作中で再起動できない場合は、
/var/log/messages
や /var/log/syslog
などに記録されている
ログ出力を見ることも有用です (5.5.2. sshd
のログを見る も参照してください)。
sshd をデバッグモードで起動する |
---|
$ /絶対パス名/sshd [-d [-d [-d]]] [オプション] |
実行例:
# /usr/sbin/sshd -d debug1: sshd version OpenSSH_4.3p2 debug1: read PEM private key done: type RSA debug1: private host key: #0 type 1 RSA debug1: read PEM private key done: type DSA debug1: private host key: #1 type 2 DSA debug1: rexec_argv[0]='/usr/sbin/sshd' debug1: rexec_argv[1]='-d' socket: Address family not supported by protocol debug1: Bind to port xxx on 0.0.0.0. Server listening on 0.0.0.0 port xxx. ...
ユーザが ssh
コマンドを実行してから
sshd
サーバデーモンがログインを許可するまでには
多くの段階が存在し、さまざまな設定ファイルが介在しています。
図 openssh-layers はログインまでの各段階で関連する設定ファイルを
それぞれクライアント側とサーバ側とでまとめたものです。
ssh
コマンドを実行してもまったく反応しないか、
あるいは
"Connection refused
"、
"Name or service not known
"
といったエラーが表示され、すぐに終了してしまう場合は、
sshd
サーバデーモンへの TCP 接続が可能かどうか確認してください。
まず sshd
サーバデーモンが接続を待ち受けている TCPポート番号を調べ、
telnet 相手先ホスト ポート番号
などと実行して、
OpenSSH のバージョン情報
(SSH-1.99-OpenSSH_4.3
、SSH-2.0-OpenSSH_4.3
など)
が返されるかどうかを確認します。
$ telnet server.example.com 22 Trying xx.xx.xx.xx... Connected to server.example.com. Escape character is '^]'. SSH-1.99-OpenSSH_4.3
このようなメッセージが現れない場合は、以下のことを確認してください。
ifconfig -a
コマンドを実行して、
ネットワークインターフェイスが起動しているかどうか確かめてください。
また、IPアドレスが DHCP によって割り当てられている場合は、
正しい IPアドレスが割り当てられていることを確認してください。
ping
コマンドを使ってネットワーク接続を確認してください。
"No route to host.
" というエラーが出た場合は、
netstat -rn
と実行してルーティングテーブルが正しく設定されているかどうかを確認します。
ただしファイヤーウォールあるいは途中のルータの設定によっては、
ping パケットには反応しないこともあるので注意してください。
"Unknown host.
" というエラーが出た場合は
DNS が正しく機能していない可能性があるので、
/etc/hosts
や /etc/resolv.conf
などの
設定をチェックしてください。
Connection refused.
" エラーが出た場合は、
ファイヤーウォールの設定が正しくないか、あるいは接続する TCP ポート番号が
間違っている可能性があります。
サーバ側の sshd_config
における Port
設定項目を確認してください。
/etc/hosts.allow
と /etc/hosts.deny
、
および sshd_config
設定ファイルの ListenAddress
設定項目があります。
これらがクライアントの IP アドレスから接続を許可するように設定されていることを
確認してください。
クライアントがサーバに接続してから
以下のようなメッセージが表示される場合は、認証以前の段階で
SSH プロトコル上のトラブルが発生しています。
この場合はクライアント側の
~/.ssh/config
個人設定ファイル (あるいは ssh_config
設定ファイル)
および、サーバ側の sshd_config
設定ファイルを確認してください。
Protocol major versions differ: 1 vs. 2
(プロトコルのバージョンが異なっている)Protocol
設定項目および
サーバ側の Protocol
設定項目を確認してください。
なお、サーバ側の HostKey
設定項目で
指定されたホスト秘密鍵ファイルが読み込めない場合は、
たとえ Protocol
設定項目が正しく設定されていても、
そのバージョンのプロトコルが使用できなくなります。
no matching cipher found: client arcfour server arcfour256,...
(暗号化アルゴリズムが一致しない)Ciphers
設定項目を確認してください。
no matching comp found: client zlib server none,zlib@openssh.com
(圧縮アルゴリズムが一致しない)Compression
設定項目で、
OpenSSH 4.2 からサポートされた新しい圧縮方式を意味する値 delayed
が指定されている場合、
古いバージョンの ssh
から圧縮を許可して接続したときにこのエラーが発生することがあります。
このような場合はクライアント側で Compression no
を指定するか、
サーバ側の Compression
設定項目を delayed
以外の値に変更してください。
デフォルトの OpenSSH の設定では、
クライアントがユーザ認証に成功してサーバにログインすると
/etc/motd
のメッセージや
前回ログインした時刻が表示されます。
クライアント側で以下のように表示される場合は、
サーバ側のユーザ認証が失敗したことを示しています。
$ ssh yusuke@server.example.com Permission denied (publickey,password,keyboard-interactive,hostbased).
この場合は、まず (…)
内に表示されている文字列を確認してください。
これらはサーバ側が許可している認証方式で、それぞれ
公開鍵認証 ("publickey
")、
パスワード認証 ("password
")、
PAM を経由したパスワード認証 ("keyboard-interactive
")、
Hostbased認証 ("hostbased
")
を表します。
クライアントとサーバの双方で正しい認証方法を許可しているか確認してください。
それぞれ該当する設定項目をクライアント側とサーバ側の両方で yes
に設定する必要があります。
PubkeyAuthentication
設定項目を yes
に設定する。
PasswordAuthentication
設定項目を yes
に設定する。
HostbasedAuthentication
設定項目を yes
に設定する。
また、特定のユーザ (例えば yusuke) がログインできたかどうかはサーバ側の
"Accepted publickey for yusuke ...
",
"Accepted password for yusuke ...
" などのログ項目で確認することができます。
ユーザがログインできていない場合は、サーバ側で以下を確認してください。
/etc/passwd
で正しく設定されていますか?sshd
はそのユーザ (例えば yusuke) のログインを拒否し、
"User yusuke not allowed because shell /sbin/nologin is not executable
"
のようなメッセージがログに記録されます。
/etc/passwd
においてそのユーザのパスワード欄が禁止されていませんか?*
" や "!!
" といった文字列になっている場合、
sshd
はそのユーザのアカウントが完全に禁止されているとみなします (5.3.2. 公開鍵認証を使っているユーザのパスワード認証を禁止する 参照)。
sshd_config
設定ファイルの
AllowGroups
や AllowUsers
、
DenyGroups
、DenyUsers
などの設定項目 (5.2.2. 特定のユーザのログインを禁止する 参照) によって禁止されていませんか?User yusuke from 127.0.0.1 not allowed because none of user's groups are listed in AllowGroups
"
などのメッセージが残されます。また root がログインする場合は
PermitRootLogin
の値も調べる必要があります (5.2.3. Root のログインを禁止する 参照)。
ユーザが公開鍵認証でログインできない場合、以下のような原因が考えられます。
sshd
プロセスが、
ログインしようとしているユーザの権限でそのホームディレクトリにアクセスできていますか? ~/.ssh/authorized_keys
ファイルが存在しており、
正しいパーミッションに設定されていますか? authorized_keys
ファイルが
(そのユーザ以外の) 誰にでも書きこめるようになっている場合、
sshd
サーバデーモンは公開鍵認証の使用を拒否します。
これは登録された公開鍵が書き換えられている可能性があるためです。
この場合、サーバのログには
"Authentication refused: bad ownership or modes for directory /home/yusuke/.ssh
"
といったエラーが記録されます。
なお authorized_keys
ファイルのパーミッションだけでなく、
~/.ssh/
ディレクトリのパーミッションもログインの可否に影響するということに注意してください。
なぜなら、~/.ssh/
ディレクトリが誰にでも書き込めるようになっている場合 (world-writable)、
他のユーザが authorized_keys
ファイルを新しく作成できてしまう危険があるからです。
authorized_keys
ファイルに正しく 1行につきひとつの公開鍵が登録されていますか?authorized_keys
ファイルをテキストエディタなどで編集した場合、予期せず行が途中で
分かれてしまったり、余計な文字列が混入してしまう場合があります。
authorized_keys
ファイル中の公開鍵のオプションに余計な文字列が入っている場合は、
サーバのログに
"Bad options in /home/yusuke/.ssh/authorized_keys file
"
などのエラーが記録されます。
authorized_keys
ファイルに登録されている公開鍵に from="..."
オプションを
指定している場合、その制限は正しいですか?Authentication tried for yusuke with correct key but not from a permitted host (host=xx.xx.xx.xx, ip=yy.yy.yy.yy).
"
などのエラーが記録されます。
authorized_keys
ファイルに登録されている公開鍵に強制コマンド実行オプション
(command="..."
オプション) を指定している場合、そのコマンド文字列は正しく実行されていますか?bash: コマンド名: command not found
"
などのエラーが表示される場合は、強制コマンドで指定されたプログラムが見つからない可能性があります。
~/.ssh/id_rsa
または ~/.ssh/id_dsa
) の
パーミッションは正しいですか? ssh
コマンドは以下のようなメッセージを表示してその秘密鍵の使用を拒否します。
client$ ssh yusuke@server.example.com @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0777 for '/home/yusuke/.ssh/id_rsa are too open. It is recommended that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: /home/yusuke/.ssh/id_rsa Enter passphrase for /home/yusuke/.ssh/id_rsa:
なお、この問題は秘密鍵ファイルのパーミッションだけでなく、
~/.ssh/
ディレクトリのパーミッションも影響するということに注意してください。
なぜなら、~/.ssh/
ディレクトリが誰にでも書き込めるようになっている場合 (world-writable)、
他のユーザが別の id_rsa
ファイルを新しく作成できてしまう危険があるからです。
ssh
コマンドを実行する際に
秘密鍵が正しくエージェントに登録されていますか? ssh-add -l
コマンドを実行してください。
"Could not open a connection to your authentication agent.
" などのメッセージが表示された場合は、
認証エージェントと通信できていないことを示しています。
認証エージェントが動作しており SSH_AUTH_SOCK
環境変数の値が
正しく設定されているかどうかを確認してください。
-A
オプションを指定するか、
ForwardAgent
設定項目に yes
を指定します。
また、サーバ側の ~/.ssh/authorized_keys
ファイル中の
公開鍵のオプションに no-agent-forwarding
オプションが指定されていないかどうかを
確認してください。
Hostbased 認証がうまく動かない場合には、以下のような原因が考えられます。
ssh_config
設定ファイルで
EnableSSHKeysign
が yes
に設定されていますか?yes
に設定されていない場合、ssh
コマンドの実行時に以下のようなエラーが発生します。
client$ ssh yusuke@server.example.com ssh-keysign not enabled in /etc/ssh/ssh_config ssh_keysign: no reply key_sign failed
ssh_host_rsa_key
または ssh_host_dsa_key
) は
ssh-keysign
プログラムによって
正しく利用できるようになっていますか?ssh-keysign
プログラムは setuid root されています。
ホスト秘密鍵ファイルが利用できない場合は以下のようなエラーが発生します。
client$ ssh yusuke@server.example.com could not open any host key ssh_keysign: no reply key_sign failed
shosts.equiv
ファイルは正しく設定されていますか?userauth_hostbased mismatch: client sends client.example.com, but we resolve 11.22.33.44 to 11.22.33.44
"
などのメッセージが記録されている場合は、shosts.equiv
ファイルに
正しい IP アドレスが設定されていない可能性があります。いっぽう、
sshd_config
設定ファイルの UseDNS
設定項目が
yes
になっている場合には、
"userauth_hostbased mismatch: client sends client, but we resolve 11.22.33.44 to client.example.com
"
などのメッセージが残されます。この場合 shosts.equiv
ファイルには
IP アドレスではなく FQDN で表されたホスト名を指定する必要があります。
ssh_known_hosts
ファイルに登録されていますか?ssh
のデバッグ出力に
Remote: Accepted for xx.xx.xx.xx [xx.xx.xx.xx] by /etc/ssh/shosts.equiv.
というメッセージが表示された場合は、その IP アドレスがサーバの shosts.equiv
ファイルで
許可されていることを示していますが、公開鍵を使ったホスト間の認証が正しく行われない場合
ログインは許可されません。
本節では通常のログインが成功した後に起きるトラブルについて説明します。
通常、X11転送が使える場合は、サーバにログインすると
環境変数 DISPLAY
に "localhost:10.0
"
などの値が設定されています。サーバ上で X11 アプリケーションがうまく動作しない場合には
以下のような原因が考えられます。
DISPLAY
が正しく設定され、xterm
などの
アプリケーションが動くことを確認してください。
X11Forwarding
設定項目が
yes
になっている必要があります。加えて、
クライアントで ssh
コマンドを実行する際に
-X
オプションをつけるか、あるいは ~/.ssh/config
個人設定ファイル中の ForwardX11
設定項目に yes
を指定しなくてはなりません。
また、サーバ側の ~/.ssh/authorized_keys
ファイル中の
公開鍵のオプションに no-x11-forwarding
オプションが指定されていないかどうか
確認してください。
xauth
コマンドが使えるようになっていますか?sshd
は X11 転送を開始するさいに、サーバ上の
xauth
コマンドを使ってローカルな Xサーバに対する権限を設定します。
ssh
コマンドのデバッグ出力に
"Remote: No xauth program; cannot forward with spoofing.
"
と表示されるか、あるいはログイン時に
"Warning: No xauth data; using fake authentication data for X11 forwarding.
"
などと表示される場合は xauth
が正しく実行できていないことを示しています。
サーバ上の xauth
パスが標準的でない場合は sshd_config
設定ファイルの
XAuthLocation
設定項目で正しいパス名を指定してください。
.Xauthority
ファイルが
作成できるようになっていますか?.Xauthority
ファイルが書き込めない設定となっていると、
/etc/motd
の内容と前回のログイン時刻が表示されたあとに処理が止まってしまうことがあります。
このような場合は X11 転送を禁止するか、そのユーザのホームディレクトリにファイルが
書き込める状態になっていることを確認してください。
X Error of failed request: ...
" などのエラーが出る場合は、
そのアプリケーションが安全でない X11 の描画コマンドを使用しようとしていることを示しています。
このようなアプリケーションを使用する場合は ssh
コマンドの実行時に
-Y
オプションを指定するか、~/.ssh/config
個人設定ファイルで
ForwardX11Trusted yes
を指定してください。
ポート転送や VPN は通常のシェルとは独立して起動されます。
ポート転送が正しく実行されている場合、
ローカル→リモート (L) のポート転送ではクライアント上で、
リモート→ローカル (R) のポート転送ではサーバ上で、
netstat -an
コマンドを実行すれば、
それぞれ listen しているポート番号が表示されます。
ポート転送がうまく動かない場合は、以下のような原因が考えられます。
AllowTcpForwarding
設定項目が
yes
になっている必要があります。
また、サーバ側の ~/.ssh/authorized_keys
ファイル中の
公開鍵のオプションに no-port-forwarding
オプションが指定されていないことも確認してください。
なお、このオプションが指定されている場合、ssh
コマンドのデバッグ出力に
"Remote: Server has disabled port forwarding.
"
というメッセージが表示されます。
また、root 権限以外のプロセスが 1023番以下のポートを開くことはできません。
(開こうとすると "Privileged ports can only be forwarded by root.
" というエラーが表示されます。)
bind: Address already in use
"
というエラーが表示される場合は、転送 (bind) したいポートがすでに
クライアント上あるいはサーバ上で別のプロセスによって開かれていることを示しています。
ssh
コマンドの
GetewayPorts
設定項目を、
リモート→ローカル (R) のポート転送ではサーバ上の
sshd_config
設定ファイルの GetewayPorts
設定項目を、
それぞれ yes
に設定しておく必要があります。
通常、 GetewayPorts
設定項目が no
に設定されている場合は、
netstat -an
でポートを確認すると bind している IP アドレスは
127.0.0.1
になっています。
GetewayPorts
設定項目を yes
に設定すると
このアドレスは 0.0.0.0
になり、どのホストからでも
このポートに接続できるようになります。
VPN のトンネリングが動かない場合は、クライアント側で
ssh
コマンドのデバッグ出力に以下のようなエラーが表示されます。
sys_tun_open: failed to open tunnel control interface: No such device
(tun
デバイスが存在しない)tun
デバイスをサポートしており、
/dev/net/tun
デバイスが存在するかどうかを確認してください。
debug1: Remote: Failed to open the tunnel device.
(サーバ側がトンネリングの開始に失敗した)tun
デバイスをサポートしており、
/dev/net/tun
デバイスが存在することを確認してください。
debug1: Remote: Server has rejected tunnel device forwarding
(トンネリングが禁止されている)PermitTunnel
設定項目が no
に設定されているか、
あるいはクライアント側の Tunnel
設定項目で指定されたトンネリングと合致しない場合に発生します。
どちらか、あるいは双方の設定ファイルを書き換えてトンネリングの種類を一致させるようにしてください。
リモートホストのシェルからログアウトした際、
ssh
コマンドが終了せずに止まってしまうことがあります。
これは
ssh
コマンドがリモートホスト上で実行したプロセスがすべて終了するのを待っているために起こります。
ここでいう「プロセス」とはサーバ上のシェルから実行したすべての
フォアグラウンドおよびバックグラウンドのプロセス、それから
X11 転送やポート転送、および VPN トンネリングも含まれます。
ssh が止まってしまう例:
client$ ssh yusuke@server.example.com ... server$ sleep 10 & (sleep コマンドをバックグラウンドで実行する) server$ exit (ログアウトする) logout (ssh が止まってしまう)
このような場合は、ssh
コマンドに SIGHUP シグナルを
送って強制的に終了するか、あるいはエスケープシーケンスを使って
ssh
コマンドをバックグラウンドに移行させることができます
(4.1.3. 公開鍵認証でログインする 参照)。
ssh
が止まってしまったあとでも端末からの入力はまだ受けつけられていますので、
チルダ文字 (~
) のあとにピリオド (.
) を押すと ssh
は終了し、
チルダ文字のあとに Control-Z を押すと ssh
はバックグラウンドに移行します。
なお、 ssh
を強制的に終了させても、リモートホスト上の
バックグラウンド プロセスは終了しません。
また、リモートホストにおいてコマンドをバックグラウンドで実行させるときに、
そのプロセスの標準入出力をすべて端末から切り離した状態にしておくと、
このような現象は発生しません。具体的には、プロセスの実行時に
そのプロセスの標準入力、標準出力、標準エラー出力をすべて
特定のファイルかあるいは /dev/null
にリダイレクトしておけばよいのです。
こうすることにより、そのプロセスが端末に対して入出力をおこなわ
ないことが保証されるため、ssh
はそのプロセスの完了を待たずに終了できるのです。
プロセスを端末から切り離す:
client$ ssh yusuke@server.example.com ... server$ sleep 10 >/dev/null 2>&1 </dev/null & (sleep コマンドを端末から切り離した状態で実行する) server$ exit (ログアウトする) logout client$
ssh
以外のコマンド
(sftp
、rsync
、cvs
など) で
OpenSSH に関連したエラーが発生する場合、おもに以下の 2つの原因が考えられます。
ssh: ...
" というエラーメッセージが表示される場合:ssh
コマンド上で接続あるいは認証のエラーが発生した。
bash: ...: command not found
" というエラーメッセージが表示される場合:
これらのエラーが発生した場合、呼び出された ssh
はすぐに終了します。
たいていのプログラムは ssh
を単なる TCP 接続の代わりとして使っているために、
このような場合は「データが送られて来ない」「0バイトしか転送されない」といった
エラーメッセージを表示し、とくにそれが OpenSSH によるものかどうかを区別しません。
したがって、これらのエラーが発生した場合は、まず通常の ssh
コマンドで
サーバに正しくログインできるかどうかを確認してください。サーバにログインできる場合は、
そのアプリケーションが実行するであろうコマンドがサーバ上で正しく実行できるかどうかを
確かめてください。ssh
コマンドを使う
各アプリケーションの代表的なエラーメッセージを以下に示します。
client$ scp yusuke@server.example.comm ssh: server.example.comm: hostname nor servname provided, or not known (sshでログインできない) client$ scp yusuke@server.example.com bash: scp: command not found (サーバ上でリモートコマンドが実行できない)
client$ sftp yusuke@server.example.comm ssh: server.example.comm: hostname nor servname provided, or not known (sshでログインできない) client$ sftp yusuke@server.example.com bash: sftp: command not found (サーバ上でリモートコマンドが実行できない) Request for subsystem 'sftp' failed on channel 0 Couldn't read packet: Connection reset by peer
client$ rsync -a yusuke@server.example.comm:/opt/yusuke backup ssh: server.example.comm: hostname nor servname provided, or not known (sshでログインできない) rsync: connection unexpectedly closed (0 bytes read so far) rsync error: error in rsync protocol data stream (code 12) at io.c(189) client$ rsync -a yusuke@server.example.com:/opt/yusuke backup bash: rsync: command not found (サーバ上でリモートコマンドが実行できない) rsync: connection unexpectedly closed (0 bytes read so far) rsync error: error in rsync protocol data stream (code 12) at io.c(189)
client$ cvs -d :ext:yusuke@cvs.example.comm:/cvs checkout docs ssh: cvs.example.comm: hostname nor servname provided, or not known (sshでログインできない) cvs [checkout aborted]: end of file from server (consult above messages if any) client$ cvs -d :ext:yusuke@cvs.example.com:/cvs checkout docs bash: cvs: command not found (サーバ上でリモートコマンドが実行できない) cvs [checkout aborted]: end of file from server (consult above messages if any)
client$ svn checkout svn+ssh://yusuke@svn.example.comm/svn/pyvnc2swf/ ssh: svn.example.comm: hostname nor servname provided, or not known (sshでログインできない) svn: Connection closed unexpectedly client$ svn checkout svn+ssh://yusuke@svn.example.com/svn/pyvnc2swf/ bash: svnserve: command not found (サーバ上でリモートコマンドが実行できない) svn: Connection closed unexpectedly
コラム - 公開鍵認証がすべて安全とは限らない |
---|
公開鍵暗号技術はユーザ認証や電子署名に広く用いられていますが、
じつはこれを正しく使うのは簡単ではありません。使い方をまちがえると、
簡単にユーザのなりすましができてしまうことがあるのです。
たとえば初期の SSH プロトコルでは、クライアントは公開鍵認証のさいに サーバに対するレスポンスとして「秘密鍵の証明(K) + ユーザ名(U) + 現在時刻(T)」を 送っていました。現在時刻を送る必要があるのはなぜかといと、 もしここに現在時刻が含まれていない場合、第三者はこの情報を覚えておいて、 あとで同じ情報をサーバに送りつけることでログインできてしまうからです。 この情報は暗号化されているため、第三者が解読したり改ざんしたりすることはできませんが、 盗聴した情報を覚えておいてあとで再利用することを 「再送攻撃 (repetition attack)」と呼びます。 初期の SSH プロトコルはこの種の単純な再送攻撃を防ぐように設計されてはいましたが、 じつは別の再送攻撃を受けてしまう欠陥がありました。ユーザが異なるサーバ 1 と サーバ2 に対して 同じ公開鍵 A を使っていたと仮定します。第三者はユーザがサーバ 1 にログインする瞬間、 サーバ 2 にもチャレンジを送り、サーバ 1 に送られたのとまったく同じ レスポンスをサーバ 2 に送ることで、サーバ 2 にログインできてしまうのです。 第三者が暗号を解読する必要はありません。 これはレスポンスを受け取るサーバが、「そのレスポンスがどこに宛てられたものか」 を判定できないために起こる問題です。 したがって現在の SSH プロトコルでは、クライアントはレスポンスに受けとり先のサーバ名も含ませた 「秘密鍵の証明(K) + ユーザ名(U) + 現在時刻(T) + ログインするサーバ名(S)」を 送るようになっています。こうすればサーバは自分以外に向けられたレスポンスを検出し、 受け取りを拒否することができるからです。このような暗号の使い方に関する 一連の仕組みは「暗号プロトコル」と呼ばれ、現在もさかんに研究がされています。 しかしこの例から見ても、本当に安全な暗号プロトコルを考案するのは 困難な作業であることがわかります。 図 repetition-attack. 第三者がレスポンスを再利用する 参考文献: Martin Abadi and Roger Needham, "Prudent Engineering Practice for Cryptographic Protocols," SRC Research Report 125, 1994. |