From 2014d5ce77a01f650f57be882d2eac2aecbb1aed Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 9 Dec 2022 14:16:48 +0000 Subject: [PATCH] servo: bridge port 80/53 from ovpns to native using iptables instead of socat i should probably narrow the rules to match specifically things destined for the ovpns address, but for now this should work. --- hosts/servo/net.nix | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/hosts/servo/net.nix b/hosts/servo/net.nix index 00fc8528c..84bb26147 100644 --- a/hosts/servo/net.nix +++ b/hosts/servo/net.nix @@ -28,6 +28,8 @@ 1900 7359 # DLNA: https://jellyfin.org/docs/general/networking/index.html 4001 # IPFS ]; + # this is needed to forward packets from the VPN to the host + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; # we need to use externally-visible nameservers in order for VPNs to be able to resolve hosts. networking.nameservers = [ @@ -69,18 +71,38 @@ Type = "oneshot"; RemainAfterExit = true; - ExecStart = with pkgs; writeScript "wg0veth-start" '' - #!${bash}/bin/bash + ExecStart = let + ip = "${pkgs.iproute2}/bin/ip"; + in-ns = "${ip} netns exec ovpns"; + iptables = "${pkgs.iptables}/bin/iptables"; + in pkgs.writeScript "wg0veth-start" '' + #!${pkgs.bash}/bin/bash + # DOCS: + # - some of this approach is described here: + # - iptables primer: # create veth pair - ${iproute2}/bin/ip link add ovpns-veth-a type veth peer name ovpns-veth-b - ${iproute2}/bin/ip addr add 10.0.1.5/24 dev ovpns-veth-a - ${iproute2}/bin/ip link set ovpns-veth-a up + ${ip} link add ovpns-veth-a type veth peer name ovpns-veth-b + ${ip} addr add 10.0.1.5/24 dev ovpns-veth-a + ${ip} link set ovpns-veth-a up + # mv veth-b into the ovpns namespace - ${iproute2}/bin/ip link set ovpns-veth-b netns ovpns - ${iproute2}/bin/ip -n ovpns addr add 10.0.1.6/24 dev ovpns-veth-b - ${iproute2}/bin/ip -n ovpns link set ovpns-veth-b up - # forward HTTP traffic, which we need for letsencrypt to work - ${iproute2}/bin/ip netns exec ovpns ${socat}/bin/socat TCP4-LISTEN:80,reuseaddr,fork,su=nobody TCP4:10.0.1.5:80 & + ${ip} link set ovpns-veth-b netns ovpns + ${ip} -n ovpns addr add 10.0.1.6/24 dev ovpns-veth-b + ${ip} -n ovpns link set ovpns-veth-b up + + # bridge HTTP traffic: + # any external port-80 request sent to the VPN addr will be forwarded to the rootns. + # this exists so LetsEncrypt can procure a cert for the MX over http. + # old socat impl: + # ${in-ns} ${pkgs.socat}/bin/socat TCP4-LISTEN:80,reuseaddr,fork,su=nobody TCP4:10.0.1.5:80 & + ${in-ns} ${iptables} -A PREROUTING -t nat -p tcp --dport 80 -j DNAT --to-destination 10.0.1.5:80 + ${in-ns} ${iptables} -A POSTROUTING -t nat -p tcp --dport 80 -j SNAT --to-source 10.0.1.6 + + # we also bridge DNS traffic (TODO: test TCP) + ${in-ns} ${iptables} -A PREROUTING -t nat -p udp --dport 53 -j DNAT --to-destination 10.0.1.5:53 + ${in-ns} ${iptables} -A PREROUTING -t nat -p tcp --dport 53 -j DNAT --to-destination 10.0.1.5:53 + ${in-ns} ${iptables} -A POSTROUTING -t nat -p udp --dport 53 -j SNAT --to-source 10.0.1.6 + ${in-ns} ${iptables} -A POSTROUTING -t nat -p tcp --dport 53 -j SNAT --to-source 10.0.1.6 ''; ExecStop = with pkgs; writeScript "wg0veth-stop" ''