アクセスする必要のあるArchLinux(GUIなし)を実行している複数のラズベリーパイがあります。これらのpiは、それぞれの固有の場所のファイアウォールの背後にあります。現在、私はこれらに接続するためにopenvpnを使用していますが、そのシステムのコストはライセンスごとに高価です。私は彼らからのアクセスサーバーを使用しています。
その結果、VPNサーバー(vps)にログインし、次のような特定の名前(OfficeDevice1991)を検索するコマンドを実行できるシステムを設計およびセットアップしようとしています。customcommandsearch "OfficeDevice1991"
次に、マシンのIPアドレスまたはSSHで接続するために使用できるものを返します。また、接続されているすべてのアクティブなデバイスを一覧表示するコマンドを実行する機能も探しています。 IP、名前、そしておそらくそれがアクティブであった期間が一覧表示されます。
この目標のために、もちろん、デバイスの名前(この場合はOfficeDevice1991)を含むものを作成する必要があります。そうすれば、そのpiは私のvpsパブリックサーバーにフックできるようになります。パブリックサーバーから、ログインして接続されているすべてのデバイスを検索し、SSH接続に必要な情報を返すことができます。
私はリバースSSHを検討してきましたが、これまでのところ、次のコマンドを使用して、テストpiの1つを接続し、vpsからアクセスできるようにしました。
PI:
ssh -fN -R 12345:localhost:22 -i /publickeyfile [email protected] //Pi's command to connect to vpn
VPS:
ssh -p 12345 [email protected] //command for vpn to connect to pi
これはうまく機能しますが、この方法を使用して実装すると、いくつかの問題が発生します。
- 一意の未使用のポートを設定する必要があります
- これらのポート/トンネルを開いたままにする方法
- 各デバイスを識別するためのシステムを考え出す必要があります。各ポートをテキストファイルのような名前でローカルにログインできますか?可能であれば、各デバイスのsshセットアップにそれを含めることができると便利です。使用しているポートが他のプログラムやすでに存在するデバイスによって使用されていないことを確認する必要があります。
やりたくないこと
-
各RPIで自由に使用できるポートを確認してください
-
.ssh/config
を手動で編集する必要があります 上記のパート1でRPIに割り当てられた各ポートを表す名前を追加します。
私は自分の目標のために何をすべきかについての情報/支援のためにこれを書いています。
誰かが私に適切な解決策を提供できますか?
承認された回答:
OpenSSHを使用したソリューションは次のとおりです>=6.7 + socat:
-
OpenSSH>=6.7はUnixドメインソケット転送を使用できます
つまり、リバーストンネルエンドポイントは、従来のTCPリスニングソケットではなく、UNIXリスニングソケットになります。その後、簡単な命名スキームを使用して、RPIのフロティラをより簡単に管理できます。ソケットの名前は、
OfficeDevice1991
のようにRPIが選択した(および固定された)名前になります。 。有効なファイル名である限り、RPIの一意のプロパティである可能性もあります(UNIXソケット名はファイル名の規則に準拠しているため)。たとえば、ホスト名、イーサネットまたはWi-FiカードのMACアドレス…SSHは、それ自体を接続するためではなく、トンネル用のUNIXソケットを処理できます。
ProxyCommand
の助けが必要になります UNIXソケットクライアントとして機能できるようにするため。 socatは、unixソケットを含む多くの種類の接続を処理できます。更新:
処理すべき特定の問題もあります。UNIXソケットファイルはクリーンな終了時に削除されません。また、クラッシュ後などに削除されることもありません。これには、オプションStreamLocalBindUnlink=yes
が必要です。 。名前が示すように、このオプションはUNIXソケットを作成するノードで設定する必要があることを最初は見つけませんでした。したがって、最終的には、ローカルフォワード(-L
)を使用してクライアントに設定されます。 )またはその他 サーバー上(sshd_config
内) )リモートフォワード(-R
)。 OPはそこでそれを見つけました。このソリューションはリモートフォワードを使用します。VPSでの構成:
mkdir /rpi-access
(ルートとして)
sshd_config
を編集します ファイル(/etc/ssh/sshd_config
)。この追加オプションが必要です:StreamLocalBindUnlink yes
デフォルトのオプションによっては、
AllowStreamLocalForwarding yes
も必要になる場合がありますUPDATE2:
sshd_config
にも設定されています パラメータClientAliveInterval
およびClientAliveCountMax
、したがって、妥当な時間内に切断を検出できます。例:ClientAliveInterval 300 ClientAliveCountMax 2
その後、古いssh接続をVPSで早期に検出する必要があり(例では約10分)、対応するsshdプロセスが終了します。
RPIでの使用法:
ssh -fN -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected]
構成ファイルでは、これは次のようになります。
Host ip User useraccount RemoteForward /rpi-access/OfficeDevice1991:localhost:22 IdentityFile /privatekeyfile
もう一度繰り返します:
StreamLocalBindUnlink yes
sshd
に設定 VPS側 オプションは重要です。作成したばかりのソケットは、通常の終了時でも削除されません。このオプションにより、ソケットが使用前に存在する場合は確実に削除されるため、再接続のために再利用できます。これは、ソケットが存在するだけではRPIが接続されているとは見なされないことも意味します(ただし、後で参照してください)。これでVPSで実行できるようになりました:
ssh -o 'ProxyCommand=socat UNIX:/rpi-access/%h -' [email protected]
構成ファイルとして、たとえばRPIの名前がすべて OfficeDeviceで始まることを考慮します。 :
Host OfficeDevice* User rpiuseraccount ProxyCommand socat UNIX:/rpi-access/%h -
-
リンクを維持するには、ループを使用するだけです
RPIは、接続が終了するたびにsshをVPSに再接続するループを実行できます。このため、バックグラウンドモードを使用することはできません(
-f
は使用しないでください)。 )。キープアライブメカニズムも使用する必要があります。 TCPKeepAlive(システムレベル)またはServerAliveInterval(アプリケーションレベル)を使用できます。 TCPKeepAliveはサーバー(接続を受信する側)でのみ役立つと思うので、ServerAliveIntervalを使用しましょう。その値(およびServerAliveCountMax)は、さまざまな基準に応じて調整する必要があります。ファイアウォールが一定時間後に非アクティブな接続をドロップする、希望するリカバリ遅延、無駄なトラフィックを生成しない、…ここでは300秒としましょう。
OfficeDevice1991 RPI:
#!/bin/sh while : ; do ssh -N -o ConnectTimeout=30 -o ServerAliveInterval=300 -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile [email protected] sleep 5 # avoid flood/DDoS in case of really unexpected issues done
リモート側が以前の接続障害をまだ検出しておらず、しばらくの間、古いssh接続がまだ実行されている場合でも、
StreamLocalBindUnlink yes
とにかく、UNIXソケットを新しい接続に強制的に更新します。 -
すでに1で処理されています。
customcommandsearch
はありません 必要です。 1.で適切な設定を設定し、ssh OfficeDevice1991
を使用するだけです。 OfficeDevice1991に接続します。VPSで必要な場合は、
root
ユーザーのみ、このコマンド:fuser /rpi-access/*
現在接続されているRPIを表示できます(もちろん、検出前に最近接続を失ったRPIを除く)。プロセスが関連付けられていないため、古いUNIXソケットファイルは表示されません。