# Access a Tailscale network from iOS with MintFlow Route via VPN

Canonical: https://galaxnet.dev/mintflow/articles/tailscale-via-wireguard-route-via-vpn/
Language: en-US

Use MintFlow'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 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:

```text
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:

```ini
[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:

```sh
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:

```sh
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:

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:

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

Enable IPv4 forwarding:

```sh
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:

```sh
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:

```sh
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, 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:

- [Tailscale userspace networking mode](https://tailscale.com/docs/concepts/userspace-networking)
- [Tailscale subnet router documentation](https://tailscale.com/docs/features/subnet-routers)


