4

I'm running firwalld on a VPS / webserver.

The public zone is active and default (and I do not want the change that). How do I allow only these two external IP-addresses to access the VPS (i.e. all of the services I have defined in the public zone):

   IP1:  11.22.33.44/24
   IP2:  55.66.77.88/24

These are fake IP addresses and notice that they are intentionally not on the same subnet.

I think I understand why the following doesn't work (it locks out one or the other IP).

user$ sudo firewall-cmd --zone=public --permanent --add-source=11.22.33.44/24
user$ sudo firewall-cmd --zone=public --permanent --add-source=55.66.77.88/24

user$ sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="11.22.33.44/24" invert="True" drop' 
user$ sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="55.66.77.88/24" invert="True" drop'
user$ sudo firewall-cmd --reload

What do I need to modify for this to work (so it doesn't lock out one IP or the other or both)?

Thank you! :)

EDIT: I also tried a /32 bit mask for all four commands above. Sadly it did not help. Still looking for a solution.

I think the logic might sound something like: if IP1 or IP2, allow it and stop processing the chain. else Continue processing the chain, where the very next rule would be to DROP.. Something like that.

EDIT2: Posting the output of sudo firewall-cmd --list-all-zones below. Note that I removed all the rules mentioned above since they weren't working. So the below is back to square one.

user$ sudo firewall-cmd --list-all-zones
block
  target: %%REJECT%%
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


dmz
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


drop
  target: DROP
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


external
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


home
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


internal
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


public (active)
  target: default
  icmp-block-inversion: no
  interfaces: venet0:0 venet0
  sources: 
  services: ssh-vps http https
  ports: 8080/tcp 8080/udp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: echo-reply echo-request timestamp-reply timestamp-request
  rich rules: 

trusted
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


work
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:
3
  • 1
    Can you show the policy of the public zone. cat /etc/firewalld/public.xml or firewall-cmd --list-all --zone=public. Oct 9, 2017 at 9:01
  • I don't see the source IP addresses in the public zone. Oct 9, 2017 at 9:22
  • As mentioned in EDIT2, I removed all rules and starting over. :) But you can use any two ISP range IP-addresses. Thanks.
    – NYCeyes
    Oct 9, 2017 at 9:30

2 Answers 2

1

This is a very good question. firewalld interacts with iptables which in turn interacts with netfilter. Therefore iptables has more flexibility than firewalld. But this does not mean that you must switch back to iptables, but you can still use firewalld for advanced packet filtering. One cool option in firewalld is the use of direct rules or rich rules

In this case, direct rules option will meet your needs.

First of all, wipe all the firewalld rules to default (Don't worry, SSH access or TCP-22 will remain open after wiping)

$ sudo rm -rf /etc/firewalld/zones/*
$ sudo rm -rf /usr/etc/firewalld/zones/*
$ sudo firewall-cmd --complete-reload

Allow ISP-1 and ISP-2 access to your VPS using direct rules (Both INPUT and FORWARD chain)

$ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 11.22.33.44/32 -j ACCEPT
$ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 55.66.77.88/32 -j ACCEPT
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -s 11.22.33.44/32 -j ACCEPT
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -s 55.66.77.88/32 -j ACCEPT

Allow return traffic (in other words, turn on stateful inspection. By default, firewalld is statefu)

$ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Then block any other IP that is not part of ISP-1 or ISP-2

$ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -j DROP
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -j DROP

Reload the rules

$ sudo firewall-cmd --reload

Verify the rules

$ sudo firewall-cmd --direct --get-all-rules
0

Here are 2 issues:

1) You are trying to access the public zone which is also the interface zone since it has 2 interfaces assigned to it. The default target for this zone is to accept icmp packets and reject everything else.

2) You would need a privileged zone (call it source zone) that allows specific IP's to have access to the system services. This privileged zone will have target ACCEPT and will have precedence over the public zone.

So my answer would be this.

1) Have the trusted zone handle your source IP's (traffic coming from). E.g:

firewall-cmd --permanent --zone=trusted --add-source=11.22.33.44 --add-source=55.66.77.88
firewall-cmd --reload

The trusted zone will pass the traffic on to the public zone. The public zone will handle ssh-vps http https services. This is the recommended way of configuring firewalld.

2) Set target to default for the trusted zone.

firewall-cmd --permanent --zone=trusted --set-target=default
firewall-cmd --reload
10
  • Hi. Thanks. I tried what you showed above, but it doesn't work. See my current configuration (which reflects your instructions) in this pastebin: pastebin.com/XZwqQRCt When I start my VPN to originate from a foreign IP address, I can still get in. So something is missing that says if not either of these IPs, REJECT.
    – NYCeyes
    Oct 9, 2017 at 15:43
  • @prismalytics.io See my update. Oct 9, 2017 at 19:36
  • I added the extra command you posted above, resulting in this configuration: pastebin.com/2Ggp5B5y . Same issue: When I start my VPN to originate from a foreign IP address, I can still get in.
    – NYCeyes
    Oct 9, 2017 at 19:55
  • Can you run conntrack -L on your machine? Do you see anything coming from an IP that's not supposed to get access to? Oct 9, 2017 at 20:01
  • @prismalytics.io I see there are other answers in here: unix.stackexchange.com/questions/159873/… Oct 9, 2017 at 20:10

You must log in to answer this question.

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