Signed-off-by: Jörg Thalheim <joerg@xxxxxxxxxxxxx> --- .gitignore | 2 + configure.ac | 35 +++++++++++++ files/Makefile.am | 7 +++ files/nftables.service.in | 12 +++++ files/nftablesctl.in | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 185 insertions(+) create mode 100644 files/nftables.service.in create mode 100755 files/nftablesctl.in diff --git a/.gitignore b/.gitignore index 63ef1a2..e6f8065 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,8 @@ depcomp ylwrap src/parser_bison.c src/parser_bison.h +files/nftables.service +files/nftablesctl # Debian package build temporary files build-stamp diff --git a/configure.ac b/configure.ac index 57ea99d..19980d1 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,8 @@ AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax no-dist-gzip dist-bzip2 1.6]) +AC_PATH_TOOL(PKGCONFIG, pkg-config) + dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -112,6 +114,36 @@ AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T +AC_ARG_WITH(systemd, [ --with-systemd set directory for systemd service files], + [systemd_unitdir="$withval"; with_systemd=yes], + [systemd_unitdir=""; with_systemd=no]) +AC_SUBST(systemd_unitdir) + +AC_ARG_WITH(systemdutildir, [ --with-systemdutildir set directory for systemd helper scripts], + [systemd_utildir="$withval"], [systemd_utildir=""]) +AC_SUBST(systemd_utildir) + +AM_CONDITIONAL([INSTALL_SYSTEMD], [test "x$with_systemd" != xno]) +AM_COND_IF([INSTALL_SYSTEMD], + [AS_IF([test "x$PKGCONFIG" = "x"], + [AC_MSG_ERROR(Need pkg-config to enable systemd support.)], + + [AC_MSG_CHECKING(for systemd) + AS_IF([$PKGCONFIG --exists systemd], + [AC_MSG_RESULT(yes) + AS_IF([$PKGCONFIG --exists systemd], + [AS_IF([test "x$systemd_unit_dir" = "x"], + [ systemd_unitdir="`$PKGCONFIG --variable=systemdsystemunitdir systemd`"]) + AS_IF([test "x$systemd_util_dir" = "x"], + [ systemd_utildir="`$PKGCONFIG --variable=systemdutildir systemd`"]) + ]) + ] + [AC_MSG_RESULT(no)]) + ] + + )] +) + # Checks for library functions. AC_CHECK_FUNCS([memmove memset strchr strdup strerror strtoull]) @@ -124,10 +156,13 @@ AC_CONFIG_FILES([ \ doc/Makefile \ files/Makefile \ files/nftables/Makefile \ + files/nftables.service \ + files/nftablesctl \ ]) AC_OUTPUT echo " nft configuration: cli support: ${with_cli} + systemd support: ${with_systemd} enable debugging: ${with_debug}" diff --git a/files/Makefile.am b/files/Makefile.am index a8394c0..4da6432 100644 --- a/files/Makefile.am +++ b/files/Makefile.am @@ -1 +1,8 @@ SUBDIRS = nftables + +if INSTALL_SYSTEMD +systemd_unit_DATA = nftables.service + +systemd_scriptsdir = ${systemd_utildir}/scripts +systemd_scripts_SCRIPTS = nftablesctl +endif diff --git a/files/nftables.service.in b/files/nftables.service.in new file mode 100644 index 0000000..3c8c921 --- /dev/null +++ b/files/nftables.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=nftables +Documentation=man:nftables(8) + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@systemd_utildir@/scripts/nftablesctl start +ExecStop=@systemd_utildir@/scripts/nftablesctl stop + +[Install] +WantedBy=multi-user.target diff --git a/files/nftablesctl.in b/files/nftablesctl.in new file mode 100755 index 0000000..080f980 --- /dev/null +++ b/files/nftablesctl.in @@ -0,0 +1,129 @@ +#!/bin/sh + +set -e + +usage() { + name=$(basename "$0") + echo "Usage: $name start|stop|restart|list" + echo + echo " $name start load the rules" + echo " $name stop flush the rules" + echo " $name restart reload the rules" + echo " $name list list the loaded rules" + echo + echo "Using --confirm in the following manner will prompt you to check if" + echo "your network connection is working fine:" + echo + echo " $name start --confirm" + echo " $name restart --confirm" +} + +if [ "$(id -u)" -ne 0 ] +then + echo "Warning: Only root can run this script" >&2 + echo + usage + exit 1 +fi + +if [ ! -d /etc/nftables ] +then + echo "Rules directory /etc/nftables does not exist" >&2 + exit 1 +fi + +ctrl_c() { + echo + echo "nftables rules successfully applied" + exit 0 +} + +nft_clear_table() { + @sbindir@nft flush table "$1" "$2" + @sbindir@nft list table "$1" "$2" \ + | awk '/^[ \t]+chain/{ print $2 }' \ + | xargs -r -L 1 @sbindir@nft delete chain "$1" "$2" + @sbindir@nft list sets "$1" "$2" \ + | awk '/^[ \t]+set/{ print $2 }' \ + | xargs -r -L 1 @sbindir@nft delete set "$1" "$2" +} + +nft_delete_table() { + nft_clear_table "$1" "$2" + if @sbindir@nft list table "$1" "$2" > /dev/null + then + @sbindir@nft delete table "$1" "$2" + fi +} + +nft_clear_protocol() { + for T in $(@sbindir@nft list tables "$1" | cut -d ' ' -f 2) + do + nft_delete_table "$1" "$T" + done +} + +nft_list_protocol() { + for T in $(@sbindir@nft list tables "$1" | cut -d ' ' -f 2) + do + @sbindir@nft list table "$1" "$T" + done +} + +nftables_start() { + find /etc/nftables -maxdepth 1 -type f -name '*.rules' -print0 | \ + sort -z | xargs --null --no-run-if-empty --max-args=1 @sbindir@nft -f + + if [ -t 0 ] && [ "$1" = "--confirm" ] + then + echo "Please confirm that your network connection is working and press Ctrl+C on success" + trap ctrl_c INT + + sleep 20 + + echo "No response, flushing rules" + nftables_stop + fi +} + +nftables_list() { + for P in ip inet ip6 arp bridge + do + nft_list_protocol "$P" + done +} + +nftables_stop() { + for P in ip inet ip6 arp bridge + do + nft_clear_protocol "$P" + done +} + +nftables_restart() { + nftables_stop + nftables_start "$1" +} + +case "$1" in + start) + nftables_start "$2" + ;; + + stop) + nftables_stop + ;; + + restart) + nftables_restart "$2" + ;; + + list) + nftables_list + ;; + + *) + usage
Attachment:
pgpsIN6ogKYxq.pgp
Description: OpenPGP digital signature