94
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reverse ssh tunnel を安定運用する

Last updated at Posted at 2014-03-16

追記(2022/02): 本記事の想定するユースケースでは, 長期稼働する場合 tailscale(wireguard)がよさそうです!
ただ, tailscale は sudo 権限いるようなので, sudo が使えない場合のとき(第三者のサーバやクライアント PC 使っているとか)は本記事の reverse ssh tunnel がいいかもしれません. (一応いろいろ設定すれば user 権限でもうごく. パフォーマンスも問題ないようである! https://tailscale.com/blog/throughput-improvements/)

Reverse ssh tunnel は便利な機能で, たとえばグローバル IP などで直接アクセスできない自宅 PC に外部からアクセスしたり, VPN をオフィス(仕事場環境)で使えない(が, ssh port は使える. or VPN を建てるほどの構成でない)とか, NAT 越えなどを, SSH のポートフォワーディング(の逆を使って)セキュアに接続できるという利点があります.

たとえば, 自宅の Raspberry Pi マシンへ, Reverse SSH tunneling を使い外部からアクセスするとかができます.

利用には, 何かしらグローバル IP を持つサーバ(中継サーバ)が必要になります.

+---------+ ssh -R  +------------------+   ssh fw  +-----------+
| home PC | ------> | global IP server | <-------- | Office PC |
+---------+         +------------------+           +-----------+
    /|                                                   | 
     +---------------------------------------------------+  ssh login(server 経由)

このような構成になります.

Google GCP ですと, 海外拠点にはなりますが, free でインスタンスを立てることができますので, とりあえず中継サーバとして使うのも手です. 最近は Docker + コンテナ用 OS などで, サービス(ssh)だけ動かし OS は自動アップデートさせるなどで, サーバーレスっぽいのができるようになってきて便利ですね.

GCE f1-micro インスタンスを介して reverse SSH 接続する
https://qiita.com/syoyo/items/e54c2fe8525c9f68a39c

(追記 2023/02: 最近だと free で使えるのは e2-micro になってました. https://nellab.net/archives/01036/ )

海外サーバだと, レイテンシはやはりどうしてもかかってしまいますので, うまくいくのを確認したら国内の GCP リージョンなり各社の VPS サービスなど使うのがよいでしょう.

reverse ssh tunneling を実際に 3 ヶ月くらい試してみたところ, 時々繋がらなくなる現象がありました. ssh のプロセスとしては動いているようなので, どうも keep alive あたりの問題のようです.

ClientAliveInterval(サーバ側で設定, reverse ssh でログインするリモート PC)と, ServerAliveInterval(クライアント側, reverse ssh を発行する PC)はどちらかを設定すればよいようですので, sshd_config に変更を与えない ServerAliveInterval を利用してみます.

リバース SSH tunneling を発行するマシンで, ~/.ssh/conig に以下の設定をしてみました.

Host remote.com
   ServerAliveInterval 60

60 秒の設定.

また, ときどき

debug1: remote port forwarding failure for listen port xxxxx

と出るので,

を参考に ExitOnForwardFailure を設定し, フォワード接続に失敗したら終了する(あとのスクリプトで再起動させるため)ように設定してみます.

Host remote.com
   ServerAliveInterval 60
   ExitOnForwardFailure yes
   TCPKeepAlive no

TCPKeepAlive も no にしておきます.

さらに, reverse tunnel を行うスクリプトを cron 化して自動的に処理するようにします

# reverse_ssh_tunnel.sh
#!/bin/sh
COMMAND="ssh -N -f -R 2200:localhost:22 remote.com"
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND

crontab -e で以下の行を追加します.

*/1 * * * * /bin/sh /home/username/reverse_ssh_tunnel.sh

これで, プロセスが動いていなかったら 1 分ごとに再起動されるようになります.

これにより, reverse SSH tunneling が安定して運用されます.
(まだ完全ではないが, 概ね数ヶ月は安定して動く様になりました)

TODO

  • cron ではなくて autossh や systemd(Ubuntu, CentOS client の場合)で ssh 接続を自動化・永続化する.
  • バックアップとして VPN を使う(IPsec などの暗号強度の弱い VPN の利用はあまり推奨されないようなので, tailscale(wireguard)で暗号強度保ち, 最低限 ssh プロセスの再起動用の経路だけ確保にするのがよさそう) https://qiita.com/syoyo/items/f4ed1186b644dfdc8c0c
94
89
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?