firewalld public zone and internal zone clash?

Issues related to configuring your network
mutex77
Posts: 5
Joined: 2012/11/02 18:46:28

firewalld public zone and internal zone clash?

Post by mutex77 » 2020/01/17 00:29:21

Can I have a multi-zone setup and use both the public zone and internal zone?

Im trying to allow http from everyone and only allow ssh from my network. I add the http service to public and I can connect to it from other machines as expected. The next action would be to add a source to another zone, in this case "internal", then add ssh to it

As soon as I do firewall-cmd --zone=internal --add-source=192.168.0.0/16 I can no longer connect to http from a remote machine even though its still defined in the default active zone public. I remove the source and I can connect again. If I do this with zone "trusted" I dont get this behavior.

Do zone public and zone internal clash or override each other in some way? Ive tried removing all my modifications from /etc/firewalld/zones and starting fresh but run into the same problem.

hunter86_bg
Posts: 2019
Joined: 2015/02/17 15:14:33
Location: Bulgaria
Contact:

Re: firewalld public zone and internal zone clash?

Post by hunter86_bg » 2020/01/17 02:47:19

You are not specifying what is the IP you are connecting from.
Also what is the output of:

Code: Select all

 firewall-cmd --list-all-zones 

User avatar
KernelOops
Posts: 428
Joined: 2013/12/18 15:04:03
Location: xfs file system

Re: firewalld public zone and internal zone clash?

Post by KernelOops » 2020/01/17 03:01:23

You know what... its interesting that I hit the same issue on all my CentOS 8 servers, once I upgraded them to 8.1.

I think something changed the way firewalld works in 8.1, compared to 7.x and 8.0. Previously, the "internal" zone could have just the ssh port and you'd be allowed both "public+internal" zones together. Now it seems that when your IP is matched in the "internal" zone, it only matches that zone and no other.

Maybe its a documented change and I missed it?
--
R.I.P. CentOS :cry:
--

hunter86_bg
Posts: 2019
Joined: 2015/02/17 15:14:33
Location: Bulgaria
Contact:

Re: firewalld public zone and internal zone clash?

Post by hunter86_bg » 2020/01/17 03:25:05

I think that it was always the same.
Maybe a bug allowed you to reach public instead of internal zone.

User avatar
KernelOops
Posts: 428
Joined: 2013/12/18 15:04:03
Location: xfs file system

Re: firewalld public zone and internal zone clash?

Post by KernelOops » 2020/01/17 06:53:07

I don't think its a bug, I believe firewalld was designed and documented to act like that, when multiple zones have the same target.
--
R.I.P. CentOS :cry:
--

User avatar
KernelOops
Posts: 428
Joined: 2013/12/18 15:04:03
Location: xfs file system

Re: firewalld public zone and internal zone clash?

Post by KernelOops » 2020/01/17 07:06:50

Maybe this is an after effect, moving from iptables to nftables.
--
R.I.P. CentOS :cry:
--

User avatar
jlehtone
Posts: 4530
Joined: 2007/12/11 08:17:33
Location: Finland

Re: firewalld public zone and internal zone clash?

Post by jlehtone » 2020/01/17 09:10:38

What do you have in

Code: Select all

nft list table inet firewalld
when you have the "erroneus" config?

User avatar
KernelOops
Posts: 428
Joined: 2013/12/18 15:04:03
Location: xfs file system

Re: firewalld public zone and internal zone clash?

Post by KernelOops » 2020/01/17 09:32:44

Here is a test VM running CentOS 8.1, which has the identical firewalld configuration as a VM running CentOS 7.7.


/etc/centos-release

Code: Select all

CentOS Linux release 8.1.1911 (Core) 
/etc/firewalld/zones/public.xml

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>Public</description>
  <port protocol="tcp" port="80"/>
  <port protocol="tcp" port="443"/>
  <icmp-block name="redirect"/>
  <icmp-block name="source-quench"/>
  <icmp-block name="parameter-problem"/>
</zone>
/etc/firewalld/zones/ssh.xml

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>ssh</short>
  <description>ssh</description>
  <source address="192.168.1.2"/>
  <port protocol="tcp" port="22"/>
</zone>
output of the command: nft list table inet firewalld

Code: Select all

table inet firewalld {
	chain raw_PREROUTING {
		type filter hook prerouting priority -290; policy accept;
		icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept
		meta nfproto ipv6 fib saddr . iif oif missing drop
		jump raw_PREROUTING_ZONES
	}

	chain raw_PREROUTING_ZONES {
		ip saddr 192.168.1.2 goto raw_PRE_ssh
		iifname "enp0s3" goto raw_PRE_public
		goto raw_PRE_public
	}

	chain mangle_PREROUTING {
		type filter hook prerouting priority -140; policy accept;
		jump mangle_PREROUTING_ZONES
	}

	chain mangle_PREROUTING_ZONES {
		ip saddr 192.168.1.2 goto mangle_PRE_ssh
		iifname "enp0s3" goto mangle_PRE_public
		goto mangle_PRE_public
	}

	chain filter_INPUT {
		type filter hook input priority 10; policy accept;
		ct state established,related accept
		ct status dnat accept
		iifname "lo" accept
		jump filter_INPUT_ZONES
		ct state invalid drop
		reject with icmpx type admin-prohibited
	}

	chain filter_FORWARD {
		type filter hook forward priority 10; policy accept;
		ct state established,related accept
		ct status dnat accept
		iifname "lo" accept
		ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable
		jump filter_FORWARD_IN_ZONES
		jump filter_FORWARD_OUT_ZONES
		ct state invalid drop
		reject with icmpx type admin-prohibited
	}

	chain filter_OUTPUT {
		type filter hook output priority 10; policy accept;
		oifname "lo" accept
		ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable
	}

	chain filter_INPUT_ZONES {
		ip saddr 192.168.1.2 goto filter_IN_ssh
		iifname "enp0s3" goto filter_IN_public
		goto filter_IN_public
	}

	chain filter_FORWARD_IN_ZONES {
		ip saddr 192.168.1.2 goto filter_FWDI_ssh
		iifname "enp0s3" goto filter_FWDI_public
		goto filter_FWDI_public
	}

	chain filter_FORWARD_OUT_ZONES {
		ip daddr 192.168.1.2 goto filter_FWDO_ssh
		oifname "enp0s3" goto filter_FWDO_public
		goto filter_FWDO_public
	}

	chain filter_IN_public {
		jump filter_IN_public_pre
		jump filter_IN_public_log
		jump filter_IN_public_deny
		jump filter_IN_public_allow
		jump filter_IN_public_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_IN_public_pre {
	}

	chain filter_IN_public_log {
	}

	chain filter_IN_public_deny {
		icmp type redirect reject with icmp type admin-prohibited
		icmpv6 type nd-redirect reject with icmpv6 type admin-prohibited
		icmp type source-quench reject with icmp type admin-prohibited
		icmp type parameter-problem reject with icmp type admin-prohibited
		icmpv6 type parameter-problem reject with icmpv6 type admin-prohibited
	}

	chain filter_IN_public_allow {
		tcp dport http ct state new,untracked accept
		tcp dport https ct state new,untracked accept
	}

	chain filter_IN_public_post {
	}

	chain filter_FWDI_public {
		jump filter_FWDI_public_pre
		jump filter_FWDI_public_log
		jump filter_FWDI_public_deny
		jump filter_FWDI_public_allow
		jump filter_FWDI_public_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_FWDI_public_pre {
	}

	chain filter_FWDI_public_log {
	}

	chain filter_FWDI_public_deny {
		icmp type redirect reject with icmp type admin-prohibited
		icmpv6 type nd-redirect reject with icmpv6 type admin-prohibited
		icmp type source-quench reject with icmp type admin-prohibited
		icmp type parameter-problem reject with icmp type admin-prohibited
		icmpv6 type parameter-problem reject with icmpv6 type admin-prohibited
	}

	chain filter_FWDI_public_allow {
	}

	chain filter_FWDI_public_post {
	}

	chain raw_PRE_public {
		jump raw_PRE_public_pre
		jump raw_PRE_public_log
		jump raw_PRE_public_deny
		jump raw_PRE_public_allow
		jump raw_PRE_public_post
	}

	chain raw_PRE_public_pre {
	}

	chain raw_PRE_public_log {
	}

	chain raw_PRE_public_deny {
	}

	chain raw_PRE_public_allow {
	}

	chain raw_PRE_public_post {
	}

	chain mangle_PRE_public {
		jump mangle_PRE_public_pre
		jump mangle_PRE_public_log
		jump mangle_PRE_public_deny
		jump mangle_PRE_public_allow
		jump mangle_PRE_public_post
	}

	chain mangle_PRE_public_pre {
	}

	chain mangle_PRE_public_log {
	}

	chain mangle_PRE_public_deny {
	}

	chain mangle_PRE_public_allow {
	}

	chain mangle_PRE_public_post {
	}

	chain filter_FWDO_public {
		jump filter_FWDO_public_pre
		jump filter_FWDO_public_log
		jump filter_FWDO_public_deny
		jump filter_FWDO_public_allow
		jump filter_FWDO_public_post
	}

	chain filter_FWDO_public_pre {
	}

	chain filter_FWDO_public_log {
	}

	chain filter_FWDO_public_deny {
	}

	chain filter_FWDO_public_allow {
	}

	chain filter_FWDO_public_post {
	}

	chain filter_IN_ssh {
		jump filter_IN_ssh_pre
		jump filter_IN_ssh_log
		jump filter_IN_ssh_deny
		jump filter_IN_ssh_allow
		jump filter_IN_ssh_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_IN_ssh_pre {
	}

	chain filter_IN_ssh_log {
	}

	chain filter_IN_ssh_deny {
	}

	chain filter_IN_ssh_allow {
		tcp dport ssh ct state new,untracked accept
	}

	chain filter_IN_ssh_post {
	}

	chain raw_PRE_ssh {
		jump raw_PRE_ssh_pre
		jump raw_PRE_ssh_log
		jump raw_PRE_ssh_deny
		jump raw_PRE_ssh_allow
		jump raw_PRE_ssh_post
	}

	chain raw_PRE_ssh_pre {
	}

	chain raw_PRE_ssh_log {
	}

	chain raw_PRE_ssh_deny {
	}

	chain raw_PRE_ssh_allow {
	}

	chain raw_PRE_ssh_post {
	}

	chain mangle_PRE_ssh {
		jump mangle_PRE_ssh_pre
		jump mangle_PRE_ssh_log
		jump mangle_PRE_ssh_deny
		jump mangle_PRE_ssh_allow
		jump mangle_PRE_ssh_post
	}

	chain mangle_PRE_ssh_pre {
	}

	chain mangle_PRE_ssh_log {
	}

	chain mangle_PRE_ssh_deny {
	}

	chain mangle_PRE_ssh_allow {
	}

	chain mangle_PRE_ssh_post {
	}

	chain filter_FWDI_ssh {
		jump filter_FWDI_ssh_pre
		jump filter_FWDI_ssh_log
		jump filter_FWDI_ssh_deny
		jump filter_FWDI_ssh_allow
		jump filter_FWDI_ssh_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_FWDI_ssh_pre {
	}

	chain filter_FWDI_ssh_log {
	}

	chain filter_FWDI_ssh_deny {
	}

	chain filter_FWDI_ssh_allow {
	}

	chain filter_FWDI_ssh_post {
	}

	chain filter_FWDO_ssh {
		jump filter_FWDO_ssh_pre
		jump filter_FWDO_ssh_log
		jump filter_FWDO_ssh_deny
		jump filter_FWDO_ssh_allow
		jump filter_FWDO_ssh_post
	}

	chain filter_FWDO_ssh_pre {
	}

	chain filter_FWDO_ssh_log {
	}

	chain filter_FWDO_ssh_deny {
	}

	chain filter_FWDO_ssh_allow {
	}

	chain filter_FWDO_ssh_post {
	}
}


The 8.1 VM, allows the .2 address to connect to ssh port 22 (ssh zone) but not 80/443 (public zone).

The 7.7 VM, allows the .2 address to connect to ssh port 22 (ssh zone) AND ports 80/443 (public zone).

The two VM's run identical /etc/firewalld files, they have no helpers, no icmptypes, no ipsets and no service files. Lockdown is not enabled.
--
R.I.P. CentOS :cry:
--

User avatar
jlehtone
Posts: 4530
Joined: 2007/12/11 08:17:33
Location: Finland

Re: firewalld public zone and internal zone clash?

Post by jlehtone » 2020/01/17 15:46:03

Code: Select all

chain filter_INPUT_ZONES {
		ip saddr 192.168.1.2 goto filter_IN_ssh
		iifname "enp0s3" goto filter_IN_public
		goto filter_IN_public
	}
The keyword here is goto.
If a packet arrives from 192.168.1.2, then it will go to filter_IN_ssh.
If nothing in filter_IN_ssh handles that packet then it will return to filter_INPUT for these rules:

Code: Select all

ct state invalid drop
reject with icmpx type admin-prohibited
Can you post the 7.7's iptables -S too, for comparison?

mutex77
Posts: 5
Joined: 2012/11/02 18:46:28

Re: firewalld public zone and internal zone clash?

Post by mutex77 » 2020/01/17 16:16:49

I was typing up a reply to the questions some asked, but KernelOops basically summed it all up complete with configs. Thank you!!

I forgot to mention this is working for my CentOS7 servers, and I had updated my minimal install template of CentOS7 to CentOS8. I guess I know why it doesnt work now.

So....was it a bug in CentOS7 that allowed us to access the public zone once we defined a source address in internal, or is it bug in CentOS8 that blocks it?

Post Reply