VPNを使わずに、逆SSHポートフォワードを使って自宅のマシンをRDPで外から操作する (Webサービスにも応用可能)


いろいろあってVPNクライアントを使えない環境で、インターネット経由で自宅のマシンにRDPで接続したいということになりました。
TeamViewerとかChromeRDとかもありますけど、RDPです。

そこで、VPSとラズベリーパイを使って、VPNを使わずに、自宅のポート解放もせずにある程度セキュアな方法で実現したいと思います。
(ちなみにラズパイを使わずにやる方法もありますが、今回は目的がRDPですので、自宅機に一切手を加えることなく実現でき、再起動にも容易に対応できるのでラズパイでやります。もちろんラズパイじゃなくてもいいです。 (Webサービス公開だけならむしろPC本体でやったほうが良い))

環境(やりたいこと)

・ VPS(のようにグローバルIPが振られているマシン)が一個ある
・ 自宅はポート開放したくない
・ 家にラズパイなりなんなりのそういう機器がある

つまりこういうことです。

これをどう構築するかを簡単にまとめると、
- 自宅→VPSまでのリバースポートフォワードを張る(これで一旦外部からいきなりRDPできるようになる)
- セキュリティ保護のため一旦その待受ポートをVPS側でufwを使って塞ぐ
- 接続時にはクライアントもVPSに対してポートフォワードを張ってから使う(ufwで塞いでいても内部的なアクセスは対応できるため)
という感じで、全部で2つのSSHセッションを使うことになります。

(2021/1/29追記: 色々と分かりづらかったり足りなかったところがあったので修正しました。)

1. VPS側の設定をする

まずはSSHのポートフォワード自体ができるようにします。
GatewayPortsをyesにしてあげます。

/etc/ssh/sshd_config
#GatewayPorts no
GatewayPorts yes

そしてsshdの再起動をします。

$ sudo service sshd restart

次に、ufwを導入します。
詳しくは https://qiita.com/_takeuchi_/items/2a1ee9b53c6a863bf844 こちらを御覧ください。
とりあえずざっくり書くと、

$ sudo apt install ufw
$ sudo ufw allow sshに使っているポート番号
$ sudo ufw allow その他Webサーバーなど開放しなきゃいけないポート番号
$ sudo ufw enable

を叩いけおけば大丈夫です。
このとき、RDPでこの後リバースポートフォワードを張るときに使うポート番号はallowしないでください。リバースポートフォワードを張った段階で一応直接アクセスができることになるため、安全のために直接アクセスを防ぎます。

2. ラズパイからVPSにSSH接続をする

自宅→VPSへの線を張ります。

通常のSSHコマンドに、「-N -R 任意のポート番号:自宅マシンのIP:3389」を付属させます。

任意のポート番号は、外部からアクセスするときに使いたいポート番号になります。
外部からアクセスしたいポート番号:ポートフォワードしたいマシンのIP:そのポート番号
という感じですね。今回の場合はRDPをしたいので、13389番として外部からアクセスしながら、最終的には自宅マシンの3389番に飛ばします。なので、

ssh -R 13389:<自宅マシンのIPアドレス>:3389 <ユーザー名>@<VPSのアドレス> 

となります。ちなみに-NをつけるとSSHがバックグラウンドで動いてくれます。ずっと動かしたいとき便利ですね。

(なお、これを応用すると、自宅のマシンで立ててる80番のWebサーバーに、VPS経由で一時的に外部からアクセスできるようになったりします。二段ルーターだったり、ポート開放ができないときに便利ですね。もちろんVPS側でufwでのポート開放は必要ですが。
ssh ~~~~ -R 8080:localhost:80とかをすれば、自宅マシンの80番へ、VPSのアドレス:8080でアクセスできるようになります。)

3. クライアントからVPSにSSH接続する

先程ufwで13389番への直接アクセスを塞いでしまった(安全のため)ので、アクセスできるようにポートフォワード経由で13389番につなぎます。
通常のSSHポートフォワードを使います。これまでの例だと、通常のSSHコマンドに、「-L 任意のポート番号:localhost:13389」を付属させることになります。

以下の例だと、「サーバーのlocalhostの13389番を、クライアントの50000番にポートフォワードする」(クライアントのlocalhost:50000につなぐとVPS側の13389番にいく)という設定になります。

ssh <ユーザー名>@<VPSのアドレス> -L 50000:localhost:13389

(先程から13389や50000などでていますが、自宅→VPSの際の3389以外は何でも大丈夫です)

4. RDPでつなぐ

アドレスは、先程の例だと50000番を使っているのでlocalhost:50000となります。
これだけで繋がります。

まとめ

つまりこういうことをしたわけです

接続経路だけを文字で書くと、

クライアント:50000→(SSH)→VPS:13389→(SSH)→自宅マシン:3389
となります。

このシステムを構築することで、SHARPのNetWalkerみたいにVPNつなぐのにも一苦労みたいな端末でも、簡単にポート開放せずにRDPで自宅マシンを操作することが出来ます。また、先程も書きましたがVPNを組まなくても外部から自宅のサーバーへのアクセス環境を作ることができます。
(管理者権限がなかったりしてVPNを繋げることは出来ないけどSSHはできるという環境でも使えますね。)

参考URL:
http://toshtone.hatenablog.jp/entry/2018/03/21/232245