ファイアウォールの背後にある複数のクライアントからのSSH接続を受け入れるパブリックサーバーがあります。
これらの各クライアントは、ポート80のWebサーバーからパブリックサーバーへのssh -R
コマンドを使用して、リバースSSHトンネルを作成します。
リバースSSHトンネルの宛先ポート(クライアント側)は80であり、送信元ポート(パブリックサーバー側)はユーザーによって異なります。各ユーザーのポートアドレスのマップを維持することを計画しています。
たとえば、クライアントAは、ポート80のWebサーバーをポート8000にトンネリングします。クライアントBは80から8001まで。クライアントCは80から8002まで。
Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver
Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver
Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver
基本的に、私たちがやろうとしているのは、各ユーザーをポートにバインドし、許可しない他のポートにトンネリングすることです。
SSHのフォワードトンネリング機能をssh -L
で使用している場合、permitopen=Host:port
構成を使用して、どのポートをトンネリングするかを許可できます。ただし、逆SSHトンネルに相当するものはありません。
ユーザーごとにリバーストンネリングポートを制限する方法はありますか?
not allowを太字で示しているので、SSHクライアント側でポートバインドを防ぐ何らかの実行時拒否が必要だと思います。だから、私はあなたのためにソースコードの掘り出し物を持っています:
/* check permissions */
if (!options.allow_tcp_forwarding ||
no_port_forwarding_flag ||
(!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
|| (listen_port != 0 && listen_port < IPPORT_RESERVED &&
pw->pw_uid != 0)
#endif
) {
success = 0;
packet_send_debug("Server has disabled port forwarding.");
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(
listen_address, listen_port,
&allocated_listen_port, options.gateway_ports);
}
残念ながら、ご覧のとおり、標準の条件を除いて、ポート転送を妨げるように見える条件は多くありません。
iptables
内でmod_owner
を使用するための同じ提案を推奨しようとしていましたが、Jeffは私を殴りました。
最もクリーンな解決策は、このファイルを変更し(たとえば、pw->pw_uid
を使用して、接続しているユーザーのuidを取得し、それを正しいポートにマップできます)、SSHサーバーを再コンパイルすることですが、それは方法によって異なります。これで快適です。
私の提案は、これにSELinuxを使用することです。どのポートを開くことができるかを許可するユーザープロファイルを構成する必要があります。 sshd
プロセスは、転送するポートを開く前にユーザーの特権をフォークおよびドロップするため、ユーザーのプロセスに適用されるものはすべてsshd
に適用されます。かつてはnetcat
を使用して別のポートを転送する可能性があるため、すべてのユーザープロセスに制限する必要があることに注意してください。後で適切な構文を整理しようとします(または、他のユーザーが編集してくれます)。
または、iptables
を使用してみることもできます。
iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT
ただし、ポートを開いて別のユーザーを拒否することを妨げることはありません。