Contents

Intranet Penetration via SSH Tunnel Forwarding

Requirements

I want to connect to my home PC from my iPad Pro anytime, anywhere.

  +---------+                 +----------+
  |         |                 |          |
  |  ipad:A |                 |PcAtHome:B|
  |         |                 |          |
  +---------+                 +----------+
       |                            |
       |                            |
       |                            |
       |      +--------------+      |
       +------+              +------+
              |     VPS:C    |
              |              |
              +--------------+

Both the iPad and the PC can connect to the VPS, but they cannot connect to each other directly. Therefore, we can establish a tunnel via the VPS to enable the connection, meaning A connects to B through C.

By understanding SSH forwarding configurations and principles, we can achieve this goal.

SSH Tunnel Forwarding

SSH offers three port forwarding modes: Local Port Forwarding, Remote Port Forwarding, and Dynamic Port Forwarding. Local and remote port forwarding operate in opposite directions. The concepts of “local” or “remote” are relative to the host initiating the SSH connection. Forwarding on the initiating host is local forwarding, while forwarding on the remote machine is remote forwarding. Dynamic port forwarding acts as a SOCKS proxy, which can be used for bypassing network restrictions.

Local Port Forwarding

Scenario Topology

This is used when host A cannot directly access a specific [remote interface]:[remote port] pair and needs to go through host-C to access it.

   curl   ssh          +      sshd      web
     |     |           |        |        |
     |     |           |        |        |
   +----------+        |      +------------+
   | |     |  |        |      | |        | |
   | |  A  +---------------->22-+ host-C | |
   | |     |  |        |      | |        | |
   +----------+        |      +------------+
     |     |           |        |        |
     +---> +           |        +------> +
         lo:2000       |                lo:80
                       +

Connection Command

ssh -L [local interface]:[local port]:[remote interface]:[remote port] user@host-C

Execute the following command on A to establish local forwarding:

ssh -L localhost:2000:localhost:80 user@host-C

Then, running the following on A:

curl http://localhost:2000

will access port 80 on host-C through the SSH tunnel.

After executing this command, host A will have a new port 2000 listening. The listening process is the SSH process connecting local host A to host-C:

see@17:03:32 ~  netstat -tlpn | grep 2000
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.1:2000          0.0.0.0:*               LISTEN      27104/ssh           
tcp6       0      0 ::1:2000                :::*                    LISTEN      27104/ssh 

If you use the command:

ssh -L 3000:www.google.com:80 user@host-C

If host-C has internet access, you can use A:3000 to access the web.

curl http://localhost:3000

This will access Google.

Remote Port Forwarding

Scenario Topology

   +---------+                 +--------------+
   |         |                 |PcAtHome:B +--+->--sshd
   |  ipad:A |          ssh0---+-----+     |  |
   |   ssh1  |                 |     |---->+  |
   +----+----+                 +-----+--------+
        |            sshd            |    lo:22
        |              +             |
        |              |             ^
        |              |             |
        |      +-------+-------+     |
        |      |       |       |     |
        |      |       |       |     |
        +--->8989 +----+----->22--->-+
               |     VPS:C     |
               +---------------+

Connection Command

Initiate an SSH tunnel connection from PcAtHome:B to VPS:C.

ssh -R "*:8989:localhost:22" user@VPS:C

Or:

# -qTfNn lets the ssh session run silently in the background
ssh -qTfNn -R "*:8989:localhost:22" user@VPS:C

This allows access to PcAtHome from VPS:C via port 8989 on the localhost interface.

Modify the sshd_config on VPS:C:

GatewayPorts yes

This allows ipad:A to connect directly via:

ssh -p 8989 pcUser@VPS:C

to connect directly to PcAtHome.

Once the SSH tunnel is established, a new sshd process will listen on port 8989 on the VPS. This process is the same as the SSH communication process between the PC and the VPS:

root@instance-2 zhoujinze  netstat -nltp | grep sshd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      31897/sshd          
tcp        0      0 0.0.0.0:8989            0.0.0.0:*               LISTEN      3243/sshd: zhoujinz 
tcp6       0      0 :::8989                 :::*                    LISTEN      3243/sshd: zhoujinz

Dynamic Port Forwarding

Scenario Topology

         chrome
         |
     msn |    ssh             sshd
      |  |     |                |
      |  |     |                |
   +-----------------+     +------------------+
   |  |  |     |     |     |    |             |
   |  |  |     +-------->-------+------------------>
   |  |  |     |     |     |                  |
   |  |  |     ^     |     |      VPS:C       |
   |  |  |     |     |     +------------------+
   |  |  |  +----+   |
   |  +---->|    |   |
   |     |  |7001|   |
   |     +->|    |   |
   |        +----+   |
   |   PcAtHome      |
   +---------------- +

Connection Command

Execute the command on local host A:

ssh -D 7001 user@VPS:C

Here, SSH creates a SOCKS proxy service. As shown in the topology, if Chrome is configured with a SOCKS proxy, it can access the network through the VPS.

Implementation

Using SSH remote port forwarding can fulfill the requirements. To improve the user experience, it needs to be automatically created and stably maintained.

Persistent Connection

For persistent connections, refer to Maintaining SSH Connections

Automatic Creation

Simply create a service to connect automatically at startup.

References