summaryrefslogtreecommitdiffstats
path: root/src/shared/firewall-util.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* firewall-util: introduce fw_ctx_get_reply_callback_count()Yu Watanabe2023-12-011-0/+8
|
* firewall: allow selecting firewall backend via env varLennart Poettering2023-11-031-5/+24
|
* shared/firewall-util: make NFT table init optionalTopi Miettinen2023-08-231-4/+8
|
* firewall-util: probe firewall backend in fw_ctx_new()Yu Watanabe2021-03-231-12/+2
| | | | | | | | | | | | | FirewallContext is used by networkd and nspawn. Both allocates the context when it is really necessary. Hence, it is not necessary to delay probing backend. Moreover, if iptables backend is not enabled on build, and nftables is not supported by kernel, previously `fw_nftables_init()` is called everytime when we try to configure masquerade or dnat. It causes significant performance loss. Fixes test-firewall-util issue in #19052.
* firewall-util: logs which backend will be usedYu Watanabe2021-03-231-37/+61
| | | | This also modernizes code a bit.
* firewall-util: add nftables backendFlorian Westphal2020-12-161-5/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* firewall-util: introduce context structureFlorian Westphal2020-12-161-15/+40
| | | | | | | | | | | | | | | for planned nft backend we have three choices: - open/close a new nfnetlink socket for every operation - keep a nfnetlink socket open internally - expose a opaque fw_ctx and stash all internal data here. Originally I opted for the 2nd option, but during review it was suggested to avoid static storage duration because of perceived problems with threaded applications. This adds fw_ctx and new/free functions, then converts the existing api and nspawn and networkd to use it.
* firewall-util: prepare for alternative to iptables backendFlorian Westphal2020-12-161-310/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | In a nutshell: 1. git mv firewall-util.c firewall-util-iptables.c 2. existing external functions gain _iptables_ in their names 3. firewall-util.c provides old function names 4. build system always compiles firewall-util.c, firewall-util-iptables.c is conditional instead (libiptc). 5. On first call to any of the 'old' API functions performs a probe that should return the preferred backend. In a future step, can add firewall-util-FOOTYPE.c, add its probe function to firewall-util.c and then have calls to fw_add_masq/local_dnat handed to the detected backend. For now, only iptables backend exists, and no special probing takes place for it, i.e. when systemd was built with iptables, that will be used. If not, requets to add masquerade/dnat will fail with same error (-EOPNOTSUPP) as before this change. For reference, the rules added by the libiptc/iptables backend look like this: for service export (via systemd-nspawn): [0:0] -A PREROUTING -p tcp -m tcp --dport $exportedport -m addrtype --dst-type LOCAL -j DNAT --to-destination $containerip:$port [0:0] -A OUTPUT ! -d 127.0.0.0/8 -p tcp -m tcp --dport $exportedport -m addrtype --dst-type LOCAL -j DNAT --to-destination $containerip:$port for ip masquerade: [0:0] -A POSTROUTING -s network/prefix -j MASQUERADE
* firewall-util: reject NULL source or address with prefixlen 0Florian Westphal2020-12-161-0/+3
| | | | | | | | | | | | | | | | | | | | | | Make sure we don't add masquerading rules without a explicitly specified network range we should be masquerading for. The only caller aside from test case is networkd-address.c which never passes a NULL source. As it also passes the network prefix, that should always be > 0 as well. This causes expected test failure: Failed to modify firewall: Invalid argument Failed to modify firewall: Invalid argument Failed to modify firewall: Invalid argument Failed to modify firewall: Protocol not available Failed to modify firewall: Protocol not available Failed to modify firewall: Protocol not available Failed to modify firewall: Protocol not available The failing test cases are amended to expect failure on NULL source or prefix instead of success.
* fw_add_masquerade: remove unused function argumentsFlorian Westphal2020-12-031-9/+5
| | | | | | | | Similar to the previous commit. All callers pass NULL. This will ease initial nftables backend implementation (less features to cover). Add the function parameters as local variables and let compiler remove branches. Followup patch can remove the if (NULL) conditionals.
* fw_add_local_dnat: remove unused function argumentsFlorian Westphal2020-12-031-5/+5
| | | | | | | | | | | | | | | All users pass a NULL/0 for those, things haven't changed since 2015 when this was added originally, so remove the arguments. THe paramters are re-added as local function variables, initalised to NULL or 0. A followup patch can then manually remove all if (NULL) rather than leaving dead-branch optimization to compiler. Reason for not doing it here is to ease patch review. Not requiring support for this will ease initial nftables backend implementation. In case a use-case comues up later this feature can be re-added.
* license: LGPL-2.1+ -> LGPL-2.1-or-laterYu Watanabe2020-11-091-1/+1
|
* tree-wide: drop socket.h when socket-util.h is includedYu Watanabe2019-11-031-1/+0
|
* tree-wide: drop alloca.h when alloc-util.h is includedYu Watanabe2019-11-031-1/+0
|
* firewall-util: use fixed size array for chain nameYu Watanabe2019-07-041-11/+13
| | | | | | | xt_chainlabel is defined as ``` typedef char xt_chainlabel[32]; ```
* tree-wide: use htobe{32,16}() instead of hton{l,s}()Yu Watanabe2019-06-191-2/+2
|
* firewall-util: add an assert that we're not overwriting a bufferDavid Tardon2018-10-121-1/+7
| | | | | ... like commit f28501279d2c28fdbb31d8273b723e9bf71d3b98 does for out_interface.
* tree-wide: remove Lennart's copyright linesLennart Poettering2018-06-141-3/+0
| | | | | | | | | | | These lines are generally out-of-date, incomplete and unnecessary. With SPDX and git repository much more accurate and fine grained information about licensing and authorship is available, hence let's drop the per-file copyright notice. Of course, removing copyright lines of others is problematic, hence this commit only removes my own lines and leaves all others untouched. It might be nicer if sooner or later those could go away too, making git the only and accurate source of authorship information.
* tree-wide: drop 'This file is part of systemd' blurbLennart Poettering2018-06-141-2/+0
| | | | | | | | | | | | | | | | This part of the copyright blurb stems from the GPL use recommendations: https://www.gnu.org/licenses/gpl-howto.en.html The concept appears to originate in times where version control was per file, instead of per tree, and was a way to glue the files together. Ultimately, we nowadays don't live in that world anymore, and this information is entirely useless anyway, as people are very welcome to copy these files into any projects they like, and they shouldn't have to change bits that are part of our copyright header for that. hence, let's just get rid of this old cruft, and shorten our codebase a bit.
* tree-wide: drop spurious newlines (#8764)Lennart Poettering2018-04-191-1/+0
| | | | | | | | Double newlines (i.e. one empty lines) are great to structure code. But let's avoid triple newlines (i.e. two empty lines), quadruple newlines, quintuple newlines, …, that's just spurious whitespace. It's an easy way to drop 121 lines of code, and keeps the coding style of our sources a bit tigther.
* tree-wide: drop license boilerplateZbigniew Jędrzejewski-Szmek2018-04-061-13/+0
| | | | | | | | | | Files which are installed as-is (any .service and other unit files, .conf files, .policy files, etc), are left as is. My assumption is that SPDX identifiers are not yet that well known, so it's better to retain the extended header to avoid any doubt. I also kept any copyright lines. We can probably remove them, but it'd nice to obtain explicit acks from all involved authors before doing that.
* shared: silence gcc warning (#7402)Shawn Landden2017-11-211-1/+2
| | | | | | | | [346/1860] Compiling C object 'src/shared/systemd-shared-235@sha/firewall-util.c.o'. ../src/shared/firewall-util.c: In function ‘entry_fill_basics’: ../src/shared/firewall-util.c:81:79: warning: logical ‘and’ of equal expressions [-Wlogical-op] [543/1860] Compiling C object 'src/shared/systemd-shared-235@sta/firewall-util.c.o'. ../src/shared/firewall-util.c: In function ‘entry_fill_basics’: ../src/shared/firewall-util.c:81:79: warning: logical ‘and’ of equal expressions [-Wlogical-op]
* Add SPDX license identifiers to source files under the LGPLZbigniew Jędrzejewski-Szmek2017-11-191-0/+1
| | | | | This follows what the kernel is doing, c.f. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
* tree-wide: use IN_SET macro (#6977)Yu Watanabe2017-10-041-2/+2
|
* in-addr-util: be more systematic with naming our functionsLennart Poettering2017-09-221-2/+2
| | | | | | | | | Let's rename all our functions that process IPv4 in_addr structures in4_addr_xyz(), following the already establishing naming logic for this. Leave the in_addr_xyz() prefix for functions that process the IPv4/IPv6 in_addr_union union instead.
* firewall-util: add an assert that we're not overwriting a bufferZbigniew Jędrzejewski-Szmek2017-02-201-1/+4
| | | | Check for CID #1368267.
* shared/firewall-util: remove warning about net/if.h workaroundZbigniew Jędrzejewski-Szmek2016-12-101-2/+3
| | | | | This is already fixed upstream, so warning is not useful. Let's keep the workaround until the fix has percolated downstream.
* Make the fix for net/if.h fuckup even worse (#3287)Zbigniew Jędrzejewski-Szmek2016-05-201-4/+2
| | | | | | | | | | | | | | | | | | | The original conflict is fixed in the kernel in v4.6-rc7-40-g4a91cb61bb, but now our work-around causes a compilation failure. Keep the workaround to support 4.5 kernels for now, and layer more ugliness on top. Tested with: kernel-headers-4.6.0-1.fc25.x86_64 glibc-devel-2.23.90-18.fc25.x86_64 kernel-headers-4.5.4-300.fc24.x86_64 glibc-devel-2.23.1-7.fc24.x86_64 kernel-headers-4.4.9-300.fc23.x86_64 glibc-devel-2.22-16.fc23.x86_64 kernel-headers-4.1.13-100.fc21.x86_64 glibc-devel-2.20-8.fc21.x86_64
* tree-wide: port more code to use ifname_valid()Lennart Poettering2016-05-091-3/+3
|
* shared: add a temporary work-around for kernel header inclusion fuck-upLennart Poettering2016-04-121-1/+11
| | | | See: #2864
* tree-wide: remove Emacs lines from all filesDaniel Mack2016-02-101-2/+0
| | | | | This should be handled fine now by .dir-locals.el, so need to carry that stuff in every file.
* shared: include what we useThomas Hindoe Paaboel Andersen2015-12-061-2/+8
| | | | | The next step of a general cleanup of our includes. This one mostly adds missing includes but there are a few removals as well.
* tree-wide: sort includesThomas Hindoe Paaboel Andersen2015-11-161-1/+1
| | | | Sort the includes accoding to the new coding style.
* util-lib: split out allocation calls into alloc-util.[ch]Lennart Poettering2015-10-271-1/+2
|
* firewall: rename fw-util.[ch] → firewall-util.[ch]Daniel Mack2015-06-151-0/+344
The names fw-util.[ch] are too ambiguous, better rename the files to firewall-util.[ch]. Also rename the test accordingly.