ufw

Support for ipset

Bug #1571579 reported by Jean Revertera
36
This bug affects 6 people
Affects Status Importance Assigned to Milestone
ufw
Wishlist
Unassigned

Bug Description

Firewalld 0.4 will have built-in support for ipset: http://www.firewalld.org/2015/12/ipset-support/

It would be nice to have something similar in ufw.

This may also resolve #801833

description: updated
Revision history for this message
txemi (txemitron) wrote :

I would love this too, I would like use symbolic names and lists on rules and ipset integration in ufw could be easy to implement. Now rules with ipset names fail as they are not recognized as IP addresses.

Not having this forces me to write similar rules for groups of addresses or networks making rules difficult to understand and maintain.

More references to this:

http://askubuntu.com/questions/755008/using-ufw-with-ipsets/888534

Changed in ufw:
importance: Undecided → Wishlist
status: New → Triaged
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

Revision history for this message
txemi (txemitron) wrote :

Yes, I was thinking adding ipset this way before ufw rules are loaded and then use ipset aliases in ufw rules. This fails:

root:~# ipset -N myset iphash
root:~# ipset -A myset 1.1.1.1
root:~# ipset -A myset 2.2.2.2
root:~# ufw allow from myset
ERROR: Dirección de orígen errónea
root:~#

As you say I was thinking adding ipset commands in /etc/ufw/before.init.

I suppose it would be easy modifying ufw to allow rules using ipset previously added aliases.

Revision history for this message
Ilya Ka (ilka2018) wrote :

I use ``sshguard`` to protect ssh server.
One of its usages is based on ipset: it simply fills ipset with bad ip addresses,
and you block connections when source is in this address,
like
``m set --match-set sshguard4 src -j DROP``

With ufw this can be added to ``rules.before``, but ufw starts before ``sshguard``, so it doesn't see this set, and simply fails leaving my machine with an empty INPUT chain with DROP policy :)

People even wrote systemd units that run before ufw just to create ipset

https://selivan.github.io/2018/07/27/ipset-save-with-ufw-and-iptables-persistent-and.html

While I can use chains instead of ipset (unlike ipset, a chain could be created with ufw) I believe
ipset is a better solution of the huge list of IP addresses.

``netfilter-persistent`` tool loads ipset before iptables, so there is no such problem there.

I think ``ufw`` must have the ability to create an empty ipset to be compatible with sshguard.

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

@Ilya, I suggest looking at comment #2 since with that mechanism (adapting it for your needs), you can ensure that the ipset is setup in time.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers