为什么 `curl <this machine's IP>` 与 `curl localhost` 的行为不同?

scu*_*bbo 6 networking ssh ip-address port-forwarding ip

(重定向自networkengineering.stackexchange

我的网络上有两个 Raspberry Pi——我们称它们为 Pi 和 Rho。

我正在尝试通过它们之间的 ssh 隧道设置端口转发,以便应用程序可以连接到 Rho 上的端口并从侦听 Pi 上的端口的服务器获取结果(我的最终目标实际上是设置端口转发,例如不同网络上的主机可以通过到 Rho 的 ssh 连接访问 Pi 上的 Samba 共享,而我不必完全打开到 Pi 的防火墙端口)。

我局域网中 Pi 的 IP 是192.168.42.69,而 Rho 的192.168.42.112IP是- 这些是我从本地网络通过 ssh 连接到它们的 IP。

为了对此进行测试,我SimpleHTTPServer在 Pi 的端口 8000 上启动了一个最小的 Python 服务器(带有),并sudo ssh -L 140:localhost:8000 root@192.168.42.69 -N在 Rho 上运行。当我curl localhost:140curl 127.0.0.1:140在 Rho 上时,我得到了我期望的响应。但是,当我curl 192.168.42.112:140在 Rho 上时,连接被拒绝;下面的详细输出:

$ curl -vvv 192.168.42.112:140
* Expire in 0 ms for 6 (transfer 0x2cd880)
*   Trying 192.168.42.112...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x2cd880)
* connect to 192.168.42.112 port 140 failed: Connection refused
* Failed to connect to 192.168.42.112 port 140: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 192.168.42.112 port 140: Connection refused
Run Code Online (Sandbox Code Playgroud)

这种差异的原因是什么?

已经检查这个其他问题,我证实了环境变量HTTP_PROXY未设置上罗镇,也不是NO_PROXY

gnu*_*ard 7

在您的 ssh 命令中,您没有bind_address为您的-L选项指定 a 。

根据man ssh

默认情况下,根据GatewayPorts设置绑定本地端口。但是,bind_address可以使用显式将连接绑定到特定地址。该bind_addresslocalhost指示监听端口绑定仅为本地使用,而空的地址或*表明端口应该可以从所有接口。

要允许所有接口上的连接而不仅仅是localhost(它是 的别名127.0.0.1回送接口的地址),请在您的选项中指定一个bind_addressof ,例如0.0.0.0-L

sudo ssh -L 0.0.0.0:140:localhost:8000 root@192.168.42.69 -N
Run Code Online (Sandbox Code Playgroud)

如果您希望它侦听特定 IP,则可以指定它而不是0.0.0.0.


Kam*_*ski 5

这是什么man 1 ssh状态:

-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
Run Code Online (Sandbox Code Playgroud)

指定到本地(客户端)主机上给定 TCP 端口或 Unix 套接字的连接将转发到远程端的给定主机和端口或 Unix 套接字。[…]

默认情况下,根据GatewayPorts设置绑定本地端口。但是,可以使用显式 bind_address 将连接绑定到特定地址。bind_address oflocalhost表示侦听端口只绑定本地使用,而空地址或*表示端口应可从所有接口使用。

GatewayPorts提到的是一个来自ssh_config(不是那个来自sshd_config,这个是为了-R)。来自man 5 ssh_config

GatewayPorts
Run Code Online (Sandbox Code Playgroud)

指定是否允许远程主机连接到本地转发端口。默认情况下,ssh(1)将本地端口转发绑定到环回地址。这可以防止其他远程主机连接到转发端口。GatewayPorts可用于指定ssh应将本地端口转发绑定到通配符地址,从而允许远程主机连接到转发端口。参数必须是yesor no(默认值)。

你的命令

ssh -L 140:localhost:8000 root@192.168.42.69 -N
Run Code Online (Sandbox Code Playgroud)

没有指定bind_address,它有资格“默认”。它看起来像GatewayPortssshIS no

注意“空地址”看起来不同:-L :140:localhost:8000. 额外的冒号很重要。此变体确实指定bind_address为空字符串,而-L 140:localhost:8000您使用的则根本没有指定bind_address

要绑定到所有接口,请使用空地址 ( -L :140:localhost:8000) 或*(在 shell 中,您应该引用它,例如-L '*':140:localhost:8000)。