Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Shells Virtual Desktop
BMail.ag - Secure Email Service
Server.net
CPLicense.net
VPS Server
Buy VPN
Vultr
VMs for AI
HostDare
ReliableSite White-Label Dedicated Hosting for Resellers
InterServer VPS
BMail.ag - Secure Email Service
Best VPN
High-Performance Bare Metal Server Solutions
Karvl.com
Server Mania Cloud Hosting
DataWagon Hosting
AlphaVPS Hosting
Evoxt.com
Clouvider
VPS Hosting with NVMe
Residential IPs in the US & 4G Mobile Proxies in EU & US with Unlimited Bandwidth
ReliableSite White-Label Dedicated Hosting for Resellers
Rabisu - Hosting Solutions
Shells Virtual Desktop
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

Any working solutions that allow using Tailscale and a regular VPN simultaneously?

I am trying to use Tailscale and Private Internet Access (PIA) active at the same time. I enabled split tunnel in PIA so to bypass PIA for Tailscale's IPs, but it's not working and Google isn't helping much. Any suggestions?

Comments

  • run other inside virtualbox

  • @stefeman said:
    run other inside virtualbox

    I had a Kali Linux VM (with VMWare) on my Mac for when I do security work, and that allowed me to easily keep the VPN active in the VM while on the host I can use Tailscale just fine. The problem is that I would very much prefer using macOS for everything.

  • WebProjectWebProject Veteran, 🚩 Host Rep Tag Suspended

    @vitobotta said: but it's not working and Google isn't helping much. Any suggestions?

    use ChatGPT :)

  • M66BM66B Veteran
    edited December 2024

    @vitobotta said:
    I am trying to use Tailscale and Private Internet Access (PIA) active at the same time. I enabled split tunnel in PIA so to bypass PIA for Tailscale's IPs, but it's not working and Google isn't helping much. Any suggestions?

    Perhaps run Tailscale on your router and PIA on your smartphone / desktop computer?

    Edit: the problem is not clear because perhaps you are trying to use an Android device (one VPN at a time), or you want to put Tailscale behind PIA or the other way around?

    https://tailscale.com/kb/1105/other-vpns

  • emghemgh Member, Megathread Squad

    @beanman109 help this man

    Thanked by 1beanman109
  • beanman109beanman109 Member, Host Rep, Megathread Squad

    @emgh said:
    @beanman109 help this man

    tailscale routes break my mind i don't think i can help

    Thanked by 2emgh admax
  • I don't know about PIA but in some VPNs the settings toggle is "vpn kill switch" / "allow local network access"

  • emghemgh Member, Megathread Squad
    edited December 2024

    @beanman109 said:

    @emgh said:
    @beanman109 help this man

    tailscale routes break my mind i don't think i can help

    u n lik tail skale ?

    my it s enjoy but traffic it s enkrypted so when I ran my bekep thro it they toq muh longe r times

    stop usage (cpu usage it s 💯)

    Thanked by 1beanman109
  • beanman109beanman109 Member, Host Rep, Megathread Squad

    @emgh said:

    @beanman109 said:

    @emgh said:
    @beanman109 help this man

    tailscale routes break my mind i don't think i can help

    u n lik tail skale ?

    my it s enjoy but traffic it s enkrypted so when I ran my bekep thro it they toq muh longe r times

    stop usage (cpu usage it s 💯)

    i'm actually a wireguard main because i can't get tailscale to do things i want it to do because tailscale

    Thanked by 3emgh Peppery9 admax
  • @M66B said:

    @vitobotta said:
    I am trying to use Tailscale and Private Internet Access (PIA) active at the same time. I enabled split tunnel in PIA so to bypass PIA for Tailscale's IPs, but it's not working and Google isn't helping much. Any suggestions?

    Perhaps run Tailscale on your router and PIA on your smartphone / desktop computer?

    Edit: the problem is not clear because perhaps you are trying to use an Android device (one VPN at a time), or you want to put Tailscale behind PIA or the other way around?

    https://tailscale.com/kb/1105/other-vpns

    I didn't mention Android, did I?

    So, to recap. My host OS is macOS, and I have both Tailscale and PIA installed. The two work fine as long as they are not active at the same time. I already tried the Split Tunnel config as described on that page but it doesn't work for me.

  • @vitobotta said:

    @M66B said:

    @vitobotta said:
    I am trying to use Tailscale and Private Internet Access (PIA) active at the same time. I enabled split tunnel in PIA so to bypass PIA for Tailscale's IPs, but it's not working and Google isn't helping much. Any suggestions?

    Perhaps run Tailscale on your router and PIA on your smartphone / desktop computer?

    Edit: the problem is not clear because perhaps you are trying to use an Android device (one VPN at a time), or you want to put Tailscale behind PIA or the other way around?

    https://tailscale.com/kb/1105/other-vpns

    I didn't mention Android, did I?

    Indeed, you didn't mention anything about what OS / device you are using, and it wasn't clear what you wanted, so we need to guess or ask.

  • @M66B said:

    @vitobotta said:

    @M66B said:

    @vitobotta said:
    I am trying to use Tailscale and Private Internet Access (PIA) active at the same time. I enabled split tunnel in PIA so to bypass PIA for Tailscale's IPs, but it's not working and Google isn't helping much. Any suggestions?

    Perhaps run Tailscale on your router and PIA on your smartphone / desktop computer?

    Edit: the problem is not clear because perhaps you are trying to use an Android device (one VPN at a time), or you want to put Tailscale behind PIA or the other way around?

    https://tailscale.com/kb/1105/other-vpns

    I didn't mention Android, did I?

    Indeed, you didn't mention anything about what OS / device you are using, and it wasn't clear what you wanted, so we need to guess or ask.

    Sorry, you're right. I should have given more context in the OP :)

  • split tunneling is what you are looking at. it depends on what hardware / software you are using to achieve this

  • mandalamandala Member, Megathread Squad

    Can I use Tailscale alongside other VPNs?
    Guide: Tailscale Exit Node LXC to NordVPN LXC to internet
    How to run Tailscale alongside another VPN

    These are to route your traffic through the VPN and stay in the VPN.

    Another way is to set an exit node, every interaction with outer internet will go through that node, and you can set up the VPN condom on the node, but that will tank performance. Btw Mullvad teamed up with Tailscale, if you use Mullvad you can use their servers as exit node effortlessly.

    Thanked by 1yoursunny
  • @stackr said:
    split tunneling is what you are looking at. it depends on what hardware / software you are using to achieve this

    I tried with it several times, it made no difference :(

    @mandala said:
    Can I use Tailscale alongside other VPNs?
    Guide: Tailscale Exit Node LXC to NordVPN LXC to internet
    How to run Tailscale alongside another VPN

    These are to route your traffic through the VPN and stay in the VPN.

    Another way is to set an exit node, every interaction with outer internet will go through that node, and you can set up the VPN condom on the node, but that will tank performance. Btw Mullvad teamed up with Tailscale, if you use Mullvad you can use their servers as exit node effortlessly.

    I could try Mullvad but it's annoying because I literally just renewed PIA :(

  • @yoursunny might have a solution

  • I ended up buying the Mullvad addon in Tailscale and it works beautifully! It's $5/mo for 5 devices so I'm happy. Thanks everyone for your help!

    This is nice because when I am hacking and need the VPN I can still securely access other devices in my Tailscale network just fine. Love it!

    Thanked by 1siemens
  • mandalamandala Member, Megathread Squad

  • @vitobotta said:
    I ended up buying the Mullvad addon in Tailscale and it works beautifully! It's $5/mo for 5 devices so I'm happy. Thanks everyone for your help!

    This is nice because when I am hacking and need the VPN I can still securely access other devices in my Tailscale network just fine. Love it!

    In case you ever come back to this, you would solve this with adding and removing routes when the VPN link goes up and down.

    The most common scenario (for inspiration to google) would be wanting your ssh traffic to a VPS to be direct and return incoming data back out same interface instead of VPN and not working.

  • @mandala said:
    Can I use Tailscale alongside other VPNs?
    Guide: Tailscale Exit Node LXC to NordVPN LXC to internet
    How to run Tailscale alongside another VPN

    These are to route your traffic through the VPN and stay in the VPN.

    Another way is to set an exit node, every interaction with outer internet will go through that node, and you can set up the VPN condom on the node, but that will tank performance. Btw Mullvad teamed up with Tailscale, if you use Mullvad you can use their servers as exit node effortlessly.

    Is this possible to achieve if you already have active mullvad subscription? Or they would need to somehow move it to Tailscale?

  • I'm a bit late to this, but I came across this thread whilst trying to figure out a solution for this myself and I made a mental note that I'd leave a comment if I ever figured it out.

    It turns out there's at least two ways of doing this, although the best known solution is bloated, (requires two Docker containers), and gives dire performance, (maxes out at about ~30Mbps). You can read how to set it up here: https://lemmy.world/post/7281194

    However, the solution I've found that really works well is to build a single Docker container with both Tailscale and Wireguard clients installed, as described in this Github post: https://github.com/juanfont/headscale/issues/1545#issuecomment-2267081979

    To make it work you need to be able to download Wireguard config files from your VPN provider and run them using wg-quick, which you can test by installing Wireguard and running:

    wg-quick up <path-to-config-file>

    Assuming you're able to connect your Wireguard tunnel, you can follow the steps below to setup an Exit Node that routes its traffic through your VPN.

    .
    1. BUILD THE DOCKER CONTAINER

    To build the Docker Image you need to create a directory named build, (or whatever else you want to call it), and in that directory you need to create a file named Dockerfile and copy this content into it:

    # Base image
    FROM debian:bullseye-slim
    
    # Install necessary packages
    RUN apt-get update && apt-get install -y \
            curl \
            iproute2 \
            iptables \
            wireguard-tools \
            bash \
            procps \
            openresolv \
            && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    # Install additional packages
    RUN curl -fsSL https://tailscale.com/install.sh | sh
    
    # Copy and set the entrypoint script into the container if active
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    In the same build directory you also need to create a file named entrypoint.sh and copy the contents of this bash script into it:

    #!/bin/bash
    
    # Check if necessary environment variables are set
    : "${TS_EXTRA_ARGS:?Environment variable TS_EXTRA_ARGS must be set}"
    : "${WG_CONFIG:?Environment variable WG_CONFIG must be set}"
    
    # Start Tailscale in the background
    echo "Starting tailscaled"
    tailscaled &
    TAILSCALE_PID=$!
    
    # Function to check if tailscaled is running
    check_tailscaled() {
        pgrep tailscaled > /dev/null
    }
    
    # Wait for tailscaled to start up
    echo "Waiting for tailscaled to initialize..."
    for i in {1..10}; do
        if check_tailscaled; then
            echo "tailscaled is running"
            break
        fi
        sleep 2
    done
    
    # Check again if tailscaled is running after waiting
    if ! check_tailscaled; then
        echo "tailscaled failed to start. Exiting."
        tail -f /dev/null  # Keeps the container running for debugging
        exit 1
    fi
    
    # Authenticate with Tailscale
    echo "Running Tailscale up"
    tailscale up $TS_EXTRA_ARGS
    
    # Check if Tailscale is connected
    if ! tailscale status | grep -q "Tailscale is stopped"; then
        echo "Tailscale is connected"
        # Ensure WireGuard is up and running
        if [ -f $WG_CONFIG ]; then
            echo "Starting WireGuard"
            wg-quick up "$WG_CONFIG"
        else
            echo "WireGuard configuration file not found!"
        fi
        tail -f /dev/null  # Keeps the container running for debugging
    else
        echo "Tailscale failed to connect. Exiting."
        tailscale status # Optionally: Print Tailscale logs for further debugging
        tail -f /dev/null  # Keeps the container running for debugging
    fi
    

    This should leave you with a directory structure that looks like this:

        build
        |
        |-- Dockerfile
        |-- entrypoint.sh
    

    You then need to build the Docker Image, which you can do by running this command inside the build directory, where ts_vpn will be the name of the image you're creating. You can change the name, but make sure you update it everywhere the image will be referred to:

    docker build -t ts_vpn .

    All being well, you will now have a Docker Image named ts_vpn, (or whatever you chose to name it). It will be stored in your Image Cache, (as if you'd done docker pull whatever-image:latest). You can check it exists by running the following command:

    docker image ls

    .
    2. PREPARE YOUR WIREGUARD CONFIG FILE

    The config file you've downloaded from your VPN provider will look something like this:

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    By default, wg-quick creates routes and rules that conflict with the Tailscale client so you first need to update your Wireguard config file to disable the automatic creation of rules and manually setup the ones you need and that won't conflict with Tailscale.

    The updated Wireguard config file will look like this, (assuming your config file is named wg0.conf)

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    Table = off # stops wg-quick from auto-generating routing tables
    MTU = 1380 # seems to give better network speed when running inside a docker container
    
    PostUp = wg set wg0 fwmark 51820 # copied from wg-quck. Interface name should match config file name
    PostUp = ip -4 route add 0.0.0.0/0 dev wg0 table 51820 # copied from wg-quick
    PostUp = ip -4 rule add not fwmark 51820 table 51820 pref 32765 # important - I believe this sets the preference of the wireguard tunnel to be higher (i.e. lower priority) than tailscale, allowing both to co-exist
    PostUp = ip -4 rule add table main suppress_prefixlength 0 # copied from wg-quick
    PostUp = sysctl -q net.ipv4.conf.all.src_valid_mark=1 # copied from wg-quick
    PreDown = ip -4 rule del table 51820 # copied from wg-quick
    PreDown = ip -4 rule del table main suppress_prefixlength 0 # copied from wg-quick
    
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    If your config file is named something other than "wg0.conf" you will need to update the rules to match the name of your config file, changing "wg0" to the name of your config file without the .conf extension.

    For example, if your config file is named "city-country.conf" then you'd need to update these two rules to match the filename like this:

        PostUp = wg set city-country fwmark 51820 # copied from wg-quck. Interface name should match config file name
        PostUp = ip -4 route add 0.0.0.0/0 dev city-country table 51820 # copied from wg-quick
    

    You can test that your modified config file still works and connects to your VPN provider with the new rules by testing it with wg-quick again:

    wg-quick up <path-to-config-file>

    Assuming you can still connect to the VPN with your config file, you can now use Docker Compose to launch the container and connect to both your VPN and Tailscale.

    .
    3. LAUNCH YOUR NEW CONTAINER WITH DOCKER COMPOSE

    Create a new directory and copy your Wireguard config file into it. Then create a new file named docker-compose.yaml and copy the following content into it:

    services:
      ts_vpn:
        image: ts_vpn
        container_name: ts_vpn
        privileged: True
        cap_add:
          - net_admin
          - sys_module
        volumes:
          - ./ts_data:/var/lib/tailscale
          - ./wg0.conf:/etc/wireguard/wg0.conf
        environment:
          - TS_EXTRA_ARGS=--hostname TS_VPN --authkey=<TAILSCALE-AUTH-KEY> --advertise-exit-node=true --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True
          - WG_CONFIG=/etc/wireguard/wg0.conf
        sysctls:
          # Required by Tailscale
          - net.ipv4.ip_forward=1
          - net.ipv6.conf.all.forwarding=1
          # Required by WireGuard
          - net.ipv4.conf.all.src_valid_mark=1
    

    NB: if your Wireguard config file is named something other than wg0.conf, you should update the docker-compose.yaml to mount the correct file.

    You will also need to edit the - TS_EXTRA_ARGS section to add a reusable auth key with a long expiry period so that you can relaunch the container whenever needed. The following elements of the section are optional.

    --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True

    I use Headscale so I need to add the --login-server option. I use Tailscale ACLs so I've added the --advertise-tags option and I have my own DNS servers so I'm using the --accept-dns_option. Depending on your setup you may or may not need those extra options.

    However, regardless of your setup you will definitely need to include the --authkey and --advertise-exit-node options to get this working. I'd also recommend using the --hostname option to give the container a memorable name.

    Assuming you've copied the Wireguard config file and the docker-compose.yaml into the directory, you should have a directory structure that looks like this:

        ts_vpn
        |
        |-- docker-compose.yaml
        |-- wg0.conf
    

    You can then run the following command from inside the directory to launch the container:

    docker compose up -d

    You should then check your Tailscale coordination server to make sure the new container has joined your Tailnet and allow it to serve as an Exit Node.

    You can also test whether the Wireguard VPN is working by running the following command:

    docker exec <CONTAINER-NAME> curl ipinfo.io

    If everything has worked as intended then you should now be able to connect to the Exit Node and route your traffic over the VPN.

    You can also repeat Steps 2 and 3 with new Wireguard config files to create multiple VPN Exit Nodes using the same image created in Step 1, like this:

    VPNs

    I wouldn't recommend trying this unless you're familiar with Docker, Wireguard and Tailscale because you may need to debug things and I can't guarantee I will be able to help with it, but hopefully this will help someone out in future.

    Thanked by 2ScreenReader 0xC7
  • @CloudHopper said:
    I'm a bit late to this, but I came across this thread whilst trying to figure out a solution for this myself and I made a mental note that I'd leave a comment if I ever figured it out.

    It turns out there's at least two ways of doing this, although the best known solution is bloated, (requires two Docker containers), and gives dire performance, (maxes out at about ~30Mbps). You can read how to set it up here: https://lemmy.world/post/7281194

    However, the solution I've found that really works well is to build a single Docker container with both Tailscale and Wireguard clients installed, as described in this Github post: https://github.com/juanfont/headscale/issues/1545#issuecomment-2267081979

    To make it work you need to be able to download Wireguard config files from your VPN provider and run them using wg-quick, which you can test by installing Wireguard and running:

    wg-quick up <path-to-config-file>

    Assuming you're able to connect your Wireguard tunnel, you can follow the steps below to setup an Exit Node that routes its traffic through your VPN.

    .
    1. BUILD THE DOCKER CONTAINER

    To build the Docker Image you need to create a directory named build, (or whatever else you want to call it), and in that directory you need to create a file named Dockerfile and copy this content into it:

    # Base image
    FROM debian:bullseye-slim
    
    # Install necessary packages
    RUN apt-get update && apt-get install -y \
            curl \
            iproute2 \
            iptables \
            wireguard-tools \
            bash \
            procps \
            openresolv \
            && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    # Install additional packages
    RUN curl -fsSL https://tailscale.com/install.sh | sh
    
    # Copy and set the entrypoint script into the container if active
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    In the same build directory you also need to create a file named entrypoint.sh and copy the contents of this bash script into it:

    #!/bin/bash
    
    # Check if necessary environment variables are set
    : "${TS_EXTRA_ARGS:?Environment variable TS_EXTRA_ARGS must be set}"
    : "${WG_CONFIG:?Environment variable WG_CONFIG must be set}"
    
    # Start Tailscale in the background
    echo "Starting tailscaled"
    tailscaled &
    TAILSCALE_PID=$!
    
    # Function to check if tailscaled is running
    check_tailscaled() {
        pgrep tailscaled > /dev/null
    }
    
    # Wait for tailscaled to start up
    echo "Waiting for tailscaled to initialize..."
    for i in {1..10}; do
        if check_tailscaled; then
            echo "tailscaled is running"
            break
        fi
        sleep 2
    done
    
    # Check again if tailscaled is running after waiting
    if ! check_tailscaled; then
        echo "tailscaled failed to start. Exiting."
        tail -f /dev/null  # Keeps the container running for debugging
        exit 1
    fi
    
    # Authenticate with Tailscale
    echo "Running Tailscale up"
    tailscale up $TS_EXTRA_ARGS
    
    # Check if Tailscale is connected
    if ! tailscale status | grep -q "Tailscale is stopped"; then
        echo "Tailscale is connected"
        # Ensure WireGuard is up and running
        if [ -f $WG_CONFIG ]; then
            echo "Starting WireGuard"
            wg-quick up "$WG_CONFIG"
        else
            echo "WireGuard configuration file not found!"
        fi
        tail -f /dev/null  # Keeps the container running for debugging
    else
        echo "Tailscale failed to connect. Exiting."
        tailscale status # Optionally: Print Tailscale logs for further debugging
        tail -f /dev/null  # Keeps the container running for debugging
    fi
    

    This should leave you with a directory structure that looks like this:

        build
        |
        |-- Dockerfile
        |-- entrypoint.sh
    

    You then need to build the Docker Image, which you can do by running this command inside the build directory, where ts_vpn will be the name of the image you're creating. You can change the name, but make sure you update it everywhere the image will be referred to:

    docker build -t ts_vpn .

    All being well, you will now have a Docker Image named ts_vpn, (or whatever you chose to name it). It will be stored in your Image Cache, (as if you'd done docker pull whatever-image:latest). You can check it exists by running the following command:

    docker image ls

    .
    2. PREPARE YOUR WIREGUARD CONFIG FILE

    The config file you've downloaded from your VPN provider will look something like this:

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    By default, wg-quick creates routes and rules that conflict with the Tailscale client so you first need to update your Wireguard config file to disable the automatic creation of rules and manually setup the ones you need and that won't conflict with Tailscale.

    The updated Wireguard config file will look like this, (assuming your config file is named wg0.conf)

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    Table = off # stops wg-quick from auto-generating routing tables
    MTU = 1380 # seems to give better network speed when running inside a docker container
    
    PostUp = wg set wg0 fwmark 51820 # copied from wg-quck. Interface name should match config file name
    PostUp = ip -4 route add 0.0.0.0/0 dev wg0 table 51820 # copied from wg-quick
    PostUp = ip -4 rule add not fwmark 51820 table 51820 pref 32765 # important - I believe this sets the preference of the wireguard tunnel to be higher (i.e. lower priority) than tailscale, allowing both to co-exist
    PostUp = ip -4 rule add table main suppress_prefixlength 0 # copied from wg-quick
    PostUp = sysctl -q net.ipv4.conf.all.src_valid_mark=1 # copied from wg-quick
    PreDown = ip -4 rule del table 51820 # copied from wg-quick
    PreDown = ip -4 rule del table main suppress_prefixlength 0 # copied from wg-quick
      
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    If your config file is named something other than "wg0.conf" you will need to update the rules to match the name of your config file, changing "wg0" to the name of your config file without the .conf extension.

    For example, if your config file is named "city-country.conf" then you'd need to update these two rules to match the filename like this:

        PostUp = wg set city-country fwmark 51820 # copied from wg-quck. Interface name should match config file name
        PostUp = ip -4 route add 0.0.0.0/0 dev city-country table 51820 # copied from wg-quick
    

    You can test that your modified config file still works and connects to your VPN provider with the new rules by testing it with wg-quick again:

    wg-quick up <path-to-config-file>

    Assuming you can still connect to the VPN with your config file, you can now use Docker Compose to launch the container and connect to both your VPN and Tailscale.

    .
    3. LAUNCH YOUR NEW CONTAINER WITH DOCKER COMPOSE

    Create a new directory and copy your Wireguard config file into it. Then create a new file named docker-compose.yaml and copy the following content into it:

    services:
      ts_vpn:
        image: ts_vpn
        container_name: ts_vpn
        privileged: True
        cap_add:
          - net_admin
          - sys_module
        volumes:
          - ./ts_data:/var/lib/tailscale
          - ./wg0.conf:/etc/wireguard/wg0.conf
        environment:
          - TS_EXTRA_ARGS=--hostname TS_VPN --authkey=<TAILSCALE-AUTH-KEY> --advertise-exit-node=true --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True
          - WG_CONFIG=/etc/wireguard/wg0.conf
        sysctls:
          # Required by Tailscale
          - net.ipv4.ip_forward=1
          - net.ipv6.conf.all.forwarding=1
          # Required by WireGuard
          - net.ipv4.conf.all.src_valid_mark=1
    

    NB: if your Wireguard config file is named something other than wg0.conf, you should update the docker-compose.yaml to mount the correct file.

    You will also need to edit the - TS_EXTRA_ARGS section to add a reusable auth key with a long expiry period so that you can relaunch the container whenever needed. The following elements of the section are optional.

    --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True

    I use Headscale so I need to add the --login-server option. I use Tailscale ACLs so I've added the --advertise-tags option and I have my own DNS servers so I'm using the --accept-dns_option. Depending on your setup you may or may not need those extra options.

    However, regardless of your setup you will definitely need to include the --authkey and --advertise-exit-node options to get this working. I'd also recommend using the --hostname option to give the container a memorable name.

    Assuming you've copied the Wireguard config file and the docker-compose.yaml into the directory, you should have a directory structure that looks like this:

        ts_vpn
        |
        |-- docker-compose.yaml
        |-- wg0.conf
    

    You can then run the following command from inside the directory to launch the container:

    docker compose up -d

    You should then check your Tailscale coordination server to make sure the new container has joined your Tailnet and allow it to serve as an Exit Node.

    You can also test whether the Wireguard VPN is working by running the following command:

    docker exec <CONTAINER-NAME> curl ipinfo.io

    If everything has worked as intended then you should now be able to connect to the Exit Node and route your traffic over the VPN.

    You can also repeat Steps 2 and 3 with new Wireguard config files to create multiple VPN Exit Nodes using the same image created in Step 1, like this:

    VPNs

    I wouldn't recommend trying this unless you're familiar with Docker, Wireguard and Tailscale because you may need to debug things and I can't guarantee I will be able to help with it, but hopefully this will help someone out in future.

    Thanks for the detailed post! In my situation, I need to switch locations really frequently when I'm doing bug bounty hunting, so setting up Wireguard in multiple locations would take way too much time and just wouldn't be practical.

    I ended up buying the Mullvad VPN addon for Tailscale and replacing my other VPNs with it, and it works really well. I use Mullvad nodes as exit nodes for Tailscale, which means I can switch between nodes without any network interruptions.

  • emperoremperor Member

    I have GL-MT3000 (Beryl AX ) router and this can be done easy in setting.. You can enable tailscale in router, also in latest beta firmware they added mutli vpn connections so you can enable more vpns and choose which lan clients to use them. Pretty much you can do anything. Great little router


  • @vitobotta said:

    @CloudHopper said:
    I'm a bit late to this, but I came across this thread whilst trying to figure out a solution for this myself and I made a mental note that I'd leave a comment if I ever figured it out.

    It turns out there's at least two ways of doing this, although the best known solution is bloated, (requires two Docker containers), and gives dire performance, (maxes out at about ~30Mbps). You can read how to set it up here: https://lemmy.world/post/7281194

    However, the solution I've found that really works well is to build a single Docker container with both Tailscale and Wireguard clients installed, as described in this Github post: https://github.com/juanfont/headscale/issues/1545#issuecomment-2267081979

    To make it work you need to be able to download Wireguard config files from your VPN provider and run them using wg-quick, which you can test by installing Wireguard and running:

    wg-quick up <path-to-config-file>

    Assuming you're able to connect your Wireguard tunnel, you can follow the steps below to setup an Exit Node that routes its traffic through your VPN.

    .
    1. BUILD THE DOCKER CONTAINER

    To build the Docker Image you need to create a directory named build, (or whatever else you want to call it), and in that directory you need to create a file named Dockerfile and copy this content into it:

    # Base image
    FROM debian:bullseye-slim
    
    # Install necessary packages
    RUN apt-get update && apt-get install -y \
            curl \
            iproute2 \
            iptables \
            wireguard-tools \
            bash \
            procps \
            openresolv \
            && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    # Install additional packages
    RUN curl -fsSL https://tailscale.com/install.sh | sh
    
    # Copy and set the entrypoint script into the container if active
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    In the same build directory you also need to create a file named entrypoint.sh and copy the contents of this bash script into it:

    #!/bin/bash
    
    # Check if necessary environment variables are set
    : "${TS_EXTRA_ARGS:?Environment variable TS_EXTRA_ARGS must be set}"
    : "${WG_CONFIG:?Environment variable WG_CONFIG must be set}"
    
    # Start Tailscale in the background
    echo "Starting tailscaled"
    tailscaled &
    TAILSCALE_PID=$!
    
    # Function to check if tailscaled is running
    check_tailscaled() {
        pgrep tailscaled > /dev/null
    }
    
    # Wait for tailscaled to start up
    echo "Waiting for tailscaled to initialize..."
    for i in {1..10}; do
        if check_tailscaled; then
            echo "tailscaled is running"
            break
        fi
        sleep 2
    done
    
    # Check again if tailscaled is running after waiting
    if ! check_tailscaled; then
        echo "tailscaled failed to start. Exiting."
        tail -f /dev/null  # Keeps the container running for debugging
        exit 1
    fi
    
    # Authenticate with Tailscale
    echo "Running Tailscale up"
    tailscale up $TS_EXTRA_ARGS
    
    # Check if Tailscale is connected
    if ! tailscale status | grep -q "Tailscale is stopped"; then
        echo "Tailscale is connected"
        # Ensure WireGuard is up and running
        if [ -f $WG_CONFIG ]; then
            echo "Starting WireGuard"
            wg-quick up "$WG_CONFIG"
        else
            echo "WireGuard configuration file not found!"
        fi
        tail -f /dev/null  # Keeps the container running for debugging
    else
        echo "Tailscale failed to connect. Exiting."
        tailscale status # Optionally: Print Tailscale logs for further debugging
        tail -f /dev/null  # Keeps the container running for debugging
    fi
    

    This should leave you with a directory structure that looks like this:

        build
        |
        |-- Dockerfile
        |-- entrypoint.sh
    

    You then need to build the Docker Image, which you can do by running this command inside the build directory, where ts_vpn will be the name of the image you're creating. You can change the name, but make sure you update it everywhere the image will be referred to:

    docker build -t ts_vpn .

    All being well, you will now have a Docker Image named ts_vpn, (or whatever you chose to name it). It will be stored in your Image Cache, (as if you'd done docker pull whatever-image:latest). You can check it exists by running the following command:

    docker image ls

    .
    2. PREPARE YOUR WIREGUARD CONFIG FILE

    The config file you've downloaded from your VPN provider will look something like this:

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    By default, wg-quick creates routes and rules that conflict with the Tailscale client so you first need to update your Wireguard config file to disable the automatic creation of rules and manually setup the ones you need and that won't conflict with Tailscale.

    The updated Wireguard config file will look like this, (assuming your config file is named wg0.conf)

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    Table = off # stops wg-quick from auto-generating routing tables
    MTU = 1380 # seems to give better network speed when running inside a docker container
    
    PostUp = wg set wg0 fwmark 51820 # copied from wg-quck. Interface name should match config file name
    PostUp = ip -4 route add 0.0.0.0/0 dev wg0 table 51820 # copied from wg-quick
    PostUp = ip -4 rule add not fwmark 51820 table 51820 pref 32765 # important - I believe this sets the preference of the wireguard tunnel to be higher (i.e. lower priority) than tailscale, allowing both to co-exist
    PostUp = ip -4 rule add table main suppress_prefixlength 0 # copied from wg-quick
    PostUp = sysctl -q net.ipv4.conf.all.src_valid_mark=1 # copied from wg-quick
    PreDown = ip -4 rule del table 51820 # copied from wg-quick
    PreDown = ip -4 rule del table main suppress_prefixlength 0 # copied from wg-quick
      
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    If your config file is named something other than "wg0.conf" you will need to update the rules to match the name of your config file, changing "wg0" to the name of your config file without the .conf extension.

    For example, if your config file is named "city-country.conf" then you'd need to update these two rules to match the filename like this:

        PostUp = wg set city-country fwmark 51820 # copied from wg-quck. Interface name should match config file name
        PostUp = ip -4 route add 0.0.0.0/0 dev city-country table 51820 # copied from wg-quick
    

    You can test that your modified config file still works and connects to your VPN provider with the new rules by testing it with wg-quick again:

    wg-quick up <path-to-config-file>

    Assuming you can still connect to the VPN with your config file, you can now use Docker Compose to launch the container and connect to both your VPN and Tailscale.

    .
    3. LAUNCH YOUR NEW CONTAINER WITH DOCKER COMPOSE

    Create a new directory and copy your Wireguard config file into it. Then create a new file named docker-compose.yaml and copy the following content into it:

    services:
      ts_vpn:
        image: ts_vpn
        container_name: ts_vpn
        privileged: True
        cap_add:
          - net_admin
          - sys_module
        volumes:
          - ./ts_data:/var/lib/tailscale
          - ./wg0.conf:/etc/wireguard/wg0.conf
        environment:
          - TS_EXTRA_ARGS=--hostname TS_VPN --authkey=<TAILSCALE-AUTH-KEY> --advertise-exit-node=true --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True
          - WG_CONFIG=/etc/wireguard/wg0.conf
        sysctls:
          # Required by Tailscale
          - net.ipv4.ip_forward=1
          - net.ipv6.conf.all.forwarding=1
          # Required by WireGuard
          - net.ipv4.conf.all.src_valid_mark=1
    

    NB: if your Wireguard config file is named something other than wg0.conf, you should update the docker-compose.yaml to mount the correct file.

    You will also need to edit the - TS_EXTRA_ARGS section to add a reusable auth key with a long expiry period so that you can relaunch the container whenever needed. The following elements of the section are optional.

    --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True

    I use Headscale so I need to add the --login-server option. I use Tailscale ACLs so I've added the --advertise-tags option and I have my own DNS servers so I'm using the --accept-dns_option. Depending on your setup you may or may not need those extra options.

    However, regardless of your setup you will definitely need to include the --authkey and --advertise-exit-node options to get this working. I'd also recommend using the --hostname option to give the container a memorable name.

    Assuming you've copied the Wireguard config file and the docker-compose.yaml into the directory, you should have a directory structure that looks like this:

        ts_vpn
        |
        |-- docker-compose.yaml
        |-- wg0.conf
    

    You can then run the following command from inside the directory to launch the container:

    docker compose up -d

    You should then check your Tailscale coordination server to make sure the new container has joined your Tailnet and allow it to serve as an Exit Node.

    You can also test whether the Wireguard VPN is working by running the following command:

    docker exec <CONTAINER-NAME> curl ipinfo.io

    If everything has worked as intended then you should now be able to connect to the Exit Node and route your traffic over the VPN.

    You can also repeat Steps 2 and 3 with new Wireguard config files to create multiple VPN Exit Nodes using the same image created in Step 1, like this:

    VPNs

    I wouldn't recommend trying this unless you're familiar with Docker, Wireguard and Tailscale because you may need to debug things and I can't guarantee I will be able to help with it, but hopefully this will help someone out in future.

    Thanks for the detailed post! In my situation, I need to switch locations really frequently when I'm doing bug bounty hunting, so setting up Wireguard in multiple locations would take way too much time and just wouldn't be practical.

    Well, it took me about 2 hours to setup 25 locations, (although it would have been quicker if I'd scripted it rather than doing each manually), but it's a one time job and now they're setup I can switch locations instantly by choosing the Exit Nodes in the same way you would with Mullvad.

  • @CloudHopper said:

    @vitobotta said:

    @CloudHopper said:
    I'm a bit late to this, but I came across this thread whilst trying to figure out a solution for this myself and I made a mental note that I'd leave a comment if I ever figured it out.

    It turns out there's at least two ways of doing this, although the best known solution is bloated, (requires two Docker containers), and gives dire performance, (maxes out at about ~30Mbps). You can read how to set it up here: https://lemmy.world/post/7281194

    However, the solution I've found that really works well is to build a single Docker container with both Tailscale and Wireguard clients installed, as described in this Github post: https://github.com/juanfont/headscale/issues/1545#issuecomment-2267081979

    To make it work you need to be able to download Wireguard config files from your VPN provider and run them using wg-quick, which you can test by installing Wireguard and running:

    wg-quick up <path-to-config-file>

    Assuming you're able to connect your Wireguard tunnel, you can follow the steps below to setup an Exit Node that routes its traffic through your VPN.

    .
    1. BUILD THE DOCKER CONTAINER

    To build the Docker Image you need to create a directory named build, (or whatever else you want to call it), and in that directory you need to create a file named Dockerfile and copy this content into it:

    # Base image
    FROM debian:bullseye-slim
    
    # Install necessary packages
    RUN apt-get update && apt-get install -y \
            curl \
            iproute2 \
            iptables \
            wireguard-tools \
            bash \
            procps \
            openresolv \
            && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    # Install additional packages
    RUN curl -fsSL https://tailscale.com/install.sh | sh
    
    # Copy and set the entrypoint script into the container if active
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    In the same build directory you also need to create a file named entrypoint.sh and copy the contents of this bash script into it:

    #!/bin/bash
    
    # Check if necessary environment variables are set
    : "${TS_EXTRA_ARGS:?Environment variable TS_EXTRA_ARGS must be set}"
    : "${WG_CONFIG:?Environment variable WG_CONFIG must be set}"
    
    # Start Tailscale in the background
    echo "Starting tailscaled"
    tailscaled &
    TAILSCALE_PID=$!
    
    # Function to check if tailscaled is running
    check_tailscaled() {
        pgrep tailscaled > /dev/null
    }
    
    # Wait for tailscaled to start up
    echo "Waiting for tailscaled to initialize..."
    for i in {1..10}; do
        if check_tailscaled; then
            echo "tailscaled is running"
            break
        fi
        sleep 2
    done
    
    # Check again if tailscaled is running after waiting
    if ! check_tailscaled; then
        echo "tailscaled failed to start. Exiting."
        tail -f /dev/null  # Keeps the container running for debugging
        exit 1
    fi
    
    # Authenticate with Tailscale
    echo "Running Tailscale up"
    tailscale up $TS_EXTRA_ARGS
    
    # Check if Tailscale is connected
    if ! tailscale status | grep -q "Tailscale is stopped"; then
        echo "Tailscale is connected"
        # Ensure WireGuard is up and running
        if [ -f $WG_CONFIG ]; then
            echo "Starting WireGuard"
            wg-quick up "$WG_CONFIG"
        else
            echo "WireGuard configuration file not found!"
        fi
        tail -f /dev/null  # Keeps the container running for debugging
    else
        echo "Tailscale failed to connect. Exiting."
        tailscale status # Optionally: Print Tailscale logs for further debugging
        tail -f /dev/null  # Keeps the container running for debugging
    fi
    

    This should leave you with a directory structure that looks like this:

        build
        |
        |-- Dockerfile
        |-- entrypoint.sh
    

    You then need to build the Docker Image, which you can do by running this command inside the build directory, where ts_vpn will be the name of the image you're creating. You can change the name, but make sure you update it everywhere the image will be referred to:

    docker build -t ts_vpn .

    All being well, you will now have a Docker Image named ts_vpn, (or whatever you chose to name it). It will be stored in your Image Cache, (as if you'd done docker pull whatever-image:latest). You can check it exists by running the following command:

    docker image ls

    .
    2. PREPARE YOUR WIREGUARD CONFIG FILE

    The config file you've downloaded from your VPN provider will look something like this:

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    By default, wg-quick creates routes and rules that conflict with the Tailscale client so you first need to update your Wireguard config file to disable the automatic creation of rules and manually setup the ones you need and that won't conflict with Tailscale.

    The updated Wireguard config file will look like this, (assuming your config file is named wg0.conf)

    [Interface]
    Address = IP.Address/CIDR
    PrivateKey = <PRIVATE-KEY>
    
    Table = off # stops wg-quick from auto-generating routing tables
    MTU = 1380 # seems to give better network speed when running inside a docker container
    
    PostUp = wg set wg0 fwmark 51820 # copied from wg-quck. Interface name should match config file name
    PostUp = ip -4 route add 0.0.0.0/0 dev wg0 table 51820 # copied from wg-quick
    PostUp = ip -4 rule add not fwmark 51820 table 51820 pref 32765 # important - I believe this sets the preference of the wireguard tunnel to be higher (i.e. lower priority) than tailscale, allowing both to co-exist
    PostUp = ip -4 rule add table main suppress_prefixlength 0 # copied from wg-quick
    PostUp = sysctl -q net.ipv4.conf.all.src_valid_mark=1 # copied from wg-quick
    PreDown = ip -4 rule del table 51820 # copied from wg-quick
    PreDown = ip -4 rule del table main suppress_prefixlength 0 # copied from wg-quick
      
    [Peer]
    PublicKey = <PUBLIC-KEY>
    AllowedIPs = 0.0.0.0/0
    Endpoint = city.country.vpn.com:51820
    PersistentKeepalive = 25
    

    If your config file is named something other than "wg0.conf" you will need to update the rules to match the name of your config file, changing "wg0" to the name of your config file without the .conf extension.

    For example, if your config file is named "city-country.conf" then you'd need to update these two rules to match the filename like this:

        PostUp = wg set city-country fwmark 51820 # copied from wg-quck. Interface name should match config file name
        PostUp = ip -4 route add 0.0.0.0/0 dev city-country table 51820 # copied from wg-quick
    

    You can test that your modified config file still works and connects to your VPN provider with the new rules by testing it with wg-quick again:

    wg-quick up <path-to-config-file>

    Assuming you can still connect to the VPN with your config file, you can now use Docker Compose to launch the container and connect to both your VPN and Tailscale.

    .
    3. LAUNCH YOUR NEW CONTAINER WITH DOCKER COMPOSE

    Create a new directory and copy your Wireguard config file into it. Then create a new file named docker-compose.yaml and copy the following content into it:

    services:
      ts_vpn:
        image: ts_vpn
        container_name: ts_vpn
        privileged: True
        cap_add:
          - net_admin
          - sys_module
        volumes:
          - ./ts_data:/var/lib/tailscale
          - ./wg0.conf:/etc/wireguard/wg0.conf
        environment:
          - TS_EXTRA_ARGS=--hostname TS_VPN --authkey=<TAILSCALE-AUTH-KEY> --advertise-exit-node=true --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True
          - WG_CONFIG=/etc/wireguard/wg0.conf
        sysctls:
          # Required by Tailscale
          - net.ipv4.ip_forward=1
          - net.ipv6.conf.all.forwarding=1
          # Required by WireGuard
          - net.ipv4.conf.all.src_valid_mark=1
    

    NB: if your Wireguard config file is named something other than wg0.conf, you should update the docker-compose.yaml to mount the correct file.

    You will also need to edit the - TS_EXTRA_ARGS section to add a reusable auth key with a long expiry period so that you can relaunch the container whenever needed. The following elements of the section are optional.

    --advertise-tags=tag:vpn --login-server=<VPN-SERVER-DOMAIN> --accept-dns=True

    I use Headscale so I need to add the --login-server option. I use Tailscale ACLs so I've added the --advertise-tags option and I have my own DNS servers so I'm using the --accept-dns_option. Depending on your setup you may or may not need those extra options.

    However, regardless of your setup you will definitely need to include the --authkey and --advertise-exit-node options to get this working. I'd also recommend using the --hostname option to give the container a memorable name.

    Assuming you've copied the Wireguard config file and the docker-compose.yaml into the directory, you should have a directory structure that looks like this:

        ts_vpn
        |
        |-- docker-compose.yaml
        |-- wg0.conf
    

    You can then run the following command from inside the directory to launch the container:

    docker compose up -d

    You should then check your Tailscale coordination server to make sure the new container has joined your Tailnet and allow it to serve as an Exit Node.

    You can also test whether the Wireguard VPN is working by running the following command:

    docker exec <CONTAINER-NAME> curl ipinfo.io

    If everything has worked as intended then you should now be able to connect to the Exit Node and route your traffic over the VPN.

    You can also repeat Steps 2 and 3 with new Wireguard config files to create multiple VPN Exit Nodes using the same image created in Step 1, like this:

    VPNs

    I wouldn't recommend trying this unless you're familiar with Docker, Wireguard and Tailscale because you may need to debug things and I can't guarantee I will be able to help with it, but hopefully this will help someone out in future.

    Thanks for the detailed post! In my situation, I need to switch locations really frequently when I'm doing bug bounty hunting, so setting up Wireguard in multiple locations would take way too much time and just wouldn't be practical.

    Well, it took me about 2 hours to setup 25 locations, (although it would have been quicker if I'd scripted it rather than doing each manually), but it's a one time job and now they're setup I can switch locations instantly by choosing the Exit Nodes in the same way you would with Mullvad.

    It only took me about 5 seconds to turn on Mullvad through Tailscale, and I instantly had tons of different server nodes I could use. Plus it's super affordable at just $5 a month :)

Sign In or Register to comment.