Skip to main content

IPsets with UFW

This is an example that lets you use UFW (https://wiki.ubuntu.com/UncomplicatedFirewall) and IPsets to dynamically allowlist IPs for a common host-based firewall. 

This is achieved in only a few steps:

  1. Install the Knocknoc orchestration agent on the UFW host and enrol it into the Knocknoc server. Follow these steps.
  2. Edit the IPSet names, as you will likely want others (knoc_ssh/knoc_https are created by default). Do this by editing /opt/knocknoc-agent/etc/ipset.list and then restarting with systemctl restart create-ipsets
  3. Edit your UFW rules files to make use of the IPSets (/etc/ufw/after.rules).
  4. You're done!

1. Install the Knocknoc Agent

Install the Knocknoc Agent, which creates basic IPSets for you along with a startup script to initiate them on boot. These IPSets are editable as noted above. You can use the 'knoc_https' one to test access to port 443 on the orchestration-agent machine.

2. Integrating IPset with UFW

For integrating the ipset with UFW, you will typically use direct iptables rules. However, UFW does not directly support ipset in its regular configuration files, so you'll have to add these rules in the after.rules file for them to be applied with UFW.

Add Rules to UFW's after.rules

Edit the /etc/ufw/after.rules file to add your custom iptables rules referencing the ipset.


# At the end of /etc/ufw/after.rules

-A ufw-after-input -m set --match-set knoc_https src -p tcp --dport 443 -j ACCEPT
COMMIT

This rule will allow HTTPS connections on port 443 for IP addresses that are in the knoc_https IPset.

You can do the same to protect SSH, by using knoc_ssh and --dport 22.

Notes and Considerations

  • Testing: Always test firewall and startup scripts in a controlled environment before deploying them on a production server. "Cutting your hands off" is too easy if you are not careful! Try it first with a port other than SSH, eg: 443, and use Netcat in listen mode to verify access.
  • Order of Execution: The systemd script needs to execute before UFW starts, hence the Before=ufw.service directive. Ensure that the network is available before the script runs.

With this setup, your system will create and populate the ipset at startup, and UFW will utilize these sets to allow traffic as specified. This approach provides a balance between the simplicity of UFW and the power of ipset and iptables. Always ensure to test and verify your configuration in a safe environment before applying it to a live system.

Still having issues? Check the Troubleshooting IPSets page