mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-10 19:55:41 +03:00

After final improvements to the official formatter implementation, this commit now performs the first treewide reformat of Nix files using it. This is part of the implementation of RFC 166. Only "inactive" files are reformatted, meaning only files that aren't being touched by any PR with activity in the past 2 months. This is to avoid conflicts for PRs that might soon be merged. Later we can do a full treewide reformat to get the rest, which should not cause as many conflicts. A CI check has already been running for some time to ensure that new and already-formatted files are formatted, so the files being reformatted here should also stay formatted. This commit was automatically created and can be verified using nix-builda08b3a4d19
.tar.gz \ --argstr baseRevb32a094368
result/bin/apply-formatting $NIXPKGS_PATH
176 lines
5.5 KiB
Nix
176 lines
5.5 KiB
Nix
{ config, lib, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.networking.nat;
|
|
|
|
mkDest = externalIP: if externalIP == null then "masquerade" else "snat ${externalIP}";
|
|
dest = mkDest cfg.externalIP;
|
|
destIPv6 = mkDest cfg.externalIPv6;
|
|
|
|
toNftSet = list: concatStringsSep ", " list;
|
|
toNftRange = ports: replaceStrings [ ":" ] [ "-" ] (toString ports);
|
|
|
|
ifaceSet = toNftSet (map (x: ''"${x}"'') cfg.internalInterfaces);
|
|
ipSet = toNftSet cfg.internalIPs;
|
|
ipv6Set = toNftSet cfg.internalIPv6s;
|
|
oifExpr = optionalString (cfg.externalInterface != null) ''oifname "${cfg.externalInterface}"'';
|
|
|
|
# Whether given IP (plus optional port) is an IPv6.
|
|
isIPv6 = ip: length (lib.splitString ":" ip) > 2;
|
|
|
|
splitIPPorts =
|
|
IPPorts:
|
|
let
|
|
matchIP = if isIPv6 IPPorts then "[[]([0-9a-fA-F:]+)[]]" else "([0-9.]+)";
|
|
m = builtins.match "${matchIP}:([0-9-]+)" IPPorts;
|
|
in
|
|
{
|
|
IP = if m == null then throw "bad ip:ports `${IPPorts}'" else elemAt m 0;
|
|
ports = if m == null then throw "bad ip:ports `${IPPorts}'" else elemAt m 1;
|
|
};
|
|
|
|
mkTable =
|
|
{
|
|
ipVer,
|
|
dest,
|
|
ipSet,
|
|
forwardPorts,
|
|
dmzHost,
|
|
externalIP,
|
|
}:
|
|
let
|
|
# nftables maps for port forward
|
|
# [daddr .] l4proto . dport : addr . port
|
|
fwdMap = toNftSet (
|
|
map (
|
|
fwd:
|
|
with (splitIPPorts fwd.destination);
|
|
"${
|
|
optionalString (externalIP != null) "${externalIP} . "
|
|
}${fwd.proto} . ${toNftRange fwd.sourcePort} : ${IP} . ${ports}"
|
|
) forwardPorts
|
|
);
|
|
|
|
# nftables maps for port forward loopback dnat
|
|
# daddr . l4proto . dport : addr . port
|
|
fwdLoopDnatMap = toNftSet (
|
|
concatMap (
|
|
fwd:
|
|
map (
|
|
loopbackip:
|
|
with (splitIPPorts fwd.destination);
|
|
"${loopbackip} . ${fwd.proto} . ${toNftRange fwd.sourcePort} : ${IP} . ${ports}"
|
|
) fwd.loopbackIPs
|
|
) forwardPorts
|
|
);
|
|
|
|
# nftables set for port forward loopback snat
|
|
# daddr . l4proto . dport
|
|
fwdLoopSnatSet = toNftSet (
|
|
map (fwd: with (splitIPPorts fwd.destination); "${IP} . ${fwd.proto} . ${ports}") forwardPorts
|
|
);
|
|
in
|
|
''
|
|
chain pre {
|
|
type nat hook prerouting priority dstnat;
|
|
|
|
${optionalString (fwdMap != "") ''
|
|
iifname "${cfg.externalInterface}" meta l4proto { tcp, udp } dnat ${
|
|
optionalString (externalIP != null) "${ipVer} daddr . "
|
|
}meta l4proto . th dport map { ${fwdMap} } comment "port forward"
|
|
''}
|
|
|
|
${optionalString (fwdLoopDnatMap != "") ''
|
|
meta l4proto { tcp, udp } dnat ${ipVer} daddr . meta l4proto . th dport map { ${fwdLoopDnatMap} } comment "port forward loopback from other hosts behind NAT"
|
|
''}
|
|
|
|
${optionalString (dmzHost != null) ''
|
|
iifname "${cfg.externalInterface}" dnat ${dmzHost} comment "dmz"
|
|
''}
|
|
}
|
|
|
|
chain post {
|
|
type nat hook postrouting priority srcnat;
|
|
|
|
${optionalString (ifaceSet != "") ''
|
|
iifname { ${ifaceSet} } ${oifExpr} ${dest} comment "from internal interfaces"
|
|
''}
|
|
${optionalString (ipSet != "") ''
|
|
${ipVer} saddr { ${ipSet} } ${oifExpr} ${dest} comment "from internal IPs"
|
|
''}
|
|
|
|
${optionalString (fwdLoopSnatSet != "") ''
|
|
iifname != "${cfg.externalInterface}" ${ipVer} daddr . meta l4proto . th dport { ${fwdLoopSnatSet} } masquerade comment "port forward loopback snat"
|
|
''}
|
|
}
|
|
|
|
chain out {
|
|
type nat hook output priority mangle;
|
|
|
|
${optionalString (fwdLoopDnatMap != "") ''
|
|
meta l4proto { tcp, udp } dnat ${ipVer} daddr . meta l4proto . th dport map { ${fwdLoopDnatMap} } comment "port forward loopback from the host itself"
|
|
''}
|
|
}
|
|
'';
|
|
|
|
in
|
|
|
|
{
|
|
|
|
config = mkIf (config.networking.nftables.enable && cfg.enable) {
|
|
|
|
assertions = [
|
|
{
|
|
assertion = cfg.extraCommands == "";
|
|
message = "extraCommands is incompatible with the nftables based nat module: ${cfg.extraCommands}";
|
|
}
|
|
{
|
|
assertion = cfg.extraStopCommands == "";
|
|
message = "extraStopCommands is incompatible with the nftables based nat module: ${cfg.extraStopCommands}";
|
|
}
|
|
{
|
|
assertion = config.networking.nftables.rulesetFile == null;
|
|
message = "networking.nftables.rulesetFile conflicts with the nat module";
|
|
}
|
|
];
|
|
|
|
networking.nftables.tables = {
|
|
"nixos-nat" = {
|
|
family = "ip";
|
|
content = mkTable {
|
|
ipVer = "ip";
|
|
inherit dest ipSet;
|
|
forwardPorts = filter (x: !(isIPv6 x.destination)) cfg.forwardPorts;
|
|
inherit (cfg) dmzHost externalIP;
|
|
};
|
|
};
|
|
"nixos-nat6" = mkIf cfg.enableIPv6 {
|
|
family = "ip6";
|
|
name = "nixos-nat";
|
|
content = mkTable {
|
|
ipVer = "ip6";
|
|
dest = destIPv6;
|
|
ipSet = ipv6Set;
|
|
forwardPorts = filter (x: isIPv6 x.destination) cfg.forwardPorts;
|
|
dmzHost = null;
|
|
externalIP = cfg.externalIPv6;
|
|
};
|
|
};
|
|
};
|
|
|
|
networking.firewall.extraForwardRules = optionalString config.networking.firewall.filterForward ''
|
|
${optionalString (ifaceSet != "") ''
|
|
iifname { ${ifaceSet} } ${oifExpr} accept comment "from internal interfaces"
|
|
''}
|
|
${optionalString (ipSet != "") ''
|
|
ip saddr { ${ipSet} } ${oifExpr} accept comment "from internal IPs"
|
|
''}
|
|
${optionalString (ipv6Set != "") ''
|
|
ip6 saddr { ${ipv6Set} } ${oifExpr} accept comment "from internal IPv6s"
|
|
''}
|
|
'';
|
|
|
|
};
|
|
}
|