パスワード無しでSSH
www.ssh.com の ssh (有料) は対象外
2001-07-10 作成 福島
2001-08-11 更新 福島
2001-08-16 更新 福島
2001-10-21 更新 福島
2002-03-18 更新 福島
2002-07-20 更新 福島
TOP > tips > ssh-shosts
OpenSSH 2.9p1 で .shosts を使用するときの注意点
・.shosts は ssh protocol 1 のみ有効 (ssh protocol 2 では取り扱わないので注意)
指定方法は以下のいずれか
1. sshd_config (サーバ側設定ファイル) に
Protocol 1
あるいは
Protocol 1,2
と記述する
ssh, scp コマンドに有効
2. ssh (クライアントプログラム) に -1 オプションをつける
ssh コマンドに有効
3. ssh_config (クライアント側設定ファイル) に
Protocol 1
と記述する
ssh コマンドに有効
・クライアント側のポート番号は 512 <= X < 1024 の範囲であること
限定しなくても良いような気がするが…。
理由は良く分からないが、接続元の root しか使えないポートからアクセスしないと接続先で弾かれる。
(コメントには、「侵入者に root を取られた時にはこのポートも使われてしまう」云々が書いてあった)
これを回避するためにはオプション
UsePrivilegedPort yes
を ssh_config (クライアント側コンフィグ) に指定する。
コマンドラインからの指定は
ssh -o 'UsePrivilegedPort yes'
ssh protocol 1 を指定した場合、大きなポート番号でも接続できます。
sshd_conf, ssh_conf のありか
/etc/ssh/*
/usr/local/etc/*
のどちらか。
sshd -f /etc/ssh/sshd_conf 等としての起動も可。
sshd_config を更新した後は sshd デーモンのリスタートが必要。
/usr/local/etc/sshd_config の注意点
PidFile /var/run/sshd.pid PID ファイル名 (/var/run/sshd.pid がデフォルト)
Port 22 ポート番号 (22 がデフォルト)
PermitRootLogin no root のログインは禁止 (no を指定)
IgnoreRhosts no ~/.rhosts ~/.shosts を無視しない (no を指定)
RhostsAuthentication no ~/.rhosts を有効にしない (no を指定)
RhostsRSAAuthentication yes ~/.shosts を有効にする (yes を指定)
#AllowHosts host.trust.com SSH 2.9 には存在しない
AllowUsers TargetUserID 特定のユーザ ID を有効にする
|
AllowUsers を指定すると、他のユーザが自動的に DenyUsers になるので注意!!
.shosts が指定してあっても、DenyUsers であれば無視される(ログインできない)
~/.ssh/authorized_key 0644
・~/.shosts の使い方 (誰を自分とみなすかを記述する)
TargetUserID@target.servers.com <- Visitor1@host.trust1.com ---(a)
TargetUserID@target.servers.com <- Visitor2@host.trust2.com ---(b)
を許可する場合
target.servers.com:/home/TargetUserID/.shosts 0600
host.trust1.com Visitor1 ---(a)
host.trust2.com Visitor2 ---(b)
|
ログインコマンドは
host.trust1.com:Visitor1$ ssh -1 -o 'UsePrivilegedPort yes' -l TargetUserID target.servers.com
とする。(青字はプロンプトです)
相手の公開鍵 (互いのサーバ鍵、ユーザ鍵) がそれぞれ必要
1.ローカル、リモート共に相手サーバの公開鍵が必要。(.ssh/known_hosts 0644)
ssh や slogin でログインしたときに公開鍵を登録するかを聞いてくるので、
これを互いに行うことで登録できる。
それが出来ないときは、/usr/local/etc/ssh_host_key.pub をコピーし、適宜修正して .ssh/known_hosts に加える
xxxxx...xSPrrr@hostnameLF
というフォーマットなので、(xxxxx...x は公開鍵、rrr@hostname は管理者アドレス)
FQDN,IPSPxxxxx...xLF
というフォーマットに変更して格納すれば良い。 (FQDN はコピー元のホスト名、IP はコピー元の IP アドレス)
SP は空白 1 文字
LF は改行 1 文字
※ログイン時には、パスワードを入力する前に公開鍵の登録を聞いてくる。
つまり、ログインは出来なくても良い。(→ パスワードが設定されてなくても可)
※ protocol 1 を使用するため、コマンドは ssh -1 を使用します。
そうしないと .ssh/known_hosts に登録できません。
※ .ssh/known_hosts2 は protocol 2 のファイルです。混同し易いので注意。
2.ローカル、リモート共に相手ユーザの公開鍵が必要。(.ssh/authorized_keys 0644)
互いに相手の .ssh/identity.pub を自分の .ssh/authorized_keys に追加する。
相手が .ssh/identity.pub を持っていなければ、ssh-keygen で作成する。
$ ssh-keygen ~/.ssh/identity と ~/.ssh/identity.pub を作る (それぞれ、バイナリとテキスト)
$ ssh-keygen -t rsa ~/.ssh/id_rsa と ~/.ssh/id_rsa.pub を作る (新バージョンはこちらを使う)
$ ssh-keygen -f file file と file.pub を作る (それぞれ、バイナリとテキスト)
ssh-keygen を実行すると pass phrase (パスフレーズ) の入力を行うが、ここでは空を指定する。
空を指定しないと、ログイン時にパスフレーズを聞かれてしまう。
運用時の弱点
弱点1..shosts の許可を限定出来ない。
弱点2.scp コマンドが接続先の shell を介してして動作する。
説明と対処1..shosts の許可を限定出来ない。
.shosts を許可してしまうと、全ユーザに許可することになる。
例えば、
・UserA に .shosts を許可
・UserB に .shosts を禁止
という条件を同時に満たすことが出来ない。
UserA は MachineA から接続 (MachineA は信頼性が高い)
UserB は MachineB から接続 (MachineB は管理者がタコ)
という状況でも UserB に .shosts を認める事になってしまう。
(UserB には パスワードログインだけを認めたいのに…)
対処 (別ポートで sshd を立ち上げる)
通常 sshd は Port 22 で動作するが、これとは別のポートで複数動作させ、AllowUsers での制御を行う。
方法は幾つかあるが、変更した設定ファイル (sshd_config_another) が別途必要 (当然自分で作ること)。
1. inetd の場合 (root 権限が必要)
/etc/services
sshd-another PortNumber/tcp
/etc/inetd.conf
sshd-another stream tcp nowait root /usr/local/sbin/sshd sshd-another -i -f sshd_config_another
2. standalone の場合 (root 権限が必要)
/etc/rc.d/init.d/sshd-another として、
/etc/rc.d/init.d/sshd を変更したスクリプトを登録する
/usr/local/sbin/sshd -p PortNumber -f sshd_config_another 変更個所はこの行
3.ユーザ権限で起動する場合 (root 権限は不要)
/usr/local/bin/ssh-keygen -q -b 1024 -f hostkey_another -C '' -N '' ホストキーの作成
/usr/local/sbin/sshd -p PortNumber -f sshd_config_another -h hostkey_another
クライアントは
/usr/local/bin/ssh -p PortNumber -1 -o 'UsePrivilegedPort yes' -l TargetUserID ServerName
等として接続する。
※注意1:sshd が libwrap.a 付きでコンパイルされている場合、
/etc/hosts.allow /etc/hosts.deny が有効になる。
この制限を越えるには管理者の協力が必要。
(対策: libwrap.a 無しでコンパイル (--without-tcp-wrappers) すれば考えなくて良い)
※注意2:PAM を使用している環境でパスワードログインをするとき、
/etc/pam.d/sshd が可読である必要がある。
この制限を越えるには管理者の協力が必要。
(.shosts だけを使うので、ログインは行わないため考えなくて良い)
※注意3:他ユーザのログインは不能。
sshd を起動したユーザ以外の権限は無い。
※注意4:nohup コマンドは不要。
常駐させたくないときは -d オプションを使用する。
※注意5:上記のようにホストキーを自前で用意する (本物は root しか読めないため) ので、
クライアント機の .ssh/known_hosts で矛盾が起きてしまう。
(対策1. UserKnownHostFile を指定して回避する)
(対策2. ssh protocol 2 で接続すれば known_hosts は使用しない)
説明と対処2.scp コマンドが接続先の shell を介して動作する。
scp でファイル転送するためだけのアカウントを用意したい時、ログインもできてしまう。
パスワードを知っている人間が公開鍵を登録することにより、他のサーバからもアクセス出来てしまう。
対処 (パスワードを無効にし、shell を入れかえる)
.shosts はパスワードを必要としないので、当該ユーザの
パスワードをロックしてしまえば、とりあえず他人のログインは出来なくなる。
(.shosts の有無に関わらずパスワードを知っていれば ssh ログインが出来てしまうため、これを抑止)
※通常の shell を禁止すれば接続元の公開鍵を登録できなくなる。
接続先ユーザの .ssh/known_hosts と .ssh/authorized_keys に接続元ユーザの情報が必要なため、
これを変更しない限り接続元ユーザは限定される。
scp だけを実行する shell を作ってみた。
これを接続先ユーザの shell として登録しておくことにより、動作を制限させる。
scp を実行すると、相手シェルに
-c scp -f FilePath … 受信時
または
-c scp -t FilePath … 送信時
が渡ることを利用したもの。
/usr/bin/scponly
#!/usr/local/bin/perl
# /usr/bin/scponly 755
#
# SHELL -c "scp ..." がリクエストされたときだけ動作するシェル
#
use strict ;
my $log = './scponly.log' ; # 実行ログ。適宜変更すること
exit if ($ARGV[0] =~ /\`/) ; # バッククォートは駄目
exit if ($ARGV[1] =~ /\`/) ;
if ($ARGV[0] eq '-c' and $ARGV[1] =~ /^scp +/
&& $ARGV[1] !~ /-f\s+.*(known_hosts|authorized_keys)/) # 鍵ファイルは書き込み不能にする
{
my $command = $ARGV[1] ;
system($command) ;
open LOG,">> $log" ;
print LOG "$command\n" ;
close LOG ;
}
|
.shosts の書き換えを禁止 (オーナでさえも禁止) したいときは、
chattr (見るときは lsattr) で i フラグを立てれば良い。
※ i フラグを変更できるのは root のみ。