Skip to contentSkip to conversation

add systemd service file

PATCH In review Jörg Thalheim 3 participants 12 messages Dec 17, 2014 – Dec 18, 2014 netfilter

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 add systemd service file

---
 .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
.gitignore +2 -0
index 63ef1a2..e6f8065 100644
@@ -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
configure.ac +35 -0
index 57ea99d..19980d1 100644
@@ -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}"
files/Makefile.am +7 -0
index a8394c0..4da6432 100644
@@ -1 +1,8 @@
 SUBDIRS = nftables
+
+if INSTALL_SYSTEMD
+systemd_unit_DATA = nftables.service
+
+systemd_scriptsdir = ${systemd_utildir}/scripts
+systemd_scripts_SCRIPTS = nftablesctl
+endif
files/nftables.service.in new file +12 -0
new file mode 100644
index 0000000..3c8c921
@@ -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
files/nftablesctl.in new file +126 -0

126 lines not on this page · raw message

#1 lore raw
Quoted 11 lines · Jörg Thalheim
---
 .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

Thanks for your work :-)

IMHO, this belongs to distributors, don't you?

Anyway, some inlined comments.

files/nftablesctl.in line 76

Quoted 4 lines
files/nftablesctl.in new file +4 -0
+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
+

You are making lot of assumptions, for example the '.rules' suffix.

files/nftablesctl.in line 89

Quoted 13 lines
files/nftablesctl.in new file +13 -0
+       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() {

Now (see latest v0.4 release) this is simply `nft list ruleset'.

files/nftablesctl.in line 96

Quoted 7 lines
files/nftablesctl.in new file +7 -0
+       for P in ip inet ip6 arp bridge
+       do
+               nft_list_protocol "$P"
+       done
+}
+
+nftables_stop() {

Now this is simply `nft flush ruleset'.

files/nftablesctl.in line 105

Quoted 9 lines
files/nftablesctl.in new file +9 -0
+       for P in ip inet ip6 arp bridge
+       do
+               nft_clear_protocol "$P"
+       done
+}
+
+nftables_restart() {
+       nftables_stop
+       nftables_start "$1"

Here, I think the time between the stop and start, there is not ruleset in the kernel.
I guess we can do it better, flushing the old ruleset and loading the new one in a single,atomic step.

Signature · 5 lines
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw
Quoted 13 lines · Arturo Borrero Gonzalez
Quoted 10 lines · Jörg Thalheim

---

.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

Quoted 3 lines

Thanks for your work :-)

IMHO, this belongs to distributors, don't you?

this was in the old sysvinit world. Thesedays it is common for upstream projects to come along with service files, as they are more portable then shell scripts.

Quoted 27 lines

Anyway, some inlined comments.

files/nftablesctl.in line 76

Quoted 4 lines
files/nftablesctl.in new file +4 -0
+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
+

You are making lot of assumptions, for example the '.rules' suffix.

Quoted 4 lines
files/nftablesctl.in new file +3 -0
+       if [ -t 0 ] && [ "$1" = "--confirm" ]
+       then
+               echo "Please confirm that your network connection is working and press Ctrl+C on

success"

files/nftablesctl.in line 89

Quoted 10 lines
files/nftablesctl.in new file +10 -0
+               trap ctrl_c INT
+
+               sleep 20
+
+               echo "No response, flushing rules"
+               nftables_stop
+       fi
+}
+
+nftables_list() {

Now (see latest v0.4 release) this is simply `nft list ruleset'.

Quoted 9 lines

files/nftablesctl.in line 96

Quoted 7 lines
files/nftablesctl.in new file +7 -0
+       for P in ip inet ip6 arp bridge
+       do
+               nft_list_protocol "$P"
+       done
+}
+
+nftables_stop() {

Now this is simply `nft flush ruleset'.

Ok. I did not have a look at latest release, when the script was written a year before, this was not possible.

Quoted 15 lines

files/nftablesctl.in line 105

Quoted 10 lines
files/nftablesctl.in new file +9 -0
+       for P in ip inet ip6 arp bridge
+       do
+               nft_clear_protocol "$P"
+       done
+}
+
+nftables_restart() {
+       nftables_stop
+       nftables_start "$1"

Here, I think the time between the stop and start, there is not ruleset in the kernel.
I guess we can do it better, flushing the old ruleset and loading the new one in a single,atomic step.

Is this possible with nft? If so, how?

Quoted 3 lines
Signature · 2 lines
-- 
Arturo Borrero González

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw
Quoted 11 lines · Jörg Thalheim
Quoted 8 lines

files/nftablesctl.in line 105

Quoted 3 lines
files/nftablesctl.in new file +3 -0
+nftables_restart() {
+       nftables_stop
+       nftables_start "$1"

Here, I think the time between the stop and start, there is not ruleset in the kernel.
I guess we can do it better, flushing the old ruleset and loading the new one in a single,atomic step.

Is this possible with nft? If so, how?

add a heading 'flush ruleset' to the file to be loaded.

Also, to load multiple files you can use "include" statements, and still be atomic B-)

Signature · 5 lines
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw
Quoted 11 lines · Arturo Borrero Gonzalez
Quoted 9 lines · Jörg Thalheim
Quoted 8 lines

files/nftablesctl.in line 105

Quoted 3 lines
files/nftablesctl.in new file +3 -0
+nftables_restart() {
+       nftables_stop
+       nftables_start "$1"

Here, I think the time between the stop and start, there is not ruleset in the kernel.
I guess we can do it better, flushing the old ruleset and loading the new one in a single,atomic step.

Quoted 6 lines
Quoted 1 line

Is this possible with nft? If so, how?

add a heading 'flush ruleset' to the file to be loaded.

Also, to load multiple files you can use "include" statements, and still be atomic B-)

Is the "include" statement a new feature? Never saw this feature in the wild. Does it works for directories too? Something like include "/etc/nftables.d/*" or includedir "/etc/nftables/" would be awesome.

Quoted 7 lines
Signature · 6 lines
-- 
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw
Quoted 3 lines

Is the "include" statement a new feature? Never saw this feature in the wild. Does it works for directories too? Something like include "/etc/nftables.d/*" or includedir "/etc/nftables/" would be awesome.

I should have read the manpage before asking. Anyway glob(3) would be cool addition.

#6 lore raw
In reply to Arturo Borrero Gonzalez
Quoted 1 line

You are making lot of assumptions, for example the '.rules' suffix.

Having some identifier is actually useful for administrators, this way you can just use

$ mv /etc/nftables/{some.rules,some.rules-disabled}

to disable rules. Having an extension also allow editors to provide syntax highlighting.

#7 lore raw
In reply to Jörg Thalheim

Hi netfilter community,
Patrick McHardy ask me to submit our work on systemd support for nftables (https://github.com/devkid/nftables-systemd)

It currently consists of a service file for systemd and a script to load/remove nftables rules. The script does more than actually needed for fundamental systemd support.

It allows to test rules:

$ nftablesctl start --confirm

which resets after 20s if you accidentally kill your ssh connection.

It allows to list all rules with one command:

$ nftables list

Instead of storing all rules in a single file (/etc/nftables.conf), it applys all files ending with .rules from directory /etc/nftables/ in lexical order, which make it more useful for configuration management like chef/puppet/ansible, where generating a single file from multiple modules is a pain.

So the question is the nftables project wants such a script. If you are just looking for a systemd service the following approach would be much easier:

[Unit]
Description=Netfilter Tables
Documentation=man:nft(8)
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/bin/nft -f /etc/nftables.conf
ExecStop=/usr/lib/systemd/scripts/nftables-flush
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

where /usr/lib/systemd/scripts/nftables-flush would just drop all rules

#8 lore raw
Quoted 6 lines · Jörg Thalheim

Instead of storing all rules in a single file (/etc/nftables.conf), it applys all files ending with .rules from directory /etc/nftables/ in lexical order, which make it more useful for configuration management like chef/puppet/ansible, where generating a single file from multiple modules is a pain.

But it means there will be a time where only half of the ruleset is loaded.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw
Quoted 2 lines

But it means there will be a time where only half of the ruleset is loaded.

Good point, so i will replace it with a pipe into nft.

#10 lore raw
In reply to Jörg Thalheim
Quoted 5 lines · Jörg Thalheim
files/nftablesctl.in new file +5 -0
+
+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
+

files/nftablesctl.in line 86

Quoted 10 lines
files/nftablesctl.in new file +10 -0
+       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

Also, it would be nice to rollback to the old ruleset rather than leaving the machine without firewall (think on mission critical firewalls, where human mistakes happens after all)

Signature · 5 lines
Arturo Borrero González
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#11 lore raw
In reply to Jörg Thalheim

files/nftablesctl.in line 49

Quoted 10 lines · Jörg Thalheim
files/nftablesctl.in new file +10 -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"
+}

Loading an empty ruleset would be a lot better (and likely faster too) - iptables was able to do that.

files/nftablesctl.in line 57

Quoted 7 lines
files/nftablesctl.in new file +7 -0
+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
+}

This too should perhaps become some single step in some way.

files/nftablesctl.in line 64

Quoted 6 lines
files/nftablesctl.in new file +6 -0
+nft_clear_protocol() {
+	for T in $(@sbindir@nft list tables "$1" | cut -d ' ' -f 2)
+	do
+		nft_delete_table "$1" "$T"
+	done
+}

as should this.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html