サーバーと複数のクライアントボックスの間に信頼性の高いリバーストンネルを設定しようとしています。接続が切断されたり古くなったりした場合に、autosshを使用して接続を再確立していますが、いくつか問題があります。
サーバー:サーバーには、DDNSサービスにリンクされた動的IPがあります。 SSHの '-o "CheckHostIP = no"'引数が、サーバーのIPが変更されたときの問題を防ぐことを望んでいます。サーバーは、ゲートウェイルーターからポート転送を介してSSHを取得します。ルーターポート3141での着信接続は、サーバーポート22に行きます。
クライアント:各クライアントは、構成ファイルから異なるautossh監視ポートとリバーストンネルポートを取得します。 pythonスクリプトはcfgファイルを読み取り、「os.system(cmd)」で実行されるautossh cmdを構築します。それぞれがサーバーへのアクセスに使用するのと同じキーを持っています。現在、AutoSSHコマンドは再起動時にcronから実行され、すべての出力はテキストファイルに記録されます。コマンドは次のとおりです。
autossh -v -M 23000 -N -o "CheckHostIP=no" -o "ExitOnForwardFailure=yes" -o "ServerAliveInterval=10" -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /home/client1/.ssh/id_ed25519 -R 22000:localhost:22 [email protected] -p 3141
このコマンドは、ターミナルで呼び出された場合は正常に機能しますが、cronからは機能しません。
Cronから:
OpenSSH_6.7p1 Raspbian-5+deb8u1, OpenSSL 1.0.1k 8 Jan 2015
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to server.org [x.x.x.x] port 3141.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /home/user/.ssh/id_ed25519 type 4
debug1: key_load_public: No such file or directory
debug1: identity file /home/user/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.7p1 Raspbian-5+deb8u1
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.7p1 Raspbian-5
debug1: match: OpenSSH_6.7p1 Raspbian-5 pat OpenSSH* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr [email protected] none
debug1: kex: client->server aes128-ctr [email protected] none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server Host key: ECDSA 82:dd:b6:88:33:00:bb:aa:ee:08:7b:19:01:ae:da:34
debug1: Host '[server.org]:3141' is known and matches the ECDSA Host key.
debug1: Found key in /root/.ssh/known_hosts:2
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
SERVER: Server hello message
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering ED25519 public key: /home/user/.ssh/id_ed25519
debug1: Server accepts key: pkalg ssh-ed25519 blen 51
debug1: Authentication succeeded (publickey).
Authenticated to server.org ([x.x.x.x]:3141).
debug1: Local connections to LOCALHOST:23000 forwarded to remote address 127.0.0.1:23000
debug1: Local forwarding listening on 127.0.0.1 port 23000.
debug1: channel 0: new [port listener]
socket: Address family not supported by protocol
debug1: Remote connections from LOCALHOST:23000 forwarded to local address 127.0.0.1:23001
debug1: Remote connections from LOCALHOST:22000 forwarded to local address localhost:22
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: remote forward failure for: listen 23000, connect 127.0.0.1:23001
Error: remote port forwarding failed for listen port 23000
ターミナルから同じコマンドを実行すると、最後の数行を除いて出力は同じになります。
socket: Address family not supported by protocol
debug1: Remote connections from LOCALHOST:23000 forwarded to local address 127.0.0.1:23001
debug1: Remote connections from LOCALHOST:22000 forwarded to local address localhost:22
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: remote forward success for: listen 23000, connect 127.0.0.1:23001
debug1: remote forward success for: listen 22000, connect localhost:22
debug1: All remote forwarding requests processed
Cronから機能しない理由について何かアイデアはありますか?起動時にこれを実行し、監視するようにするにはどうすればよいですか?
編集:クライアントの再起動後に「psaux | grep autossh」を呼び出すと、python autosshコマンドが実行されていないことが示されます。ログファイルは「エラー:リモートポート転送に失敗しました」というメッセージで終了し、試行を続行しません。これはpythonの問題、autosshの問題、またはcronの問題ですか?
問題は、クリーンでない切断後もサーバー上でポートが開いたままになることでした。 terminal/cron/python全体は、私がうさぎの穴を追いかけて問題を追跡しただけでした。
とにかく、ここに良い答えがあります: 他のスタック交換の答え
Cronから実行する場合は、-f
をautosshに渡して(バックグラウンドにドロップするため)、Nohup
を使用する必要がある場合があります。
0 0 * * * Nohup autossh -f <your params> >/dev/null 2>&1 &
ターミナルなしで実行する場合は、sshの引数であるバックグラウンドに配置する-fを使用する必要があります。
-fの使用に関する1つのことは、リモートマシンでプログラムを実行する必要があります。そうしないと、プログラムが接続され、要求したトンネルがセットアップされてから終了します。特定のケースでは、次の変更をお勧めします。
autossh -v -M 23000 -N \
-o "CheckHostIP=no" \
-o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval=10" \
-o "PubkeyAuthentication=yes" \
-o "PasswordAuthentication=no" \
-i /home/client1/.ssh/id_ed25519 \
-R 22000:localhost:22 \
-f \
[email protected] -p 3141 \
sleep 31536000
-fとsleepは新しいものです。スリープは接続時に実行するコマンドです。365日間スリープするように選択しました。十分な長さになると思います。