接続先のサーバーへインターネット接続を共有しつつssh接続する

# はじめに: 内部で閉じたネットワークでのインストール作業は大変

ネットワーク内部でつながっているインターネット接続を持たないようなサーバーへssh接続したとき、以下のような問題が生じます。

* 各種インストール作業の際にインターネットに接続できず不便
* gitコマンドでGitHubにアクセスできず不便

例えば、以下の図のようにプライベートなネットワークに接続されたラズパイにssh接続する状況では、そのままではラズパイからインターネットに繋げないので何かと不便です。
ラズパイの例に限らず、Linuxの入ったクラスタPCのセットアップ作業など色々な場面で同じような状況が発生します。
![ssh_raspi_internet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/10b8aa73-bcc9-4971-dcf5-e7896c8195e2.png)
(※図中のRaspberry Piはあくまで一例です。本記事の方法は他のLinuxサーバーでも使えます。)

これらの問題の解決策として、リモート側(sshの接続先)からローカル側(sshの接続元)のインターネット接続を使用する方法を紹介します。

# やり方

### 接続方法(リモート側にsocks5プロキシを立てつつssh接続)

ssh接続の際、以下のように`-R (適当なポート番号)`を付けて接続します。これだけです。
(`user@hostname`は適宜変えてください)

```bash
$ ssh -R 6666 user@hostname
```

すると、ssh接続先(リモート側)の6666番ポートにsocks5プロキシが立ちます。
そこを経由して接続すればインターネットに接続できます。

### ssh接続先でのインターネットの使い方

上のように`ssh -R`で接続した後、接続先では6666番ポートのsocks5プロキシを経由して各種コマンドを使用します。
![ssh_raspi_internet2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/2f546f2c-da87-213a-a612-2dec0b65dc0a.png)

例えば、gitコマンドを使う場合なら以下のようになります。

```bash:一時的に使う例(git&nbsp;pull)
$ git -c http.proxy=socks5h://localhost:6666 -c https.proxy=socks5h://localhost:6666 pull
```

```bash:git&nbsp;configでプロキシを設定する例
$ git config --global http.proxy socks5h://localhost:6666
$ git config --global https.proxy socks5h://localhost:6666
```

例えば、aptコマンドを使う場合なら以下のようになります。

```bash:一時的に使う例(apt&nbsp;update):
$ sudo apt -o Acquire::http::proxy="socks5h://localhost:6666" -o Acquire::https::proxy="socks5h://localhost:6666" update
```

使えはしますがコマンドが長くてかなり面倒です。そこで、楽にする方法を紹介します。

# proxychainsを入れるとコマンドごとのプロキシ設定が不要になって楽

proxychainsというソフトを入れるとプロキシを経由させるのが楽になります。

通常、以下のコマンドでインストールできます(aptの場合)。

```bash
$ sudo apt update
$ sudo apt install proxychains
```

ただし、上記コマンドはインターネット接続がないとできないので、以下のように6666番ポートを経由させてインストールしてください。

```bash:※上のコマンドをプロキシ経由で行う場合
$ sudo apt -o Acquire::http::proxy="socks5h://localhost:6666" -o Acquire::https::proxy="socks5h://localhost:6666" update
$ sudo apt -o Acquire::http::proxy="socks5h://localhost:6666" -o Acquire::https::proxy="socks5h://localhost:6666" install proxychains
```


次に、`/etc/proxychains.conf`をテキストエディタで開き、末尾を以下のように編集します。

```:/etc/proxychains.conf
※中略

[ProxyList]
socks5 127.0.0.1 6666
```

これで完了です。

以下のように各種コマンドが楽にプロキシ経由で使えるようになります。

```bash:だいたいproxychainsを前につけるだけでOKになる
$ sudo proxychains apt update
$ proxychains git pull
$ proxychains curl google.com
```

`proxychains git`と打つのもだるいという方は、`~/.bashrc`の末尾に`alias pgit="proxychains git"`と書いておけば`pgit pull`だけでpullできるようになると思います。

# 補足

* プロキシのURLは`socks5h://`ではなくhのない`socks5://`でも一応は接続できます
    * ただし、`socks5://`だとDNSルックアップがプロキシ経由で行われなくなってしまいます
    * 別でDNSサーバーへのアクセスができる環境でないと名前解決に失敗します<br><br>
* aptコマンドは`http_proxy`、`https_proxy`という環境変数を指定すれば、毎回`-o`で指定しなくてもプロキシを経由させられるかもしれません
    * うちの環境(ラズパイ)では上手く行きませんでした
    * `-o`で指定したものと同様のものを`/etc/apt/apt.conf`に書けば大抵上手く行きますが、一時使用の場合は毎回書き替えるのが面倒です<br><br>
* 他の多くの記事はなぜか面倒な方の方法を紹介しています
    * 例えば、`ssh -f -N -D 54321 localhost`でローカルにsocks5プロキシを立ててから、`ssh -R 6666:localhost:54321`で接続することで、リモート側の6666番ポートにローカルの54321番ポートをポートフォワーディングする、など
    * 昔のバージョンのsshコマンドでは、このような面倒な方法を取る必要があるかもしれません
    * (ちなみに、上の例で54321にしているのは同じ番号だと紛らわしいからというだけなので、両方6666にしても構いません)
    * 例えば、つい最近(2019/6/16)に公開された記事→ https://blog.amedama.jp/entry/remote-port-forward-squid-proxy でもプロキシサーバー(Squid)をインストールした上でポートフォワードしていますが、このような作業は全く必要ありません

# 参考

* [with SSH only: reverse tunnel web access via ssh SOCKS proxy - Server Fault](https://serverfault.com/questions/361794/with-ssh-only-reverse-tunnel-web-access-via-ssh-socks-proxy/932003#932003?newreg=d010fb09436e47e5b5a1d4092812b17f)
    * この記事で紹介しているのは、ベストアンサーではなく2番目の回答の方のやり方です