質問(TL; DR)
リモート転送(-R
オプション)のためにポートを動的に割り当てる場合、リモートマシン上のスクリプト(たとえば、からソース.bashrc
)は、どのポートがOpenSSHによって選択されたかをどのように判断できますか?
バックグラウンド
私は(両端で)OpenSSHを使用して、他の複数のユーザーと共有している中央サーバーに接続します。私のリモートセッション(今のところ)では、X、cups、pulseaudioを転送したいと思います。
最も簡単なのは、-X
オプションを使用してXを転送することです。割り当てられたXアドレスは環境変数に保存され、DISPLAY
そこからほとんどの場合、対応するTCPポートを特定できます。しかし、Xlibが名誉を与えられてDISPLAY
いるので、私はほとんど必要としません。
cupsとpulseaudioにも同様のメカニズムが必要です。両方のサービスの基本は、それぞれ環境変数CUPS_SERVER
との形式で存在しPULSE_SERVER
ます。次に使用例を示します。
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
問題は正しく設定されCUPS_SERVER
ているPULSE_SERVER
ことです。
ポート転送を頻繁に使用するため、動的なポート割り当てが必要です。静的ポート割り当てはオプションではありません。
OpenSSHには、0
リモート転送用のバインドポートとして指定することにより(-R
オプション)、リモートサーバーでの動的ポート割り当てのメカニズムがあります。OpenSSHは次のコマンドを使用して、カップとパルス転送にポートを動的に割り当てます。
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
そのコマンドを使用するとssh
、次のように出力されSTDERR
ます:
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
欲しい情報があります!最終的に私は生成したいと思います:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
ただし、「割り当てられたポート...」メッセージはローカルマシンで作成され、に送信されますがSTDERR
、リモートマシンではアクセスできません。奇妙なことに、OpenSSHにはポート転送に関する情報を取得する手段がないようです。
どのように私は適切に設定するためのシェルスクリプトにそれを置くために、その情報を取得しないCUPS_SERVER
とPULSE_SERVER
、リモート・ホスト上で?
行き止まり
私が見つけた唯一の簡単なことはsshd
、ログから情報を読み取ることができるまで、の冗長性を増やすことでした。root以外のユーザーがアクセスできるようにするのが賢明な情報よりもはるかに多くの情報が開示されているため、これは現実的ではありません。
OpenSSHにパッチを適用して、内部構造体の適切な表現を出力する追加のエスケープシーケンスをサポートすることを考えてpermitted_opens
いましたが、それでもいいのに、サーバー側からクライアントエスケープシーケンスにアクセスするスクリプトを作成することはできません。
より良い方法があるはずです
次のアプローチは非常に不安定で、ユーザーごとに1つのSSHセッションに制限されています。ただし、少なくとも2つの同時セッションと他のユーザーがさらに必要です。しかし、私は試しました...
星が適切に配置され、1羽か2羽の鶏を犠牲にしたsshd
場合、ユーザーとして開始されていないという事実を悪用することができますが、ログインが成功すると特権を破棄して、これを行います。
ユーザーに属するすべてのリスニングソケットのポート番号のリストを取得する
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
ユーザーが開始したプロセスに属するすべてのリスニングソケットのポート番号のリストを取得する
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
最初のセットにあるが2番目のセットにはないすべてのポートは、転送ポートである可能性が高く、実際にセットを差し引くと
41273
、55710
と6010
; カップ、パルス、X。6010
を使用してXポートとして識別されDISPLAY
ます。41273
はをlpstat -h localhost:41273 -a
返すため、cupsポート0
です。55710
はをpactl -s localhost:55710 stat
返すため、パルスポート0
です。(クライアントのホスト名も表示されます!)
(設定sort -u
減算を実行し、上記のコマンドラインからの出力を保存し、減算comm
を実行するために使用します。)
Pulseaudioを使用すると、クライアントを識別できます。これは、すべての目的と目的で、分離が必要なSSHセッションを分離するためのアンカーとして機能する場合があります。しかし、私はネクタイする方法を発見していない41273
、55710
と6010
同じにsshd
プロセス。netstat
非rootユーザーにその情報を開示しません。(この特定のインスタンスでは)読み取りたい列にのみが表示さ-
れます。とても近い...PID/Program name
2339/54
netstat
所有していない、またはカーネル空間のプロセスのPIDを表示しないと言う方が正確です。例