遠隔地のPCはNAT内、中継サーバーはグローバルIP持ちで名前解決可能という前提です。
OS: Ubuntu 24.04 sshのversion: 9.6 ドメイン名: server.example.com 管理用ユーザー: hiro トンネル専用ユーザー: ssh-tunnel
OS: Ubuntu 24.04 sshのversion: 9.6 autosshのversion: 1.4 ユーザー: user
下記のような感じで接続する。あくまでイメージなのでその他コマンドオプションを指定していない。このまま使わない方が良い。
[遠隔地PC] | # 逆向きトンネルを作っておく | ssh -R 12345:localhost:22 ssh-tunnel@server.example.com | | | # 中継サーバーの12345番ポートで遠隔地PCのsshにログインできる | ssh -p 12345 user@localhost [中継サーバ] | | | # 中継サーバーは12345番をポート開放しないので | # sshで中継サーバーにログインして内部から接続する | ssh hiro@server.example.com [クライアントPC]
中継サーバーでの設定
はじめに中継サーバー上で最低限の設定を行う。専用ユーザーを作成して、超長ぇセキュアなパスワードを設定する。
# useradd -s /usr/sbin/nologin ssh-tunnel # passwd ssh-tunnel
sshの機能を制限するためsshサーバーの設定に下記を追記する。
Match User ssh-tunnel X11Forwarding no AllowTcpForwarding remote PermitTTY no PermitOpen localhost:22 ForceCommand echo 'Not permitted.' ClientAliveInterval 60 ClientAliveCountMax 1
sshサービスをリロードする。
# systemctl reload ssh
遠隔地PCでの設定
遠隔地PCで中継サーバーに逆向きトンネルを常時接続させるためsshpassをインストールする。
# apt install sshpass
パスワードをスクリプトに記述するので、rootしか触れないようにパーミッション700で接続用スクリプトを作成する。rootのcronで毎分実行するので、sshpassのプロセスが存在しない場合のみ接続する。
#!/bin/bash PASSWORD="password" killall -0 sshpass > /dev/null 2>&1 if [ $? = 1 ]; then sshpass -p "${PASSWORD}" ssh -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ConnectTimeout 15" -o "ExitOnForwardFailure yes" -N -R 12345:localhost:22 ssh-tunnel@server.example.com fi
cronにジョブを登録する。
* * * * * /root/bin/connect-reverse-ssh-tunnel.sh
sshのオプション
-o “ServerAliveInterval 30” | 30秒ごとにサーバーの応答を確認する。 |
---|---|
-o “ServerAliveCountMax 3” | サーバーの応答確認を最大3回まで再試行する。 |
-o “ConnectTimeout 15” | 15秒以内に接続できなければエラー終了する。 |
-o “ExitOnForwardFailure yes” | ポートフォワーディングが確立できなかった場合にエラー終了する。 |
-N | リモートシェルを実行しない。 |
-R 12345:localhost:22 | リモートホストの12345番ポートに来た接続を、localhostの22番ポートへ転送する。 |