1

I have a network topology that looks like so:

Internet--------------------Firewall-------------------------Server

0.0.0.0/0-----172.8.45.140 & 192.168.1.1-----192.168.1.2

I need to configure the Firewall using iptables to port forward incoming ssh connections from my remote client (on the Internet) to the server (on 192.168.1.2). Essentially executing ssh user@172.8.45.140 on the client to remote into the server on 192.168.1.2.

The Firewall has two NICs to communicate:

172.8.45.140 (public) is on interface ens33

192.168.1.1 (private) is on interface ens37

The Server has the private IP of 192.168.1.2 and has been configured to use port for 54045 for SSH, not the default 22.

Iptables on the Firewall has been configured that both chains INPUT and FORWARD have been changed to the policy DROP, the chain OUTPUT still has the default policy ACCEPT.

Chain INPUT (policy DROP)

target     prot opt source               destination         

Chain FORWARD (policy DROP)

target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

I have seen some guides online detailing how to port forward web requests to a web server behind a firewall, see:

https://www.systutorials.com/port-forwarding-using-iptables/

https://www.digitalocean.com/community/tutorials/how-to-forward-ports-through-a-linux-gateway-with-iptables

https://wikileaks.org/ciav7p1/cms/page_16384684.html

Following these tutorials I have enabled port forwarding on the Firewall via the /etc/sysctl.conf file and tried the following rules:

1st Attempt

INPUT and FORWARD policy DROP, OUTPUT policy ACCEPT.

sudo iptables -A PREROUTING -t nat -i ens33 -p tcp --dport 22 -j DNAT --to 192.168.1.2:54045

sudo iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 54045 -j ACCEPT

Result: SSH operation timed out. Also tired INPUT and FORWARD policy ACCEPT still operation timed out.

2nd Attempt

INPUT and FORWARD policy DROP, OUTPUT policy ACCEPT.

sudo iptables -A FORWARD -i ens33 -o ens37 -p tcp --syn --dport 22 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i ens33 -o ens37 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i ens37 -o ens33 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

sudo iptables -t nat -A PREROUTING -i ens33 -p tcp --dport 54045 -j DNAT --to-destination 192.168.1.2

sudo iptables -t nat -A POSTROUTING -o ens37 -p tcp -d 192.168.1.2 -j SNAT --to-source 192.168.1.1

Result: SSH operation timed out. Also tired INPUT and FORWARD policy ACCEPT connection refused.

3rd Attempt

INPUT, FORWARD and OUTPUT policy ACCEPT.

sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j DNAT --to-destination 192.168.1.2:54045

sudo iptables -t nat -A POSTROUTING -j MASQUERADE

Result: This did work but only when the chain FORWARD had its policy on ACCEPT. This is the only time I got a connection through the firewall. When I changed the chain FORWARD to DROP the SSH connection would time out again.

My guess it is something to with it being masqueraded or that FORWARD policy DROP has something to do with it.

My question is what am I overlooking? It’s probably something I’ve missed all this time that is staring me in the face. Please be kind and thank you for your help.

  • You should really check/paste iptables-save outputs instead, as no one knows what rules you "actually" have in your "attempts". – Tom Yan May 9 at 3:05
  • I should have made it more clear that on each attempt iptables was flushed so there were no pre-existing rules. The only things modified were the chains policy prior to adding the rules as stated in each attempt. However I will note that for next time. – MacGenius May 9 at 6:16
1

Assuming you are relying on the rules in the second attempt, --dport 22 is wrong. After the DNAT / leaving the PREROUTING chain, you need to instead allow traffics to the actual/new destination port, that is 54045, in the FORWARD chain.

P.S. Both -j MASQUERADE and -o ens37 -j SNAT --to-source 192.168.1.1 should work fine, and the latter is preferred if the firewall has static IP. Also, if 192.168.1.1 is the default gateway of 192.168.1.2, you shouldn't even need to use either of them.

| improve this answer | |
  • Thank you for your help @Tom Yan I can't believe I overlooked that. I think I was under the assumption that because SSH is on port 22 the public interface on ens33 would be listening to incoming connection there, but as you explained that is not the case. Another point of note once implementing the change, on the remote client the SSH command was ssh user@172.8.45.140 -p54045 I was using ssh user@172.8.45.140 which timed out. – MacGenius May 9 at 6:22
  • What I meant was you are redirecting traffics from port 22 to port 54045, so as far as filtering is concerned, destination port would be the latter (as it has been changed at that point). Your client should then be able to reach it with port 22. – Tom Yan May 9 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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