質問(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 name2339/54
netstat所有していない、またはカーネル空間のプロセスのPIDを表示しないと言う方が正確です。例