Search code examples
linuxnetwork-programmingsshtunnel

SSH tunnel Port forwarding


I've got the following Network configuration of Machines: I'm using machine A and can reach Machine B over ssh. Machine B can reach further internal ones over ssh. I want to reach those too. Can I forward the ports to my machine?

My goal is to reach with ssh on my machine on port 22 all machines as usual and on port 22 all internal machines connected to B.

How can I do that in Linux?


Solution

  • basically there are two ways to do it:

    1. when you are able to preserve port numbers by leveraging loopback interface and multiple ip addresses
    2. when you remap such ports by using some intuitive(for you) scheme.

    So for example there are 5 nodes on remote network which are not visible outside of that network. So you could map all those ssh ports to your node as 22001, 22002, 22003, 22004 and 22004.

    This way you could easily map ssh ports of all 255 devices in a remote network like 192.168.0.0

    Such numbering goes hairware when you are trying to map 3-4 ports per device in a such fashion especially when port number is higher than 65 :-)

    So for example you could map ports 22 and 80 of 5 mythical nodes following way:

    ssh me@server \
     -L 22001:node1:22 -L 8001:node1:80 \
     -L 22002:node2:22 -L 8002:node2:80 \
     -L 22003:node3:22 -L 8003:node3:80 \
     -L 22004:node4:22 -L 8004:node4:80 \
     -L 22005:node5:22 -L 8005:node5:80
    

    This way you will be able to connect to node1 from your node via:

    ssh me2@localhost -p 22001
    

    and access http port of node1 via URL http://localhost:8001/

    You could also complement such tunel with changes to /etc/hosts and ~/.ssh/config file to make life easier:

    #/etc/hosts
    127.0.0.1 node1 node2 node3 node4 node5
    
    
    #~/.ssh/config
    Host node1
        Port 22001
    Host node2
        Port 22002
    Host node3
        Port 22003
    Host node4
        Port 22004
    

    then you could ssh into node1 this way:

    ssh me2@node1
    

    This approach is ok with few remote nodes and few ports to map but becomes nightmarish when you get the bigger fleet of devices.

    The better approach from my point of view is to map ports of remote nodes into the same port numbers but into local ip addresses associated with your node. So you are allocating 5 new addresses to your loopback interface:

    sudo ip addr add 127.77.77.1/8 dev lo label lo:1
    sudo ip addr add 127.77.77.2/8 dev lo label lo:2
    sudo ip addr add 127.77.77.3/8 dev lo label lo:3
    sudo ip addr add 127.77.77.4/8 dev lo label lo:4
    sudo ip addr add 127.77.77.5/8 dev lo label lo:5
    

    complement such config with dns overrides

    # /etc/hosts
    127.77.77.1 l-node1
    127.77.77.2 l-node2
    127.77.77.3 l-node3
    127.77.77.4 l-node4
    127.77.77.5 l-node5
    

    then you make ssh tunnel to map remote ports into the same port numbers.

    # here r-node# names are IP addresses of remote nodes as server sees them
    ssh me@server \
     -L l-node1:22:r-node1:22 -L l-node1:80:r-node1:80 \
     -L l-node1:22:r-node2:22 -L l-node2:80:r-node2:80 \
     -L l-node1:22:r-node3:22 -L l-node3:80:r-node3:80 \
     -L l-node1:22:r-node4:22 -L l-node4:80:r-node4:80 \
     -L l-node1:22:r-node5:22 -L l-node5:80:r-node5:80
    

    Once such tunnel is established you will be able to access node3 via ssh:

    ssh me2@l-node3
    #or
    ssh [email protected]
    

    and in browser use URLs like http://l-node3/ or http://127.77.77.3