Hi, so been working on this for a week but not really happy with the solutions I find as they seem to be done by induviduals who rely heavily on ai. I got wireguard easy going and can remotly connect which is great but id love to be able to route any internet traffic to and from the wireguard clients to go though another server while filtering my local onsite services. Felt that if i can crack this i dont need to rely on tailscale. The end goal is to have no reliance on tailscale as i am preparing for the eventual enshitification.

all 26 comments

sorted by: hot top controversial new old
[–] 13 points 4 months ago* (6 children)

I have a custom made ansible role that does what you are asking for. I've wanted to clean it up a bit before putting it up on Github, and your post just gave me a motivation to stop procrastinating it :) This was initially made for my own use, and I'm not an Ansible expert so it can have some rough edges, but I tried my best to make it adhere to the Ansible way of doing things (applying the same role to a host twice should be idempotent).

Using this role, I'm able to quickly define wireguard networks, define which peer participates in which network, optionally configure a peer as a router (with NAT and port forwarding) for a given network. For Ansible-managed hosts, it installs wireguard, generates and deploys wireguard configurations, and enables IP forwarding on exit nodes. It can also generate ready-to-deploy wireguard configurations for externally managed hosts.

The repo is at https://github.com/pcouy/ansible-wireguard . I tried giving some instructions in the readme but they may not be detailed enough. If you try it, please open an issue for anything that's not clear enough from the readme so I can improve it. (I tried making a "Quick start" section for people who never used ansible before)

  • source
  • hideshow 6 child comments
  • [–] [S] 3 points 4 months ago* (4 children)

    Quick question (love your solution btw so eloquent could follow along easily which was such a nice change from the week i have had) does your solution manage multiple clients with different firewall requirements? Why i was heading down the wireguard ui route was the ease of firewall configuration per client. Its a weird thing where i feel headscale is a little bit more than i need and wireguard vanilla is a little too simplistic. I know nothing about ansible other than what i quickly read up on now.

  • source
  • parent
  • hideshow 4 child comments
  • [–] 4 points 4 months ago (3 children)

    Do you have specific examples of the "different firewall requirements" ?

  • source
  • parent
  • hideshow 3 child comments
  • [–] [S] 3 points 4 months ago (2 children)

    Its via gui but its basically just server side allow list so the client cant modify the ips it can access. The ips i use for https internet are 0.0.0.0/0:443 for example

  • source
  • parent
  • hideshow 2 child comments
  • [–] 2 points 4 months ago (1 child)

    The ansible role I made does not cover this. If you make a server an exit node for a network, the server gets configured to forward everything that comes from the wireguard network. Since my use case does not need this, I don't think I'll add it, but the role could be expanded to support ACLs by taking inspiration from how it deals with port forwarding.

  • source
  • parent
  • hideshow 1 child comment
  • [–] 6 points 4 months ago (2 children)

    Have a look at self hosted netbird on a VPS. Its free and has very little feature restrictions https://netbird.io/

  • source
  • hideshow 2 child comments
  • [–] [S] 1 point 4 months ago (1 child)

    I will tomorrow :) originally i was thinking about it then i got all caught up with wg-easy. Its looked promising when i first looked but it had one or two cavietes that made me decide against it. Will definantly revisit thanks for the suggestion!

  • source
  • parent
  • hideshow 1 child comment
  • [–] 4 points 4 months ago*

    The end goal is to have no reliance on tailscale as i am preparing for the eventual enshitification.

    Tailscale is mostly open-source. If they do anything bad then someone could fork the project. The coordination server isn't open-source, but you could self-host Headscale as a replacement.

    If it still doesn't suit your use cases, there's some alternatives.

    I personally wouldn't directly deal with iptables or nftables rules, and instead use some other software to deal with that.

  • source
  • [–] 5 points 4 months ago (11 children)

    You could use headscale. Its the heart of tailscale but in an open source format.

  • source
  • hideshow 11 child comments
  • [–] [S] 5 points 4 months ago (9 children)

    I did consider it. But then im still using tailscale ecosystem which as much as i want to they are still an american company.

  • source
  • parent
  • hideshow 9 child comments
  • [–] 12 points 4 months ago (8 children)

    Just a bit of a nitpik, but tailscale is a Canadian company.

  • source
  • parent
  • hideshow 8 child comments
  • [–] [S] 4 points 4 months ago (7 children)

    Well. That changes everything :D i shall look more seriously into this then. Would still love anythoughts on iptable routing tho >.<

  • source
  • parent
  • hideshow 7 child comments
  • [–] 6 points 4 months ago (6 children)

    iptables is deprecated... If you really do want to do your own custom thing you should learn nftables.

  • source
  • parent
  • hideshow 6 child comments
  • [–] [S] 2 points 4 months ago (5 children)

    Thats probably where im having the issue then thanks for the heads up.

  • source
  • parent
  • hideshow 5 child comments
  • [–] 3 points 4 months ago (4 children)

    iptables should still work, but these days it gets converted to nftables so you may as well just learn nftables.

    Having said that, I find it a pain to manually configure iptables or nftables. There might be a better way to do what you want.

  • source
  • parent
  • hideshow 4 child comments
  • [–] [S] 2 points 4 months ago (3 children)

    Ahh good so im not just me its actually a bit of a headache. The more i talk to folk the more i feel headscales orobably going to be the way. And rely on folk smarter than i to implement the nftables. Atm im kinda doing a hamfisted approach as the two programs i am using 1 uses nftables and thebother iptables so im already making it hard for myself. Thanks so much this is the kind of clarity i was seeking.

  • source
  • parent
  • hideshow 3 child comments
  • [–] 2 points 4 months ago (2 children)

    I run head scale on a Vps and it has been 100% reliable and provides an exit node for me via that VPS. But you are going to have the exact same issue, I think with your VPN.

    You want your default route from the exit node to go over mullivard's interface, but you need wireguard or tailscale to talk to the other clients directly, via their clearnet IP. You can tell the exit nodes tailscale/wireguard client to bind the clearnet interface, but that may or may not help. Mullivard probably takes the default gateway, which will likely cut off the clients. You could set dedicated routes to the IP addresses of the clients, but they can change if those clients are mobile. You will need to maintain a routing table somehow or keep the pre-existing connection active (fragile).

    I am sure its well trodden ground, just be aware that head scale probably won't solve your problem automatically. Its a routing and or firewall config issue.

  • source
  • parent
  • hideshow 2 child comments
  • [–] [S] 1 point 4 months ago (1 child)

    Thankyou for the insight. I have started looking at headscale and there seems to be chatter about implementing a mullvad exit node which seems promising. Ill spin up a vps tomorrow and explore options. I also want to run it on my own hardware (its a use what i have on hand situation).

  • source
  • parent
  • hideshow 1 child comment
  • [–] 2 points 4 months ago

    Serving headscale is basically a webserver plus a couple of ports. Super minimal hardware requirement but the typical difficulty of needing those ports on a publicly addressable static IP or dynamic DNS.

  • source
  • parent
  • [–] 2 points 4 months ago

    Head scale is actually a simpler implementation rather than the heart of what tailscale uses directly. It is perfectly complete for a single persons homelab application IMHO. Would be easy for the community to maintain a fork, but its also good to see other approaches that solve the same problem.

  • source
  • parent
  • [–] [B] 3 points 4 months ago* (last edited 4 months ago)

    Acronyms, initialisms, abbreviations, contractions, and other phrases which expand to something larger, that I've seen in this thread:

    Fewer Letters More Letters
    DNS Domain Name Service/System
    ISP Internet Service Provider
    NAT Network Address Translation
    SSH Secure Shell for remote terminal access
    Unifi Ubiquiti WiFi hardware brand
    VPN Virtual Private Network
    VPS Virtual Private Server (opposed to shared hosting)

    [Thread #14 for this comm, first seen 15th Jun 2026, 11:10] [FAQ] [Full list] [Contact] [Source code]

  • source
  • [–] [S] 1 point 4 months ago*

    Here is the compose and post up im working on

    services:
      gluetun:
        image: qmcgaw/gluetun:v3
        hostname: gluetun
        restart: always
        networks:
          wg:
            ipv4_address: 192.168.1.10    
        ports:
          - 51720:51720/udp # wireguard ui
          - 51821:51821 # wireguard tunnel
        cap_add:
          - NET_ADMIN
        devices:
          - /dev/net/tun:/dev/net/tun
        environment:
          - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER}
          - VPN_TYPE=${VPN_TYPE}
          - WIREGUARD_PRIVATE_KEY=${PRIVATE_KEY}
          - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
          - SERVER_CITIES=${SERVER_CITIES}
          - ALLOWED_IPS=0.0.0.0/1
          - FIREWALL_OUTBOUND_SUBNETS=${OUTBOUND_SUBNET}  #change to appropriate subnet
          - DNS_ADDRESS=${DNS}
    #      - HEALTH_TARGET_ADDRESS=cloudflare.com:80
    #      - HEALTH_VPN_DURATION_INITIAL=120s
    
      wg-easy:
        environment:
          - INSECURE=true #INITIAL SETUP NOT FOR PRODUCTION
        image: ghcr.io/wg-easy/wg-easy:15
        container_name: wg-easy
        restart: unless-stopped
        networks:
          wg:
            ipv4_address: 192.168.1.20 
        
        volumes:
          - ./data:/etc/wireguard
          - /lib/modules:/lib/modules:ro
        ports:
          - 51720:51720/udp #wireguard
          - 51821:51821/tcp #web ui
        cap_add:
          - NET_ADMIN
          - SYS_MODULE
        sysctls:
          - net.ipv4.ip_forward=1
          - net.ipv4.conf.all.src_valid_mark=1
          - net.ipv6.conf.all.disable_ipv6=0
          - net.ipv6.conf.all.forwarding=1
          - net.ipv6.conf.default.forwarding=1
    
    networks:
      vpn:
        driver: bridge
        enable_ipv6: false
        ipam:
          driver: default
          config:
            - subnet: 192.168.1.0/24 #container ipgateway
    #        - subnet: fdcc:ad94:bacf:61a3::/64
    
    
    

    Post up

    # Detect the VPN bridge interface by wg-easy's container IP
    VPN=$(ip -o -4 addr show | awk '$4 ~ /^192.168.1.20\// {print $2; exit}'); test -n "$VPN";
    iptables -P FORWARD DROP;
    ip6tables -P FORWARD DROP;
    iptables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT;
    ip6tables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT;
    
    # Direct subnets:
    ip route -A 10.1.0.0/16 via 192.168.1.0/24 dev $VPN table 200;
    ip -6 route -A 10.1.0.0/16 via 192.168.1.0/24 dev $VPN table 200;
    
  • source
  • [–] -3 points 4 months ago

    Is this english that i am reading ? or is it some other language ?

    i can't understand a thing!

  • source