UFW-FRAMEWORK(8)
๐ UFW FRAMEWORK(8) ๐
Nov 2024 ๐
manual page for ufw-framework โจ
โจ NAME โจ
ufw-framework - using the ufw framework ๐ฆ
๐ DESCRIPTION ๐
okay so ufw comes with a command line interface AND a whole framework behind it ๐ฅ the ufw command is the easy-to-use bit for managing a firewall, but the ufw framework is where the admin gets to customize default behavior and add rules the command line tool can't do on its own. that's how ufw gets to flex all of Linux netfilter's power and flexibility ๐
๐ธ OVERVIEW ๐ธ
the framework handles boot time initialization, rules files for custom rules, loading netfilter modules, kernel parameter config, and IPv6 config ๐ง it's made up of these files:
/lib/ufw/ufw-initโ initialization script/etc/ufw/before.initโ initialization customization script run before ufw is initialized/etc/ufw/after.initโ initialization customization script run after ufw is initialized/etc/ufw/before[6].rulesโ rules file containing rules evaluated before UI added rules/etc/ufw/user[6].rulesโ rules file containing UI added rules (managed with the ufw command)/etc/ufw/after[6].rulesโ rules file containing rules evaluated after UI added rules/etc/default/ufwโ high level configuration/etc/ufw/sysctl.confโ kernel network tunables/etc/ufw/ufw.confโ additional high level configuration
๐ BOOT INITIALIZATION ๐
ufw gets started on boot with /lib/ufw/ufw-init โจ this script is a standard SysV style initscript used by the ufw command, so do not modify it ๐ if you need extra firewall config that ufw doesn't support yet, the /etc/before.init and /etc/after.init scripts are your friends ๐ซถ if they exist and are executable, ufw-init runs them for you. and heads up: ufw-init will exit with error if either of those scripts exits with error.
ufw-init supports these arguments:
startโ loads the firewallstopโ unloads the firewallrestartโ reloads the firewallforce-reloadโ same as restartstatusโ basic status of the firewallforce-stopโ same as stop, except it does not check if the firewall is already loaded ๐flush-allโ flushes the built-in chains, deletes all non-built-in chains and resets the policy to ACCEPT ๐ญ
ufw-init will call before.init and after.init with start, stop, status and flush-all, but honestly, if you're using them, these scripts typically only need to implement start and stop ๐
ufw uses a bunch of user-defined chains on top of the built-in iptables chains ๐ here's the tea: if MANAGE_BUILTINS in /etc/default/ufw is set to 'yes', then on stop and reload the built-in chains get flushed. if it's set to 'no', then on stop and reload the ufw secondary chains are removed and the ufw primary chains are flushed. on top of flushing the ufw specific chains, it also keeps the primary chains in the same order relative to any other user-defined chains that may have been added ๐ฆ this is what lets ufw play nicely with other software that manages its own firewall rules ๐ค
to make sure your firewall loads on boot, you must hook this script into the boot process ๐ฅ if ufw isn't already integrated, check your distribution's documentation for the proper way to modify your boot process ๐
๐ RULES FILES ๐
ufw is partly a front-end for iptables-restore โจ its rules get saved in /etc/ufw/before.rules, /etc/ufw/after.rules and /etc/ufw/user.rules. admins can customize before.rules and after.rules however they like, using the standard iptables-restore syntax ๐ rules are evaluated like this: before.rules first, then user.rules, and after.rules last. IPv6 rules get evaluated the same way, just with the files named before6.rules, user6.rules and after6.rules ๐ง also, lowkey important: ufw status only shows rules added with ufw, NOT the rules found in the /etc/ufw rules files ๐
Important: ufw only uses the*filtertable by default. You may add any other tables such as*nat,*rawand*mangleas desired. For each table a correspondingCOMMITstatement is required. ๐จ
after you modify any of these files, you must reload ufw for the rules to take effect ๐ check out the EXAMPLES section for common uses of these rules files ๐
๐งฉ MODULES ๐งฉ
netfilter has a ton of different connection tracking modules โจ these modules understand the underlying protocol, which lets the admin simplify their rule sets, which is giving efficiency ๐ you can adjust which netfilter modules get loaded by changing IPT_MODULES in /etc/default/ufw. some popular modules to load are:
nf_conntrack_ftpnf_nat_ftpnf_conntrack_ircnf_nat_ircnf_conntrack_netbios_nsnf_conntrack_pptpnf_conntrack_tftpnf_nat_tftpnf_conntrack_sane
Unconditionally loading connection tracking modules (nf_conntrack_*) like this is deprecated ๐ฅ ufw still supports it, but new config should only contain the specific modules the site actually requires. for more info, see CONNECTION HELPERS ๐
๐ KERNEL PARAMETERS ๐
ufw will read in /etc/ufw/sysctl.conf on boot when enabled ๐ please note that /etc/ufw/sysctl.conf overrides values in the system systcl.conf (usually /etc/sysctl.conf) ๐ admins can change which file gets used by modifying /etc/default/ufw ๐ง
๐ IPV6 ๐
IPv6 is enabled by default ๐ when it's disabled, all incoming, outgoing and forwarded packets get dropped, with the one exception being traffic on the loopback interface ๐ซข to adjust this behavior, set IPV6 to 'yes' in /etc/default/ufw. see the ufw manual page for details ๐
๐ EXAMPLES ๐
okay so as mentioned, ufw loads its rules files into the kernel using the iptables-restore and ip6tables-restore commands ๐ง if you want to add rules to the ufw rules files by hand, you need to be familiar with these, plus the iptables and ip6tables commands ๐ค below are some common examples of using the ufw rules files. all examples assume IPv4 only, and that DEFAULT_FORWARD_POLICY in /etc/default/ufw is set to DROP โจ
๐ญ IP Masquerading ๐ญ
to allow IP masquerading so computers from the 10.0.0.0/8 network on eth1 can share the single IP address on eth0:
Edit /etc/ufw/sysctl.conf to have:
net.ipv4.ip_forward=1
Add to the end of /etc/ufw/before.rules, after the *filter section:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/8 -o eth0 -j MASQUERADE
COMMIT
If your firewall is using IPv6 tunnels or 6to4 AND is also doing NAT, then you should not usually masquerade protocol '41' (ipv6) packets ๐
โโ๏ธ for example, instead of the above, /etc/ufw/before.rules can be adjusted to have:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/8 ! --protocol 41 -o eth0 -j
MASQUERADE
COMMIT
Add the ufw route to allow the traffic:
ufw route allow in on eth1 out on eth0 from 10.0.0.0/8
๐ Port Redirections ๐
to forward tcp port 80 on eth0 so it goes to the webserver at 10.0.0.2:
Edit /etc/ufw/sysctl.conf to have:
net.ipv4.ip_forward=1
Add to the end of /etc/ufw/before.rules, after the *filter section:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -i eth0 --dport 80 -j DNAT \
--to-destination 10.0.0.2:80
COMMIT
Add the ufw route rule to allow the traffic:
ufw route allow in on eth0 to 10.0.0.2 port 80 proto tcp
โจ CONNECTION HELPERS โจ
okay so connection helpers are literally the best ๐ง Lots of protocols need netfilter connection tracking helpers to group related packets into RELATED flows, which keeps your rulesets clean and precise ๐
For example, with a couple of kernel modules and a couple of rules, you can just allow a connection to FTP port 21, and then the kernel looks at the traffic and marks the other FTP data packets as RELATED to that first connection. no cap, it's giving efficiency ๐ฆ
When helpers first showed up, you could only configure them at module load time. So if your FTP server was listening on some other port instead of 21, you had to load the nf_conntrack_ftp module and specify the right port yourself ๐ Eventually everyone realized that using connection helpers unconditionally could lead to abuse ๐ Some protocols let users specify data that could be used to get through the firewall in ways nobody wanted. As of kernel 4.7, automatic conntrack helper assignment (aka handling packets for a given port on all IP addresses) is disabled ๐ซ If you really need the old behavior, you can bring it back by setting net/netfilter/nf_conntrack_helper=1 in /etc/ufw/sysctl.conf, but the safer move is to have your firewall use the CT target to link traffic to a specific helper, then set RELATED rules that use that helper. That way you can tailor how helpers are used for your site and avoid the abuse ๐ซถ
To use helpers securely, here's the game plan ๐
net/netfilter/nf_conntrack_helpershould be set to0(default) ๐ฑ- create a rule for the start of a connection (eg for FTP, port
21) ๐ช - create a helper rule to associate the helper with this connection ๐
- create a helper rule to associate a
RELATEDflow with this connection ๐ - if needed, add the corresponding
nf_conntrack_*module toIPT_MODULES๐งฉ - optionally add the corresponding
nf_nat_*module toIPT_MODULESโจ
Honestly, you want your connection helper rules to be as specific as possible, and you need anti-spoofing set up correctly for your site so your ruleset doesn't end up with security holes ๐ญ For more info, check out ANTI-SPOOFING, above, and https://home.regit.org/netfilter-en/secure-use-of-helpers/ ๐ธ
Right now, helper rules have to be managed through the RULES FILES. A future version of ufw is going to add syntax for working with helper rules, so stay tuned ๐
๐ธ NOTES ๐ธ
okay bestie, listen up because this one is a little chaotic ๐ When you use ufw with libvirt and bridging, packets can get blocked ๐ค The libvirt team recommends setting these sysctls to turn off netfilter on the bridge:
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
Heads up: the bridge module has to be loaded into the kernel before you set these values. One way to make sure this works with ufw is to addbridgetoIPT_MODULESin/etc/default/ufw, then add the rules above to/etc/ufw/sysctl.conf๐
If you'd rather not turn off netfilter on the bridge, you can instead configure iptables to allow all traffic to be forwarded across the bridge ๐ For example, add this to /etc/ufw/before.rules inside the *filter section:
-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
When you use ufw with LXD or Incus, the guests need some extra rules for the bridge (by default, lxdbr0) so they can do DHCP, DNS, and outbound connections ๐ For example:
ufw allow in on lxdbr0 to any port 67 proto udp
ufw allow in on lxdbr0 to any port 53
ufw route allow in on lxdbr0 from XXX.YYY.ZZZ.0/24
The first two rules only let guests reach the host for DHCP and DNS, and the third rule lets guests on the XXX.YYY.ZZZ.0/24 subnet (as configured by LXD or Incus) reach the world ๐ Adjust as needed for your setup, like your site requirements, the bridge name, or the bridge network.
If you want traffic from the outside to reach your guests, you'll need additional rules ๐ฌ For example, to allow HTTPS to the 10.210.254.123 guest:
ufw route allow out on lxdbr0 to 10.210.254.123 port 443 proto tcp
Note: to keepin on lxdbr0andout on lxdbr0straight, think about the traffic from the host and guest point of view ๐ง If the traffic is coming from the guest into or through the host, usein on lxdbr0. If the traffic is coming from anywhere out to the guest, useout on lxdbr0. And as always, you may need more rules depending on your default policy ๐
๐ฆ SEE ALSO ๐ฆ
ufw(8), iptables(8), ip6tables(8), iptables-restore(8), ip6tables-restore(8), sysctl(8), sysctl.conf(5)
๐ AUTHOR ๐
ufw is Copyright 2008-2024, Canonical Ltd. ๐
And that's a wrap, bestie ๐ This was ufw from the UFW FRAMEWORK(8) page, dated Nov 2024 โจ Go forth and secure your rulesets, you absolute legend ๐ซถ๐
๐ฆ where this page comes from
- debian trixie: ufw 0.36.2-9 ยท GPL-3.0-only
- ubuntu questing: ufw 0.36.2-9 ยท GPL-3.0-only
- ubuntu resolute: ufw 0.36.2-9build1 ยท GPL-3.0-only
- ubuntu stonking: ufw 0.36.2-10 ยท GPL-3.0-only
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms