SSHポートフォワード、活用してますか？

SSHポートフォワードの話をする前に、おさらいも兼ねてさらっとSSHにふれたいと思います。
SSHはSecure SHellの略で、他のコンピューターと安全にリモート接続するためのプロトコル（通信規約）です。

以前は、telnet（端末）やftp（ファイル転送）というプロトコルがリモート接続で使用されていましたが、これらは暗号化されていないデータ（平文データ）でやりとりしていたので、盗聴される危険がありました。IDやパスワードも平文でネットワーク上に流れるため、システムを乗っ取られる危険さえあったのです。一方で、SSHはパスワード認証よりも安全と言われる公開鍵暗号方式による認証を備えており、また、暗号化されたデータでやりとりするので安心です。そのため、現在では当たり前のようにSSHを利用するシーンが多くなっています。

Windows環境でSSHを利用して他のコンピューターに接続する場合には、コマンドプロンプトかPowerShellからSSHコマンド（ssh.exe）を起動して使うこともできますが、「TeraTerm」や「PuTTY」などのSSHクライアント機能を持つGUIアプリを使うケースが多いと思います。また、Linux、Macでは主にターミナルからSSHコマンドを使用します。

# SSHポートフォワードとは？

SSHを普段から使っている方でも、SSHポートフォワード（ポートフォワーディングとも言う）をご存じないという方がいるかもしれません。そうであれば、これは知っておくと本当に便利で、業務の幅が広がるような機能ですから、ぜひ覚えてください。

まず、ポートとは、「TCPポート番号」のことで、これはTCP/IPを利用するサービスを識別するための番号です。例えば、メールのプロトコルであるSMTPであれば「25」、ウェブのプロトコルであるhttpならば「80」といった具合に割り当てられています。詳しくは[こちら](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml)をご覧ください。



続いて、「ポートフォワード」とは、特定のポートに送られてきたデータを他のポートに転送することを言います。SSHポートフォワードとは、SSH接続上でのポートフォワードのことです。つまり、SSH上の通信を特定のポートへ転送する機能のことです。これはSSHにデフォルトで備わっている機能です。SSHでは、あるポートの通信を他のサーバーのポートに転送することができ、異なるサーバー間でセキュリティやネットワーク設定によって直接アクセスができないときに威力を発揮します。

# ローカルポートフォワードとリモートポートフォワード
SSHポートフォワードには、ローカルポートフォワードとリモートポートフォワードの2種類があります。

***ローカルポートフォワード***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/246aff1c-1620-4663-a7d3-5ebe10dd5c90.png)

 


ローカルポートフォワードとは、SSHクライアントの任意のポー」」トに、利用したいサービスがあるサーバーのポートを引き込み、通信を転送する機能です。下図のようなイメージになります。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/f37fcb84-2f61-4333-981c-054045ab1d5b.png)


***リモートポートフォワード***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/598a68ff-25dc-48a4-8576-921df5f4545d.png)

 
リモートポートフォワードとは、利用したいサービスがあるサーバーのポートに、SSHサーバーの任意のポートを引き込み、通信を転送する機能です。下図のようなイメージになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/3bfd092b-fde9-46e9-a6d7-da1d0a8da6f3.png)

 
リモートポートフォワードを単独で使うシーンは少ないですが、覚えているとSSHでできる幅が広がるので、ぜひ覚えておいてください。

SSHポートフォワードをSSHコマンドで利用する場合は、次のようになります。

***ローカルポートフォワードの場合***
ssh -L SSHクライアントのポート番号:サービスのIPアドレス:サービスのポート番号 ユーザー名＠SSHサーバーのアドレス 

***リモートポートフォワードの場合***
　ssh -R SSHサーバーのポート番号:サービスのIPアドレス:サービスのポート番号 ユーザー名@SSHサーバーのアドレス 

ローカルポートフォワードが「-L」、リモートポートフォワードが「-R」です。

***rootアカウントでの接続を禁止するSSHポートフォワード設定例***

SSHで接続可能なサーバーがあり、その先にTCP通信ができる機器（サーバーやネットワーク機器など）があれば、SSHポートフォワードを使って、その先のサーバーをSSHクライアントから直接操作できるようになります。

例えば、Windowsのサーバーに接続したい時、SSHサーバーがあればSSHポートフォワードを利用して、手元のPCからさまざまな作業ができます（SSHサーバーをWindows上で動かすこともできますが、この話はまた別の機会に）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/df341df0-32e6-492d-81de-e821aafe1254.png)

 
SSHコマンドで設定する場合、IPアドレスやポート番号を上図の通りとすると、以下の通りに入力することになります。

ssh -L 13389:192.168.1.20:3389 ユーザー名@192.168.1.10 

SSHポートフォワードは、SSHコマンド以外でも設定できます。TeraTermやPuTTYなどのSSHクライアント機能を持つGUIアプリでも、画面上で設定できるようになっています。

下図はTeraTermでの設定例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/047d7b5b-27ce-4ed5-846f-7ab0c882e957.png)


 
TeraTermで設定後、リモートデスクトップクライアントを起動して、「localhost:13389」（SSHクライアントである自分のPCの 13389番ポート）を接続先に指定します。そうすると、リモートのWindowsのサーバーの画面が表示されます。

また、下図はPuTTYでの設定例になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/fedcd0b1-4aa7-43b6-adaf-291130b328ce.png)

 

***【活用例1】PCのデータベースツールでリモートの非公開データベースにアクセスする***

以下に、SSHポートフォワードの活用例を２つほど示します。

開発者であれば、PCのデータベースツールを使って、リモートの非公開データベースにアクセスして直接操作したいことがあります。例えば、「pgAdmin」を使って、ファイアウォールの中にあるPostgreSQLのデータベースに直接スキーマやデータを流し込んだり、データベースのバックアップを取ったりしたいといったケースです。

このようなケースではSSHポートフォワードを使用するのが便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/bd5d55e1-2121-43aa-ad47-7efddefdff6f.png)

 
上図の構成だとすると、SSHコマンドでの設定は以下のようになります。これで、データベースサーバーを直接操作できるようになります。

ssh -L 15432:192.168.10.20:5432 ユーザー名@192.168.1.10

TeraTermとpgAdminを使う場合は、下図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/807193cd-fa48-460a-b1cd-a5d955352c6f.png)

 
***【活用例2】複雑なネットワーク構成でも利用可能***

もっと複雑なネットワーク構成でもSSHポートフォワードで直接操作することができます。

例えば、PCから2つ先のネットワークにあるウェブカメラ（同じネットワークのサーバーからアクセス可能）を操作するケース（下図）を考えてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/d3a50e1c-7374-44a9-81ad-78917559bf3d.png)

 

接続手順は、以下の通りです。

###### 1.いったんサーバーBにSSＨでアクセスする
サーバーAにSSH接続後、サーバーBにさらにSSHで接続します。

###### 2.サーバーB上でSSHコマンドを入力して、ウェブカメラのポートをサーバーＡのポートにマッピングする（リモートポートフォワード）

ssh -R 10080:192.168.100.100:80 ユーザー名@192.168.1.10

###### 3.PCからサーバーＡにSSHポートフォワードを設定する（ローカルポートフォワード）

ssh -L 10081:192.168.1.10:10080 ユーザー名@192.168.1.10

これでPCの10081番ポートはサーバーＡの10080番ポートにマッピングされ、PCの10081番ポートがウェブカメラの80番ポートに中継されるようになります。

***【余談】セキュアなファイル転送もSSHで可能になる***
SSHポートフォワードとは関係ありませんが、知っていると便利なのでふれておきます。
コマンドプロンプトなどからscpコマンドやsftpコマンドを使用すれば、セキュアな転送ができます（詳細はマニュアルを参照してください）。また、TeraTermやPuTTYを使えば、もっと簡単にファイル転送ができます。以下はTeraTermでの使用例です。

###### 1.PCからサーバーにファイルを送る場合（アップロード）
SSHでサーバーに接続して、送りたいファイルを端末ウィンドウにドラッグ＆ドロップするだけで転送できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/c856e39d-36c3-41ae-9de6-74fed9d4da5d.png)

 

###### 2.サーバーからPCにファイルを送る場合（ダウンロード）
ファイルメニューからSSH SCPをクリックし、出てきた画面の「From」にPCに送りたいファイルのパス名、「To」にPCでの保存フォルダを指定して「Receive」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3869727/0a485ec0-5899-4e29-a9dd-e94ee511831e.png)


SSHを使えば、直接操作できないと思っていたサービスにアクセスできたり、安全なファイル転送ができたりすることがお分かりいただけたかと思います。わざわざデータセンターなど遠く離れた場所に出向かなくても操作ができるなら、時間もお金も節約できます。ぜひご活用ください！