Ubuntu: How to add an iptables rule that UFW can't create

Solution 1:

According to this Ubuntu wiki page (scroll down to "Advanced Functionality"), you can achieve what you want by putting your own iptables rules into the following files:

  • /etc/ufw/before.rules
  • /etc/ufw/after.rules

The before file is evaluated before any ufw rules are applied; the after file is evaluated after. (There are also corresponding before6 and after6 rules files, for your ip6tables rules.)

These rules files are expected to be in iptables-restore-compatible syntax, presumably because ufw simply loads them using iptables-restore. Finally, note that you need to stop and restart ufw after you make any changes to the rules files.

Solution 2:

UFW will purge any MANUALLY added rule in /etc/ufw/user.rules which is NOT prefaced with a comment:

### tuple ### allow tcp 80 0.0.0.0/0 any 0.0.0.0/0 out
-A ufw-user-output -p tcp --dport 80 -j ACCEPT

When UFW sanity checks the rules on startup, it expects an accompanying comment. If it's NOT present, even if the syntax of the rule is correct, UFW will still purge it.

And don't just use any arbitrary comment: it MUST be the comment that UFW would insert when creating a user rule via the cli, ie:

sudo ufw allow http/tcp

So if you want to pre-seed a series of rules in a ruleset in a simple file, you'd still need to create the rules via UFW's CLI interface to learn the syntax of the comments it expects for the rule to pass validation and persist.

Try the foregoing with and WITHOUT the comment and reload the specimen HTTP rule above; you'll remark only with the comment does the manually added rule survive a restart (ufw enable) of UFW.

This is really counter-intuitive behaviour and not documented at all.