ssh の SOCKS 化

防火壁によりネットワークが分断されているところで中継により通信できるように するためのプロトコルとして SOCKS が ありますが、ここでは、 ssh を SOCKS 対応にする方法を説明します。

ここで説明する方法は、 移植版 OpenSSH を対象としています。 また、 SOCKS の実装として、 Dante を用います。

追記

以下に示す方法は、 OpenSSH 3.5 以降で SSH1 プロトコルの Rhosts with RSA ホスト認証を使わない場合は、意味がなくなっています。 ssh コマンドを setuid しておかなくても良いからです。 普通のコマンドと同じように socksify ssh として実行してください。

ただし、 Hostbased 認証と ssh-keysign を有効にしていると、 次のようなエラーが出ます。

/usr/libexec/openssh/ssh-keysign: error while loading shared libraries: libdl.so: cannot open shared object file: No such file or directory
ssh_keysign: no reply
key_sign failed

これを避けるためには、オプションで Hostbased 認証を無効にしてください (-o HostbasedAuthentication=no)。 シェルスクリプトにしておくと便利です。 なお、 SOCKS を使うと Hostbased 認証を使うことは原理的にできません。

以下は資料のために残しておきます。 RPM パッケージの配布は中止しています。

方法

RPM 系 Linux ディストリビューションの場合

RPM パッケージを用意しています。

バイナリインストールと、 ソースパッケージから構築する方法とがあります。 バイナリは、 Vine Linux 2.1 (i386) 用です。

いずれの場合も、 Dante を RPM でインストールする必要があります。 Dante のバイナリパッケージも用意しています。 Dante の配布に spec ファイルが含まれているので、それで構築することもできます。

バイナリインストール

RPM 置き場から、 RPM パッケージをダウンロードします。 Dante は、 dante のみインストールすれば良いです。 OpenSSH は、 openssh が SOCKS 化されていないもの、 openssh+dante が SOCKS 化されているものです。普通は、クライアントのみ SOCKS 化すれば充分なので、 openssh, openssh+dante-clients, openssh-server の組合わせでインストールします。 openssh+dante-clients は以前のバージョンの openssh-clients から アップグレードできます。 openssh-askpass と openssh-askpass-gnome はお好みでどうぞ。

ソースパッケージから構築

ソース RPM 置き場から、 ソース RPM パッケージをダウンロードします。 OpenSSH のソースを持っている場合は、代りに パッチと spec ファイルのみダウンロードしても良いです。

openssh を構築する前に、 dante と dante-devel をインストールしておく 必要があります。

openssh の RPM を構築するときに、 rpm コマンドの引数に --define 'with_dante 1' をつけると openssh+dante パッケージが、 つけないと openssh パッケージができます。 このようにして2種類のパッケージを作り、 サブパッケージ毎に SOCKS 化したものとしないものとを選んでインストールします。 バイナリインストールの項も参照してください。 一般的な RPM の構築の仕方については、 Vine Linux のマニュアルMaking RPM 等を参照してください。

OpenSSH のソースにパッチを当ててコンパイル

  1. まず、 Dante バージョン 1.1.7 以降をインストールします。
  2. OpenSSH のソースを展開します。
  3. OpenSSH のソースにパッチを当てます。 OpenSSH のソースを展開してできたディレクトリで、次のコマンドを実行します。
    patch -p1 < パッチファイル
  4. configure スクリプトを更新します。 GNU autoconf が必要です。 autoheader, autoconf とコマンドを2つ実行します。
  5. configure--with-dante オプションをつけて 実行します。
  6. 後は、普通に make, make install します。

この方法だと、サーバもクライアントも全て SOCKS 化されてしまいます。 サーバを SOCKS かするのは無意味なのでそれは避けたいという場合は、 先に --with-dante オプションをつけないでコンパイル・インストール した後、 --with-dante オプションをつけて make して、 make install せずに ssh だけ手動でインストールするのが 良いでしょう。

関連ファイル

他から入手するもの

RPM を利用する場合は不要

OpenSSH 移植版
配布サイト
Dante バージョン 1.1.7 以降
KDD R&D Labs INC. のミラーサイト

ここで配布しているもの

openssh+dante.patch
OpenSSH 2.9p2 に対するパッチ
openssh.spec
RPM spec ファイル
RPM
ソース及び i386 用バイナリ

詳細

このパッチは、次の方法で SOCKS 化しています。 これは、 OpenSSH に限らず一般的に使える方法です。

  1. CPP のマクロで、 connect などのソケット関連の関数の呼び出しを SOCKS ライブラリの関数の呼び出しに置き換える。
  2. オブジェクトを SOCKS ライブラリ (libsocks) とリンクする。

CPP のマクロは、 Dante に含まれるヘッダファイル socks.h で定義されています。 このヘッダファイルをできるだけ早い段階で include することにより SOCKS 化が行えます。 OpenSSH の場合、 defines.h の先頭で include すれば 良いです。

背景

このパッチを作った背景として、次のようなことがあります。

ssh は後から SOCKS 化することができない。
Dante には、 socksify という、既存のソフトウェアを SOCKS 化する ラッパスクリプトが含まれていますが、これは ssh のような setuid されている コマンドにはセキュリティ上の保護機構のために適用することができません。 というのは、 SOCKS 化するというのはコマンドの振る舞いを変えることであり、 これを認めるとコマンドをインストールした人 (管理者) の想定外のことが その人の権限で実行されてしまってセキュリティ上問題になるというわけです。 このため、 setuid コマンドの SOCKS 化は管理者が初めから行っておかなければ なりません。
OpenSSH 移植チームは SOCKS 対応をしない。
SSH Communications Security 版の ssh は SOCKS (NEC 版) 対応していました。 このため、 OpenSSH でも対応して欲しいという要望はしばしば出るのですが、 OpenSSH 移植チームは次の理由でこれを拒んでいます。
ProxyCommand は使いにくい・効率が悪い
ProxyCommand には、 SSH サーバへの接続を代行するコマンドを指定できます。 しかし、 SOCKS 化するために使える標準的なコマンドがありません。 また、 ProxyCommand を使うとプロセス間通信が1つ余分に入るために 効率が悪くなります。


西村 大介 <nishi@graco.c.u-tokyo.ac.jp>