Reverse ssh tunneling で踏み台サーバを経由して自宅サーバにアクセスするやつ

概要

これまで Raspberry Pi 2 Model B を自宅用 NAS 兼メディアサーバとしてこのように運用していたが、やはりメモリ 1 GB だとつらく USB 2.0 だときついという感じになり、なんやかんやあって Intel NUC を買ってしまった。メモリ は 8 GB、SSD は 256 GB にした。やっていくぜ NUC(ネクスト・ユニット・オブ・コンピューティング)。

で、正月の帰省中も自宅サーバのデータにアクセスしたいということになり、Reverse ssh tunneling の設定を真面目にやることにした。登場人物は以下の通り。

  • private.local(非公開サーバ)
    • 固定 IP アドレスを持たない Linux サーバ
    • 私の場合 Intel NUC とか Raspberry Pi とか
  • public.example.com(踏み台サーバ)
    • 固定 IP アドレス持ちのサーバ
    • VPS とか
  • client.local(クライアント PC)
    • 一般的な PC
    • 筆者は Linux 環境だけど openssh クライアントが使えればなんでも

public.example.com を経由して client.local から private.local にアクセスしたい、という感じ。
単純化すると以下のような構図になる。実際には安定した接続や DynamicForwarding のためにもう少し設定をする必要がある。

[   private.local    ]
    ↓ ssh -NR 2222:localhost:22 public.example.com
[ public.example.com ]
    ↑ ssh -W localhost:2222 public.example.com
[    client.local    ]

非公開サーバの設定

非公開サーバ (private.local) で ssh 接続設定と接続切れ時の自動再起動設定を行う。

ssh クライアント設定

~/.ssh/config に Reverse ssh tunneling 用の設定をいくつか追加する必要がある。 IdentifyFile (秘密鍵)もパスフレーズなしのものを用意しておく必要があるのでどうにかしておく。

Host public.example.com.rev  
    HostName public.example.com
    ServerAliveInterval 60
    ExitOnForwardFailure yes
    TCPKeepAlive no
    IdentityFile /path/to/public.example.com.rev.id_ecdsa

接続切れ時に自動で再起動する

ssh 接続を systemd ユーザサービスとして作成しておき、接続切れ時に自動再起動がかかるようにする。
~/.config/systemd/user/ 下に *.service ファイルを用意する。 ここでは ~/.config/systemd/user/public-rev.service という名前で作る。

[Unit]
Description=Reverse SSH Tunneling

[Service]
ExecStart=ssh -NR 2222:localhost:22 public.example.com.rev  
Type=simple  
Restart=always

[Install]
WantedBy=default.target  

ユーザサービスを有効にする。

systemctl --user daemon-reload  
systemctl --user start public-rev  
systemctl --user enable public-rev  

設定の確認

設定がうまく行っているか確認したい場合、踏み台サーバで以下のコマンドを入力する。 踏み台サーバから非公開サーバにアクセスできれば成功。

ssh localhost -p 2222  

クライアント PC 側の設定

~/.ssh/config に クライアント PC (client.local) から public.example.com 経由で private.local にアクセスするための設定をする。

Host private.local.public  
    ProxyCommand ssh -W localhost:2222 public.example.com
    DynamicForward 2222
    ServerAliveInterval 60

クライアント PC から以下のコマンドで非公開サーバにアクセスできれば成功。

ssh private.local.public  

また、DynamicForward 2222 の設定により localhost:2222 を SOCKS v5 プロキシとして使うことができる。proxy.pac で SOCKS5 localhost:2222 するなどよしなに設定すれば非公開サーバ内の Web サービスにブラウザからアクセスできる。私は Firefox 派なので FoxyProxy を使っている。

FoxyProxy 設定

Future Works

ファイルサーバ (Samba) をうまいこと設定する方法は模索中です……。クライアントが Linux なら sshfs でいいかも。

sshfs private.local.public:/data ./data  

参考