ポートフォワーディング


ポートフォワーディングについてのメモです．
いろいろできそうなので書いてみました．
あ，初Qiitaです．どうも．

## とは?

PC<sub>a</sub>の特定のポート<sub>1</sub>に送られてきたデータを，PC<sub>b</sub>のポート<sub>2</sub>に送信する．
つまり，PC<sub>a</sub>のポート<sub>1</sub>とPC<sub>b</sub>のポート<sub>2</sub>に繋ぐ．

## 環境(例えば)

社内のネットワークを例に考える．
例えば，このとき，手持ちのPCから社内のPCを画面共有したい．

<table>
    <caption> <strong>環境</strong> </catption>
    <tr>
        <td><i>hoge@client.jp</i></td>
        <td>手持ちのPC</td>
    </tr>
    <tr>
        <td><i>hoge@server.co.jp</i></td>
        <td>社内へのsshサーバー<br><i>client</i>からsshでアクセス可能．</td>
    </tr>
    <tr>
        <td><i>hoge@target.co.jp</i></td>
        <td>社内のPC<br>外部からアクセスできない．</td>
    </tr>
</table>

### おまけ(踏み台でのssh接続)
> #### 二段階でのssh接続
> ```client側
$ ssh hoge@server.co.jp
> ``` 
> ```server側
$ ssh hoge@target.co.jp
> ``` 
> かっこわるい．一発で繋ぎたい．

#
> #### 踏み台でのssh接続 

> ```bash:~/.ssh/config
Host server
   HostName server.co.jp
   User hoge
Host proxy_target
   HostName target.co.jp
   User hoge
   ProxyCommand ssh -W %h:%p server
> ```
> ```client側
$ ssh proxy_target
> ```
> configでの実行が便利．


## ポートフォワーディング
 
**クライアント側からターゲットに繋ぎにいく**
<i>Address1</i>(<i>User1</i>)を経由し，<i>client</i>の<i>PortA</i>に<i>Address2</i>の<i>PortB</i>を飛ばす．
(実行したshellは，<i>Address1</i>の<i>User1</i>にログインした状態になる)

###### コマンドのみ
```client側
$ ssh <User1>@<Address1> -L <PortA>:<Address2>:<PortB>
```
###### configによる実行
Nameは任意の名前．

```~/.ssh/config
Host NAME
    HostName Address1
    User User1
    LocalForward PortA Address2:PortB 
```
```client側
$ ssh NAME
```

> ### ポイント
> * <i>Address2</i>は，<i>Address1</i>から見えるパスであること． 
>  * <i>Address1</i>==<i>Adress2</i>の場合，Address2=localhostとなる．
> * <i>PortA</i>は0~1023(特権ポート)は使えない．
>  * <i>PortB</i>は飛ばしたいPortなので，好きなポートを使える． 

### 例(画面共有)

<i>target</i>の5900番ポート(vncポート)を<i>client</i>の55900番ポートに転送する．
Windowの場合，3389番ポート(RDP)を使用する．
###### コマンドのみ
```client側
$ ssh hoge@server.co.jp -L 55900:hoge@target.co.jp:5900
```
###### configによる実行
```.ssh/config
Host test_vnc
    HostName server.co.jp
    User hoge
    LocalForward 55900 hoge@target.co.jp:5900
```
```client側
$ ssh test_vnc
```
###### vncの実行
```client側
$ open vnc://localhost:55900/
```

## リモートポートフォワーディング<br>(逆ポートフォワーディング)

**経由サーバーがターゲットをクライアントに飛ばす．**
**経由サーバーから実行する．** 
<i>Address1</i>(<i>User1</i>)を経由し，<i>client</i>の<i>PortA</i>に<i>Address2</i>の<i>PortB</i>を飛ばす．
(実行したshellは，<i>Clinet</i>の<i>User2</i>にログインした状態になる)


###### コマンドのみ
```Address1側
$ ssh <User2>@<Client> -R <PortA>:<Address2>:<PortB>
```
###### configによる実行
Nameは任意の名前．

```~/.ssh/config
Host NAME
    HostName <Client>
    User User2
    RemoteForward PortA Address2:PortB 
```
```Address1側
$ ssh NAME
```

## 例(sshポートを外のサーバーへと飛ばす)

<i>target</i>の22番ポート(vncポート)を<i>client</i>の60022番ポートに転送する．
###### コマンドのみ
```server側
$ ssh hoge@client.co.jp -L 60022:hoge@target.co.jp:22
```
###### configによる実行
```.ssh/config
Host test_ssh
    HostName client.co.jp
    User hoge
    RemoteForward 60022 hoge@target.co.jp:22
```
```server側
$ ssh test_ssh
```
###### ssh接続の実行
```client側
$ ssh hoge@localhost -p 60022
```

## ダイナミックポートフォワーディング

**socks proxyとしてsshを利用する．**
**サーバーを経由して，ブラウジングができる．** 

###### コマンドのみ
```Address1側
$ ssh -D <Port> <User1>@<Address2>
```
###### configによる実行
Nameは任意の名前．

```~/.ssh/config
Host NAME
    HostName Address2
    User User1
    DynamicForward PortA
```
```Address1側
$ ssh NAME
```