1

I'm not too familiar with firewalld, but I thought I'd try it out on Ubuntu20.04. The problem I'm having is that port=80/tcp in zone=public gets blocked every time I try to add a new zone.

So my question is: how do I add a new zone without it blocking port=80/tcp in zone=public?

I describe what I did below.

(edit - I explain at end of this questions that these same actions are successful in ubuntu 18.04 and centos 8, but fail in ubuntu 20.04)

First, I install a clean instance of Ubuntu 20.04 on a VPS. Then I run these commands as root user from terminal:

# make sure ufw is not used
systemctl stop ufw && systemctl disable ufw;

install a webserver so I can test port 80 will give me a web page

apt-get install -y apache2;

install firewalld and configure

apt-get install -y firewalld; systemctl start firewalld; firewall-cmd --permanent --zone=public --add-port=80/tcp; firewall-cmd --reload;

Now when I go to my server's ip address with a web browser, I can see the default apache web page.

Next, here is where things get unusual. I'll list my experiments in the exact order I performed them:

Experiment 1 - no active zones

I run the command firewall-cmd --get-active-zones.

The result is: terminal shows nothing.

Experiment 2 - add zone=john with no rules

I run these three commands:

firewall-cmd --new-zone=john --permanent;
firewall-cmd --reload;
firewall-cmd --get-active-zones;

The result is:

The web page renders properly.

But my terminal still does not print any active zones.

Experiment 3 - add rules to zone=john

I run these three commands:

# replace 1.1.1.1 with my home's ip address
firewall-cmd --zone=john --add-source=1.1.1.1/24 --permanent;
firewall-cmd --reload;
firewall-cmd --get-active-zones;

The result is:

Port 80 gets blocked and web page now times out and is unreachable

My terminal prints:

john
  sources: 1.1.1.1/24

Experiment 4 - delete zone=john

I run these commands:

firewall-cmd --delete-zone=john --permanent;
firewall-cmd --reload;

The result is:

My web page is able to reload again.

Experiment 5 - adding interface=eth0 to zone=public

I tried activating my public zone with this command:

firewall-cmd --zone=public --permanent --add-interface=eth0;
firewall-cmd
firewall-cmd --reload;
firewall-cmd --get-active-zones;

The result is:

My webpage is still able to load.

My terminal shows:

public
  interfaces: eth0

Experiment 6 - re-adding zone=john

I run these commands:

firewall-cmd --new-zone=john --permanent;
firewall-cmd --reload;
firewall-cmd --zone=john --add-source=1.1.1.1/24 --permanent;
firewall-cmd --reload;
firewall-cmd --get-active-zones;

The result is:

Port 80 gets blocked and web page now times out and is unreachable

My terminal prints:

john
  sources: 1.1.1.1/24
public
  interfaces: eth0

Final Result

So after all these experiments, firewall-cmd --list-all-zones will show this:

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: ssh 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: ssh ports: protocols: masquerade: yes forward-ports: source-ports: icmp-blocks: rich rules:

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

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

john (active) target: default icmp-block-inversion: no interfaces: sources: 1.1.1.1/24 services: ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:

public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client ssh ports: 80/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: 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: dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:


ADDITIONAL INFORMATION

I rebuilt this VPS machine using Ubuntu 18.04 and ran the exact same script above. The result is success. I can add a new zone without blocking port=80/tcp on zone=public.

I rebuilt this VPS machine using CentOS 8. Then I took the script above and replaced apt-get with yum or dnf. The result is success. I can add a new zone without blocking port=80/tcp on zone=public.

I rebuilt this VPS machine again with Ubuntu 20.04 and ran the exact same script. The result is failure. The new zone is blocking port=80/tcp on zone=public.

I don't understand why things fail in Ubuntu 20.04 when it succeeds on Ubuntu 18.04 and CentOS 8.

learningtech
  • 7,769

2 Answers2

1

Check AllowZoneDrifting on all systems:

grep AllowZoneDrifting /etc/firewalld/firewalld.conf

Setting it to no (and running systemctl reload firewalld) on Ubuntu 18.04 and CentOS 7 systems will yield the same behavior as Ubuntu 20.04. As a matter of fact, if you checked the logs on CentOS, you probably will see a message that looks like:

firewalld: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option.

To solve your problem, once you add 1.1.1.1/24 to your sources list, you can add the http service (or port 80/tcp). For example:

firewall-cmd --new-zone=john --permanent
firewall-cmd --zone=john --add-source=1.1.1.1/24 --permanent
firewall-cmd --zone=john --add-service=http --permanent
firewall-cmd --reload

To check you may run:

firewall-cmd --zone=john --list-all
h q
  • 181
0

This confused me for a while, because I thought zones were also filtered based on the services enabled, but the other answer here and this article revealed that this is not the case:

A source (or overlapping sources) cannot be assigned to multiple zones.

In other words, if you define a source IP, all traffic from that IP will be captured by that zone, regardless as to whether the relevant service is enabled or not.

In this case, HTTP(S) traffic from 1.1.1.1/24 will not fallback to the public zone, even if only the ssh is active on the john zone.

You need to define all services you want enabled for a zone if you are filtering it by IP.

# Make sure the public zone has HTTP(S) access
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https

Remove public SSH access

firewall-cmd --permanent --zone=public --remove-service=ssh

Add SSH and HTTP(S) access for the john zone

firewall-cmd --permanent --zone=john --add-service=http firewall-cmd --permanent --zone=john --add-service=https firewall-cmd --permanent --zone=john --add-service=ssh