SSHポートフォーワーディングの基本: ローカル、リモート、ダイナミック

## 概要

SSHポートフォーワーディングは、セキュアなネットワーク通信のための強力なツールです。この機能を使うことで、ファイアウォールやNATを越えて、安全にデータを送受信することが可能になります。ここでは、SSHポートフォーワーディングの三つの基本形態（ローカルフォーワーディング、リモートフォーワーディング、ダイナミックフォーワーディング）を、それぞれの使用シチュエーションとともに解説し、覚え方を提供します。

## ローカルフォーワーディング (Local Forwarding)
### 使用シチュエーション
企業の内部ネットワーク内にあるデータベースサーバーに、自宅や外出先から安全にアクセスしたい場合に使用します。直接アクセスはセキュリティリスクがあるため、SSHポートフォーワーディングを利用してセキュアな接続を確立します。

![Port Forwarding - local forwarding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/b7df1b36-4b53-df93-188f-8aa6f2004150.png)

```bash
ssh -L 3306:db.internal.network:3306 user@ssh.example.com
```

このコマンドは、ローカルマシン上のポート3306をリモートのdb.internal.network上のポート3306に転送します。

### 覚え方
「L」はLocal（ローカル）の「L」で、"Local to Remote"（ローカルからリモートへ）を意味します。

### SSH Config例

```.ssh/config
Host db-tunnel
    HostName ssh.example.com
    User user
    LocalForward 3306 db.internal.network:3306
```

この設定で、以下のコマンドでローカルフォワーディングを実行できます。

```bash
ssh db-tunnel
```

## リモートフォーワーディング (Remote Forwarding)
### 使用シチュエーション
自宅やオフィスのPC上で動いているウェブサーバーやアプリケーションサーバーに、インターネット経由でアクセスしたいけれども、直接公開することができない場合に使用します。リモートフォーワードを利用して、公開サーバーを経由して安全にアクセスを提供します。

![Port Forwarding - remote fowarding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/33919b33-264b-7ca7-61c4-7cbb103978c4.png)


```bash
ssh -R 9090:localhost:3000 user@ssh.example.com
```

このコマンドは、SSHサーバー上のポート9090をローカルマシンのポート3000に転送します。

### 覚え方
「R」はRemote（リモート）の「R」で、"Remote to Local"（リモートからローカルへ）を意味します。

### SSH Configの例

```.ssh/config
Host app-demo
    HostName ssh.example.com
    User user
    RemoteForward 9090 localhost:3000
```

この設定で、以下のコマンドでリモートフォワーディングを実行できます。

```bash
ssh app-demo
```

## ダイナミックフォーワーディング (Dynamic Forwarding)
### 使用シチュエーション
安全なインターネットブラウジングが必要な場合や、企業ネットワーク内のリソースへのアクセスにVPNの代わりとして使用します。一つの設定で複数のリモートサービスへの動的なアクセスが必要な場合に便利です。

![Port Forwarding - dynamic forwarding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/2b8147db-96f5-f6b1-b991-c3fa36091c05.png)


```bash
ssh -D 1080 user@ssh.example.com
```

このコマンドは、ローカルマシンのポート1080でSOCKSプロキシを開始し、すべてのトラフィックをSSHサーバー経由で転送します。

### 覚え方
「D」はDynamic（ダイナミック）の「D」で、動的に多様なリモートエンドポイントへのアクセスを可能にします。

### SSH Configの例
```.ssh/config
Host secure-proxy
    HostName ssh.example.com
    User user
    DynamicForward 1080
```

この設定で、以下のコマンドでダイナミックフォワーディングを実行できます。

```bash
ssh secure-proxy
```

### ダイナミックフォワーディングの実際の使い方
ダイナミックフォワーディングを実行して、Chrome ExtensionのProxy SwitchyOmegaを使って

- Protocol: SOCKS4
- Server: localhost
- Port: 1080

と設定することで、サーバ経由でブラウジングができるようになる。

![スクリーンショット 2024-03-17 7.00.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/8f67d3cf-9532-0681-e32a-4d9d3cee2dc6.png)

## おまけ: リモートフォワーディングとダイナミックフォワーディングを組み合わせて多段SSHをやってみる
かなり特殊な環境の例なので、同じような状況はなかなかないですが、過去に実際にあった事例を紹介します。SSHを組み合わせることで色んなことできるということを理解していただければと思います。

### 「やりたいこと」と「制約」
- やりたいこと: リモート環境 (Machine X) から社内リソースにアクセスしたい
- 制約
    - SSHサーバー (ssh.example.com) は踏み台として利用し、社内リソースにはアクセスできない
    - 踏み台用SSHサーバーには秘密鍵を置かせない
    - 社内リソースにアクセスできるマシン (Machine Y) にはSSHサーバーが起動しているが、外部のネットワークからは接続できない (直接多段SSHでログインができない)

### 実現した仕組み
- 前準備
    - Machine XとMachine YでそれぞれSSHの鍵を作成し、公開鍵を踏み台サーバー (ssh.example.com) に置く
    - Machine YにもMachine Xで作成したSSHの公開鍵を置く
- フォワーディング
    - Machine Yから踏み台サーバー (ssh.example.com) へリモートフォワーディングの接続を確立
    - Machine Xから踏み台サーバー (ssh.example.com) を多段SSHで経由して、Machine Yへダイナミックフォワーディングの接続を確立

![Port Forwarding - 発展的な例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/33113f70-6d3a-14c2-4d33-8281c4b70147.png)


### SSH Config
#### Machine XのSSH Config
```.ssh/config@machine-x
Host bastion
     HostName ssh.example.com
     User user

Host secure-proxy
     HostName localhost
     User user
     Port 10022
     DynamicForward 1080
     ProxyCommand ssh -W %h:%p bastion
```

#### Machine YのSSH Config
```.ssh/config@machine-y
Host bastion
     HostName ssh.example.com
     User user
     RemoteForward 10022 localhost:22
```

多段SSHをするためには、以下のステップで接続を確立する。

1. Machine Yでリモートフォワーディング
    ```bash:@machine-y
    ssh bastion
    ```
2. Machine Xで多段SSH
    ```bash:@machine-x
    ssh secure-proxy
    ```

これで、Webブラウザのproxyの設定を使って、Machine Yのネットワークにあるリソースにアクセスできます。

### どんなシナリオで使えるか
1. リモートワーク中の安全なインターネットアクセス:
    リモートワーク従業員が自宅から企業内ネットワークに安全に接続する必要がある場合、ダイナミックフォワーディングを使ってSOCKSプロキシ経由でインターネットにアクセスし、リモートフォワーディングを使用して企業内の特定のサービスにアクセスすることができます。
1. セキュアなリソース共有:
    特定のリソースを外部のパートナー企業と共有する必要がある場合、リモートフォワーディングを用いて外部のパートナーがアクセスできるサーバ上にリソースへの安全なアクセスポイントを作成し、ダイナミックフォワーディングを利用してそのパートナー企業からのアクセスをセキュアな通信経路で転送します。
1. 複数地点間の安全なネットワーク構築:
    企業が複数の地理的に分散した拠点を持つ場合、ダイナミックフォワーディングとリモートフォワーディングを組み合わせることで、各拠点間の安全な通信ネットワークを構築できます。これにより、どの拠点からも中央のサーバや他の拠点のリソースに安全にアクセスできるようになります。