3

Short question:

How do you enable port forwarding on only a single host ip address?

Backstory:

My Centos 7 server has 5 ip addresses. Previously I had apache listening on all of them and various domains assigned to those ip addresses which were resolved with virtual hosts.

I changed the Listen directive in httpd.conf so that now apache only listens to 4 of the ip addresses

Using node.js I created another server instance, but it won't let me listen on the standard port 80 without elevated permissions. I don't want to run it with elevated permissions.

I'd like to port forward port 80 to something like 8080, but only on the one ip address without affecting traffic directed at the other 4 ip addresses. It's important that traffic on other ip addresses are not affected by the rule.

I think the solution will look similar to:

firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent

The other questions and answers I've found have to do with source ip addresses instead of host ip addresses.

0

4 Answers 4

8
+50

A firewalld zone can be specified either by interface or by source address, but you want to filter by destination address. You'll need a rich rule to handle this particular situation.

Such a rich rule may look like:

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" destination address="198.51.100.237" forward-port port="80" protocol="tcp" to-port="8080"'

See the firewalld.richlanguage(5) man page for documentation on rich rules.

Once your rich rule is working, remember to make it permanent with

firewall-cmd --runtime-to-permanent

or adding --permanent to the previous invocation.

0
1

Suppose out of your five IP addresses, one is 192.0.2.3, which you'd like to forward port 80 on. You can use iptables to forward ports on this IP address like so:

iptables -t nat -A PREROUTING -d 192.0.2.3 -p tcp --dport 80 -j REDIRECT --to-ports 8080

This should leave all your other addresses unaffected. Should a program bind to port 80 on all addresses, 192.0.2.3 will still redirect to port 8080 since it is redirected prior to routing.

1
  • Won't the firewalld rules overwrite whatever changes are made on iptables? Mar 8, 2018 at 2:22
1

Note: I admit I am proposing a weird and possibly unsupported solution, which may get broken on future firewalld versions. Nonetheless, it will certainly work on a CentOS 7 server.

I suggest you to directly add such port forwarding rule into the iptables/ip6tables stack. You can achieve that by using firewalld's direct rules. For example:

# firewall-cmd --permanent --direct --add-rule ipv4 nat PRE_public_allow 0 \
    --destination 11.22.33.44 --protocol tcp --destination-port 80 \
    --jump REDIRECT --to-ports 8080

# firewall-cmd --permanent --direct --add-rule ipv6 nat PRE_public_allow 0 \
    --destination 11:22:33:44:55:66:77:88 --protocol tcp --destination-port 80 \
    --jump REDIRECT --to-ports 8080

I figured that CentOS's firewalld creates a PRE_<zone>_allow chain in nat table for each active zone, which gets evaluated when packets that matches zone definitions arrive. So iptables/ip6tables rules can be added there.

1

I would configure reverse proxy with different ports for different domains but same IP address. In the httpd config page, I would add Listen directives for each ports (for example: Listen 80, Listen 8081, Listen 8082 etc), include vhosts configuration port in httpd config page and update vhosts configuration page according to the ports.

1
  • Thank you for taking a moment to look at it, but the question is to do it without some other server running in front of the request. I've been doing it the way you describe already, but I would like to publicly serve a nodejs application with nothing running in front of it. Mar 8, 2018 at 2:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .