From 35b821d7233ee58b51d46c09c1ad0d123f7b30a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Mon, 7 Sep 2015 23:52:17 +0200 Subject: testing/nftables: new aport Might need some additional testing. Especially the OpenRC service wasn't tested to extensively by myself. --- .../nftables/01-fix-object-order-via-nft--f.patch | 50 +++++++ testing/nftables/APKBUILD | 70 +++++++++ testing/nftables/nftables.confd | 19 +++ testing/nftables/nftables.initd | 166 +++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 testing/nftables/01-fix-object-order-via-nft--f.patch create mode 100644 testing/nftables/APKBUILD create mode 100644 testing/nftables/nftables.confd create mode 100644 testing/nftables/nftables.initd diff --git a/testing/nftables/01-fix-object-order-via-nft--f.patch b/testing/nftables/01-fix-object-order-via-nft--f.patch new file mode 100644 index 0000000000..6092032c5a --- /dev/null +++ b/testing/nftables/01-fix-object-order-via-nft--f.patch @@ -0,0 +1,50 @@ +From 454ffab9cc695b9618324a6a0a4dead6d5289f8d Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Sat, 14 Feb 2015 21:41:23 +0100 +Subject: rule: fix object order via nft -f + +The objects need to be loaded in the following order: + + #1 tables + #2 chains + #3 sets + #4 rules + +We have to make sure that chains are in place by when we add rules with +jumps/gotos. Similarly, we have to make sure that the sets are in place +by when rules reference them. + +Without this patch, you may hit ENOENT errors depending on your ruleset +configuration. + +Signed-off-by: Pablo Neira Ayuso + +diff --git a/src/rule.c b/src/rule.c +index feafe26..8d76fd0 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -658,14 +658,19 @@ static int do_add_table(struct netlink_ctx *ctx, const struct handle *h, + if (netlink_add_table(ctx, h, loc, table, excl) < 0) + return -1; + if (table != NULL) { ++ list_for_each_entry(chain, &table->chains, list) { ++ if (netlink_add_chain(ctx, &chain->handle, ++ &chain->location, chain, ++ excl) < 0) ++ return -1; ++ } + list_for_each_entry(set, &table->sets, list) { + handle_merge(&set->handle, &table->handle); + if (do_add_set(ctx, &set->handle, set) < 0) + return -1; + } + list_for_each_entry(chain, &table->chains, list) { +- if (do_add_chain(ctx, &chain->handle, &chain->location, +- chain, excl) < 0) ++ if (netlink_add_rule_list(ctx, h, &chain->rules) < 0) + return -1; + } + } +-- +cgit v0.10.2 + diff --git a/testing/nftables/APKBUILD b/testing/nftables/APKBUILD new file mode 100644 index 0000000000..0679b5bac2 --- /dev/null +++ b/testing/nftables/APKBUILD @@ -0,0 +1,70 @@ +# Contributor: Sören Tempel +# Maintainer: Sören Tempel +pkgname=nftables +pkgver=0.4 +pkgrel=0 +pkgdesc="Netfilter tables userspace tools" +url="http://netfilter.org/projects/nftables/" +arch="all" +license="GPL2" +depends="" +depends_dev="libmnl-dev libnftnl-dev gmp-dev readline-dev ncurses-dev" +makedepends="$depends_dev bison flex" +install="" +subpackages="" # -doc would require docbook2x which isn't packaged yet +source="http://netfilter.org/projects/$pkgname/files/$pkgname-$pkgver.tar.bz2 + nftables.confd + nftables.initd + 01-fix-object-order-via-nft--f.patch" + +_builddir="$srcdir"/$pkgname-$pkgver +prepare() { + cd "$_builddir" + + update_config_sub || return 1 + sed -i '1i#include "config.h"' src/proto.c + + local i= + for i in $source; do + case $i in + *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; + esac + done +} + +build() { + cd "$_builddir" + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + --localstatedir=/var \ + || return 1 + make || return 1 +} + +package() { + cd "$_builddir" + make DESTDIR="$pkgdir" install || return 1 + + install -Dm755 "$srcdir"/$pkgname.initd \ + "$pkgdir"/etc/init.d/$pkgname || return 1 + install -Dm644 "$srcdir"/$pkgname.confd \ + "$pkgdir"/etc/conf.d/$pkgname || return 1 +} + +md5sums="09b686c489ff10db670ca60dbed7ff43 nftables-0.4.tar.bz2 +00f7dc61bcc1f7c2e48ebeaeb8b6b6b5 nftables.confd +f5703f86eb2129cdece8c230cc036bd7 nftables.initd +c0a18f43a5ce02cb61c9e0071725529a 01-fix-object-order-via-nft--f.patch" +sha256sums="f6ca69b75c68915f9f3a3972274ec68354dfbbcfc0b9fc55c813a0525c351d3c nftables-0.4.tar.bz2 +d5e3077345dfea02849a70aea220396322a10c3808f0303b988119adbc56fdbd nftables.confd +293d5a0ef687c69fffdce912a833cf5812272c0baae9f59d603ada8efa5828a6 nftables.initd +ab5068a30e4a0df72b589aec500a4a6a1c3a5ab50ee73fad034eee676eabe9bb 01-fix-object-order-via-nft--f.patch" +sha512sums="0932cf987da602285fbf7c7f61328b0d74d687889c2d4a5bd2bd7fe11e8b99433bc5ee53ebbddadf2c90e40acdcb28f6babf07e11feedff815c571c3b782dffc nftables-0.4.tar.bz2 +8370abcdc89fcd9da5dc7d1620be6afb4633b8bcd0a8a120b464cc1a7e1fab6f34956c293da3f6d3cbe1f7a2e03038fd0c94a614137ae5657d29ffdb5f3fa144 nftables.confd +ec43cc630b45ea2726044b30925e04f16fdb48ff2ee1871c112fde5b406f47c75b53ce05db4dfab8558156da96e9bf484ebab1f00f5cda20bbe8597c63b178fe nftables.initd +9b7b51c55681fc25bb53fef6bf38e125377a3b32bdf6e9c8c7056a72deb7f24b7b6e2dcccb3065645e69675848585c6051e8992d9179f1609fbe1d873cb3bddf 01-fix-object-order-via-nft--f.patch" diff --git a/testing/nftables/nftables.confd b/testing/nftables/nftables.confd new file mode 100644 index 0000000000..e83a4b9620 --- /dev/null +++ b/testing/nftables/nftables.confd @@ -0,0 +1,19 @@ +# /etc/conf.d/nftables + +# Location in which nftables initscript will save set rules on +# service shutdown +NFTABLES_SAVE="/var/lib/nftables/rules-save" + +# Options to pass to nft on save +SAVE_OPTIONS="-n" + +# Save state on stopping nftables +SAVE_ON_STOP="yes" + +# If you need to log nftables messages as soon as nftables starts, +# AND your logger does NOT depend on the network, then you may wish +# to uncomment the next line. +# If your logger depends on the network, and you uncomment this line +# you will create an unresolvable circular dependency during startup. +# After commenting or uncommenting this line, you must run 'rc-update -u'. +#rc_use="logger" diff --git a/testing/nftables/nftables.initd b/testing/nftables/nftables.initd new file mode 100644 index 0000000000..c726393056 --- /dev/null +++ b/testing/nftables/nftables.initd @@ -0,0 +1,166 @@ +#!/sbin/runscript +# Copyright 2014 Nicholas Vinson +# Copyright 1999-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +extra_commands="clear list panic save" +extra_started_commands="reload" + +depend() { + need localmount #434774 + before net +} + +checkkernel() { + if ! nft list tables >/dev/null 2>&1; then + eerror "Your kernel lacks nftables support, please load" + eerror "appropriate modules and try again." + return 1 + fi + return 0 +} + +checkconfig() { + if [ ! -f ${NFTABLES_SAVE} ]; then + eerror "Not starting nftables. First create some rules then run:" + eerror "rc-service nftables save" + return 1 + fi + return 0 +} + +getfamilies() { + local families + for l3f in ip arp ip6 bridge inet; do + if nft list tables ${l3f} > /dev/null 2>&1; then + families="${families}${l3f} " + fi + done + echo ${families} +} + +clearNFT() { + local l3f line table chain + + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + table=$(echo ${line} | sed "s/table[ \t]*//") + nft flush table ${l3f} ${table} + nft list table ${l3f} ${table} | while read l; do + chain=$(echo $l | grep -o 'chain [^[:space:]]\+' |\ + cut -d ' ' -f2) + if [ -n "${chain}" ]; then + nft flush chain ${l3f} ${table} ${chain} + nft delete chain ${l3f} ${table} ${chain} + fi + done + nft delete table ${l3f} ${table} + done + done +} + +addpanictable() { + local l3f=$1 + nft add table ${l3f} panic + nft add chain ${l3f} panic input \{ type filter hook input priority 0\; \} + nft add chain ${l3f} panic output \{ type filter hook output priority 0\; \} + nft add chain ${l3f} panic forward \{ type filter hook forward priority 0\; \} + nft add rule ${l3f} panic input drop + nft add rule ${l3f} panic output drop + nft add rule ${l3f} panic forward drop +} + +start_pre() { + checkkernel || return 1 + checkconfig || return 1 + return 0 +} + +start() { + ebegin "Loading nftables state and starting firewall" + clearNFT + nft -f ${NFTABLES_SAVE} + eend $? +} + +stop() { + if yesno ${SAVE_ON_STOP:-yes}; then + save || return 1 + fi + + ebegin "Stopping firewall" + clearNFT + eend $? +} + +reload() { + checkkernel || return 1 + # checkrules || return 1 + ebegin "Flushing firewall" + clearNFT + + start +} + +clear() { + clearNFT +} + +list() { + local l3f + + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + echo "$(nft list ${line})" + done + done +} + +save() { + ebegin "Saving nftables state" + checkpath -q -d "$(dirname "${NFTABLES_SAVE}")" + checkpath -q -m 0600 -f "${NFTABLES_SAVE}" + + local l3f line tmp_save="${NFTABLES_SAVE}.tmp" + + touch "${tmp_save}" + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + # The below substitution fixes an issue where nft -n output may not + # always be parsable by nft -f. For example, nft -n might print + # + # ip6 saddr ::1 ip6 daddr ::1 counter packets 0 bytes 0 accept + # + # but nft -f refuses to parse that string with error: + # + # In file included from internal:0:0-0: + # /var/lib/nftables/rules-save:1:1-2: Error: Could not process rule: + # Invalid argument + # table ip6 filter { + # ^^ + echo "$(nft ${SAVE_OPTIONS} list ${line} |\ + sed 's/\(::[0-9a-fA-F]\+\)\([^/]\)/\1\/128\2/g')" >> "${tmp_save}" + done + done + mv "${tmp_save}" "${NFTABLES_SAVE}" +} + +panic() { + checkkernel || return 1 + if service_started ${RC_SVCNAME}; then + rc-service ${RC_SVCNAME} stop + fi + + ebegin "Dropping all packets" + clearNFT + + local l3f + for l3f in $(getfamilies); do + case ${l3f} in + ip) addpanictable ${l3f} ;; + ip6) addpanictable ${l3f} ;; + esac + done +} -- cgit v1.2.3