如何在 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 行

如果你好奇的话,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

详细阐述解决方案本·马雷斯多于,

下面是一个衬垫,其中:

打开两个远程端口转发:
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      -

相关内容