パケットリピータstoneを使う
2009-11-26 : この文書はstoneおよびSSHなどを使用したポート転送についてまとめています
- 関連サイト
- Stone -- http://www.gcd.org/sengoku/stone/Welcome.ja.html
- PortForwarder -- http://toh.fuji-climb.org/pf/JP/
stoneとは
stone は、アプリケーションレベルの TCP & UDP リピーターです。ファイアウォールの内から外へ、あるいは外から内へ、TCP あるいは UDP を中継します。
ということで、ファイアウォールを超えるときになかなか便利なツールです。
組織によっては外部のサーバにはポート80番(HTTP)または443(HTTPS)にしか接続を許していないところもあると思いますが、「自宅のファイルをネット越しにダウンロードしたい」などを実現するためのツールです。Windows版はバイナリ(98/NT/2000/XP)が提供されています。Linux環境では自分でビルドするかディストリビューションに収録されているものを使います。Vine 5.0ではaptでインストールすることができました。
stoneの設定
サーバ側とクライアント側で設定が必要ですが、それほど難しくはありません。サーバ側(通常自宅サーバになると思います)ではデーモンとして起動しておきます。ここでの例はstone 2.3eを使用しています。
サーバ側
- SSLを使用するための証明書を作成する
# cd /usr/share/ssl/certs # make stone.pem
- /etc/stone.confの設定
/* -l: sends error messages to the syslog instead of stderr. */ -l /* -D: runs as a Unix daemon. */ -D /* -o: process owner, -g: process group. */ -o 99 -g 99 localhost:22 443/ssl
こんな感じ。localhost:22 443/sslではポート443(HTTPS)で待ち受けておいて22(SSH)に転送する設定になります。/sslオプションを付けているので経路はSSLによる暗号化が行われます。RPMパッケージなどでインストールすると/etc/init.dに起動スクリプトが追加されるのでchkconfigで起動スクリプトをONにすれば使用可能になります。
なお設定ファイルを読み込む場合はcppが必要になるようです。cppが存在しない場合は設定ファイルが存在していてもfile not foundエラーが出るので注意!
クライアント側
Windowsの場合はポート22を使ってもいいと思いますが、Linuxで使う場合は22以外になるでしょう。例えばポート10443で待ち受けてサーバの443にover SSLで転送する場合は以下のようになります。
% stone myserver:443/ssl 10443
ここのmyserverは転送先のサーバアドレスです。
面倒なのですが無駄にリソースを使わないように使用するときのみ接続しています。
stoneとSSHによる接続
stoneとSSHのPort Forwardingを使うことでファイアウォールを超えつつ任意のポートに接続するということが可能になります。経路は以下の通り。
[クライアント] -> (SSH) -> (Stone) -> (SSHD) -> [接続先] |<--ここでポート転送-->|
こんな感じだと思います。Linuxの場合は通常のsshコマンド、Windowsの場合はPortForwarderあたりを使うのが簡単でよさそうです。Linuxの場合手順はこんな感じ。
- 転送用接続の準備
- stoneで接続(例:自宅サーバmyhome.foo.comのポート443 over SSLでローカルポート10022を使用)
% stone myhome.foo.com:443/ssl 10022
- SSHのポート転送を使用する(上記で待ち受けている10022に接続し自宅ネットワークの192.168.0.1のWebサーバに転送)
% ssh -L 8080:192.168.0.1:80 -oPort=10022 nobrin@localhost
この段階でローカルの8080に接続すると自宅ネットワークの192.168.0.1:80に接続される。sshの-Lオプションはローカルポート(待受ポート):転送先アドレス:転送先ポートという書式です。転送先アドレスは接続先のサーバから見たアドレスなので注意して下さい。
- stoneで接続(例:自宅サーバmyhome.foo.comのポート443 over SSLでローカルポート10022を使用)
- 転送を利用する
例えばFirefoxなどでhttp://localhost:8080/に接続すると自宅ネットワークのhttp://192.168.0.1/に接続される。[クライアント] -> 8080(SSH) -> (stone) -> (SSHD[myhome.foo.com]) -> 80(Webサーバ[192.168.0.1]) |-> 自宅ネットワーク
変な書き方ですがイメージとしてはこんな感じでしょうか。
半分自分のメモ用なのでちょっとわかりにくいかも・・・
stoneとSSHによるSMB接続の転送
2009-11-26 : Windows環境での転送
Windows環境になってしまうのでLinuxで遊ぼう!とは少し趣旨がずれてしまうのですが、stoneの扱いと言うことでここにメモしておきます。
stoneとSSHでポート転送ができることは解説しましたが、ここではファイアウォール越しにWindowsファイル共有を使用するために、Windows環境のSMB接続(Windowsファイル共有)をStoneとSSH経由で転送してみます。SMB over SSH + Stoneって感じでしょうか
Linux環境だと前述のSSH転送で割と簡単に実現できると思うのですが、Windows環境で実現するためにはループバックデバイスを使用するようです。
ループバックデバイスの作成
SMB接続で使用するポート139は既に使われているので新たにループバックデバイスを作成して、ループバック経由で転送するようにします。
- ループバックデバイスの追加
- [コントロールパネル] -> [ハードウェアの追加]からハードウェアの追加ウィザードを起動します
- 「既にこのハードウェアをコンピュータに接続していますか?」と聞かれたら「はい」を選択
- [新しいハードウェアデバイスの追加]を選択
- [一覧から選択したハードウェアをインストールする(詳細)]を選択
- [ネットワークアダプタ] -> [Microsoft] -> [Microsoft Loopback Adapter]を選択
- インストール完了
- ループバックデバイスの設定
- [マイネットワーク]を右クリックして[プロパティ]を開きます
- 新たに追加された接続(例:ローカルエリア接続 2など)の名前をわかりやすいものに変更(例:ループバック接続)
- 右クリックして[プロパティ]を開きます
- Microsoftネットワーク用ファイルとプリンタ共有のチェックを外す
- インターネットプロトコル(TCP/IP)のプロパティを変更
- 次のIPアドレスを使うの項目でIPアドレス、サブネットマスクを設定
例:192.168.0.1/255.255.255.0とか169.254.0.1/255.255.0.0 - ディフォルトゲートウェイとDNSサーバは空白でよい
- [詳細設定] -> [WINS]のNetBIOS設定で[NetBIOS over TCP/IPを無効にする]を選択
- 次のIPアドレスを使うの項目でIPアドレス、サブネットマスクを設定
以上でループバックデバイスが作成できました。不要になって削除するときはデバイスマネージャから行います。
転送設定
転送はStone + SSH Port Forwardingと同様です。ここではループバックデバイスのIPアドレスを169.254.0.1に設定したとします。
- stoneで接続
% stone myhome.foo.com:443/ssl 10022
- SSHでポート転送
- CygwinのSSHを使う場合
% ssh -L 169.254.0.1:139:localhost:139 -oPort=10022 nobrin@localhost
- PortForwarder 2.9.0を使う場合の設定ファイル
Host MyHome HostName localhost Port 10022 User nobrin LocalForward 169.254.0.1:139 localhost:139 Compression yes
例えばconfig.txtにこのように記述してPortForwarderでMyHomeに接続するとポート転送が行われます。
- CygwinのSSHを使う場合
この状態で転送が行われるようになっているので、[スタートメニュー] -> [ファイル名を指定して実行]で\\169.254.0.1を入力すると接続できるはずです。
[クライアント] -> [ループバック(169.254.0.1:139)] -> (SSH) -> (stone) -> (SSHD[myhome.foo.com]) -> [SAMBAなど]
stoneでのクライアント認証
2011-11-21 : 追加
以上のようにstoneを使えば、ファイアウォールに穴を開けることができますが、反面大きなキケンを伴います。そこでSSLクライアント認証を行うことで証明書がない場合にはアクセスできないようにします。必要なファイルは以下の通り
- 上で作成したstone.pem
- プライベート認証局の証明書cacert.pem
- プライベート認証局で署名された個人証明書および秘密鍵
以上のファイルがそろっていれば可能なようです。
サーバ側設定ファイル
- /etc/stone.confの設定例
-l /* エラーメッセージをSTDERRではなくsyslogに送る */ -D /* UNIXデーモンとして起動 */ -o 99 -g 99 /* プロセスオーナーとグループ */ -dd /* デバッグレベル */ -z key=/usr/share/ssl/certs/server.key /* 秘密鍵の指定 */ -z cert=/usr/share/ssl/certs/server.crt /* 証明書の指定 */ -z CAfile=/usr/share/ssl/demoCA/cacert.pem /* プライベート認証局の証明書 */ -z verify /* クライアント認証を行う */ -z re1="^/C=JP/ST=Tokyo/O=Private/CN=My Private CA$" /* Depth=1の正規表現 */ -z re0="^/C=JP/ST=Tokyo/O=BioKids/CN=Dobuo$" /* Depth=0の正規表現 */ -z verbose /* SSL認証時の詳細なログを出力 */ localhost:22 443/ssl
このような感じになります。グレーで示したオプションは状況に応じて入れて下さい。初めに作成したstone.pemを使用する場合、秘密鍵および証明書(署名済み公開鍵)を指定して下さい。Vine 5.2の場合、/usr/share/ssl/certs/stone.pemがディフォルトで使われるため、そのstone.pemを使う場合は指定する必要はありません。
またプライベート認証局の証明書はプライベート認証局を作成した際に作成される証明書になります。
青で示したre0、re1はそれぞれ証明書のDepthに対する正規表現であり、ざっくり説明するなら自分自身がDepth=0、署名した認証局がDepth=1、さらにそれに署名した認証局がDepth=2…というようになるみたいです。
クライアント側の設定
以上のようにサーバを設定されているとき、接続の際には証明書を提出しなければなりません。それらの指定は-qオプションで行うことができます。
% stone -q key=mykey.pem -q cert=mycert.pem myhome.foo.com:443/ssl 10022
このように個人の秘密鍵であるmykey.pemおよび証明書mycert.pemを指定します。
参考サイト
- stoneでクライアント認証をしよう -- http://mizushima.ne.jp/Windows/SSL/stone/stone-client.php
- stone開発者の仙石氏のブログ
- stoneのSSL認証(1) -- http://www.gcd.org/blog/2006/08/94/
- stoneのSSL認証(2) -- http://www.gcd.org/blog/2006/08/95/
- stoneのSSL認証(3) -- http://www.gcd.org/blog/2006/08/96/
コメント
間違い等あればコメント下さい