MintFlow
MintFlow Menu
Get MintFlow app

Access a Tailscale network from iOS with MintFlow Route via VPN

Use MintFlow NetStack's free WireGuard and Route via VPN features to reach a Tailscale tailnet through a SOCKS5 proxy, with an iptables SNAT alternative for Linux gateways.

MintFlow NetStack can route selected traffic through an HTTP or SOCKS proxy, and that proxy can itself be reached over a WireGuard peer. This makes it possible to access a Tailscale network from iOS without installing a separate Tailscale client on the phone.

The useful part is that this setup only needs MintFlow’s free networking features:

  • a WireGuard interface and peer in MintFlow;
  • a SOCKS5 proxy reachable over that WireGuard link;
  • Route via VPN enabled on that proxy;
  • a route for the Tailscale CGNAT range, 100.64.0.0/10, pointing to the proxy.

Topology

The gateway server joins two networks:

  • the WireGuard network between MintFlow and the server, for example 10.7.0.0/24;
  • the Tailscale network, where nodes normally use addresses from 100.64.0.0/10.

MintFlow sends traffic for 100.64.0.0/10 to a SOCKS5 proxy on the server’s WireGuard address. The proxy then sends the traffic into the tailnet.

For example:

iPhone / MintFlow
  WireGuard IP: 10.7.0.2
        |
        | WireGuard
        v
Linux gateway
  WireGuard IP: 10.7.0.1
  tailscaled userspace SOCKS5: 10.7.0.1:1055
        |
        v
Tailscale tailnet
  Routes: 100.64.0.0/10

Method 1: tailscaled userspace SOCKS5

This method is the simplest because the gateway does not need to forward packets at the Linux kernel layer. Tailscale documents userspace networking mode with a SOCKS5 server for environments where a normal TUN device is not available, and the same mode works well as a bridge for MintFlow’s Route via VPN feature.

On the Linux gateway, bring up WireGuard first. The exact WireGuard configuration depends on your server, but the server side usually looks like this:

[Interface]
Address = 10.7.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

[Peer]
PublicKey = IPHONE_PUBLIC_KEY
AllowedIPs = 10.7.0.2/32

Then start tailscaled in userspace networking mode and bind the SOCKS5 listener to the WireGuard address.

Use a separate state directory and Unix control socket so this gateway instance does not conflict with the default system Tailscale daemon:

sudo mkdir -p /var/lib/tailscale-mintflow /run/tailscale-mintflow

sudo tailscaled \
  --tun=userspace-networking \
  --socks5-server=10.7.0.1:1055 \
  --state=/var/lib/tailscale-mintflow/tailscaled.state \
  --socket=/run/tailscale-mintflow/tailscaled.sock

In another shell, authenticate the gateway into your tailnet:

sudo tailscale --socket=/run/tailscale-mintflow/tailscaled.sock up

If you prefer a systemd service, put the same tailscaled flags into an override for your Tailscale daemon, or run a separate service dedicated to this gateway role.

In MintFlow NetStack:

  1. Add a WireGuard interface that connects to the gateway.
  2. Add the WireGuard peer and routing rules needed to reach the gateway’s WireGuard IP, such as 10.7.0.1/32.
  3. Add a SOCKS5 proxy with server 10.7.0.1 and port 1055.
  4. Enable Route via VPN on that SOCKS5 proxy.
  5. Add a route for 100.64.0.0/10 and point it to the SOCKS5 proxy.

After that, connections from iOS to Tailscale IPs such as 100.x.y.z go through MintFlow, over WireGuard to the gateway, then through the userspace Tailscale SOCKS5 server into the tailnet.

Method 2: normal Tailscale client with Linux SNAT

You can also run the regular Tailscale client on the gateway and let Linux forward packets between WireGuard and tailscale0. In this mode MintFlow does not need a SOCKS5 proxy. It sends 100.64.0.0/10 over the WireGuard tunnel and the gateway uses kernel routing plus SNAT.

Install and authenticate Tailscale normally:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Enable IPv4 forwarding:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-mintflow-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-mintflow-tailscale.conf

Add forwarding and masquerade rules. Replace wg0 with your WireGuard interface name if different:

sudo iptables -A FORWARD -i wg0 -o tailscale0 -d 100.64.0.0/10 -j ACCEPT
sudo iptables -A FORWARD -i tailscale0 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 10.7.0.0/24 -d 100.64.0.0/10 -o tailscale0 -j MASQUERADE

With nftables, the same idea is:

sudo nft add table inet mintflow
sudo nft add chain inet mintflow forward '{ type filter hook forward priority 0; policy drop; }'
sudo nft add rule inet mintflow forward iifname "wg0" oifname "tailscale0" ip daddr 100.64.0.0/10 accept
sudo nft add rule inet mintflow forward iifname "tailscale0" oifname "wg0" ct state established,related accept

sudo nft add table ip mintflow_nat
sudo nft add chain ip mintflow_nat postrouting '{ type nat hook postrouting priority 100; policy accept; }'
sudo nft add rule ip mintflow_nat postrouting ip saddr 10.7.0.0/24 ip daddr 100.64.0.0/10 oifname "tailscale0" masquerade

In MintFlow NetStack, configure the WireGuard peer and route 100.64.0.0/10 directly through the WireGuard peer instead of through a SOCKS5 proxy.

Which method should you choose?

Use the userspace SOCKS5 method if you want a minimal gateway and want to keep the route control inside MintFlow’s proxy routing model. It is also a good fit when you only need TCP-style application access through a SOCKS5 proxy.

Use the regular Tailscale plus SNAT method if you want packet forwarding at the gateway and do not want to expose a SOCKS5 service. This is closer to a traditional router setup, but it requires Linux forwarding and firewall/NAT rules.

Notes

  • Bind the SOCKS5 listener to the WireGuard address, not to a public interface.
  • Restrict your firewall so only the WireGuard peer can reach the SOCKS5 port.
  • 100.64.0.0/10 is the Tailscale IPv4 address range. If you also need access to advertised subnet routes, add those destination prefixes in MintFlow too.
  • If MagicDNS names are required, configure DNS carefully. Routing raw Tailscale IPs is simpler than routing names.

References: