パスワード無しでSSH
OpenSSH 2.9p1 に対応
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 のみ。