Ninjatrappeur's systemd working tree
Go to file
Florian Westphal 715a70e721 firewall-util: add nftables backend
Idea is to use a static ruleset, added when the first attempt to
add a masquerade or dnat rule is made.

The alternative would be to add the ruleset when the init function is called.
The disadvantage is that this enables connection tracking and NAT in the kernel
(as the ruleset needs this to work), which comes with some overhead that might
not be needed (no nspawn usage and no IPMasquerade option set).

There is no additional dependency on the 'nft' userspace binary or other libraries.
sd-netlinks nfnetlink backend is used to modify the nftables ruleset.

The commit message/comments still use nft syntax since that is what
users will see when they use the nft tool to list the ruleset.

The added initial skeleton (added on first fw_add_masquerade/local_dnat
call) looks like this:

table ip io.systemd.nat {
        set masq_saddr {
                type ipv4_addr
                flags interval
                elements = { 192.168.59.160/28 }
        }

        map map_port_ipport {
                type inet_proto . inet_service : ipv4_addr . inet_service
                elements = { tcp . 2222 : 192.168.59.169 . 22 }
        }

        chain prerouting {
                type nat hook prerouting priority dstnat + 1; policy accept;
                fib daddr type local dnat ip addr . port to meta l4proto . th dport map @map_port_ipport
        }

        chain output {
                type nat hook output priority -99; policy accept;
                ip daddr != 127.0.0.0/8 oif "lo" dnat ip addr . port to meta l4proto . th dport map @map_port_ipport
        }

        chain postrouting {
                type nat hook postrouting priority srcnat + 1; policy accept;
                ip saddr @masq_saddr masquerade
        }
}

Next calls to fw_add_masquerade/add_local_dnat will then only add/delete the
element/mapping to masq_saddr and map_port_ipport, i.e. the ruleset doesn't
change -- only the set/map content does.

Running test-firewall-util with this backend gives following output
on a parallel 'nft monitor':

$ nft monitor
add table ip io.systemd.nat
add chain ip io.systemd.nat prerouting { type nat hook prerouting priority dstnat + 1; policy accept; }
add chain ip io.systemd.nat output { type nat hook output priority -99; policy accept; }
add chain ip io.systemd.nat postrouting { type nat hook postrouting priority srcnat + 1; policy accept; }
add set ip io.systemd.nat masq_saddr { type ipv4_addr; flags interval; }
add map ip io.systemd.nat map_port_ipport { type inet_proto . inet_service : ipv4_addr . inet_service; }
add rule ip io.systemd.nat prerouting fib daddr type local dnat ip addr . port to meta l4proto . th dport map @map_port_ipport
add rule ip io.systemd.nat output ip daddr != 127.0.0.0/8 fib daddr type local dnat ip addr . port to meta l4proto . th dport map @map_port_ipport
add rule ip io.systemd.nat postrouting ip saddr @masq_saddr masquerade
add element ip io.systemd.nat masq_saddr { 10.1.2.3 }
add element ip io.systemd.nat masq_saddr { 10.0.2.0/28 }
delete element ip io.systemd.nat masq_saddr { 10.0.2.0/28 }
delete element ip io.systemd.nat masq_saddr { 10.1.2.3 }
add element ip io.systemd.nat map_port_ipport { tcp . 4711 : 1.2.3.4 . 815 }
delete element ip io.systemd.nat map_port_ipport { tcp . 4711 : 1.2.3.4 . 815 }
add element ip io.systemd.nat map_port_ipport { tcp . 4711 : 1.2.3.5 . 815 }
delete element ip io.systemd.nat map_port_ipport { tcp . 4711 : 1.2.3.5 . 815 }
CTRL-C

Things not implemented/supported:
1. Change monitoring.  The kernel allows userspace to learn about changes
   made by other clients (using nfnetlink notifications). It would be
   possible to detect when e.g. someone removes the systemd nat table.
   This would need more work.  Its also not clear on how to react to
   external changes -- it doesn't seem like a good idea to just auto-undo
   everthing.
2. 'set masq_saddr' doesn't handle overlaps.
   Example:

   fw_add_masquerade(true, AF_INET, "10.0.0.0" , 16);
   fw_add_masquerade(true, AF_INET, "10.0.0.0" , 8); /* fails */

With the iptables backend the second call works, as it adds an
independent iptables rule.

With the nftables backend, the range 10.0.0.0-10.255.255.255 clashes with
the existing range of 10.0.0.0-10.0.255.255 so 2nd add gets rejected by the
kernel.

This will generate an error message from networkd ("Could not enable IP
masquerading: File exists").

To resolve this it would be needed to either keep track of the added elements
and perform range merging when overlaps are detected.

However, the add erquests are done using the configured network on a
device, so no overlaps should occur in normal setups.

IPv6 support is added in a extra changeset.

Fixes: #13307
2020-12-16 01:07:08 +01:00
.github Add Pull Request Labeler 2020-12-14 09:43:38 +09:00
.lgtm/cpp-queries lgtm: complain about accept() [people should use accept4() instead, due to O_CLOEXEC] 2019-04-10 20:03:38 +02:00
.mkosi mkosi: Add strace to final images 2020-12-09 17:34:45 +00:00
catalog license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
coccinelle coccinelle: ignore specific cases to use SYNTHETIC_ERRNO() macro 2020-11-27 14:35:20 +09:00
docs docs/RELEASE: clarify which steps are done when 2020-11-26 13:54:37 +01:00
factory/etc man: move 'files' module in NSS 'hosts:' line before myhostname 2020-08-17 18:55:59 +02:00
hwdb.d Update 60-keyboard.hwdb 2020-12-13 10:49:46 +00:00
man network: Allow to configure interface promiscuous mode 2020-12-15 20:25:08 +00:00
modprobe.d license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
network meson: add option to skip installing to $sysconfdir 2020-11-12 11:21:46 +01:00
po Translated using Weblate (German) 2020-12-15 17:40:56 +01:00
presets license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
rules.d udev: Fix sound.target dependency 2020-12-10 14:29:50 +09:00
semaphoreci Revert "semaphore: temporarily disable the timedated test suite" 2020-12-04 18:47:12 +01:00
shell-completion license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
src firewall-util: add nftables backend 2020-12-16 01:07:08 +01:00
sysctl.d meson: add option to skip installing to $sysconfdir 2020-11-12 11:21:46 +01:00
sysusers.d license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
test network: Allow to configure interface promiscuous mode 2020-12-15 20:25:08 +00:00
tmpfiles.d meson: add option to skip installing to $sysconfdir 2020-11-12 11:21:46 +01:00
tools meson: Respect MESON_INSTALL_QUIET 2020-12-06 22:11:11 +00:00
travis-ci ci: also set -Dfuzz-tests=true if -Dslow-tests=true 2020-11-13 18:15:41 +09:00
units unit: make systemd-networkd.service support reload command 2020-12-09 12:55:51 +09:00
xorg scripts: use 4 space indentation 2019-04-12 08:30:31 +02:00
.clang-format clang-format: set SpaceBeforeParens to ControlStatementsExceptForEachMacros 2020-11-16 16:57:51 +09:00
.ctags editors: Prevent ctags from following symlinks 2019-02-15 11:01:20 -08:00
.dir-locals.el scripts: use 4 space indentation 2019-04-12 08:30:31 +02:00
.editorconfig editorconfig: add man configuration 2020-05-26 15:37:05 +02:00
.gitattributes git: indicate that tabs are never OK in the systemd tree 2013-10-30 02:25:38 +01:00
.gitignore mkosi: Keep mkosi.default out of the repository. 2020-07-16 21:44:02 +01:00
.lgtm.yml lgtm: drop the TMPDIR/meson workaround 2020-03-03 20:27:42 +01:00
.mailmap NEWS: update contributors list for v246-pre 2020-07-23 17:30:54 +02:00
.travis.yml coverity: switch back to Fedora 31 2020-07-12 22:00:16 +00:00
.vimrc scripts: use 4 space indentation 2019-04-12 08:30:31 +02:00
.ycm_extra_conf.py ycm: add doc string for all the functions in configuration file 2017-11-29 13:21:49 -07:00
LICENSE.GPL2 relicense to LGPLv2.1 (with exceptions) 2012-04-12 00:24:39 +02:00
LICENSE.LGPL2.1 licence: remove references to old FSF address 2012-12-17 11:41:31 +01:00
Makefile build-sys: Fix Makefile wrapper for install target (#6548) 2017-08-07 11:29:20 +02:00
NEWS tree-wide: fix typo 2020-12-14 12:05:55 +00:00
README meson: add min version for libfdisk 2020-08-19 10:18:33 +02:00
README.md README.md: update CentOS CI badges 2020-10-06 13:59:52 +02:00
TODO Update TODO 2020-12-14 13:51:10 +01:00
azure-pipelines.yml Free up some resources on Azure Pipelines 2019-07-17 13:28:38 +09:00
configure treewide: more portable bash shebangs 2020-03-05 17:27:07 +01:00
meson.build meson: Fix reallocarray check 2020-12-13 09:44:29 +01:00
meson_options.txt Drop compat "gateway" name 2020-12-10 20:44:41 +01:00
mkosi.build mkosi: Silence locale checking in mkosi.build 2020-12-06 22:11:11 +00:00
zanata.xml po: add basic fedora.zanata.org configuration 2018-02-19 13:56:57 +01:00

README.md

Systemd

System and Service Manager

Count of open issues over time Count of open pull requests over time Semaphore CI Build Status
Coverity Scan Status
OSS-Fuzz Status
CIFuzz
CII Best Practices
Travis CI Build Status
Language Grade: C/C++
CentOS CI - CentOS 7
CentOS CI - Arch
CentOS CI - Arch (sanitizers)
Build Status
Fossies codespell report
Packaging status

Details

Most documentation is available on systemd's web site.

Assorted, older, general information about systemd can be found in the systemd Wiki.

Information about build requirements is provided in the README file.

Consult our NEWS file for information about what's new in the most recent systemd versions.

Please see the Hacking guide for information on how to hack on systemd and test your modifications.

Please see our Contribution Guidelines for more information about filing GitHub Issues and posting GitHub Pull Requests.

When preparing patches for systemd, please follow our Coding Style Guidelines.

If you are looking for support, please contact our mailing list or join our IRC channel.

Stable branches with backported patches are available in the stable repo.