1

I am running firewalld on my server and I am trying to setup a fail2ban (using firewalld) in order to improve security. The problem is: I can't get it to kill established connections.

Firewalld has the default config with just some services added (ssh and so on).

I think I know where the problem is: iptables -L INPUT gives me this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination      
ACCEPT     all  --  anywhere             anywhere        ctstate RELATED,ESTABLISHED   
ACCEPT     all  --  anywhere             anywhere            
INPUT_direct  all  --  anywhere             anywhere            
INPUT_ZONES_SOURCE  all  --  anywhere             anywhere            
INPUT_ZONES  all  --  anywhere             anywhere            
ACCEPT     icmp --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere        reject-with icmp-host-prohibited

From what I understand of iptables this means related and established connections get accepted no matter what, because it is the first rule (I have no idea why the second rule exists and at the same time only the specified ports are open, but let's ignore that for now).

What I tried was to remove the first rule iptables -D INPUT 1 but that left me with a system that had no network at all, neither in- nor outgoing. So I added the rule again but as the second last. iptables -I INPUT 7 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT.

Chain INPUT (policy ACCEPT)
target     prot opt source               destination      
ACCEPT     all  --  anywhere             anywhere            
INPUT_direct  all  --  anywhere             anywhere            
INPUT_ZONES_SOURCE  all  --  anywhere             anywhere            
INPUT_ZONES  all  --  anywhere             anywhere            
ACCEPT     icmp --  anywhere             anywhere    
ACCEPT     all  --  anywhere             anywhere        ctstate RELATED,ESTABLISHED           
REJECT     all  --  anywhere             anywhere        reject-with icmp-host-prohibited

That seemd to have the desired effect. Established connections are now killed when the fail2ban entries are made and the rest of the network seems to work.

The question: How do I persist this with firewalld? I know I can do permanent changes to firewalld via firewall-cmd --permanent and I know I can do some more low level stuff via --direct and --xxx-rich-rule but I haven't found a way of going as deep as manipulating the INPUT chain.

EDIT: I found out, that you can use --passthrough in order to manipulate the INPUT chain. However, if I try to make it permanent:

firewall-cmd --direct --passthrough ipv4 -I INPUT 7 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
firewall-cmd --direct --passthrough ipv4 -D INPUT 1
systemctl restart firewalld

The insert works, but the delete does not. After this iptables -L INPUT yields:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
INPUT_direct  all  --  anywhere             anywhere            
INPUT_ZONES_SOURCE  all  --  anywhere             anywhere            
INPUT_ZONES  all  --  anywhere             anywhere            
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

EDIT:

I still havent found a way to make this work with the firewalld action of fail2ban, so at this point I assume it is not possible.

If I use the iptables action of fail2ban instead though it works, so I will stick to that.

  • Look at the rules with iptables -vL INPUT, it might be that the second rule just lets through packets local to the machine, i.e. the lo interface. – ilkkachu Sep 22 '16 at 10:29
1

Seems that firewalld expects to block requests on PREROUTING in mangle table that it is checked before filter table where you are trying to add the rule.

Simple Ban

In order to block established sessions the easy option is to adding a source rule in drop zone.

firewall-cmd --zone=drop --remove-source=192.168.1.xx

This will add the source IP in PREROUTING_ZONES_SOURCE chain on mangle table.

# iptables -L PREROUTING_ZONES_SOURCE -nv --line -t mangle
Chain PREROUTING_ZONES_SOURCE (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1       23  1656 DROP       all  --  *      *       192.168.1.xx        0.0.0.0/0

PREROUTING_ZONES_SOURCE is called in PREROUTING chain that handles all the traffic before any INPUT chain in filter or mangle.

# iptables -L PREROUTING -nv --line -t mangle
Chain PREROUTING (policy ACCEPT 1809 packets, 90324 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     227K   22M PREROUTING_direct  all  --  *      *       0.0.0.0/0            0.0.0.0/0
2     227K   22M PREROUTING_ZONES_SOURCE  all  --  *      *       0.0.0.0/0            0.0.0.0/0
3     226K   22M PREROUTING_ZONES  all  --  *      *       0.0.0.0/0            0.0.0.0/0

Custom Ban rules

If you need to add more specific rule, use the --direct --add-rule to add the rule in mangle/INPUT that is executed after mangle/PREROUTING. Here you have an example for blocking port 443 for an specific IP:

# firewall-cmd --direct --add-rule ipv4 mangle INPUT 0 -p tcp --dport 443 -s 192.168.1.xx -j DROP

WHere the format is the following:

--direct --add-rule { ipv4 | ipv6 | eb } table chain priority args

In the example this is:

  • { ipv4 | ipv6 | eb } -> ipv4: to specify the IPv4 protocol
  • table -> mangle: in order to execute as soon as packet is received and before checking any rule in filter table, like the one that allow packets from ESTABLISHED connections.
  • chain -> INPUT: this INPUT chain is checked after PREROUTING but notice that this INPUT is related to mangle table.
  • priority -> 0 : rule priority where 0 is the highest priority.
  • args -> -p tcp --dport 443 -s 192.168.1.xx -j DROP: same parameters you would pass to iptables.

Then, this is how mangle/INPUT_direct looks like:

# iptables -L INPUT_direct -nv --line -t mangle
Chain INPUT_direct (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1       30  1888 DROP       tcp  --  *      *       192.168.1.181        0.0.0.0/0            tcp dpt:443

Some notes

Note that first example will block any packet from the source IP, but the second example will be executed after PREROUTING rules so, if you modify the packet before reaching INPUT or packet is routed to FORWARD table, packet will not reach your DROP rule.

Here you have a simple flow diagram of the netfilter tables. netfilter packet processing flow Image extracted from http://www.iptables.info/en/structure-of-iptables.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.