setcapを使用してポート80のリモートポートをローカルホストに転送するにはどうすればよいですか?

setcapを使用してポート80のリモートポートをローカルホストに転送するにはどうすればよいですか?

NATを実行するときに短期開発接続を許可したいので、次のことを試してください。

$ ssh [email protected] -R 80:localhost:80

低いポートをバインドしようとすると失敗します。

Warning: remote port forwarding failed for listen port 80

setcap 'cap_net_bind_service=+ep' /my/applicationそのため、1024より低いポートでリッスンできることがわかりました。だから私はsuders crontabでこれを得ました:

@reboot setcap 'cap_net_bind_service=+ep' /usr/sbin/sshd

しかし、まだポート80をバインドすることは許可されていません。私は何が間違っていましたか?私はnginxを使って8080やiptablesなどをプロキシするつもりですが、なぜ私がやろうとしているのがうまくいかないのか疑問に思います。

答え1

@dwurfで説明したように受け入れられた回答ssh1024未満のポートのみがユーザーにバインドされますroot

socatそれ以外の場合、これは優れたユースケースですroot

まず、8080リモートシステムのポート(または他の許可されたポート)にリモートで転送します。

ssh [email protected] -R 8080:localhost:80

その後、リモートシステムはポートを80ポートにマッピングします8080

sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

メモ:

Dirk Hoffmanの提案に従って、これら2つのコマンドを1行にまとめることができます。

ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

(パスワード-t入力に対話型端末が必要な場合はsudo必須です。)

答え2

OpenSSHは、ログインしたユーザーのユーザーIDが0(root)でない限り、特権ポートへのバインディングを絶対に拒否します。関連コード行は次のとおりです。

if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0) ||
    (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");

源泉:http://www.openssh.com/cgi-bin/cvsweb/src/usr.bin/ssh/serverloop.c?annotate=1.162ライン1092-1098

気になる場合は、pwis型struct passwd *とLinuxの場合に定義されています。/usr/include/pwd.h

答え3

同様の問題があったので、最終的な解決策はDNATテーブルチェーンにルールを追加することでした。OUTPUTnat

iptables -t nat -A OUTPUT -d 127.0.0.0/8 -p tcp --dport 80 \
-j DNAT --to-destination :8080

このルールは、ローカルで生成されたすべてのTCPパケットに対して宛先ポート80を8080に効果的に置き換えます。

着信接続の転送を許可するには、チェーンに追加のルールを追加しますPREROUTING nat

iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080

10.0.0.200着信接続をWebサービスに転送するインターフェイスのIPアドレスはどこにありますか?

答え4

ソリューションについて詳しく説明してください。ベン・マレス以上、

以下は以下のライナーです。

2つのリモートポート転送を開く:
1.リモートポート8888からローカルポート80へ
2.リモートポート8443からローカルポート443へ

リモートシステムでは、socatは何でも接続します。
1.ポート80に到着してポート8888にストリーミングし、
   localhostポート80にトンネリングします
。 2.ポート443に到着し、ポート8443にストリーミングし、
   localhostポート443にトンネリングします。

ssh -t -i ~/.ssh/id_rsa \
    -R 0.0.0.0:8888:0.0.0.0:80 \
    -R 0.0.0.0:8443:0.0.0.0:443 \
    remoteUser@remoteMachine \
    -- "(sudo socat TCP-LISTEN:80,fork TCP:localhost:8888) & \
        sudo socat TCP-LISTEN:443,fork TCP:localhost:8443"

したがって、コマンドを実行する場合は、リモートシステムのルートパスワードを指定し(ポート80/443にリストできるように)、その後(トンネルが設定されている限り)、ポート80でリモートホストに到達するすべてのエントリを提供する必要があります。 。あるいは、443はそれぞれローカルコンピュータポート80または443にトンネリングされる。

覚えている! !

すべてのネットワークインターフェイス(0.0.0.0)にバインドするには、リモートコンピュータを編集または/etc/ssh/sshd_config設定する必要があります。GatewayPorts clientspecifiedGatewayPorts yes

リモートシステムでこれを確認でき、netstat -tlpn | grep -E '8888|8443'次のものが表示されます。

tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      -

まさか

tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8443          0.0.0.0:*               LISTEN      -

関連情報