3

so after reading the firewalld man page and fedora documentation, I have come to the understanding that to add a custom rule to firewall with specific arguements i need to use the structure

 firewall-cmd [--permanent] --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>

what I am specifically trying to do is create a custom rule with geoip matching to block out all countries that don't originate from the US. Before I do this i need to first add a matching rule that allows access from my local network as I am controlling the server through ssh on a local private network, so I add a rule like so

 firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 192.168.0.0/24 -j ACCEPT

i then add a second rule like so

 firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -m geoip ! --src-cc US -j DROP

these add to the input chain, but add under a sub-chain called INPUT_direct, this sub-chain is listed in the generic unchanged INPUT rules list as 3rd and a quick

 iptables -L INPUT

shows the INPUT chain as 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
 DROP       all  --  anywhere             anywhere             ctstate INVALID
 REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

and the INPUT_direct as

 Chain INPUT_direct (1 references)
 target     prot opt source               destination
 ACCEPT     all  --  192.168.0.0/24         anywhere
 DROP       all  --  anywhere             anywhere             -m geoip ! --source-country US

this may work for some, but if i run

 ping france.fr

I get as a result

 PING france.fr (46.18.192.148) 56(84) bytes of data.
 64 bytes from ns1-sgg.produhost.net (46.18.192.148): icmp_seq=1 ttl=52 time=136 ms
 64 bytes from ns1-sgg.produhost.net (46.18.192.148): icmp_seq=2 ttl=52 time=135 ms
 64 bytes from ns1-sgg.produhost.net (46.18.192.148): icmp_seq=3 ttl=52 time=136 ms

this is more than likely due to the INPUT rule #1

 iptables  -L INPUT 1

 ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

I realize that I could just simply apply the same custom ruleset to the OUTPUT chain and block out the ping request to france.fr or anything external to the US, but how could I add the ruleset to base INPUT chain so

 iptables -L INPUT

shows this instead

 Chain INPUT (policy ACCEPT)
 target     prot opt source               destination
 ACCEPT     all  --  192.168.0.0/24         anywhere
 DROP       all  --  anywhere             anywhere             -m geoip ! --source-country US
 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
 DROP       all  --  anywhere             anywhere             ctstate INVALID
 REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

I ask this because I feel like what I want instead of what is the result of the firewall-cmd is a bit more secure, am I wrong? I would like to keep the firewall being controlled by firewalld instead of dropping firewalld and reverting back to iptables for better future integration and possible deprecation issues, so is this even possible with firewalld, or am I going to be forced to run a custom script at boot up that includes

 iptables -I INPUT 1 -s 192.168.0.0/24 -j ACCEPT
 iptables -I INPUT 2 -m geoip ! --src-cc US -j DROP

and if that is the option where do I place this script?

Chris
  • 141

1 Answers1

0

at the moment the best way to effectuate this is to just do exactly what i had proposed which is to not only add the incoming drop rule but also add the outgoing drop so the commands would be

 firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -s 192.168.0.0/24 -j ACCEPT
 firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -m geoip ! --src-cc US -j DROP
 firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -d 192.168.0.0/24 -j ACCEPT
 firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -m geoip ! --dst-cc US -j DROP

currently there is no other way to add the rule directly to the INPUT or OUTPUT chain through firewall-cmd

I only set out to do this like this because i felt that if some sort of worm or malware got inside my server its outgoing connection to whatever country would be considered RELATED, ASSURED, or ESTABLISHED, but this method by just adding to the delegate_output chain seems to be working to block all outgoing connections so I am satisfied

I am more than sure someone could better this answer by explaining how i could put the command in some init script or systemd script, but i think i would be more happy if fedora would just figure out an option that would add it directly to the primary chain, but maybe this is bad practice

Chris
  • 141