Firewalld seems to be a way to "magic away" some of the manual configuration iptables rules of old.
Here are the main points that I have found:
This is for the "zones" and magic pre-configuration https://fedoraproject.org/wiki/Firewalld?rd=FirewallD
This is for the more granular rules https://fedoraproject.org/wiki/Features/FirewalldRichLanguage
So, it would seem there are a set of "zones" that per-configure the traffic assumptions...
I have repeated them here, so I have a snapshot should that link go away:
drop: Any incoming network packets are dropped, there is no reply. Only outgoing network connections are possible. block: Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated within this system are possible. public: For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. external: For use on external networks with masquerading enabled especially for routers. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. dmz: For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted. work: For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. home: For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. internal: For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted. trusted: All network connections are accepted.
So, rather than setting some defaults as you would with iptables, you just set the default zone.
The choice of the zone depends on how locked down outbound and inbound traffic needs to be.
It looks like it may interact with network-manager (should you be using that), to set the default zone.
Zones can be filled with services, ports, and protocols using the easy rules from that first link.
firewall-cmd sets them up. The services are not from /etc/services, but rather xml files in its config.
You need to define your own should they not exist for the many services that are not in the defaults.
For the harder work, you need to use the "Rich Language" bit. Looks pretty much like iptables or ip6tables.
If you don't use the --permanent flag to firewall-cmd, your added rule won't survive a reboot / reload, but they be applied immediately. So, if you want them to stick, do use the --permanent flag, but with a follow up: firewall-cmd --reload
So, for example, to add rules to the default zone (public) -
- first make sure it is installed: apt install firewalld - make sure it is running (and running at boot): systemctl enable firewalld systemctl start firewalld firewall-cmd --state - now check for what is what: firewall-cmd --list-all-zones -Now to restrict things in the default (public) zone: firewall-cmd --add-rich-rule='rule family="ipv4" service name="ssh" source address="your.ip.add.ress" accept' --permanent - do the same for ipv6, and remove the defaults (have a back way in!): firewall-cmd --zone=public --remove-service=ssh --permanent firewall-cmd --reload
So you can see how to restrict some of the defaults by adding a "rich-rule", and removing the default allow access.
Don't forget to check the other zones and rules that are in by default, so you can tweak the zone that most closely
matches the level of blocking for your use case.
You might not find a zone that matches what you want to do, so you might need to make one, and tweak it.
To put things back:
# put back the blanket allow from the default public zone, and reload the saved rule: firewall-cmd --zone=public --add-service=ssh --permanent firewall-cmd --reload # note, the more restrictive rule is still in there, but the allow all ssh overrides it, it would seem. Not sure about order. # To remove it: firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" service name="ssh" source address="your.ip.add.ress" accept' --permanent # and of course, reload to make the saved rules the default you are currently running: firewall-cmd --reload # and recheck: firewall-cmd --list-all-zones
Port example:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="your.ip.add.ress/32" port port=1022 protocol=tcp accept' --permanent
Update:
Funky interaction with fail2ban
I have been having issues with fail2ban and firewalld on reboots. Not sure why yet, but I just purge the package on restricted hosts.
Further notes for Ubuntu:
ufw status | ufw disable | ufw enable
Another update:
Rich rule to block single ip:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="off.en.der.ip" reject'
Another update:
Assuming you have the banned (drop) zone block, here is a one liner for blocking a host (until the next firewall reload):
firewall-cmd --zone=drop --add-source=bad.ip.add.ress
That is all.
Guess that is not all.
Here are more tips:
To enable full stop (disable all traffic if emergency):
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-controlling_traffic
Of course if that goes away: - to turn it on:
firewall-cmd --panic-on
And to turn it off:
firewall-cmd --panic-off
To check status: (in case you work with others :-)
firewall-cmd --query-panic
Alternative to panic is (locks down local apps net access as well!):
-check status firewall-cmd --query-lockdown -do it firewall-cmd --lockdown-on
To list services available to easily enable (not the "rich rule" as above):
firewall-cmd --get-services and enable with: firewall-cmd --add-service=<service-name> - and after you find it works as expected, save it: firewall-cmd --runtime-to-permanent
You can find this and other helpful stuff in : /etc/firewalld
Just not sure how it all works there just yet, as it is not static files when the daemon is running :-)
More for me instead of your edification...
To set up masquerade rules (just like ipchains - how quaint!)
Check if active: firewall-cmd --zone=external --query-masquerade Enable it - for this boot: firewall-cmd --zone=external --add-masquerade ( add --permanant to save it) - to remove it: firewall-cmd --zone=external --remove-masquerade
So, if that doc has not gone away, here is more fun - ipsets: line https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-setting_and_controlling_ip_sets_using_firewalld
- check ipsets supported: firewall-cmd --get-ipset-types (for non RedHat scum): firewall-cmd --permanent --get-ipsets - To add a new ipset type (note: ipv4 only - ipv6 is still rich rule only) -- update add "--option=family=inet6" for the not available ipv6: firewall-cmd --permanent --new-ipset=test --type=hash:net - Check that it worked with: firewall-cmd --permanent --get-ipset (or check the xml crap in etc).... .... blah blah blah... - to shove the ips you want to bring up defenses against: firewall-cmd --permanent --ipset=test --add-entry=192.168.0.1 - or more broadly: cat > iplist.txt <<EOL 192.168.0.2 192.168.0.3 192.168.1.0/24 192.168.2.254 EOL - or from a file: firewall-cmd --permanent --ipset=test --add-entries-from-file=iplist.txt - check it with: firewall-cmd --permanent --ipset=test --get-entries - to remove them: firewall-cmd --permanent --ipset=test --remove-entries-from-file=iplist.txt - and the big finale is: firewall-cmd --permanent --zone=drop --add-source=ipset:test - (of course to drop any packets from the above mentioned set test)...
To block before firewalld starts:
vi /etc/systemd/system/ipset_name.service [Unit] Description=ipset_name Before=firewalld.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/ipset_name.sh start ExecStop=/usr/local/bin/ipset_name.sh stop [Install] WantedBy=basic.target
vi /etc/firewalld/direct.xml <?xml version="1.0" encoding="utf-8"?> <direct> <rule ipv="ipv4" table="filter" chain="INPUT" priority="0">-m set --match-set <replaceable>ipset_name</replaceable> src -j DROP</rule> </direct>
firewall-cmd --reload
(Bluehat does not recommend you take this route however)...
- For more fun check out the footgun --direct can do for your iptables makes it work, firewall-cmd is not there yet pleasure...
Enable logging:
firewall-cmd --get-log-denied firewall-cmd --set-log-denied=all (all, unicast, broadcast, multicast, and off)