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:
NYCeyes
  • 229
  • 1
  • 3
  • 9

2 Answers2

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
Valentin Bajrami
  • 9,244
  • 3
  • 25
  • 38
  • Hi. Thanks. I tried what you showed above, but it doesn't work. See my current configuration (which reflects your instructions) in this pastebin: https://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 09 '17 at 15:43
  • @prismalytics.io See my update. – Valentin Bajrami Oct 09 '17 at 19:36
  • I added the extra command you posted above, resulting in this configuration: https://pastebin.com/2Ggp5B5y . Same issue: When I start my VPN to originate from a foreign IP address, I can still get in. – NYCeyes Oct 09 '17 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? – Valentin Bajrami Oct 09 '17 at 20:01
  • @prismalytics.io I see there are other answers in here: https://unix.stackexchange.com/questions/159873/whitelist-source-ip-addresses-in-centos-7 – Valentin Bajrami Oct 09 '17 at 20:10
  • I tried that post last night. It's not exactly the same. It didn't work for me. This needs a fresh start. Two IP addresses, not on the same subnet nor even related to each other. What exact firewalld commands are run to exclusively allow those two IP address to access all service ports, and only those two; and nothing else. I've never seen this. (._,). Thank you for helping though. =:) – NYCeyes Oct 09 '17 at 20:13
  • Can you safely block some services in the `public` zone and see if it has any affect? Try for example to reach port `8080`. Be careful not to lock yourself out. – Valentin Bajrami Oct 09 '17 at 20:22
  • To respond to your previous comment. The source IP addresses doesn't have to be the same, that's the whole idea!. If this is going to give you head ache you can try `iptables` – Valentin Bajrami Oct 09 '17 at 20:28
  • Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/66844/discussion-between-val0x00ff-and-prismalytics-io). – Valentin Bajrami Oct 09 '17 at 20:28
  • \@val0x00ff see my chat reply and the accompanying pastebin: https://pastebin.com/8nyGgUTA (I formatted it for clarity as well as add multiple ports). – NYCeyes Oct 10 '17 at 00:50
0

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
Bruce Malaudzi
  • 1,522
  • 1
  • 4
  • 11