I'm working on local git project and I'm running separated SSH service on port 2222 with non-root user. Along that I'm using ufw firewall and opened port 2222 - I opened it just for testing if connection to it works as expected and it's OK.Because default port for SSH is 22 and I wouldn't like for users to write additional ports in address for access to repositories I want to preroute it from 22 to 2222. Also I want that port 2222 wouldn't be accessible from outside when prerouting is effective.Basically I already done the first part - I prerouted traffic from 22 to 2222 and it works without a problem if port 2222 is also opened, but when trying to close down port 2222 also the connection to 22 stops working (the rule for opened port is still there). This is somehow logical since iptables seeems to just convert port 22 to 2222 and forward it to ufw, which then recognizes this and deny connection because port 2222 is not opened.Currently this is what I have in ufw's before.rules and it works if port 2222 is also opened:*nat:PREROUTING ACCEPT [0:0]:POSTROUTING ACCEPT [0:0]-A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222Is there a way to do this prerouting without a need to have port 2222 opened?
Prerouting SSH to a different internal port
ssh;networking;iptables;routing;ufw
In principle, no. Using ufw here isn't important, since it only acts as a frontend, creating iptables rules. As you noticed, the NAT rules are handled before any filtering, so the filter sees the resulting packet after any NAT rules. (Wikipedia has a rather scary looking chart of the packet flow inside netfilter, which represents them as independent.)I'm not sure if it's much of a problem that the server can be reached on the other port too.However, if you actually want to drop packets going directly to port 2222, you can do it with some trickery, using connection marks, i.e. the CONNMARK target and connmark module:In the nat table, set a mark on the connection, and redirect it to the target port.iptables -t nat -A PREROUTING -p tcp --dport 22 -j CONNMARK --set-mark 1234iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222In the filter (default) table, reject the connection if it doesn't have the mark.iptables -A INPUT -p tcp --dport 2222 -m connmark ! --mark 1234 -j REJECTIt doesn't matter what the mark number is, as long as it doesn't collide with your other rules.(I'm not sure if it would be possible to create DROP rules in the NAT table, too. iptables v1.4.21 doesn't seem to allow it, but the complaint comes from iptables itself, not from the kernel, like it does for REJECT.)