如何在 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 中所解釋的接受的答案ssh只會為使用者綁定小於 1024 的連接埠root

socat如果您不是的話,這是一個很好的用例root

首先,遠端轉送至8080遠端電腦的連接埠(或任何其他允許的連接埠):

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

然後在遠端電腦上,將連接埠對應80到連接埠8080

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

筆記:

正如 Dirk Hoffman 所建議的,這兩個命令可以組合成一行:

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 行

如果你好奇的話,pw是 類型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

詳細闡述解決方案本·馬雷斯多於,

下面是一個襯墊,其中:

開啟兩個遠端連接埠轉送:
1. 遠端連接埠 8888 到本機連接埠 80
2. 遠端連接埠 8443 到本機連接埠 443

在遠端電腦上,socat 連接任何內容
1. 到達連接埠 80,將串流傳輸到連接埠 8888
   ,然後透過隧道傳輸到本地主機連接埠 80
2. 到達連接埠 443,將串流傳輸到連接埠 8443
   ,然後透過隧道傳輸到本機主機連接埠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"

因此,如果執行該命令,則必須提供遠端電腦的 root 密碼(以便能夠在連接埠 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      -

相關內容