21.7. ssh ポートフォワード機能の活用

ssh のポートフォワード機能を利用すると、ローカルホストの任意のポートに送信したデータを、リモートホストの特定ポートへ転送することができます。また、SSH で暗号化した通信経路の中に、他のセッションを潜り込ませることができるため、POP のように暗号化されていない通信を暗号化できるメリットもあります。メールの受信に SSH のポートフォワード機能を利用した例を図にすると、以下のようになります。

POP サーバー mail.example.com からメールを受信するには、メールクライアントの設定で POP サーバーのホスト名 mail.example.com と POP が使用するポート番号 110 を指定しているはずです。そこで、ローカルホストの任意のポートに接続すると、SSH で暗号化された経路を介して mail.example.com の 110 番ポートに接続されるように設定を行います。実際には、client.mydomain 上で以下のように ssh コマンドを実行します。

$ ssh -L 10110:mail.example.com:110 mail.example.com

-L はローカルホストのポートをリモートホストのポートへ転送するためのオプションです。次の 10110:mail.example.com:110 がポートフォワードの指定です。この指定により、ローカルホストの 10110 番ポートとリモートホストの 110 番ポートが SSH によって結ばれます。このとき指定するローカルポートは適当なポート番号を指定できますが、1024 以下のポート番号を指定するには、root の権限が必要です。最後の mail.example.com は、実際にログインする SSH サーバーです。この例では、mail.example.com 上で SSH サーバーが起動していることが前提です。なお、現在ログインしているユーザーと異なるユーザーでログインするには、リモートホスト名の前に user@ の指定が必要です。

コマンドを実行後、メールクライアントの POP サーバーの設定を localhost、ポート番号の設定を 10110 に変更してメールを受信してみます。いつもどおりにメールを受信できますが、この通信は SSH により暗号化されたセッションの中で行われているため、パスワードやデータが盗聴される心配はありません。

この例では、ローカルホストのポートをリモートホストのポートへ転送していますが、ssh は逆方向のポートフォワードもサポートしています。つまり、リモートホストのポートを転送することも可能です。上記の POP を例にすると、POP サーバー側からクライアントに向けてポートフォワードの設定を行うこともできます。実際には、POP サーバー mail.example.com 上で以下のように ssh コマンドを実行します。

$ ssh -R 10110:localhost:110 client.mydomain

ローカルホストのポートをリモートホストのポートへ転送する際には -L オプションを指定しましたが、リモートホストのポートを転送するには、-R オプションを指定します。次の 10110:localhost:110 がポートフォワードの指定です。この指定では、client.mydomain の 10110 番ポートと localhost(mail.example.com)の 110 番ポートが SSH によって結ばれます。client.mydomain は、実際にログインする SSH サーバーです。この例では、client.mydomain 上で SSH サーバーが起動していることが前提です。コマンドを実行後、client.mydomain のメールクライアントの設定で、POP サーバーを localhost、ポート番号を 10110 に指定すればメールを受信することができます。

このように、SSH により暗号化された通信経路に他のセッションを確立できることは、ssh のポートフォワード機能を利用する 1 つのメリットですが、ファイアウォールを越えて LAN 上のホストへアクセスするための手段としても ssh のポートフォワードは利用されています。例えば、ローカルホストの任意のポートを、ログインした SSH サーバーを介して内部 LAN 上のリモートホストに転送すれば、ローカルホスト上のクライアントから 内部 LAN 上のホストに接続できるようになります。ここでは、自宅の PC からインターネットを経由して社内の LAN 上で動作している Web サーバーにアクセスする場合を例に考えてみます。

通常、client.mydomain は内部 LAN 上で動作している Web サーバー www.local.lan にアクセスすることはできません。ここで、client.mydomain の任意のポートを Web サーバーが動作している www.local.lan の 80 番ポートへ転送できれば、client.mydomain 上の Web ブラウザから LAN 上の Web サーバーへのアクセスが可能になることがわかります。実際には、client.mydomain 上で以下のように ssh コマンドを実行します。

$ ssh -L 10080:www.local.lan:80 sshsvr.example.com

この指定により、ローカルホストの 10080 番ポートへのアクセスが、ログインした SSH サーバー sshsvr.example.com を介して、www.local.lan の 80 番ポートに転送されます。ただし、SSH サーバーが LAN 上の Web サーバー www.local.lan にアクセス可能であることが前提です。コマンドを実行後、Web ブラウザで http://localhost:10080 を指定すれば、www.local.lan で動作している Web サーバーにアクセスすることができます。

注意

通信が暗号化されるのは、ssh クライアントを実行したホスト client.mydomain と SSH サーバー sshsvr.example.com の間だけであることに注意してください。sshsvr.example.com と www.local.lan の間は暗号化されません。

環境によっては、インターネットから内部 LAN にアクセス可能な SSH サーバーが用意されていない場合もあるでしょう。このような環境においても、-R オプションを使用すれば、リモートホストのポートを LAN 上のホストへ転送する設定を LAN 上の ssh クライアントから設定することができます。ただし、内部 LAN 上のクライアントからインターネット上のリモートホストに接続できることが条件となります。例えば、以下のような環境を例に考えてみます。

実際には、myclient.local.lan 上で以下のように ssh コマンドを実行します。

$ ssh -R 10022:localhost:22 -R 10080:www.local.lan:80 client.mydomain

この指定により、client.mydomain の 10022 番ポートは、localhost(myclient.local.lan)の 22 番ポートへ転送され、client.mydomain の 10080 番ポートは内部 LAN 上の Web サーバー www.local.lan へ転送されます。つまり、client.mydomain の ssh クライアントで以下のように実行すれば、内部 LAN 上のホスト myclient.local.lan へ接続することができます。なお、-P はポート番号を指定するためのオプションです。

$ ssh -P 10022 localhost

以下のように scp コマンドを実行すれば、client.mydomain 上のファイルを myclient.local.lan のホームディレクトリにコピーすることもできます。

$ scp -P 10022 sample.txt localhost:~

また、client.mydomain 上の Web ブラウザの設定で、プロキシサーバーに localhost の 10080 番ポートを指定すれば、内部 LAN 上の Web サーバー www.local.lan にアクセスすることができます。