Firewalld ignoring rich-rule against port forwarding
3
votes
1
answer
229
views
I have an issue setting up my firewalld to have a perfect link together with docker and fail2ban.
First, what I want to achive is the following traffic routing setup:
[PUBLIC] ->
[FIREWALLD] -> (
[143/tcp FORWARD PORT] -----> [DOCKER/143/tcp]
[ 22/tcp] -----> [openssh locally running]
)
**fail2ban**
I set up fail2ban to listen to my docker container, check for auth errors and set up a ban using firewall-cmd
. That works so far. As soon as I mis-authenticate 3 times, it sends a command to firewalld.
**Port forwarding**
I also have set up the port forward for docker. I am setting it up explicitly, because I do not want to have docker destroying my networking. Maybe this is something I do not need in the future, but it is configured via the StrictForwardPorts=yes
configuration. https://firewalld.org/2024/11/strict-forward-ports
**Goal**
The goal is to whenever a fail2ban trigger happens, the IP should **not** have access to the port 143 (forwarded one) and (maybe) neither the other ones anymore. But at first, I'd like to ban port-wise.
**Problem**
The problem currently is, that if a reject rich rule is created, it will block port 22 for that IP, but not port 143.
**Attempts**
I also tried putting the IP into the drop
zone, giving it the priority -10
. Same error result. Port 22 is dropped, but 143 still works.
What am I doing wrong? Here's my zone configuration from the last try:
docker (active)
target: ACCEPT
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces: br-0aa8d4b5dde7 docker0
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule priority="-999" family="ipv4" source address="192.168.178.44" reject
drop (active)
target: DROP
ingress-priority: -10
egress-priority: -10
icmp-block-inversion: no
interfaces:
sources: 192.168.178.44
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (default, active)
target: default
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
port=143:proto=tcp:toport=143:toaddr=172.18.0.2
source-ports:
icmp-blocks:
rich rules:
rule priority="-999" family="ipv4" source address="192.168.178.44" reject
As seen: Actually, address 192.168.178.44 should be fully blocked to the public zone. But it isnt. Additionally I added the IP to the drop zone. It seems that drop zone priority is working, as my SSH connection is dropped instead of rejected, but the port 143 is still accessible
**Update 1: Some debug info**
$ sudo firewall-cmd --get-policies
allow-host-ipv6 docker-forwarding
**Update 2: --info-policy=docker-forwarding**
docker-forwarding (active)
priority: -1
target: ACCEPT
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules: `
**Update 3:**
Another idea that came to my mind was to create another policy with priority -10, containing the rich rule:
sudo firewall-cmd --permanent --new-policy ban-pre-routing
sudo firewall-cmd --permanent --policy ban-pre-routing --add-ingress-zone ANY
sudo firewall-cmd --permanent --policy ban-pre-routing --add-egress-zone HOST
sudo firewall-cmd --permanent --policy ban-pre-routing --set-priority -10
sudo firewall-cmd --permanent --policy ban-pre-routing --add-rich-rule="rule family=ipv4 source address=192.168.178.44 port port=143 protocol=tcp reject"
Still no effect. My *.44 Host can still connect to the machine. If I leave out the port port=143 protocol=tcp
part, it would block the machine though to ssh - while still being able to access the port 143.
**Update 4:**
Using Update 3 with the policy configured to egress zone docker, it does not result in a difference. My Configs look like this now:
$ sudo firewall-cmd --list-all-policies
allow-host-ipv6 (active)
priority: -15000
target: CONTINUE
ingress-zones: ANY
egress-zones: HOST
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv6" icmp-type name="neighbour-advertisement" accept
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="redirect" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
ban-pre-routing (active)
priority: -10
target: CONTINUE
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="192.168.178.44" port port="143" protocol="tcp" reject
docker-forwarding (active)
priority: -1
target: ACCEPT
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
And for zones:
$ sudo firewall-cmd --list-all --zone=public
public (default, active)
target: default
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
port=143:proto=tcp:toport=143:toaddr=172.18.0.2
source-ports:
icmp-blocks:
rich rules:
$ sudo firewall-cmd --list-all --zone=drop
drop
target: DROP
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
$ sudo firewall-cmd --list-all --zone=docker
docker (active)
target: ACCEPT
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces: br-c5f172e4effe docker0
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Asked by Marco Klein
(151 rep)
Mar 31, 2025, 07:35 PM
Last activity: Apr 3, 2025, 09:59 AM
Last activity: Apr 3, 2025, 09:59 AM