Skip to content

Route traffic to your server

Your servers sit on a private network behind a shared firewall. Traffic from the internet arrives at a public IP, and the firewall decides both whether to let it through and where to send it.

That means getting a service reachable is usually two separate things, not one:

  1. Translation: which private server should this public traffic go to? (NAT or a port forward)
  2. Permission: is this traffic allowed at all? (a rule)

Most “my site isn’t loading” tickets are one of the two being present without the other.

The Firewall page has three tabs. Rules has its own; NAT and port forwards are both sections of Advanced.

You want Use Effect
One public IP to belong to one server, for everything NAT All traffic on that public IP goes to that server
Just one service reachable, e.g. web or SSH Port forwards Only that port is redirected
To allow or block traffic that already knows where it’s going Rules Permits or denies; doesn’t redirect

If you have a public IP dedicated to a single server, NAT is simpler: set it once and every port follows. If several servers share one public IP, you need port forwards, because a given port on that IP can only lead to one of them.

A NAT mapping hands over the whole address, every port. A port forward on that same address can then never match, no matter where it sits in the list, because the two are different kinds of rule and the mapping is reached first. Nothing reports this: the forward simply never fires.

If one server needs an address to itself and another needs a single port on it, you cannot have both. Either give the second server its own public address, or drop the NAT mapping and use port forwards for everything on that address.

You need a public IP assigned to you first: see Request a public IP.

  1. Go to Firewall, open Advanced, and find the NAT section.
  2. Create a mapping from your public IP to the private IP of the server.
  3. Save.

Both addresses are offered as lists, so you pick rather than type. The server’s private IP is also on its Networking tab. If that’s blank, the panel can’t read it because the guest agent isn’t installed.

  1. Go to Firewall, open Advanced, and find the Port forwards section.
  2. Add a forward: the public port traffic arrives on, the private IP of the destination server, and the port on that server.
  3. Save.

The two ports don’t have to match. Forwarding public 2222 to private 22 is a common way to give several servers SSH access through one public IP.

Translation alone doesn’t guarantee the traffic is permitted. On the Rules tab, make sure something allows the traffic you just directed: typically by destination port.

Keep rules as narrow as the service needs:

  • A public website needs 80 and 443 from anywhere.
  • SSH does not need to be open to the whole internet. Restrict 22 to the addresses you actually connect from. This single change removes most of the noise you’ll otherwise see in firewall activity.
  • Databases should almost never be reachable from the internet. Keep them on the private network and reach them from another of your servers.

Work outwards from the server. Each step rules out one layer.

1. Is the service running and listening? On the server:

Terminal window
ss -tlnp | grep :443

Nothing listed means the problem is your application, not the network. Also check it isn’t bound to 127.0.0.1 only: that accepts local connections and nothing else.

2. Does the server’s own firewall allow it? A guest firewall (ufw, firewalld, Windows Defender Firewall) sits inside the server and is separate from ours.

Terminal window
ufw status # Debian, Ubuntu
firewall-cmd --list-all # RHEL, Rocky, Oracle Linux

3. Does it work from another of your servers? If a private-network connection succeeds, the service is healthy and the issue is at the edge: the NAT/forward or the rule.

4. From outside:

Terminal window
curl -v https://YOUR_PUBLIC_IP/
nc -vz YOUR_PUBLIC_IP 443

Then read the firewall activity tab. Seeing your attempt blocked means a rule is missing. Seeing nothing at all usually means the traffic never got translated: check NAT or the port forward.

A rule exists but nothing is translated. The rule permits traffic that has no destination. Add NAT or a port forward.

Traffic is translated but no rule allows it. You’ll see the attempt blocked in activity. Add a rule.

Two things claim the same public port. A port on one public IP can only lead to one server. Change one of them to a different public port, or use a second public IP.

It works by IP but not by domain. That’s DNS, not the firewall. Check your domain’s A record points at the public IP, and remember records take time to propagate.

It worked and then stopped. Check the server is still running and its disk isn’t full, then look at WAF and intrusion detection: in blocking mode the WAF can drop traffic that your rules permit.

Every rule, forward and mapping can be edited in place. Open its row menu and choose Edit. A forward keeps its position in the list when you edit it, which matters: see below.

Forwards are checked in the order they appear, and the first one that matches the incoming address and port is the one that acts. Two forwards covering the same address and port are therefore decided entirely by which comes first, and the loser never fires and says nothing about it.

Use Move up and Move down on a forward’s row menu to change that. The table is shown in the order they are checked, so what you see is what happens.

This has no effect on a NAT mapping, which is a different kind of rule and is always reached first for the address it covers. See “Do not mix the two on one address” above.