Below are instructions for how to set up port forwarding on various Linux distributions using the firewall. The example uses port 5901 (default VNC port) as the destination and port 443 (default HTTPS port) as the source. This setup would let you connect to VNC over port 443 instead without changing the VNC configuration.
Red Hat/CentOS 7 use firewalld as the default firewall application:
1) Login to the root account
2) Install firewalld
yum install -y firewalld
3) enable and start firewalld
systemctl enable firewalld
systemctl start firewalld
4) add rule to allow port 22 for ssh
firewall-cmd --permanent --add-port=22/tcp
5) add rule to forward port 443 to port 5901
firewall-cmd --permanent --add-forward-port=port=443:proto=tcp:toport=5901
6) reload the firewall
Ubuntu*/Debian systems can use ufw as a firewall for port
1) Login to the root account
2) Make sure ufw is installed and enabled
apt-get install -y ufw
update-rc.d ufw enable
service ufw start
3) Edit the /etc/ufw/before.rules. Add the below lines to the top of the file and save the file
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 5901
5) Allow connections on the needed ports in ufw (note 22 is for ssh and just included so you can ssh back to the server)
ufw allow 22
ufw allow 443
ufw allow 5901
6) Enable ufw
7) Reboot the server
*Note that Ubuntu 16 uses systemd so use systemctl to start/enable the firewall instead of the service command.
Distribution agnostic solution:
This solution uses iptables which is built into the Linux Kernel so is available on all distributions of Linux. Modern Distributions ‘mask’ iptables so you will not be able to save this port forwarding solution past your current session (so you would need to re-enter it every time you start/reboot the server, even with the iptables-save command), but this way you can see how to accomplish this on any system. You can also un-mask iptables if you want to use it instead of firewalld or other firewall applications.
Login as root then enter the below two commands
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 5901
A breakdown of the command so you can modify it for other services/ports if you find the need.
- “iptables” This is a firewall/routing application that is built into the Linux kernel so is on every Linux system. It is a very complicated program and is not very easy to learn (at least for me and in comparison to modern firewall applications). So instead most modern distributions come with a firewall application that ‘masks’ iptables and has easier to use/mange commands that then adjust the iptables rules for you. Firewalld used above is one that is a part of the systemd stack and is standard for Red Hat/CentOS.
“-t nat” This says you’re modifying the nat ‘table’. There are multiple tables that iptables can modify. Nat is for when new connections are made.
“-A PREROUTING” This says to append the rule to the end of the PREROUTING chain. Appending just means you’re adding it without overwriting any existing rules. The PREROUTING chain is a list of rules to apply before routing new connections. Since we want to forward from one port to a new one, we need the rule to take effect before it has been routed.
“-p tcp” This says we’re looking for tcp packets. There’s a few different types you can choose from (tcp or udp being the most common). VNC is a tcp connection so that’s what we need for this example.
“–dport 443” Packets with destination 443 are the target.
You can change this if you want to connect using a different port on your computer.
“-j REDIRECT” stands for “jump REDIRECT” which means the action is a REDIRECT. So when a packet is found that matches port 443/tcp we are going to redirect it
“–to-port 5901” Pretty autological. We are going to redirect it to port 5901. If you want to redirect to different service you can change this to whatever the normal port for that service is.
“iptables-save” This just saves the configuration so it will persist through a reboot of the server.