egress anti-spoofing: keep established bindings, load tables with bindings and leases in one transaction
This commit is contained in:
parent
c4ac01ef88
commit
70179b6c1f
2 changed files with 400 additions and 134 deletions
|
|
@ -18,9 +18,11 @@
|
|||
# traffic between two ports is bridged: the `inet` hooks see it as coming from
|
||||
# the bridge device, and only a bridge hook knows the port it came in on
|
||||
# (`iifname` is the veth). Which MAC a port may use and which IPv4 address a MAC
|
||||
# may use are not known when the ruleset loads, so they are set contents that
|
||||
# `hive-priv egress-pin` (per port, from udev) and dnsmasq's `dhcp-script`
|
||||
# (per lease) fill; `hive-priv`'s `egress.rs` documents how.
|
||||
# may use are not known until a container runs, so they are set contents.
|
||||
# `hive-priv egress-load` puts the current ones into the same transaction as the
|
||||
# tables; `egress-pin` (per new port from udev, and from a timer for the ports
|
||||
# still unbound) and dnsmasq's `dhcp-script` (per lease) keep them current.
|
||||
# `hive-priv`'s `egress.rs` documents how.
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
|
|
@ -39,7 +41,8 @@ let
|
|||
# the one every platform container's unit uses (hive-priv.nix points it at the
|
||||
# current build).
|
||||
hivePriv = (import ./lib/container-rootfs-check.nix { inherit config; }).hivePriv;
|
||||
pinCommand = args: "${hivePriv} egress-pin ${args}";
|
||||
pinCommand = args: lib.trim "${hivePriv} egress-pin ${args}";
|
||||
loadCommand = "${hivePriv} egress-load ${ruleset}";
|
||||
pinPath = [
|
||||
pkgs.nftables
|
||||
pkgs.iproute2
|
||||
|
|
@ -308,14 +311,11 @@ in
|
|||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${nft} -f ${ruleset}";
|
||||
# The sets of a freshly loaded bridge table are empty: bind the ports of
|
||||
# the running containers and load the leases from dnsmasq's file.
|
||||
ExecStartPost = pinCommand "--seed";
|
||||
ExecReload = [
|
||||
"${nft} -f ${ruleset}"
|
||||
(pinCommand "--seed")
|
||||
];
|
||||
# The tables load with the bindings of the running containers' ports and
|
||||
# the leases of dnsmasq's file in the same transaction, so a reload never
|
||||
# leaves the bridge with empty sets.
|
||||
ExecStart = loadCommand;
|
||||
ExecReload = loadCommand;
|
||||
ExecStop = [
|
||||
"-${nft} delete table inet hive_egress"
|
||||
"-${nft} delete table bridge hive_egress"
|
||||
|
|
@ -337,6 +337,30 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
# Looks again at the ports still unbound. A port a rival MAC kept unbound
|
||||
# sends nothing, so nothing else would tell the hive it can be bound now.
|
||||
# Ports with a binding cost a listing of the bridge and no container is read.
|
||||
systemd.services.hive-egress-pin = {
|
||||
description = "bind the agent bridge ports that have no binding yet";
|
||||
wants = [ "hive-egress.service" ];
|
||||
after = [ "hive-egress.service" ];
|
||||
path = pinPath;
|
||||
environment = pinEnvironment;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = pinCommand "";
|
||||
};
|
||||
};
|
||||
systemd.timers.hive-egress-pin = {
|
||||
description = "bind the agent bridge ports that have no binding yet";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnBootSec = "1min";
|
||||
OnUnitActiveSec = "30s";
|
||||
AccuracySec = "5s";
|
||||
};
|
||||
};
|
||||
|
||||
# nspawn names the host end of a container's veth `vb-<machine>` when the
|
||||
# container joins a bridge.
|
||||
services.udev.extraRules = ''
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ in
|
|||
# bridgeIp/bridgePrefixLength. All containers (agents and service
|
||||
# containers such as swarm-ci-runner) receive their IPs dynamically.
|
||||
dhcp-range = "${networkCfg.dhcpRangeStart},${networkCfg.dhcpRangeEnd},1h";
|
||||
# `hive-priv egress-pin --seed` reads this file back (hive-egress.nix).
|
||||
# `hive-priv egress-load` reads this file back (hive-egress.nix).
|
||||
dhcp-leasefile = "/var/lib/dnsmasq/dnsmasq.leases";
|
||||
# Each lease change updates the leased (MAC, IPv4) pairs the bridge
|
||||
# anti-spoofing table checks sources against (hive-egress.nix).
|
||||
|
|
|
|||
Loading…
Reference in a new issue