7.7 KiB
update-firewall-source
Update a firewall rule that relies on dynamic DNS names
What
-
This script assumes exclusive ownership of the
firewalld
direct rules file/etc/firewalld/direct.xml
or whereever configured -
List of address can be empty, direct file will then be removed
-
After every execution script will trigger systemd firewalld service restart
-
No subnet, will simply not be validated
-
Include example systemd unit file and install instructions
-
firewall-cmd --check-config
-
default location for config file and default name for config file
-
we should deduplicate list
-
is intended to help with just docker-user
-
man page https://ipset.netfilter.org/iptables.man.html we do iptables
-
added in order
-
related, established? needed?
-
section names as comments?
Config structure
Package configuration happens via a config.ini
file that follows INI-style syntax. Copy examples/config.ini.example to config.ini
to get started:
[DEFAULT]
target = ACCEPT
addr =
ports = 80, 443
proto = tcp
state = NEW
do_ipv6 = false
firewalld_direct_file_abs = /etc/firewalld/direct.xml
restart_firewalld_after_change = true
[anyone-can-access-website]
# Unsetting 'proto' while having a 'ports' value results in an invalid section
# [these-guys-can-dns]
# addr = google.li, 142.251.36.195, lowendbox.com, 2606:4700:20::ac43:4775
# ports = 53
# proto =
# do_ipv6 = true
[maybe-a-webserver]
addr = 2606:4700:20::681a:804, lowendtalk.com
ports = 80, 443
do_ipv6 = true
[allow-anyone-to-access-mail-services]
ports = 143, 993, 110, 995, 25, 465, 587
[deny-all]
target = DROP
addr =
ports =
proto =
state =
do_ipv6 = true
Layout
A config file can have an optional [DEFAULT]
section and must have at least one [section]
other than [DEFAULT]
. Any [DEFAULT]
option that's undefined retains its default value. Feel free to delete the entire [DEFAULT]
section from your file. A setting changed in [DEFAULT]
section affects all sections. A setting changed only in a custom [section]
overwrites it for only the section.
Custom sections such as [maybe-a-webserver]
in above example file are treated as organizational helper constructs. You can but don't have to group IP address rules by sections. Technically nothing's stopping you from adding all IP allow list entries into a single section.
Example explanation
With config_check_after_change
Setting restart_firewalld_after_change
controls if you want the firewalld
systemd unit to be restarted
In above example file note that [anyone-can-access-website]
makes [maybe-a-webserver]
irrelevant, the latter one could easily be deleted. [anyone-can-access-website]
does not overwrite defaults, it's an empty section. With it firewalld
will create a rule that - following all default settings - allows access from any source address on TCP ports 80 and 443. In section [maybe-a-webserver]
we do the same and additionally limit source addresses. Rules are added in config.ini
order so the first rule permitting access to TCP ports 80 and 443 from anywhere makes the second one irrelevant.
We strongly recommend you do keep the very last example section:
[deny-all]
target = DROP
addr =
ports =
proto =
state =
do_ipv6 = true
If a packet has traversed rules this far without being accepted it will be dropped. Note that if any of your custom [sections]
use do_ipv6 = true
your final DROP
rule should do the same. Otherwise you'll just get DROP
rule in iptables
but not in ip6tables
.
Options
Globals
In [DEFAULT]
section the following settings are called globals. They're only valid in [DEFAULT]
context. Adding them to a custom [section]
(see Locals below) won't do anything, in a custom [section]
the following settings are ignored.
-
do_config_check
, optional, defaults totrue
: Do afirewall-cmd --check-config
once before changing/etc/firewalld/direct.xml
. Abort if this initial check fails, inform the user. Obviously something's very wrong before we've even touched firewall configs. Otherwise back up/etc/firewalld/direct.xml
, change it then do another check. Iffirewall-cmd --check-config
finds a syntax error restore the backed up known good/etc/firewalld/direct.xml
, delete the temporary backed up one and inform the user.If
restart_firewalld_after_change
is alsotrue
(default) restart thefirewalld
systemd service unit after the second config check. See steps a through f below atrestart_firewalld_after_change
for exact order. -
restart_firewalld_after_change
, optional, defaults totrue
: After putting a new/etc/firewalld/direct.xml
file in place restart thefirewalld
systemd service unit.- If
do_config_check
is alsotrue
(default) the exact order is:- Config check, bail on error and inform user
- Back up
/etc/firewalld/direct.xml
to temporary location - Write new
/etc/firewalld/direct.xml
content - Perform config check, bail on error and restore backed up
/etc/firewalld/direct.xml
- Delete backed up
/etc/firewalld/direct.xml
- Restart
firewalld
systemd service unit
- If
do_config_check
isfalse
:- Write new
/etc/firewalld/direct.xml
content - Restart
firewalld
systemd service unit
- Write new
- If
Locals
A custom [section]
has the following options. We're calling the locals all of which are optional.
-
target
, optional, defaults toACCEPT
: A string specifying the fate of a packet that matched this rule. By default matching packets are accepted. See "TARGETS" section in iptables man page. You'll most likely want to stick to eitherACCEPT
orDROP
. -
addr
, optional: A comma-separated list of any combination of IPv4 addresses, IPv6 addresses and domain names. Whenupdate-firewall-source.py
constructsfirewalld
rules these addresses are allowed to access the server. If left undefinedaddr
defaults to an empty list meaning rules apply to any arbitrary source address.Subnets are unsupported, both as subnet masks (
142.251.36.195/255.255.255.248
) and in CIDR notation (142.251.36.195/29
). Do not single- nor double-quote list entries. Do feel free to separate entries with comma-space instead of just a comma. -
ports
, optional, defaults to80, 443
: A comma-separated list of ports that should be accessible fromaddr
. If overwritten to an empty optionaddr
may access all ports. -
proto
, optional, defaults totcp
: A protocol that should be allowed foraddr
onports
. If undefined this defaults totcp
being allowed. Sincefirewalld
direct rules useiptables
syntax the list of possible protocol names is largely identical to what the iptables man page says about its--protocol
argument:The specified protocol can be one of
tcp
,udp
,udplite
,icmp
,icmpv6
,esp
,ah
,sctp
,mh
or the special keywordall
, or it can be a numeric value, representing one of these protocols or a different one. A protocol name from/etc/protocols
is also allowed. A!
argument before the protocol inverts the test. The number zero is equivalent toall
.Your mileage may vary depending on which specific OS flavor and version you're running.