diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index e534bf8cc56..4389d6421c5 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -140,6 +140,24 @@ in ''; }; + proxyARP = mkOption { + default = false; + type = types.bool; + description = '' + Turn on proxy_arp for this device (and proxy_ndp for ipv6). + This is mainly useful for creating pseudo-bridges between a real + interface and a virtual network such as VPN or a virtual machine for + interfaces that don't support real bridging (most wlan interfaces). + As ARP proxying acts slightly above the link-layer, below-ip traffic + isn't bridged, so things like DHCP won't work. The advantage above + using NAT lies in the fact that no IP addresses are shared, so all + hosts are reachable/routeable. + + WARNING: turns on ip-routing, so if you have multiple interfaces, you + should think of the consequence and setup firewall rules to limit this. + ''; + }; + }; }; @@ -275,6 +293,14 @@ in echo "Configuring interface ${i.name}..." ip addr add "${i.ipAddress}""${optionalString (i.subnetMask != "") ("/" + i.subnetMask)}" \ dev "${i.name}" + '' + + optionalString i.proxyARP + '' + echo 1 > /proc/sys/net/ipv4/conf/${i.name}/proxy_arp + '' + + optionalString (i.proxyARP && cfg.enableIPv6) + '' + echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp '') } @@ -293,6 +319,11 @@ in ip route add default via "${cfg.defaultGateway}" ''} + # turn on forwarding if any interface has enabled proxy_arp + ${optionalString (any (i: i.proxyARP) cfg.interfaces) '' + echo 1 > /proc/sys/net/ipv4/ip_forward + ''} + # Run any user-specified commands. ${pkgs.stdenv.shell} ${pkgs.writeText "local-net-cmds" cfg.localCommands}