Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Consider the following situation:

At my home, I have a router (which is connected to internet), server (S) and my main machine (M). S is reachable from the internet (it has static IP), and it is up 24/7, while M is not.

Sometimes, I want to make some app (which listens on some port on M, for example 8888) accessible from outer internet.

For that, I wanted to set up some port on S (2222) to forward to M's port 8888, so that anybody accessing S:2222 would feel like he was accessing M:8888.

I tried to use ssh port forwarding, my best attempt was as follows:

ssh -L 2222:M:8888 -N M

But that only allows me to access 2222 port from server itself, not from other machines.

Is there some way to do it properly? Preferably, I'd like it to be a simple command, which I would be able to start and shut down with ^C when I don't need that forwarding anymore.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

Yes, this is called GatewayPorts in SSH. An excerpt from ssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

And you can use localhost instead of M in the forwarding, as you're forwarding to the same machine as you're SSH-ing to -- if I understand your question correctly.

So, the command will become this:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

and will look like this in netstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

Now anyone accessing this machine at port 2222 TCP will actually talk to localhost:8888 as seen in machine M. Note that this is not the same as plain forwarding to port 8888 of M.

share|improve this answer
    
Thanks! That works! But there is some strangeness - for some reason, the output contains line "bind: Address already in use". What that could mean? –  Rogach Dec 6 '12 at 9:29
    
You already have some process running on that port. Use the same netstat command to find out what exactly. Probably another similar SSH still running in the background and kill it using the PID netstat tells you. –  gertvdijk Dec 6 '12 at 9:40
    
Fun thing is that I already done that - no processes on those ports, on both S and M. If there were some, then the whole construction probably would have failed to work. –  Rogach Dec 6 '12 at 10:01

There is another way. You may set up port forwarding from S:2222 to W:8888 with iptables. Single command:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

where 1.2.3.4 is M's IP address. It is called NAT (Network Address Translation).

share|improve this answer
1  
As you're only doing destination NAT here (opposed to source NAT), this will only work reliably in specific situations and could require to modify routing tables. For forwarding to virtual machines (M) running on the host (S), this might work well, though. –  gertvdijk Dec 6 '12 at 10:23
    
This command should be issued on gateway. I assume that S and M are on the same LAN. Source NAT would be done automatically by connection tracker in modern Linux kernels. I have such config in my office network and it works perfectly. However, it is possible to make command more specific (for example, telling iptables -i eth0 where eth0 is outer interface). –  slimsuperhero Dec 6 '12 at 10:43
    
If S and M are on the same LAN, you don't need port forwarding there, as no traffic between them passes the gateway. –  gertvdijk Dec 6 '12 at 10:47
    
Yeap, but connecting to M:8888 is made from Internet, I assume. Somebody form Internet -> S:2222 -> M and S LAN router with iptables -> M:8888 –  slimsuperhero Dec 6 '12 at 10:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.