リバースSSHトンネル:ポート番号をサーバーに送信するにはどうすればよいですか?


12

クライアントとサーバーの2つのマシンがあります。

クライアント(企業のファイアウォールの背後にある)は、次のコマンドを使用して、パブリックにアクセス可能なIPアドレスを持つサーバーへのリバースSSHトンネルを開きます。

ssh -nNT -R0:localhost:2222 insecure@server.example.com

OpenSSH 5.3 0以降で-Rは、1つを明示的に呼び出すのではなく、「使用可能なポートを選択する」ことを意味します。これを行う理由は、すでに使用されているポートを選択したくないためです。実際、同様のトンネルを設定する必要のあるクライアントが実際にはたくさんあります。

この時点での問題は、サーバーがどのクライアントがどのクライアントであるかを知らないことです。これらのクライアントの1つに(localhostを介して)接続し直したい場合、どのポートがどのクライアントを参照しているかをどのようにして知ることができますか?

上記の方法で使用すると、sshがコマンドラインにポート番号を報告することを認識しています。ただし、セッションを維持するためにautosshを使用したいと思います。autosshはおそらくfork / execを介して子プロセスを実行するため、実際のsshコマンドの出力はエーテルで失われます。

さらに、クライアントからリモートポートを取得する他の方法は考えられません。したがって、サーバー上のこのポートを決定する方法があるかどうか疑問に思っています。

私が持っているアイデアの1つは、何らかの方法で/ etc / sshrcを使用することです。これは、おそらくすべての接続に対して実行されるスクリプトです。ただし、ここで適切な情報を取得する方法がわかりません(おそらく、その接続を処理する特定のsshdプロセスのPIDですか?)ポインターが欲しいです。

ありがとう!


2
VPNはより適切ではないでしょうか?OpenVPNは設定がとても簡単です。
ベン・レッサーニ-ソナシ

面白そう。私はVPNについてあまり知りません。これは、クライアントマシンがDHCPを使用するように設定されている場合でも機能する可能性がありますか?
トム

1
はい、別のTUN / TAPインターフェイスで実行されるため、他のインターフェイスは無関係です。
ベン・レッサーニ-ソナシ

@sonassi、このVPNがうまくいくようです。情報をありがとう。
トム

私は(具体的にはDebian / Ubuntuのに基づいて)のOpenVPNでVPNプロセスを通してあなたを導く以下の答えを追加しました
Sonassi -ベンLessani

回答:


4

VPNはより適切ではないでしょうか?OpenVPNは設定がとても簡単です。証明書作成プロセスをガイドするサンプル設定といくつかのリンクを次に示します。

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-dh
./build-key-server server
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

次に、新しいファイル/etc/openvpn/client_server.confを作成し、次のファイルをその中に入れて、SERVER_IP_ADDRESS必要に応じて変更します

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0

次に、接続するユーザーごとにキーを作成し、ccd dirに構成ファイルを作成します

./build-key-pkcs12 user1@domain.com
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/user1@domain.com

IPアドレスは、/ 30サブネットに適している必要があります(http://www.subnet-calculator.com/cidr.phpを参照)。接続ごとに2つのアドレス(サーバーとクライアント)しか使用できないためです。したがって、次に利用可能なクライアントIPは192.168.100.6となります。

次に、接続ユーザーごとに静的IPがあります。

次にthe user1@domain.com.p12、エンドユーザーにファイルを提供し、次の構成ファイルを使用します

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 user1@domain.com.p12
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0

徹底的な回答をありがとう!ただし、これについては2つの質問があります。A)クライアントのifconfig-push行に255.255.255.0を指定しても機能しないようですが、2番目のIPアドレスを指定した場合は機能します。どうしてこれなの?B)このアプローチは、接続ごとに4つのIPアドレスが使用されることを意味しますか?
トム

一部のLinuxシステムでは、ifconfig-push行の構文が異なります。例えば。ifconfig-push 192.168.100.2 192.168.100.3-プラットフォームによって異なる理由がわかりません。そして、はい、それはクライアントごとに4つのIPが使用されることを意味します(無駄ですが、獣の性質)。
ベン・レッサーニ-ソナシ

3

クライアントがそれぞれ異なるユーザー名を持っている場合、netstatそのユーザーのsshdプロセスがリッスンしているポートを見つけるために使用できます。例えば:

% sudo netstat -tlpn | grep 'sshd: mgorven@'
tcp        0      0 127.0.0.1:22220         0.0.0.0:*               LISTEN      5293/sshd: mgorven@
tcp        0      0 127.0.0.1:5120          0.0.0.0:*               LISTEN      5293/sshd: mgorven@

3

一時ポート範囲(/proc/sys/net/ipv4/ip_local_port_rangeLinuxの場合)を変更し、その範囲外の静的に割り当てられたポートを使用できます。


そのために一時的な範囲を変更する必要はありません。デフォルトでは、短命範囲は61000で終了するため、その数を超える数千の使用可能なポート番号があります。私はよくecho $[61002+RANDOM%4532]その範囲のポート番号を選ぶのに使用しました。
カスペルド

2

私はあなたと同じセットアップが必要です。SSHサーバーのログレベルをDEBUGに上げ、ログにクライアントのローカルポートを表示しました

例えば:

クライアントコマンド: ssh -N -R0:127.0.0.1:5522 connector@example.com

サーバーログ:

Jun 30 11:28:59 debsid sshd[27577]: debug1: Local forwarding listening on 127.0.0.1 port 35391

そこにポート番号が表示されます


0

次の出力から関連情報を抽出できるはずです。

lsof -i tcp

ルートとして実行します。


0

サーバーでこのスクリプトを実行します。

sudo lsof -i -n | grep "sshd" | grep "(LISTEN)" | awk '{print $2}' | while read line; do sudo lsof -i -n | egrep $line | sed 3~3d | sed 's/.*->//' | sed 's/:......*(ESTABLISHED)//' | sed 's/.*://' | sed 's/(.*//' | sed 'N;s/\n/:/' 2>&1 ;done

2つのsudoが必要な場合と必要ない場合があります。削除しない場合は削除します。

PS-これは、しばらく前に見つけたソリューションの修正版です。StackOverflowから来たのではないかと思いますが、元の参照が見つかりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.