昔から、暗号とか秘密とかが好きで、pgpとかhttpsとかsshとか、実際に守るものがあるかどうかは別にして、使えるようにしています。(下手の横好きなので、暗号のアルゴリズムとかはさっぱりですが)
最近、Poderosaと言うWindows用のターミナルエミュレータが会社で流行っているので、ちょっと調べてみたときに、自分がやっているssh関連の設定についてまとめておいた方が良いかと思ってエントリにしました。(結局puttyに落ち着いたんですが)

sshとは

ssh とは、secure shell の略で、昔のtelnetに替わるものです。telnet はログイン時にパスワードが平文でネットワークを流れますし、ログイン後の通信も全てそのまま流れます。(もっとも、最近のFreeBSDのtelnetはパスワードが平文では流れません) sshのメリットを挙げます。
  • 通信路が暗号化されます。
  • ログイン時に、パスワード認証だけでなく鍵を使った認証ができます。
  • ホスト間の認証があるので、DNSに攻撃を受けたりしても間違ったホストにログインすることが防げます。
  • ログインするだけでなく、リモートでのコマンド実行(昔のrshの機能)や、ファイル転送(rcp/ftpの機能)もできます。
  • ポートフォワードと言う機能を使って、暗号化されていないプログラムの通信を暗号化したり、firewallを超えることができます。

ssh のバージョン

sshのバージョンと言う場合、ssh のプロトコルのバージョンと、ssh の server/client のプログラムのバージョンを分けて考える必要があります。
ssh のプロトコルには、1 と 2 があります。(1.5とかもあった気がするけど・・・) 中身が知りたかったらRFCをあたってください。
ssh の実装にはいろいろありますが、私が使っているのはFreeBSDなので、openssh と言うプログラムになります。私のFreeBSD 7.1には 5.1 が入っています。

ssh server の設定

FreeBSD の ssh server は /usr/sbin/sshd です。関連する設定ファイルは、/etc/ssh/sshd_config と /etc/rc.conf または /etc/inetd.conf です。
まずは、/etc/ssh/sshd_config の設定。修正している箇所だけ抜き出します。(FreeBSDのデフォルトの sshd_config は、中身がみんなコメントアウトされていて、どんな設定項目があるかと、デフォルト値がどうなっているかを見ることができます。)
#Port 22
#Protocol 2,1
ListenAddress 127.0.0.1
ListenAddress 192.168.0.2
AllowGroups sshd
ChallengeResponseAuthentication no
PasswordAuthentication no
Port
sshdがListenするポートです。デフォルトから変えた方が安全と言う意見もありますが、私はデフォルトのままにしています。
Protocol
受け入れるプロトコルのバージョンを指定します。SSH Version 1 を受け入れたくない場合は、Protocol 2 と書きます。
ListenAddress
複数のネットワークインターフェイスを持っているときに、特定のアドレスのみでListenしたいときに記述します。必要なければ省略してかまいません
AllowGroups
sshでログインできるユーザを特定のUnix group に所属するメンバに限定したい場合に指定します。
ChallengeResponseAuthentication
チャレンジ・レスポンス認証を許可するかどうかを指定します。FreeBSDではPAMを使うかどうかです。インターネットからアクセスするマシンでは禁止するべきです。
PasswordAuthentication
パスワード認証を許可するかどうかを指定します。ChallengeResponseAuthenticationと合わせて禁止します。
rc.conf は、sshdを使用する場合は以下の行を追加します。
sshd_enable="YES"
私は、sshd を rc から起動するのではなく、inetd から起動しているので、rc.conf には上記の記述はありません。inetd から起動するには、inetd.conf に以下の記述をします。
ssh     stream  tcp     nowait/0/5/7    root    /usr/sbin/sshd          sshd -i -4
sshdをデーモンにしないでinetdから起動するメリットは、sshdに対する総当り攻撃やDDOSを緩和することです。参考: sshdをinetdから起動する
nowait/0/5/7 の部分でこれを制御しますが、この設定だと一つのIPアドレスから、1分間に最大5回までの接続を受け付けることを意味します。6回目以降からはinetdがはじいてくれます。最後の7は、同じホストからの同時接続を7に制限するという意味です。
他に気にするファイルとしては、/etc/ssh/ssh_host*_key にマッチするいくつかのファイルがあります。
これらのファイルは、クライアントがこのサーバを識別するための鍵ファイルになります。サーバのリプレースや、OSの再インストールなどでこれらのファイルが変わってしまうと、クライアントから「サーバが偽者!?」と疑われてしまうので、必要ならばバックアップを取っておきましょう。

ssh client の設定(openssh)

クライアントの設定で最初にやることは、鍵ペアを作成することです。
> ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_dsa): ←そのままEnter
Created directory '/home/hoge/.ssh'.
Enter passphrase (empty for no passphrase): ←鍵につけるパスフレーズを入力
Enter same passphrase again: ←パスフレーズを再入力
Your identification has been saved in /home/hoge/.ssh/id_dsa.
Your public key has been saved in /home/hoge/.ssh/id_dsa.pub.
The key fingerprint is:
61:6b:20:12:fc:a8:31:95:bf:37:42:85:cf:b1:38:85 hoge@sv.wizard-limit.net
The key's randomart image is:
+--[ DSA 1024]----+
| ... o           |
|  +.E +          |
| ..+.*.oo        |
|o ..*.+o o       |
| + . o  S        |
|.   o o.         |
|     o .         |
|                 |
|                 |
+-----------------+
ssh-keygen は、特別なオプションをつけなければ ~/.ssh/ に自分用の鍵ペアを作成してくれます。最低限必要なオプションは -t だけです。-t の後には鍵のタイプを指定します。rsa1(SSH Version 1用のRSA鍵。identity/identity.pub), rsa(SSH Version 2用のRSA鍵。id_rsa/id_rsa.pub), dsa(SSH Version 2用のDSA鍵。id_dsa/id_dsa.pub)から選びます。
サーバがVersion 1しか対応していない等の特別な理由がない限りは、Version 2 用の鍵を作ります。RSA にするか DSA にするかはお好みで。
この過程で、~/.ssh ディレクトリが作成され、秘密鍵ファイルと公開鍵ファイルが作成されます。
試しに同じマシンにログインしてみます。
> cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
> ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
DSA key fingerprint is 8d:78:c0:28:ad:2e:cc:83:de:e2:7e:78:a7:34:46:39.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (DSA) to the list of known hosts.
Enter passphrase for key '/home/hoge/.ssh/id_dsa':
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
        The Regents of the University of California.  All rights reserved.

FreeBSD 7.1-RELEASE-p7 (FALSE) #1: Sat Aug  1 14:17:46 JST 2009

Welcome to FreeBSD!
>
最初の cat は、~/.ssh/authorized_keys ファイルに、公開鍵を登録しています。
ホストAからホストBにログインするとき、ホストB の ~/.ssh/authorized_keys ファイルにある公開鍵とペアになる秘密鍵がホストA の ~/.ssh にあるときに、初めてログインが可能になります。今回は同じホストにログインするので、そのまま cat でファイルに追加(この場合は作成)しています。
はじめてのサーバにログインする場合、「こんなサーバ知らないから接続できないよ」と言うメッセージが出ます。本来はここで表示されるサーバ鍵のフィンガープリントを見て、正しいことを確認してからyesを入力します。
一度yesを入力すると、~/.ssh/known_hosts にサーバの公開鍵が登録されます。先ほどサーバの設定をしたときの /etc/ssh/ssh_host*_key に対応するものです。
サーバ側の鍵が変わったり、サーバが偽者だったりして~/.ssh/known_hostsとの間に矛盾を検出すると、ssh でログインしようとしたときにエラーが出ます。
サーバ側の鍵が変わっている場合は、~/.ssh/known_hostsから該当サーバのエントリを削除します。(単なるテキストファイルです)
これで、クライアント側の基本的な設定はおしまいです。秘密鍵のファイルと、authorized_keysは大事なファイルなので、扱いに注意します。
秘密鍵(id_dsa/id_rsa)は絶対に他人に渡ってはいけませんし、authorized_keys は他人が書き換え可能ではいけません。

ssh client の設定(putty)

サーバはFreeBSDでも、作業マシンがWindows と言うのは良くあるパターンです。
sshに対応したWindows 用のターミナルエミュレータはいろいろありますが、私のオススメはputty です。英語が苦手な人は、PuTTY ごった煮版を使うと良いでしょう。
putty を使って鍵ペアを作成するには、puttygen.exe を使います。GUIなので難しいことはないと思いますので詳しい説明は省きますが、鍵の種類を選択して生成してパスフレーズをつけて保存するだけです。
putty の秘密鍵ファイルは *.ppk で openssh のものとは形式が違います。
「OpenSSHのauthorized_keysファイルにペーストするための公開鍵」と言うテキストボックスがありますので、その内容をコピーしてサーバの ~/.ssh/authorized_keys に追加します。
サーバにログインするには、putty.exe を使用します。
putty を起動すると設定ダイアログが開きますので、ホスト名を入れて、接続-データにユーザ名をいれ、接続-SSH-認証の「認証のためのプライベートキーファイル」にputtygen.exe で作成したppkファイルを指定します。
セッションに名前をつけて保存しておくと便利です。参考: svn+ssh on Windows

proxy経由の接続

クライアントとサーバの間に firewall があって、なんらかの proxy が提供されている場合、以下の手順で proxy 経由の接続ができます。
  1. connect.c と言うプログラムを探してきて、コンパイルします。(なんでこれopensshに標準で入っていないんだろう?)
    私の場合は、~/bin/connect に置きました。
  2. ~/.ssh/config に以下の記述を追加します。
    Host proxy経由で接続したいホスト名
    ProxyCommand $HOME/bin/connect -S proxyホスト名 %h %p
    
    proxyホストが socksサーバの場合は上記の通り -S オプション。http proxyの場合は -H オプションを使います。
putty の場合は、接続-プロキシに設定があります。

ssh agent の使用(openssh)

ここまでの設定だと、sshでログインするたびに鍵のパスフレーズを聞かれます。
一度ログインしているのに、同じパスフレーズを何度も入力するのは苦痛なので、代わりに覚えてくれるプログラムがあります。それが ssh-agent です。
最初にログインしたときに、ssh-agentを起動します。
> eval `ssh-agent`
Agent pid 74374
eval を忘れないようにします。これで、ssh-agentが起動して、環境変数SSH_AUTH_SOCK が設定されます。
次に、ssh-agent に鍵を登録します。
> ssh-add
Enter passphrase for /home/hoge/.ssh/id_dsa:
Identity added: /home/hoge/.ssh/id_dsa (/home/hoge/.ssh/id_dsa)
これで、ssh-agentに鍵が登録されました。試しに、localhost にsshしてみると、パスフレーズなしでログインできることがわかります。
ssh-agentは、最初に起動したシェルが終了すると終了します。ssh-agent -k で明示的に殺すこともできます。
X等を使用している場合は、~/.xinitrcや~/.xsession で ssh-agent を起動しておくと便利です。(知識が古くてすいません。最近のGNOMEやKDE等のデスクトップ環境だと、.xinitrcや.xsessionは使わないような気がします)

ssh agent の使用(putty)

putty の場合は、pageant.exe を使います。
pageant.exe(pagentでないので注意)をスタートアップ等に入れておくと、タスクトレイに常駐します。右クリックして「鍵の追加」を選ぶと、ssh-addと同等のことができます。ssh-addと違って、明示的に鍵ファイルを指定する必要があります。

agent forwarding

今、sshでログインしようとしているときに ssh agent が使われるかどうかと、ssh agentを使ってログインした後に再度 agent が使えるかどうかは分けて考える必要があります。
  • openssh では、以下の条件を満たすときに agent が使用されます。
    1. ssh-agent が起動している。
    2. ssh-agent にログインに必要な鍵が登録されている。
    3. 環境変数SSH_AUTH_SOCKにssh-agentと通信するのに必要なソケットのパスが設定されている
  • putty では、以下の条件を満たすときに agent が使用されます。
    1. pageant が起動している。
    2. pageant にログインに必要な鍵が登録されている。
    3. puttyのセッションの設定で、接続-SSH-認証の「Pageantを使って認証する」にチェックが入っている
ログインした後に再度agentが使えるかどうかは、ログイン後に上記条件が満たされている必要がありますが、デフォルトでは満たされていません。
これを満たすようにする機能がagent forwardingです。(X11を使用している場合は、ForwardX11および-Xオプションも調べておくと良いでしょう)
agent forwardingを有効にするには、以下の設定を行います。
  • openssh の場合は、以下のいずれかを行います。
    • sshを実行するときに、-A オプションを指定する
    • ~/.ssh/config で、ForwardAgent yes を設定する
    • /etc/ssh/ssh_config で、ForwardAgent yes を設定する
  • putty では、接続-SSH-認証の「エージェントフォワーディングを認める」にチェックします。
GNU screen を使用していると、環境変数 SSH_AUTH_SOCK の内容が古い状態になってしまって、せっかくのssh agent がうまく利用できない場合があります。
今回調べていて行き当たったのが、以下の記事です。
仙石浩明の日記: ssh-agent を screen の中から使う方法
set agent = "$HOME/tmp/ssh-agent-$USER"
if ($?SSH_AUTH_SOCK) then
	if (! -S $SSH_AUTH_SOCK) unsetenv SSH_AUTH_SOCK
endif
if ($?SSH_AUTH_SOCK) then
	if ($SSH_AUTH_SOCK =~ /tmp/*/agent.[0-9]*) then
		ln -snf "$SSH_AUTH_SOCK" $agent && setenv SSH_AUTH_SOCK $agent
	endif
else if (-S $agent) then
	setenv SSH_AUTH_SOCK $agent
else
	echo "no ssh-agent"
endif
unset agent
上記は.cshrc用の記述なんですが、とても良くできています。
  1. 環境変数SSH_AUTH_SOCKが設定されていて、対象のファイルが存在していてソケットでない場合はSSH_AUTH_SOCKを未定義にします。
  2. 環境変数SSH_AUTH_SOCKが設定されていて、/tmp/*/agent.[0-9]* だったら~/tmp/ssh-agent-$USER にシンボリックリンクを作成して、SSH_AUTH_SOCKはリンクを指すようにします。
  3. 環境変数SSH_AUTH_SOCKが設定されていなくて、~/tmp/ssh-agent-$USERにソケットが存在したらSSH_AUTH_SOCKを設定します。
  4. 全てを満たさない場合は、ssh-agentが動いていないと判断します。
screen を使っているかどうかにかかわらず、上記設定によって常に SSH_AUTH_SOCK は ~/tmp/ssh-agent-$USER か未設定のどちらかの状態になり、設定されていてssh-agentが動いていれば agent が利用できるのです。
同じマシンで同一のユーザが複数のagentを動かさない限り問題ないはずで、そんな使い方はまずしないと思います。(と、言いつつ、agent forwarding と組み合わせたら微妙かも知れない・・・→新しいソケットが増えてリンク先が変わったけど、無駄なだけで問題はないはず→と思ったけど後からできたソケットが消えるとリンク先がなくなっちゃうな。forwardを使う場合は要注意。)

control master

もう一つ私の~/.ssh/config に入っている設定。
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
これをやっておくと、同じホストと通信するときに新しいsshのコネクションを張らない。(代わりに、~/.ssh/master-%r@%h:%pへの接続が増える)
最初の方にあった inetd で接続数の制限をしている場合などに、この方法なら接続数が増えないので、リソース的にお得らしいです。
参考: OpenSSHのセッションを使い回す(OpenSSH ControlMaster) - jitsu102の日記

カテゴリ

トラックバック(0)

このブログ記事を参照しているブログ一覧: sshの設定とか

このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/2074

コメントする

このブログ記事について

このページは、falseが2009年8月 5日 09:48に書いたブログ記事です。

ひとつ前のブログ記事は「回顧録(1)」です。

次のブログ記事は「回顧録(2)」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

広告

Powered by Movable Type 6.1.1