2008/12/31(Wed)手軽で便利なssh Local PortForward
2008/12/31 20:50
まずはsshの説明から
sshはSecure SHellの略だが、その名の通り、通信路のデータを暗号化して安全に端末を操作できるものである。通常は、端末を制御するためのものだが、これをトンネル代わりに使うことで、平文通信をしているプロトコルの通信を、暗号化通信にかえることができる。
これをポートフォワードと言う。
今回はこれについてのTips。
VNCを使う場合を例にとって軽く説明すると、遠隔地にある*1VNCサーバーにアクセスする際、
MyPC port:12456 ---------------------------> HostPC port:5900 (自動割り当て) ( ---> : 平文通信) ( ===> : 暗号通信)という感じでアクセスされる。当然、HostPCは5900番をグローバルから見えるようにする必要がある。
このままでは簡単に制御権を見ず知らずの人に獲得されてしまうので、VNC Passwordなどを用いるがあまり安全ではない。しかも、VNCのプロトコル内に、キーボードの平文情報が流れ、二次的な流出もありうる。
そこで、ssh PortForward。PortFowardにはLocalとRemoteと二種類あり、次のような使い方ができる。
- Local
- 相手sshサーバーから見た特定コンピュータのportを、自分のPCのportに割り当てる。
- Remote
- 相手sshサーバーの特定のportに、自分のPCのportを割り当てる。
使いどころ
ここではよく使うであろうLocal Port Forwardに限って説明する。先ほどの例で、VNCサーバーと同じコンピュータ又は、同じネットワークにSSHサーバーが居るなら、このような接続を考える。
(自動割り当て) MyPC port:12456 HostPC port:5900 ↓ ↑ port:1234 ==============> HostPC or sshServer port:22 (好きな番号) ( ---> : 平文通信) ( ===> : 暗号通信)図のように、MyPCとsshサーバーの間は完全に暗号通信になっているので、盗聴の恐れが少ない。
これを実現するには、PuTTY ごった煮版のputty.exeまたは、pfwd.exeを用いるとよい。ここでは、両方の使い方を説明する。
使い方
次のように仮定する。但し、以降sshサーバーとHostPCが同じマシンの場合は、hostpc.example.comを全てlocalhostに置き換えて読んでほしい。
sshServer: ssh.example.com:22
HostPCのVNCサーバー: hostpc.example.com:5900
Windows - putty
MyPCがWindowsの場合は先のPutty.exeを起動し、sshサーバーへの設定を済ませる。ホスト名にsshサーバーのIP/ホストをセット、ポートを適切に設定。
[接続]-[SSH]-[トンネル]と進み、源ポートにローカル側の割り当て番号(Listenしていないポートなら何でもよい)、送り先にHostPCのホスト名とポートを:区切りで書く。
この例では、ローカルの1234番にフォワードさせた。
次に、[追加(D)]をクリックしてから、[開く]。
sshにログインし、その状態でputtyを放置。
あとは、VNCサーバーからlocalhost:1234にアクセスすると、sshサーバーをぐるっと通って、hostpc.example.comの5900番に繋ぎに行ってくれる。
このフォワードの優れているところは、sshサーバーさえ外部からアクセスできれば、5900番を外部に見えるように設定する必要が無いところである。
さらに、sshサーバーとVNCサーバーが同じPCなら、VNCサーバーの接続元をlocalhostに制限することで、LAN内からすらアクセスできなくなり、安全性が高い。
Windows - pfwd
先のPuTTYのリンクで、本家ではなく"ごった煮版"へリンクを張ったのは、便利なpfwd.exeが付属しているからである。pfwd_sample.iniをpfwd.iniにリネームするか、コピーして、次のように設定してみよう。
[SSH] Host=ssh.example.com Port=22 Compression=1 ProtocolVersion=2 PrivateKey= User=myuserid Password= [FORWARD] 01=L1234:hostpc.example.com:5900[SSH]ではPuTTYに設定したセッション情報を使うこともできるし、ここで指定することも可能。PrivateKeyには公開鍵暗号の秘密鍵をセットすることもできる。
[FORWARD]には01,02,03...と番号を増やして好きなだけForwardできる。
こうした後、保存して、pfwd.exeを起動すれば、パスワードを入力するだけで面倒な設定なしに一発でsshサーバーにログインし、フォワード設定をして、タスクトレイに常駐する。
右クリックして、閉じるを選択すれば、終了する。
Linux
Linuxはもっと簡単。ほとんどのディストリビューションにsshコマンドが初期装備されているはずなので。ターミナルを一枚開き、次のように打つ。
$ ssh -L 1234:hostpc.example.com:5900 user@ssh.example.com
一歩進んだ使い方。
MyPC以外のコンピュータも、自分のport:1234を通してhostpc.example.com:5900にアクセスさせる場合、-gを付ける。
但し、使用にはくれぐれも注意。アクセス権のないPCをLocalForwardで素通りさせる危険性があるからだ。*3
$ ssh -g -L 1234:hostpc.example.com:5900 user@ssh.example.com
PortForwardだけさせて、sshでloginしたターミナルが不要な場合は、-fと-Nを付ける。
$ ssh -f -N -L 1234:hostpc.example.com:5900 user@ssh.example.com
Linux Tips
2枚以上のNICが入っているマシンや、IPv4とIPv6の両方のアドレスを持っている場合は、bind addressの設定をするとよい。これは、-Lの3つのパラメータの前にもう一つパラメータを付け、そのNICのアドレスに対してForwardを行うというもの。
省略した場合は、*が割り当てられるので、全てのIPアドレスに対してbindが行われる。
マシンが、192.168.2.11と192.168.11.21というIPアドレスを持っているとして、
$ ssh -L 192.168.2.11:1234:hostpc.example.com:5900 user@ssh.example.comとすれば、192.168.2.11:1234はForwardされるが、192.168.11.21:1234はされない。
IPv6アドレスを指定するには、角括弧で囲む。
$ ssh -L [::1]:1234:hostpc.example.com:5900 user@ssh.example.comこの状況下では
$ telnet localhost 1234 Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused $ telnet ::1 1234 Trying ::1... Connected to ::1. Escape character is '^]'. ~~~応答~~~ Connection closed by foreign host.という挙動を示す。
たまに、bind: Address already in useという警告が表示されることがあるが、これは、複数のNICにフォワードされたという警告であり、使用上は問題ない。
上記のようにbind addressを設定すれば消える。
Linux ssh_config
Linuxでいちいちsshの長ったらしいコマンドを打つのはしゃくなので、登録してしまおう。まずは次のように、パーミッションを制限したディレクトリ、ファイルを作る。
$ mkdir ~/.ssh $ chmod 700 ~/.ssh $ touch ~/.ssh/config $ chmod 600 ~/.ssh/configviやemacs等で~/.ssh/configを編集。
Host example HostName ssh.example.com User myuserid Port 22 LocalFoward 1234:hostpc.example.com:5900 GatewayPorts yesと作り、保存すれば、"ssh -g -L 1234:hostpc.example.com:5900 myuserid@ssh.example.com"と同様の設定になる。
Hostという行から次にHostという行が始まるまでが、一つの設定としてみなされるので、複数定義してよい。
書き方に迷ったら、$man ssh_configをしてみるとよい。