cross-posted from: https://sh.itjust.works/post/32918493

cross-posted from: https://sh.itjust.works/post/32918427

Hello,

Recently, I’ve been interested in self-hosting various services after coming across Futo’s “How to Self Host Your Life Guide” on their Wiki. They recommend using OpenVPN, but I opted for WireGuard instead as I wanted to learn more about it. After investing many hours into setting up my WireGuard configuration in my Nix config, I planned to replace Tailscale with WireGuard and make the setup declarative.

For context, this computer is located at my residence, and I want to be able to VPN into my home network and access my services. Initially, it was quite straightforward; I forwarded a UDP port on my router to my computer, which responded correctly when using the correct WireGuard keys and established a VPN connection. Everywhere online suggests forwarding only UDP as WireGuard doesn’t respond unless the correct key is used.

The Networking Complexity

At first, this setup would be for personal use only, but I soon realized that I had created a Docker stack for me and my friends to play on a Minecraft server running on my LAN using Tailscale as the network host. This allowed them to VPN in and join the server seamlessly. However, I grew tired of having to log in to various accounts (e.g., GitHub, Microsoft, Apple) and dealing with frequent sign-outs due to timeouts or playing around with container stacks.

To manage access to my services, I set up ACLs using Tailscale, allowing only specific IP addresses on my network (192.168.8.170) to access HigherGround, nothing else. Recently, I implemented WireGuard and learned two key things: Firstly, when friends VPN into the server, they have full access to everything, which isn’t ideal by no means. not that i dont trust my friends but, i would like to fix that :P. I then tried to set allowed IPs in the WireGuard config to 192.168.8.170, but realized that this means they can only access 192.168.8.170 explicitly, not being able to browse the internet or communicate via Signal until I added their specific IP addresses (10.0.0.2 and 10.0.0.3) to their WireGuard configs.

However, I still face a significant issue: every search they perform goes through my IP address instead of theirs.

The Research

I’ve researched this problem extensively and believe that split tunneling is the solution: I need to configure the setup so that only 192.168.8.170 gets routed through the VPN, while all other traffic is handled by their local router instead of mine. Ideally, my device should be able to access everything on the LAN and automatically route certain traffic through a VPS (like accessing HigherGround), but when performing general internet tasks (e.g., searching for “how to make a sandwich”), it gets routed from my router to ProtonVPN.

I’ve managed to get ProtonVPN working, but still struggle with integrating WireGuard on my phone to work with ProtonVPN on the server. From what I’ve read, using iptables and creating specific rules might be necessary to allow only certain devices to access 192.168.8.170 (HigherGround) while keeping their local internet traffic separate.

My long-term goal is to configure this setup so that my friends’ local traffic remains on their network, but for HigherGround services, it routes through the VPN tunnel or ProtonVPN if necessary.

My nix Config for wiregaurd (please let me know if im being stoopid with somthing networking is HARRRD)

#WIREGAURD connect to higher ground networking.wg-quick.interfaces = { # “wg0” is the network interface name. You can name the interface arbitrarily. caveout0 = { #Goes to ProtonVPN address = [ “10.2.0.2/32” ]; dns = [ “10.2.0.1” ]; privateKeyFile = “/root/wiregaurd/privatekey”; peers = [ { #From HigherGround to Proton publicKey = “magic numbers and letters”; allowedIPs = [ “0.0.0.0/0” “::/0” ]; endpoint = “magic numbers”; persistentKeepalive = 25; } ]; };

cavein0 = { # Determines the IP/IPv6 address and subnet of the client’s end of the tunnel interface address = [ “10.0.0.1/24” ]; dns = [ “192.168.8.1” “9.9.9.9” ]; # The port that WireGuard listens to - recommended that this be changed from default listenPort = 51820; # Path to the server’s private key privateKeyFile = “magic numbers and letters”;

  # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
  postUp = ''
    ${pkgs.iptables}/bin/iptables -A FORWARD -i cavein0 -j ACCEPT
    ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -o enp5s0 -j MASQUERADE
  '';

  # Undo the above
  preDown = ''
    ${pkgs.iptables}/bin/iptables -D FORWARD -i cavein0 -j ACCEPT
    ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -o enp5s0 -j MASQUERADE
  '';

  peers = [
    { #friend1 
     publicKey = "magic numbers and letters";
     allowedIPs = [ "10.0.0.3/32" "192.168.8.170/24" ];
     endpoint = "magic numbers and letters";
     presharedKey = "magic numbers and letters";
     persistentKeepalive = 25;
    }
    { # My phone
      publicKey = "magic numbers and letters";
      allowedIPs = [ "10.0.0.2/32" ];
      endpoint = "magic numbers and letters";
      presharedKey = "magic numbers and letters";
      persistentKeepalive = 25;
    }
    {# friend 2
      publicKey = "magic numbers and letters";
      allowedIPs = [ "10.0.0.4/32" "192.168.8.170/24" ];
      endpoint = "magic numbers and letters";
      presharedKey = "magic numbers and letters";
      persistentKeepalive = 25;
    }
    {# friend 3
     publicKey = "magic numbers and letters";
     allowedIPs = [ "10.0.0.5/32" ];
     endpoint = "magic numbers and letters";
     presharedKey = "magic numbers and letters";
     persistentKeepalive = 25;
    }
    
    # More peers can be added here.
  ];
};

};

#Enable NAT networking.nat = { enable = true; enableIPv6 = false; externalInterface = “enp5s0”; internalInterfaces = [ “cavein0” ]; };

services.dnsmasq.settings = { enable = true; extraConfig = ‘’ interface=cavein0 ‘’; };

Any help would be appreciated thanks

References: Futo Wiki: https://wiki.futo.org/index.php/Introduction_to_a_Self_Managed_Life:_a_13_hour_%26_28_minute_presentation_by_FUTO_software

NixOS Wireguard: https://wiki.nixos.org/w/index.php?title=WireGuard&mobileaction=toggle_view_desktop

Just a FYI, the main portion of the paragraph was put into llama3.1 with the prompt “take the following prompt and fix the grammer, spelling and spacing to make it more readable” Because im bad at english and didnt want to pain people with my choppy sentences and poor grammer