第13章 SSH: 機密を保護する通信

目次

13.1. ssh—Secure Shell (機密を保持するシェル)
13.2. scp—機密保護機能付きのファイルコピー
13.3. sftp—機密保護機能付きのファイル転送
13.4. SSH デーモン (sshd)
13.5. SSH 認証の仕組み
13.6. ポート転送
13.7. YaST を利用した SSH デーモンの設定
13.8. さらなる情報

概要

ネットワークに接続された環境の場合、ネットワーク上離れた場所から特定の ホストにアクセスするような要件がしばしばあります。認証時に、利用者が ログイン (ユーザ名) とパスワードの文字列を暗号化せずに送信する場合、 それらの情報はネットワーク上で傍受することができてしまい、それらの情報を もとに許可していない利用者が特定のユーザアカウントを乗っ取ることができて しまいます。これにより、利用者のファイルを攻撃者が開くことができるほか、 場合によっては管理者 (root) の 権限を奪取するための足がかりとなりますし、他のシステムに攻撃を加えるための 踏み台としても利用できるようになってしまいます。以前はリモートからの 接続は telnetrsh, rlogin などを利用してきましたが、暗号化やその他の仕組みによる 保護が存在していませんでした。また telnet 以外にも、以前より使用されている FTP プロトコルや rcp のようなリモートファイルコピーの プログラムなど、通信データを保護していないものはいくつか存在しています。

SSH スイートでは、認証文字列 (通常はログイン名とパスワード) について暗号化を 行なうほか、ホスト間の通信そのものについても暗号化を行ない、必要な保護機能を 提供しています。 SSH でもデータの通信そのものは第三者が傍受することができて しまいますが、内容は暗号化されているため、暗号鍵を知らない限りはそれらを元の データ (暗号化前のデータ) に戻すことはできません。そのため、 SSH は機密の保護 されていないネットワーク、たとえばインターネットなどにおいて、機密を保護できる ようにすることができます。 openSUSE における SSH の実装として、 OpenSSH が利用できます。

openSUSE では既定で OpenSSH パッケージがインストールされるようになって いて、それぞれ ssh, scp, sftp の各コマンドを利用することができます。また、既定の設定 では openSUSE システムへは、 sshd を起動させて ファイアウオールでのアクセス許可を設定した状態で、 OpenSSH ユーティリティを 利用した場合にのみアクセス可能です。

13.1. ssh—Secure Shell (機密を保持するシェル)

ssh プログラムを利用することで、リモートのシステムに ログインして対話的な作業を行なうことができるようになります。たとえば sun というホストに対して tux というユーザでログインしたい場合は、 下記のコマンドラインのうちのいずれかを入力します:

ssh tux@sun
ssh -l tux sun

接続元と接続先でユーザ名が同じである場合は、ユーザ名を省略することもできます (ssh sun) 。いずれの場合も、リモート側の ユーザに対するパスワード入力を求められます。 認証が成功すると、リモート側のコマンドラインや対話的なアプリケーション (たとえば YaST など) を利用した作業を行なうことができます。

さらに ssh では、 ssh ホスト コマンド のように入力することで、 対話機能を備えていないコマンドを実行することもできます。ただし、 コマンド には適切に引用符を付ける必要があり ます。また、シェルでの作業のように、複数のコマンドを繋げて実行することも できます。

ssh root@sun "dmesg | tail -n 25"
ssh root@sun "cat /etc/issue && uptime"

13.1.1. X アプリケーションのリモートホストでの実行

SSH では、ネットワーク上離れた場所にある X アプリケーションの利用を 簡単に行なうことができます。 ssh コマンドを実行する 際に -X オプションを設定すると、リモート側の DISPLAY 環境変数が自動的に設定され、 X の出力を SSH 接続経由で手元に持ってくることができます。また同時に、自分以外の ユーザが、この出力を悪用できないようにも設定します。

13.1.2. エージェント転送

-A オプションを指定すると、 ssh-agent によって認証 情報が次のマシンにも引き継がれるようになります。この方法を利用することで、 それぞれ異なるマシンに対してログインする際、パスワードの入力を省略する ことができます。ただし、この方法を利用するには、接続先のホストに対して あらかじめ公開鍵を配布しておき、適切な場所に保存しておく必要があります。

この仕組みは既定の設定では無効化されていますが、システム全体の設定ファイル である /etc/ssh/sshd_config ファイル内で AllowAgentForwarding yes と設定することで、恒久的に 有効化することができます。

13.2. scp—機密保護機能付きのファイルコピー

scp はローカル側のファイルをリモート側のマシンにコピー したり、逆にリモート側のマシンをローカルにコピーしたりすることができます。 jupiter 上のユーザが sun 上のユーザと異なる場合でも、 ユーザ名@ホスト の形式で指定することで解決できます。 リモート側のホームディレクトリ以外にファイルをコピーしたい場合は、 sun:ディレクトリ のように指定します。 下記の例では、ローカルからリモートに対するファイルコピーと、その逆を 行なっています。

# ローカル -> リモート
scp ~/MyLetter.tex tux@sun:/tmp
# リモート -> ローカル
scp tux@sun:/tmp/MyLetter.tex ~
  
[Tip]-l オプションについて

ssh コマンドでは -l オプションを利用する ことで、リモート側のユーザを指定することができます (ユーザ名@ホスト 形式での指定と同じ意味です) 。ですが、 scp での -l は、 scp で使用するネットワーク 帯域を制限する意味で使用します。

正しいパスワードを入力すると、 scp はデータ転送を開始します。開始と同時に進捗 状況が表示され、コピー対象のファイル転送が終了するまでの時間を表示します。 -q オプションを指定すると、これらの出力を省略することができます。

scp ではディレクトリ全体をコピーするための再帰コピー機能が用意されています:

scp -r src/ sun:backup/

上記を実行すると、 src ディレクトリとそのサブディレクトリ 内にある全ての内容を、 sun 内の ~/backup ディレクトリにコピーする意味になります。なお、サブディレクトリが存在しない 場合は、自動的に作成されます。

なお、 -p オプションを指定すると、ファイルのタイムスタンプを 維持するようになります。また、 -C オプションを指定すると、 データ転送時に圧縮機能を利用するようになります。この圧縮機能により転送すべき データ量を減らすことができますが、プロセッサに対してそれなりの負荷がかかります。

13.3. sftp—機密保護機能付きのファイル転送

複数のプログラムを異なる場所にコピーするような場合は、 scp の代わりに sftp が便利です。これは通常の ftp コマンドの ように、対話的にコマンドを入力して実行するシェルとして動作します。利用可能な コマンドの一覧を表示するには、 sftp のシェルから help と入力してください。また、さらに詳しい説明は sftp (1) のマニュアルページに あります。

sftp sun
Enter passphrase for key '/home/tux/.ssh/id_rsa': 
Connected to sun.
sftp> help
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
[...]
  

13.4. SSH デーモン (sshd)

ssh や cp のような SSH クライアントプログラムで作業を行なうためには、サーバ (SSH デーモン) が裏で動き、 TCP/IP ポート 22 で接続を 待ち受けていなければなりません。デーモンは初回の起動時に 3 種類の鍵対を 生成します。それぞれの鍵対は機密鍵と公開鍵から構成されるもので、一般には 公開鍵ベースの手順と呼ばれます。 SSH を介した通信の機密を保持するため、 機密鍵へのアクセスはシステム管理者に限定しておく必要があります。既定の インストールでは、それらのファイルパーミッションは自動的に適切な値が設定 されます。機密鍵は SSH デーモンのみが読み取れればよいものであるため、 SSH デーモン以外には読み取れないようになっていて、公開鍵 (.pub という拡張子になっています) は接続が開始された 時にクライアントに送信されるものであるため、すべてのユーザから読み取ること ができるようになっています。

接続は SSH クライアント側から行なわれます。接続が行なわれると、待ち受けて いた SSH デーモンが SSH クライアントの間でプロトコルやソフトウエア バージョンなどの識別情報を交換し、正しくないポートに接続してしまったような ことを防ぐようになっています。なお、 SSH デーモンから起動された子プロセスが リクエストに対する応答を行なうため、デーモン側では複数の SSH 接続を同時に 受け入れることができます。

SSH サーバとクライアントの間の通信では、 OpenSSH はバージョン 1 と 2 の SSH プロトコルに対応しています。既定ではバージョン 2 を使用するようになっています が、 -1 オプションを指定することでバージョン 1 に強制する こともできます。

SSH のバージョン 1 を使用する場合、サーバはまず公開鍵とサーバ鍵を送信します。 サーバ鍵は毎時生成される鍵で、これら 2 種類の鍵を利用し SSH クライアント 鍵が自由に設定し、サーバ側に送信するセッション鍵を暗号化できるようになって います。 SSH クライアントでは、使用する暗号化方法もサーバ側に送信します。 SSH プロトコルのバージョン 2 ではサーバ鍵を必要とせず、 Diffie-Hellman と 呼ばれるアルゴリズムを利用して鍵の交換を行ないます。

ホスト側の機密鍵とサーバ鍵は、いずれもセッション鍵の暗号を解除するのに絶対に 必要となるもので、公開鍵からは決して導き出すことのできないものです。これにより、 接続先の SSH デーモンだけが機密鍵を利用して、セッション鍵の暗号を解除できる 仕組みになっています。接続当初の通信のやりとりを見たい場合は、 SSH クライアント 側で -v オプションを指定し、デバッグモードを有効にしてください。

/etc/ssh/ 内に保存されている公開鍵と機密鍵については、 機密を保持できる外部媒体に保管しておくことをお勧めします。このようにすること で、鍵が改変されてもそれを検出することができるほか、新しくシステムをインストール した場合でも、元の鍵を使い続けることができるようになります。

[Tip]既存の SSH ホスト鍵について

既に何らかの Linux がインストールされているマシンに openSUSE を インストールした場合、インストール処理内でもっともアクセス日時の新しい SSH の鍵を自動的に取り込みます。

あるリモートのホストに対してはじめて SSH 接続を行なうと、クライアント側では そのホストの公開鍵を ~/.ssh/known_hosts ファイル内に 保存します。これにより、 man-in-the-middle 攻撃 (中間者攻撃) を防ぐことが できます。中間者攻撃とは、ホスト名や IP アドレスを偽って本来とは異なる偽の サーバに接続させる攻撃で、あらかじめ ~/.ssh/known_hosts 内に正しい公開鍵を登録していれば、鍵が変化したことによってこれを検知すること ができます。サーバ側でも、正しい公開鍵に対応する機密鍵を持っていないこと から、セッション情報を解読することができなくなり、クライアント側の機密を 維持することができます。

ホスト側の公開鍵が変更された場合 (このようなサーバに接続する際は、 あらかじめ何らかの方法でこれを確かめておく必要があります) は、 ssh-keygen -r ホスト名 で古いほうの鍵を削除することができます。

13.5. SSH 認証の仕組み

認証でもっとも単純な形態は、ユーザがログインする際にそのユーザの パスワードを入力させる形態です。しかしながら、リモートのマシン上に 登録されたユーザのパスワードだけでは保護が不十分です。また、 これらのパスワードは変更される場合があります。たとえば root のアクセスを許可するような場合、管理者は root のパスワードを 変更したりすることなく、より明示的に不正なアクセスを拒否する必要が あります。

ユーザのパスワードを入力せずにログインさせたいような場合は、ユーザ側で 生成した SSH 鍵対を利用して認証を実施します。ユーザ側で生成した鍵対は、 公開鍵 (id_rsa.pub または id_dsa.pub) と機密鍵 (id_rsa または id_dsa) が対になっています。

パスワード無しでのログインを行なうには、生成した鍵対のうち公開鍵を、 SSH サーバの ユーザ のホームディレクトリ内、 ~/.ssh/authorized_keys ファイルに保存します。 このような方法を採ることで、ログインに関して完全な制御を実現することが できます。これは公開鍵を追加したり削除したりするには、そのユーザで (パスワードなどによる) ログインを行なう必要があるためです。

最大限のセキュリティを実現するため、これらの鍵はパスフレーズで保護して おくべきです。このパスフレーズは ssh, scp, sftp を利用するたびに入力 しなければならないもので、単純なパスワード認証に比べると、パスフレーズは 直接ユーザに紐付く情報ではなく独立した情報であるため、より安全性を 高めることに繋がります。

上述の鍵ベースの認証以外にも、 SSH ではホストベースの認証に対応しています。 ホストベースの認証を利用すると、一方のホストにいるユーザ (信頼される側) は 他方のホストにいるユーザ (信頼する側) としてログインすることができるように なります。これには両方のホストでその機能を有効にする必要があるほか、信頼 する側とされる側で同じユーザ名である必要があります。 openSUSE では 鍵ベースの認証が設定されているため、ホストベースの認証については、ここでは 説明していません。

[Note]ホストベースの認証を利用する場合のファイルパーミッションについて

ホストベースの認証を使用する場合、 /usr/lib/ssh/ssh-keysign (32 ビットシステムの場合) または /usr/lib64/ssh/ssh-keysign (64 ビットシステムの場合) に対して、 setuid ビットを設定する必要があります。 これは openSUSE では既定で設定されない項目です。ホストベースの認証を 使用する場合は、ファイルのパーミッションを手作業で設定してください。 対応の際には、 /etc/permissions.local ファイルを使用すると、 openssh のセキュリティ更新が発生したような場合でも setuid ビットを保持し 続けることができます。

13.5.1. SSH 鍵の生成

  1. 既定のパラメータ (RSA, 2048 ビット) で鍵を生成するには、 ssh-keygen コマンドを実行します。

  2. Enter を押して既定の場所 (~/.ssh/id_rsa) に鍵を保存するか、 もしくは独自の場所を指定します。

  3. 10 から 30 文字程度で構成されるパスフレーズを入力します。 パスフレーズについては必ず設定しておくことを強くお勧めします。

なお、自分自身以外には機密鍵にアクセスできないようになっていることを、 必ず確かめてください (ファイルのパーミッションを 0600 であれば問題ありません) 。また、機密鍵を他のユーザに対して開示しては なりません。

既存の鍵対に対するパスフレーズを変更するには、 ssh-keygen -p コマンドを使用します。

13.5.2. SSH 鍵のコピー

作成した公開鍵をリモート側の ~/.ssh/authorized_keys にコピーするには、 ssh-copy-id コマンドを使用します。 ローカル側で ~/.ssh/id_rsa.pub 以下に保存されて いる鍵であれば、単純なコマンドで実施できます。 DSA 鍵や他のユーザの鍵を コピーしたい場合は、パスを指定する必要があります:

# ~/.ssh/id_rsa.pub
ssh-copy-id -i tux@sun

# ~/.ssh/id_dsa.pub
ssh-copy-id -i ~/.ssh/id_dsa.pub  tux@sun

# ~notme/.ssh/id_rsa.pub
ssh-copy-id -i ~notme/.ssh/id_rsa.pub  tux@sun

鍵をコピーするには、リモートユーザ側のパスワードを入力してください。 登録済みの鍵を削除するには、 ~/.ssh/authorized_keys ファイルを手作業で編集します。

13.5.3. ssh-agent コマンドの使用

様々な SSH 接続を利用して作業を行なう場合、それぞれの接続に対してパスフレーズを 入力するのは、非常に面倒な作業です。この問題を解決するため、 SSH パッケージには ssh-agent と呼ばれるツールが付属 しています。これは X や端末セッションが維持されている間、機密鍵を保持 することができるツールです。その機密鍵を必要とする他のウインドウや プログラムを ssh-agent の子プロセスとして 動作させることで、 ssh, scp, sftp に必要な環境変数が設定され、自動的なログインを 実現することができます。詳しくは man 1 ssh-agent をお読みください。

ssh-agent を起動したあとは、 ssh-add コマンドで鍵を追加します。この時点でパスフレーズの入力を求められます。 いったんパスフレーズを入力すると、それ以降はパスフレーズを再度入力したり することなく SSH の各コマンドを使用できるようになります。

13.5.3.1. ssh-agent の X セッション内での使用

openSUSE では、 GNOME や KDE のディスプレイマネージャが自動的に ssh-agent を起動します。起動したエージェントに 対して、 X セッションの起動時に ssh-add を実行して 鍵を追加するには、下記の手順で行ないます:

  1. 設定対象のユーザでログインし、 ~/.xinitrc ファイルが存在しているかどうかを確認します。

  2. 存在していない場合は、既存の雛形を使用するか、 /etc/skel ディレクトリからコピーします:

    if [ -f ~/.xinitrc.template ]; then mv ~/.xinitrc.template ~/.xinitrc; \
    else cp /etc/skel/.xinitrc.template ~/.xinitrc; fi
  3. 雛形をコピーした場合は、下記のような行を検索し、その行のコメント マーク (#) を削除します。既に ~/.xinitrc が 存在していた場合は、下記の行を追加します (コメントマークは外して ください)。

    # if test -S "$SSH_AUTH_SOCK" -a -x "$SSH_ASKPASS"; then
    #       ssh-add < /dev/null
    # fi
  4. あとは新しく X セッションを起動すると、 SSH のパスフレーズ入力を 求められるようになります。

13.5.3.2. ssh-agent の端末セッション内での使用

端末セッションから利用する場合は、手作業で ssh-agent を起動して ssh-add を実行する必要があります。 ssh-agent の起動方法には 2 種類の方法があり、 1 つは 既存のシェル上で新しい bash シェルを起動する方法、もう 1 つは既存の シェルに置き換わる形で新しいシェルを起動し、必要な環境変数を設定する 方法です。

ssh-agent -s /bin/bash
eval $(ssh-agent)
    

エージェントを起動した後は、 ssh-add を実行して必要な 鍵を追加します。

13.6. ポート転送

ssh は TCP/IP 接続を転送する用途でも使用することができます。この機能は SSH トンネル とも呼ばれ、暗号化された通信経路を 介して、あるポート宛の通信を別のマシンに転送します。

上記のコマンドを実行すると、 jupiter のポート 25 (SMTP) に宛てた接続が、 暗号化された状態で sun の SMTP ポートに転送されるように なります。これは特に SMTP-AUTH や POP-before-SMTP の機能を持たない SMTP サーバを利用している場合に便利な仕組みです。接続を転送することで、 ネットワーク上離れた任意のホストからの接続を、 自宅 などの メールサーバに転送することができるためです。

ssh -L 25:sun:25 jupiter

同様に、 jupiter からの全 POP3 リクエスト (ポート 110) を sun 上の POP3 ポートに転送するには、下記のように実行します:

ssh -L 110:sun:110 jupiter

なお、いずれのコマンドとも root で実行しなければなりません。 これは特権ポートと呼ばれるポートを使用しているためです。また、電子メールは 通常のユーザからも SSH 接続を通して送受信することができます。メールソフト からは localhost に設定してお使いください。 上述のプログラムについて、追加情報はマニュアルページと /usr/share/doc/packages/openssh にある OpenSSH の ドキュメンテーションに記述されています。

13.7. YaST を利用した SSH デーモンの設定

YaST の SSHD 設定モジュールは、既定のインストールには含まれていません。 利用するには yast2-sshd パッケージを インストールしてください。

sshd サーバを YaST で設定するには、 YaST を起動して ネットワークサービス+SSHD の設定 を選択してから、下記の手順を行ないます:

  1. 一般 タブでは、 sshd が待ち受けるポートを SSHD TCP ポート で選択します。既定値は 22 で、 複数のポートを指定することもできます。新しいポートを追加するには、 追加 を押してからポート番号を入力し、 OK を押します。ポートを削除するには、表内から削除するポートを選んで 削除 を押したあと、確認メッセージに応答します。

  2. また sshd デーモンがサポートすべき 機能を選択することもできます。 TCP 転送機能を無効化するには、 TCP 転送を許可する のチェックを外します。ただし、 TCP 転送機能を無効化しても、ユーザがシェルにアクセスできる限り、 セキュリティの改善にはならないことに注意してください。シェルにアクセス できてしまえば、独自の転送プログラムを起動できてしまうためです。 TCP 転送について、詳しくは 13.6項 「ポート転送」 をお読みください。

    X Window System の転送を無効化するには、 X11 転送を許可する のチェックを外します。このオプションが無効化されていると、クライアント から X11 転送の要求が行なわれた際にエラーを返します。ただし上記同様に 独自の転送プログラムを起動できてしまうことに注意してください。 X Window System の転送について、詳しくは 13.1項 「ssh—Secure Shell (機密を保持するシェル)」 をお読みください。

    また 圧縮を許可する では、サーバとクライアント間の 通信を圧縮するかどうかを選択します。

  3. ログイン設定 のタブでは、一般的なログインや認証に 関する設定を行ないます。 ログイン時に '本日のメッセージ' を 表示する では、ユーザが対話的にログインした場合に /etc/motd 内のメッセージを表示するかどうかを設定 することができます。また、 root ユーザのログインを無効化したい場合は、 root ログインを許可する のチェックを外します。

    最大認証試行回数 の設定では、 1 回の接続あたりに 許可される、最大の認証試行回数を設定します。 RSA Authentication の設定では、純粋な RSA による認証 を許可するかどうかを設定します。このオプションは SSH プロトコルの バージョン 1 にのみ適用されます。また、 Public Key Authentication では、公開鍵による認証を許可するかどうかを設定します。こちらの設定は プロトコルバージョン 2 にのみ適用されます。

  4. プロトコルと暗号化 のタブでは、対応すべき SSH プロトコル のバージョンを設定することができます。バージョン 1 のみ、バージョン 2 のみ、 バージョン 1 と 2 の両方の中から選択することができます。

    許可する暗号化方法 では、許可するすべての暗号化が一覧で 表示されます。一覧から特定の暗号化方法を削除するには、一覧から選んで 削除 を押します。逆に一覧に暗号買う方法を追加するには、 ドロップダウンリストから選んで 追加 を押します。

  5. 最後に OK ボタンを押すと、設定を保存することができます。

13.8. さらなる情報

http://www.openssh.com

OpenSSH の Web ページ

http://en.wikibooks.org/wiki/OpenSSH

OpenSSH Wikibook

man sshd

OpenSSH デーモンのマニュアルページ

man ssh_config

OpenSSH のクライアント側設定ファイルのマニュアルページ

man scp , man sftp , man slogin , man ssh , man ssh-add , man ssh-agent , man ssh-copy-id , man ssh-keyconvert , man ssh-keygen , man ssh-keyscan

ファイルのコピー (scp, sftp) やログイン (slogin, ssh) 、鍵管理などの各マニュアルページ。


openSUSE セキュリティガイド 13.1