现在来看最令人困惑的部分:目的主机的地址。理解这一点非常重要:在一个client to server端口转发规则中,目标主机地址是相对于SSH服务端的,而不是客户端。这是SSH服务端在一个连接需要被转发时将要连接的地址。这种场景下,目标主机地址被设置成127.0.0.1,从而让SSH服务端连接到运行于相同机器上的应用服务端。
最后,目的端口指定了当前场景中目标TCP/IP服务器正在被监听的所在端口,123.
上述例子中所展示的端口转发配置是严格的:它通过限制SSH客户端位于相同机器作为应用客户端,而SSH服务端位于相同机器作为应用服务端,从而最小化了非加密数据的暴露。
另一方面,如果你已经注意到SSH客户端和SSH服务端之间的,不要介意本地子网中的非加密数据,你可能配置你的SSH端口转发规则如下:
---------------图2
这与如下的SSH客户端中的C2S端口转发规则一致:
监听接口:0.0.0.0(这会打开SSH客户端的转发socket,到来自于其他机器的连接)
监听端口:123
目的主机:10.2.2.9(目标应用客户端不是同一台机器来作为SSH服务端,所以我们需要从SSH服务端进入它的地址可见)
目的端口:123
按照这样启动,你只需要一个SSH客户端去转发多个应用客户端的连接;因为SSH客户端的监听地址被配置成了0.0.0.0,应用客户端不需要位于同一台机器。使用恰当配置的端口转发规则,你可以使用相同的SSH会话去转发连接给多个应用服务端,而这些服务端可以部署到不同于SSH服务端的机器上。
虽然我们的上面的例子只讨论了c2s端口转发规则,s2c的端口转发规则是完全对称的。只是角色是相反的:在s2c转发中,监听地址是相对于SSH服务端,而目的主机地址是相对于SSH客户端。
一个常见的错误是给一个相同的转发连接定义一个C2S和一个S2C规则。这是不必要的也不会起作用。S2C规则只有在你正在转发其他建立在从服务端到客户端方向上的连接时才需要。这样的连接通常是与那些建立自客户端到服务端的连接时独立不相关的。对每一条连接来说只需要一种规则。
摘自:https://www.bitvise.com/port-forwarding
A short guide to SSH port forwarding
SSH port forwarding, or TCP/IP connection tunneling, is a process whereby a TCP/IP connection that would otherwise be insecure is tunneled through a secure SSH link, thus protecting the tunneled connection from network attacks. Port forwarding can be used to establish a form of a virtual private network (VPN).
To illustrate how port forwarding works, let us use an example. Suppose you are the network administrator in a company that has two buildings. In Building #1, there are numerous workstations residing in the subnet 10.1.1.*. In Building #2, there are multiple servers residing in the subnet 10.2.2.*. The two buildings are separated by a busy street with parking spaces on each side, and the subnets in the two buildings are linked wirelessly through an antenna on the roof of each building. The workstations in Building #1 are running a legacy client application that uses an unencrypted TCP/IP session to communicate sensitive data with the servers in Building #2.
One day, someone in your company notices that an unmarked black van has remained parked on the street between the two buildings for several days. As your CEO realizes that sensitive data is being transmitted unencrypted between the two buildings, he becomes worried that the van parked outside might be collecting the company's confidential information. He orders you to solve the problem ASAP.
What you do is this:
On each of the client workstations in Building #1 (in the above example, workstation 10.1.1.7 is shown), you install an SSH client. On the machine in Building #2 that runs the server for your legacy application, you install an SSH server. You configure the SSH client with the following client-to-server port forwarding rule: for each connection that comes on interface 127.0.0.1 and port 999, forward that connection to the SSH server, and request the SSH server to forward that connection to host 127.0.0.1 (relative to the server), port 123.
Now, your application client doesn't connect to the server directly anymore. Rather, it connects to the SSH client, which encrypts all data before transmission. The SSH client forwards the encrypted data to the SSH server, which decrypts it and forwards it to your application server. Data sent by the server application is similarly encrypted by the SSH server and forwarded back to the client.
Previously, the data that was being radioed between the two buildings was sent in plaintext and could be captured by anyone parking on the street below. Now, the data is encrypted using the SSH protocol, and is virtually impossible to decipher. The next day after installing SSH, you observe that the black unmarked van is gone.
Now, let us comment on the above example. It corresponds with the following C2S (client-to-server) port forwarding rule in the SSH client:
- Listen interface: 127.0.0.1 (this ensures that only connections from the local client machine, or loopback connections, are accepted for forwarding)
- Listen port: 999
- Destination host: 127.0.0.1 (important: the target address is relative to the server, not the client, so 127.0.0.1 will work fine if the target application server is listening on all interfaces - 0.0.0.0)
- Destination port: 123
Note that the listening interface configured on the SSH client is 127.0.0.1. By configuring the listening interface, you tell the SSH client what kinds of connections it will accept. If you configure the listening interface to 127.0.0.1, the SSH client will only accept connections originating on the same machine. If you configure the listening interface to equal the IP address of one of the network cards on the machine, the SSH client will accept only those connections that arrive through that network card. If you configure the listening address to 0.0.0.0, the SSH client will accept connections regardless of their origin.
Next, you will note that the listening port has been set to 999. The listening port could be set to any figure between 1 and 65535 that is not already occupied by another application listening for connections on the same machine. In this case, the SSH client listening port has been set to 999, but it could just as well have been set to 123, the same port at which the application server is listening.
Now comes the most confusing part: the address of the destination host. It is important to understand that, in a client-to-server port forwarding rule, the target host address is relative to the SSH server, not the client. This is the address that the SSH server will connect to when a connection needs to be forwarded. In this case, the target host address is set to 127.0.0.1 to have the SSH server connect to the application server which is running on the same machine.
Finally, the destination port specifies the port on which the target TCP/IP server is listening - in this case, 123.
The port forwarding configuration shown in the above example is strict: it minimizes the exposure of unencrypted data by constraining the SSH client to reside on the same machine as the application client, and the SSH server to reside on the same machine as the application server.
On the other hand, if you are only concerned about eavesdropping between the SSH client and the server, and do not mind unencrypted data in the local subnets, you might configure your SSH port forwarding rules like this:
This corresponds with the following C2S (client-to-server) port forwarding rule in the SSH client:
- Listen interface: 0.0.0.0 (this opens up the SSH client's forwarding socket to connections from other machines)
- Listen port: 123
- Destination host: 10.2.2.9 (the target application server is not on the same machine as the SSH server, so we need to enter its address as visible from the SSH server)
- Destination port: 123
With this setup, you only need one SSH client to forward the connections of multiple application clients; since the SSH client's listening address is configured to 0.0.0.0, the application clients do not need to reside on the same machine. With appropriately configured port forwarding rules, you can use the same SSH session to forward connections to multiple application servers, which can reside on machines different from the SSH server.
Even though our examples above only discuss client-to-server port forwarding rules, the concept of server-to-client port forwarding is entirely symmetric. Only the roles are reversed: with S2C forwarding, the listening address is relative to the SSH server, and the destination host address is relative to the SSH client.
It is a common mistake to define both a C2S as well as an S2C rule for the same forwarded connection. This is not necessary and will not work. S2C rules are required only if you are forwarding other connections which are established in the direction from the server to the client. Such connections are normally independent from, and unrelated to, those established from client to server. Only one type of rule is necessary for each connection.