SSH Port ForwardingでLAN内のサーバにリモートアクセスする

OpenSSHのPort Forwarding機能を使うと、接続先のサーバを経由してLAN内のサーバにリモートでアクセスすることができる。 調べてみると普通のPort Forwarding以外にもバリエーションがあることを知ったので、それらの内容をメモ。

Local Port Forwarding

いわゆる普通のPort Forwarding。sshdサーバを中継し、その先のLAN内のサーバにアクセスする。

home-server を起点とし、remote-server にsshdが立っているとする。 このとき下記のように-Lオプションを指定して接続することで、localhost:8080へのアクセスが remote-server から見た192.168.0.2:80へのアクセスとなる。

[user@home-server]
$ ssh -L 8080:192.168.0.2:80 user@remote-server

ここで home-server のブラウザからhttp://localhost:8080/にアクセスすると、remote-server を経由してLAN内のhttp://192.168.0.2:80/にアクセスした内容が返ってくる。

ただし、HTTPリクエスト中のHostヘッダは書き換えられない(この場合はそのままlocalhost:8080となる)ため、HTTPサーバ側でVirtualHostを利用している場合はうまく表示されない可能性がある。これをどうにかするには、下記のように/etc/hosts(Windowsの場合はC:\Windows\System32\drivers\etc\hosts)を使ってアクセスしたいドメイン名を127.0.0.1に向ける。

127.0.0.1       httpserv.example.com

あるいは後述するDynamic Port Forwardingを用いて、SOCKS Proxy経由でアクセスする。

Remote Port Forwarding

ファイアウォールなどにより外部から remote-server へのSSHアクセスができない場合は、逆向きにコネクションを張ることもできる。 このとき、sshdは home-server 側で立て、remote-server 側で立てる必要はない。

まず、remote-server を起点とし、home-server に向け下記のように-Rオプションを指定して接続する。

[user@remote-server]
$ ssh -R 8080:192.168.0.2:80 user@home-server

この状態で、home-server 側のブラウザからlocalhost:8080にアクセスすると、Local Port Forwardingの場合と同様に、LAN内のhttp://192.168.0.2:80/にアクセスした内容が返ってくる。

外部から remote-server に向けたアクセスがすべて拒否されている場合でも、remote-server から外部へ向けて許可されているポートがあればこの方法が適用可能である。

Dynamic Port Forwarding

Dynamic Port Forwardingを使うと、sshdサーバをSOCKS Proxyとして使うことができる。 これを利用することで、LAN内のVirutalHostを使用しているHTTPサーバにアクセスしたり、手元のネットワークのファイアウォールを迂回することができる。

home-server を起点とし、remote-server にsshdが立っているとする。 このとき下記のように-Dオプションを指定して接続することで、home-server から見たlocalhost:1080がSOCKS Proxyとなる。 なお、SOCKS Proxyのポート番号はtcp/1080が標準的に用いられる [RFC 1928]

[user@home-server]
$ ssh -D 1080 user@remote-server

ここで home-server のブラウザ設定からlocalhost:1080をSOCKS Proxyとして指定すると、ブラウザからのすべてのアクセスが remote-server を経由したアクセスとなる。

まとめ

  • リモートのsshdを使う → -L
  • 手元のsshdを使う → -R
  • リモートのsshdをProxyとして使う → -D

参考リソース