ufw

Comment 2 for bug 1571579

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

FYI, it is possible to use ipset with ufw, but it isn't integrated into the ufw command itself. This can be done via the /etc/ufw/before.init and /etc/ufw/after.init scripts (see 'man ufw-framework' for details).

One way to do this is make after.init executable (chmod 740 /etc/ufw/after.init) and update it to have something like:

savefile="/etc/ufw/custom/ipset.save"
if [ ! -f "$savefile" ]; then
    echo "Could not find '$savefile'" >&2
    return
fi

IPSET_EXE="/sbin/ipset"

case "$1" in
start)
    # Loading ipsets
    $IPSET_EXE restore < "$savefile"

    # Setting firewall rules
    iptables -I INPUT -m set --match-set blacklist-ip src -j DROP
    iptables -I INPUT -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK IN bl-ip] "
    iptables -I FORWARD -m set --match-set blacklist-ip src -j DROP
    iptables -I FORWARD -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK FW bl-ip] "
    iptables -I OUTPUT -m set --match-set blacklist-ip src -j DROP
    iptables -I OUTPUT -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK IN bl-ip] "

    ... continue like above for each set
    ;;
stop)
    # Unset firewall rules
    iptables -D INPUT -m set --match-set blacklist-ip src -j DROP || true
    iptables -D INPUT -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK IN bl-ip] " || true
    iptables -D FORWARD -m set --match-set blacklist-ip src -j DROP || true
    iptables -D FORWARD -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK FW bl-ip] " || true
    iptables -D OUTPUT -m set --match-set blacklist-ip src -j DROP || true
    iptables -D OUTPUT -m set --match-set blacklist-ip src -j LOG --log-prefix "[UFW BLOCK IN bl-ip] " || true

    ... continue like above for each set

    # Destroy ipset lists
    $IPSET_EXE destroy blacklist-ip || true

    ... continue like above for each set
    ;;
status)
    echo "= after.init ="
    for s in blacklist-ip ... other sets ; do
        echo "== $s =="
        $IPSET_EXE list $s | grep -v '^[1-9]' | grep -v '^Members' || true
        echo ""
    done
    ;;
flush-all)
    "$0" stop
    ;;
save)
    # Custom command
    $IPSET_EXE save > "$savefile"
    ;;
*)
    echo "'$1' not supported"
    echo "Usage: after.init {start|stop|flush-all|status}"
    ;;
esac

after.init is executed last, so after the firewall is setup, the ipset saved rules are loaded into the kernel, then the -I inserted rules above are put before anything else in the primary chains. Initial setup requires:

$ sudo mkdir /etc/ufw/custom
$ sudo ipset create blacklist-ip hash:ip family inet hashsize 8192 maxelem 65536 # or however you want it set. Do this for each set you want
$ sudo /etc/ufw/after.init save

Adding rules is simply a matter of:

$ sudo ipset add blacklist-ip <ip1>
$ sudo ipset add blacklist-ip <ip2>
$ sudo /etc/ufw/after.init save # if want newly added rules to survive a reboot