OpenSSHのTipsです。ここではクライアントの話題のみを取り上げます: サー バに関しては取り扱いません。
SSH(Secure SHell)は、通信路を暗号化することで安全性を高めたネットワー ク接続ツールである。telnetやrshによるリモートログイン、rcpやftpによる 遠隔コピーを置き換えるためのコマンド群を備えている。
OpenSSHは、SSHプロトコルをフリーで実装したものである。開発はOpenBSDプ ロジェクトによって行われている。
sshコマンドは、遠隔ホストにログインする、もしくは遠隔ホストに指定の 処理を行わせるためのコマンドである。使用目的からいえば、telnetと rlogin、rshに相当するコマンドである。以下に基本的な呼び出し構文を示 す。
% ssh [options] [<user>@]<host> [command]
<host>には対象となる遠隔ホストのホスト名を、<user>には 遠隔ホスト上でのユーザ名を記述する。ユーザ名を省略すると、ローカル ホスト上のユーザ名が使用される。[command]には実行させる処理を記述す る: もしログインして対話的に作業を行うなら、[command]には何も記述し ない。
例えばremotehostというホスト名の遠隔ホストにユーザ名user1でログイン するなら、以下を実行する。
% ssh user1@remotehost
実行するとremotehostがパスワードを尋ねてくるので、入力する。パスワー ドが正しいことが確認されると、remotehost上でシェルが起動され、対話 的に作業を行える状態になる。
非対話的にコマンドを実行させる場合は、[command]に実行させるコマンド を指定する。以下の例は、remotehostでwhoコマンドを実行する。
% ssh user1@remotehost who
入力するパスワードおよび対話的に作業を行っている際のすべての通信は、 sshコマンドおよびsshサーバによって暗号化される。たとえ通信途上の何 者かに通信を盗聴されたとしても、パスワードや通信内容が漏洩する心配 はない(暗号が解読されなければ、だが)。
クライアントおよびサーバの設定、コマンドの使い方によっては、接続す るたびにパスワードを入力しないでもよいようにできる。
scpコマンドは、ローカルホストと遠隔ホスト間でのファイルコピーを行う ためのコマンドである。使用目的からいえば、rcpに相当するコマンドであ る。以下に基本的な呼び出し構文を示す。
% scp [options] <file> [<user>@]<host>:[<dir>] または % scp [options] [<user>@]<host>:<file> <dir>
1番目の呼び出し形式は、ローカルホスト上の指定したファイルを遠隔ホス ト上の宛先ディレクトリにコピーする。<file>にローカルホスト上 のファイルを、<host>に遠隔ホストのホスト名を、<user>に 遠隔ホスト上のユーザ名を、<dir>に遠隔ホスト上の宛先ディレクト リを指定する。ユーザ名を省略するとローカルホスト上のユーザ名が使用 される。<file>には複数のファイルを列挙してもよい。<dir> を省略するとホームディレクトリにコピーされる。
以下の例は、ローカルホスト上の~/make.logと/tmp/foo.txtをremotehost 上の/tmpディレクトリにコピーする。-pオプションは、可能な限り時刻情 報と許可属性を保存する指定である。
% scp -p ~/make.log /tmp/foo.txt user1@remotehost:/tmp
2番目の呼び出し形式は、遠隔ホスト上の指定したファイルをローカルホス ト上の宛先ディレクトリにコピーする。<file>に遠隔ホスト上のファ イルを、<dir>にローカルホスト上の宛先ディレクトリを指定する。 <file>にはシェルのメタキャラクタを用いて複数のファイルをまと めて指定することができる: この場合はシングルクォート文字で囲う必要 がある。
以下の例は、remotehost上の/tmpディレクトリ内のすべてのファイルとディ レクトリをローカルホスト上の~/tmpディレクトリにコピーする。-rオプショ ンはディレクトリを再帰的にコピーする指定である。
% scp -pr user1@remotehost:'/tmp/*' ~/tmp
sftpコマンドは、ローカルホストと遠隔ホスト間でのファイルコピーを行 うためのコマンドである。使用目的からいえば、ftpに相当するコマンドで ある。以下に基本的な呼び出し構文を示す。
% sftp [<user>@]<host>
<host>に遠隔ホストのホスト名を、<user>に遠隔ホスト上の ユーザ名を記述する。パスワード入力後、sftpのプロンプトが表示される。 ftpコマンドとほぼ同様のコマンド体系(例えばputやget)を用いてファイル の送受信を行う。helpコマンドでへルプを参照できる。
SSHで使用される公開鍵認証は、公開鍵暗号技術を用いた認証方式である。
公開鍵暗号(public key cryptography)は、暗号化と復号に対となる2つの 鍵、公開鍵(public key)と秘密鍵(private key)を用いる暗号系である。公 開鍵を秘匿することなく安全な通信を行うことができる点で、暗号化と復 号に同一の鍵: 共通鍵(secret key)を使用する慣用暗号(conventional cryptography: 共通鍵暗号または秘密鍵暗号とも訳される。symmetric key cryptography: 対称鍵暗号とも呼ばれる)よりも優れている。公開鍵暗号は 暗号化のほか、デジタル署名やメッセージ認証、慣用暗号の鍵交換などに も利用される。
SSHは、接続時のユーザ認証にこの公開鍵暗号による認証を用いることがで きる。
以下に、公開鍵認証を用いるためにユーザが行うべき準備の標準的手順を 示す。
接続元ホストとなるマシン上で、ユーザ認証に使用する公開鍵と秘密鍵 のペアを作成する。この際、秘密鍵にパスフレーズによる鍵をかけ、秘 密鍵自体を暗号化しておく。
公開鍵ファイルを接続先ホストに置く。同一の公開鍵を複数の接続先ホ ストに置くことができる。
これで公開鍵認証による接続が可能になる。通常と同様の手順で遠隔ホス トに接続するとパスフレーズ入力が促され、正しいパスフレーズを入力す ると接続が確立される。
これだけだと使い勝手としては「パスワード入力がパスフレーズ入力に変 わっただけ」であるが、 認証エージェント を使用すると接続ごとのパスフレーズ入力を行わずに接続することもでき る。
鍵ペアの生成は、ssh-keygenコマンドで行う。ここで行う一連の操作には 秘匿性が要求されるので、telnetやrsh、リモートからのXウィンドウ経由 で実行してはならない。
% ssh-keygen [-t {rsa1|rsa|dsa}]
-tオプションでは、鍵ペアの種類を指定する。SSH1プロトコル用のRSA1、 SSH2プロトコル用のRSAとDSAの3種類がある。デフォルトはRSA1である。接 続先サーバが受け付けるプロトコルや鍵の種類に応じて選択する必要があ るが、通常設定のOpenSSHサーバに接続するのであればDSAを選択するのが よいだろう。1人で複数種類の鍵を持つのもよい。
起動するとまず秘密鍵ファイルのファイル名を尋ねられる。デフォルトで はRSA1なら~/.ssh/identity、RSAなら~/.ssh/id_rsa、DSAなら ~/.ssh/id_dsaである。公開鍵ファイルのファイル名は、秘密鍵のファイル 名の終端に .pub を付加したファイル名となる。変更する必要がなければ そのまま改行を入力する。
次にパスフレーズを入力する。多くのUNIXパスワードと違って文字数や文 字種類の制限はほとんどないので、自由に入力してよい。エージェントを 使うようにすればかなり長いパスフレーズでもあまり困ることはないので、 なるべく長いパスフレーズをつけた方がよい。
完了すると、指定したファイル名の秘密鍵ファイルと公開鍵ファイルが生 成される。
生成した公開鍵ファイルを、接続先ホストの公開鍵リストに追加する。接 続先ホストの公開鍵リストは、当該ユーザのホームディレクトリを ~/ と すれば ~/.ssh/authorized_keys である。
配布する公開鍵ファイルが ~/.ssh/id_dsa.pub なら、以下のような手順で 公開鍵を追加する。
% cat ~/.ssh/id_dsa.pub | ssh user1@remotehost 'cat >> .ssh/authorized_keys'
これを、公開鍵認証で接続したいすべての接続先ホストについて行う。ま とめて実行するなら以下のようにしてもよいだろう。
% for i in user1@remotehost1 user2@remotehost2 ...; do \
cat ~/.ssh/id_dsa.pub | ssh $i 'cat >> .ssh/authorized_keys'; \
done
なお、OpenSSH 2.9.9より以前のバージョンでは、RSAとDSAの公開鍵は ~/.ssh/authorized_keys ではなく ~/.ssh/authorized_keys2 に置かなけ ればならない。
ここまでの操作で公開鍵認証による接続が可能になる。確認のため接続し てみるとよい。設定が正しければパスフレーズの入力が促され、入力後に 接続が確立される。
認証エージェントは、接続時に行われる公開鍵認証手続きの一部を代行す るプロセスである。認証エージェントを使うことで、結果的にパスフレー ズの入力を行わないようにすることができる。
認証エージェントがいない場合の公開鍵認証は、以下の手順で行われる。 なお、この一連の通信はすでに確立済の暗号化された通信路上で行われる。
クライアント側で起動される認証エージェントは、復号化された秘密鍵を 受け取って記憶しておくことができる。認証の際には、上記のうちのクラ イアント側での認証処理を、記憶してある秘密鍵を使って代行する。
認証エージェントを使用するためには、まず認証エージェントを起動し、 自分の秘密鍵を記憶させておく必要がある。
認証エージェントはssh-agentコマンドで起動する。起動した認証エージェ ントを使うためにはいくつかの環境変数を設定する必要があるが、 ssh-agentコマンドは起動時にこの環境変数設定を行う機能も合わせ持って いる。
起動方法は、そのまま起動する方法と子プロセスと共に起動する方法の2通 りがある。
コマンドを指定せずにssh-agentコマンドを起動すると、標準出力に環境 変数を設定するためのシェルコマンド列を出力する。これをevalコマン ドで取り込む。
% eval `ssh-agent`
起動に成功すると、認証エージェントはUNIXドメインソケットを作成し、 その絶対パスをSSH_AUTH_SOCK環境変数に返す。また、認証エージェント のプロセスIDをSSH_AGENT_PID環境変数に返す。
以降のシェルコマンドで起動される子プロセスは、これらの環境変数に 基づいて認証エージェントを使用することができる。
この方法で起動した認証エージェントは、不要になったらユーザ自身の 手で停止させる必要がある。 認証エージェントの停止 を参照のこと。
コマンドを指定してにssh-agentコマンドを起動する。
% ssh-agent <command> <args> ...
起動に成功すると、認証エージェントはUNIXドメインソケットを作成し、 その絶対パスをSSH_AUTH_SOCK環境変数に、認証エージェントのプロセス IDをSSH_AGENT_PID環境変数に設定し、子プロセスを起動する。
起動された子プロセスからさらに起動される子プロセスは、これらの環 境変数に基づいて認証エージェントを使用することができる。
この方法で起動した認証エージェントは、子プロセスの終了と同時に自 動的に停止する。
例えばXを起動すると同時に認証エージェントの使用を開始し、Xの終了 と共に認証エージェントを停止するなら、以下のようにしてXを起動する。
% ssh-agent xinit
ssh-addコマンドを使う。秘密鍵ファイルの絶対パスを引数として与える。
% ssh-add [<file> ...]
引数を省略すると、RSA1、RSA、DSAすべての鍵が選択される(3.1p1以前の バージョンではRSA1鍵のみ選択される)。引数で鍵を指定することもできる。
起動すると、それぞれの鍵のパスフレーズ入力を促される。入力経路が安 全なことを確認した上でパスフレーズを入力すること。成功するとその秘 密鍵が認証エージェントに記憶される。複数の鍵を選択している場合は、 それぞれの鍵のパスフレーズが同一ならば2つめ以降の鍵のパスフレーズ入 力を省略することができる。
ssh-addコマンドで、認証エージェント内に記憶されている秘密鍵を確認で きる。
% ssh-add -l
1行に1つの鍵が表示される。表示は先頭から順に、鍵のビット数、指紋、 コメント、鍵種別となっている。
認証エージェントが起動されていて、公開鍵認証に用いる秘密鍵が記憶さ れていて、環境変数が正しく設定されているならば、あとは通常通りsshや scpやsftpを使うだけでよい。クライアント側の認証作業は認証エージェン トが代行するので、パスフレーズの入力なしに遠隔ホストとの通信を行う ことができる。
何らかの理由で登録されている秘密鍵の記憶を消すならば、以下のように する。引数で指定した秘密鍵の記憶が消去される。
% ssh-add -d [<file> ...]
もしただ単に認証エージェントを停止するのであれば、明示的に秘密鍵の 登録を停止する必要はない。認証エージェントの停止と共にすべての情報 は消去される。
ssh-agentコマンドで、以下のようにして認証エージェントを停止する。
% ssh-agent -k
SSHおよびOpenSSHは、sshコマンドで確立された遠隔ホストとの通信路を使っ て、任意の数のTCP接続の転送を行うことができる。
例えばX11転送を使用すると、遠隔ホスト上で起動したX Windowを用いるア プリケーションが、ローカルホスト上の画面に表示される。これは、遠隔 ホスト上のアプリケーションとローカルホスト上のXサーバ間の通信をSSH が仲介することで実現される。また、中間経路はSSHプロトコルによって暗 号化されるため、SSH接続と同等のセキュリティか確保されている。
X11転送を有効にするには、以下のようにsshコマンドを-Xオプション付き で起動する(接続先ホストのsshサーバがX11転送を受け付けている必要があ る)。
% ssh -X user1@remotehost
これにより、SSH通信路確立と共にローカルホスト側のXサーバに対し遠隔 ホストから接続するための通信路が確保され、遠隔ホスト上でDISPLAY環境 変数が自動的に設定される。また、この通信路を第三者が使用できないよ う、Xの認証情報が設定される。
設定ファイルで指定することもできる。 設定に関する記述 を参照のこと。
以下のようにsshコマンドを-Lオプション付きで起動する。
% ssh -L<port>:<host>:<hostport> user1@remotehost
これにより、SSH通信路確立と共に、ローカルホストのポート<port> へのアクセスが遠隔ホストから見たホスト<host>、ポート <hostport>へと転送されるようになる。
例えば以下のようにすると、遠隔ホスト上のPOPサーバをローカル側のポー ト10000からSSH経由でアクセスすることができる。
% ssh -L10000:localhost:110 user1@remotehost (接続確立後、このsshとは別のシェルプロンプトなどでポート10000を使用する)
以下のようにsshコマンドを-Rオプション付きで起動する。
% ssh -L<port>:<host>:<hostport> user1@remotehost
これにより、SSH通信路確立と共に、遠隔ホストのポート<port> へ のアクセスがローカルホストから見たホスト<host>、ポート <hostport>へと転送されるようになる。
例えば以下のようにすると、ローカルホスト上のrsyncサーバを遠隔ホスト 側のポート10000からSSH経由でアクセスすることができる。
% ssh -R10000:localhost:873 user1@remotehost
エージェント転送とは、手元で動作している認証エージェントを遠隔ホスト からも利用可能にする機能である。エージェント転送を使うと、遠隔ホスト からさらにsshコマンドを使用する際にもローカルホスト上の認証エージェン トを使用できる。ポート転送と同様に、認証時の通信は暗号化される。これ により、単一の鍵ペアだけで多段のSSH接続を手早く使うことができる。
エージェント転送は、-Aオプションで有効にする。
% ssh -A user1@remotehost
エージェント転送は設定ファイルで指定することもできる。 設定に関する記述 を参照のこと。
設定ファイル ~/.ssh/config で、接続先ごとに個別に設定を行うことができ る。以下に簡単な例を示す。
# sample configuration Host *.domain1 Protocol 1,2 ForwardAgent yes ForwardX11 yes Host *.domain2 Protocol 2,1 User user1 ForwardAgent yes ForwardX11 no Host * Protocol 2,1 ForwardAgent yes ForwardX11 yes
ファイルはテキストファイルで、"Host"行で区切られた複数のブ ロックから構成されている。#で始まる行はコメントである。接続するたびに 先頭のブロックから読み込んでいき、接続先ホスト名が"Host"行 にマッチしたらそのブロックを設定として使用する: その他のブロックは無 視される。先頭の方により限定されたホストの集合を、終端の方により一般 的なホストの集合を記述する。
最初のブロックは、DNSドメイン domain1 に所属するすべてのホストへの接 続に関する設定である。SSH1プロトコル優先、エージェント転送あり、X11転 送ありとなっている。
2番目のブロックは、DNSドメイン domain2 に所属するすべてのホストへの接 続に関する設定である。デフォルトユーザ名はuser1、SSH2プロトコル優先、 エージェント転送あり、X11転送なしとなっている。
最後のブロックは、上記以外のすべてのホストへの接続に関する設定である。 SSH2プロトコル優先、エージェント転送あり、X11転送ありとなっている。
以下に設定項目の一部を示す。これ以外にも多くの設定項目がある: sshのマ ニュアルに詳細が記載されている。
接続に使用するプロトコル。"1"ならSSH1、"2"なら SSH2。"2,1"とすると、まずSSH2プロトコルで接続を試み、失敗 したら次にSSH1プロトコルで接続する。
ユーザ名を指定しなかった場合の遠隔ホスト上のユーザ名。ローカルホス ト上のユーザ名と遠隔ホスト上のユーザ名が異なる場合に設定すると便利。
エージェント転送 をするか否か。"yes"または"no"。デフォルトはno。
X11転送 をするか否か。"yes"または"no"。デフォルトはno。
SSH1プロトコルにおける通信路暗号化方式。3des(Triple-DES)または blowfishまたはdes。デフォルトは3des。DESは後方互換性のためだけに用 意されている: 暗号として非常に弱いので理由がない限り選択してはなら ない。
SSH2プロトコルにおける通信路暗号化方式。暗号の候補をカンマ区切りで 列挙する。デフォルトは "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc''" 。
通信路を圧縮するか否か。"yes"または"no"。デフォ ルトはno。
SSH1プロトコルにおける通信路圧縮レベル。1(高速/低圧縮率)から9(低速/ 高圧縮率)。デフォルトは6。
SSH通信に使用する中継コマンド。SSH通信の下位通信路を設ける際に指定 する。デフォルトは不使用。
なお、上記のデフォルト値はシステム設定(/etc/ssh_configや /etc/ssh/ssh_configなど: コンパイル時の設定による)に何も記載されてい ない場合の値である。
-fオプションを用いる。パスワード入力後、sshプロセスは自動的にバック グラウンドに隠れる。アプリケーション終了と共にsshプロセスも停止する。
% ssh -q -f <host> emacs
-Nオプションを用いる(SSH2プロトコルのみで有効)。遠隔ホスト上で何も コマンドを実行しなくなる。ポートを使い終わったらsshプロセスを停止さ せること。
% ssh -q -N -L... -R... <host>
エージェント転送、X11転送、標準入力転送を無効化する。もし標準入力が 必要なら-nオプションは外すこと。
% ssh -q -a -x -n <host> './a.out'
~/.ssh/config に当該ホストのエントリを作成し、Protocolを明記する。 設定に関する記述 を参照のこと。
~/.ssh/config に当該ホストのエントリを作成し、Userを明記する。 設定に関する記述 を参照のこと。
connectコマンド を中継コマンドに指定することでSOCKSサーバ経由の接続を行う。 例えば ~/.ssh/config に以下のように記述する:
Host *.socks: Protocol 2,1 ForwardAgent yes ForwardX11 yes ProxyCommand connect -n -S <socks-server>:<socks-port> `echo %h | sed 's,\.socks,,'` %p
<socks-server> にはSOCKSサーバのホスト名またはIPアドレス、 <socks-port> にはSOCKSサーバのポート番号を指定する。なお、 上記の記述ではconnectコマンドにpathを通しておく必要がある。
ssh <host>.socks などとすると、SOCKSサーバ <socks-server> 経由で <host> へと接続する。
遠隔ホスト側で ~R を入力する。これにより、通信路を暗号化している共 通鍵暗号の鍵を新しくする。SSH2プロトコルのみで有効。
通信路上に既知のサイズのデータを流し、その転送時間を測定する。例え ば以下のようにする。
% time ssh -q -n <host> 'dd if=/dev/zero bs=16M count=1' > /dev/null
通信路の暗号化方式や圧縮の有無、圧縮レベルなどの最適値を求める際に 活用できる。ただし通信路やホストに負荷をかけるので、むやみに実行し てはならない。