This guide provides a detailed walkthrough on establishing a high-performance, full-tunnel VPN across your network using Phantun and WireGuard on an OpenWrt-equipped router. This setup is particularly beneficial for environments where UDP traffic faces restrictions, yet a swift VPN solution is necessary for the entire network. Combining Phantun with WireGuard presents the fastest TCP tunneling solution available as of Q1 2024, as far as my knowledge extends. Given the scarcity of comprehensive resources on this topic, this guide aims to fill that gap and assist others in achieving a rapid, unrestricted network connection.
- Understanding the Challenge
- Exploring Solutions
- Guide Prerequisites
- Configuring WireGuard with Phantun on OpenWrt: A Step-by-Step Guide
Imagine you're connected to a public network that enforces strict limitations on UDP traffic, only permitting TCP traffic on ports 80 and 443. This severely hampers many online activities, such as video calls, streaming, and gaming. Additionally, the public nature of the network poses significant privacy and security risks, with potential exposure to traffic snooping. A viable solution to these issues is to route all traffic through a full-tunnel VPN, securing your data and circumventing restrictions by accessing an open network via a secure tunnel.
OpenVPN offers a secure method to tunnel traffic over TCP. By connecting to an OpenVPN server that operates in TCP mode, you can bypass the internet restrictions. However, tunneling over TCP can introduce performance degradation due to TCP's error correction and retransmission mechanisms. This can lead to the "TCP-over-TCP meltdown" phenomenon, where packet loss results in excessive retransmissions, increasing latency, and reducing throughput. For users requiring low latency and high performance, this is far from ideal.
WireGuard stands out as a contemporary, efficient, and secure VPN protocol, superior to OpenVPN in numerous aspects. Its primary limitation, however, is the lack of TCP tunneling support. Enter Phantun, a solution that enables WireGuard to operate over TCP without the drawbacks typically associated with TCP VPNs. Phantun efficiently converts UDP streams into obfuscated TCP streams, capable of bypassing L3 & L4 firewalls/NATs. This method preserves the inherent advantages of UDP, such as out-of-order delivery, avoiding the common pitfalls of UDP over TCP implementations.
This guide assumes the presence of a configured WireGuard and Phantun server on a remote system with open internet access, focusing solely on the client-side configuration within an OpenWrt environment. It is also assumed that you have a capable router with OpenWrt and WireGuard installed via the opkg package manager. My setup involves a Linksys WRT1900ACS router running Divested-WRT, a custom build of OpenWrt (build r25277), but this guide also applies for stock OpenWrt firmware versions. For server-side configuration details, refer to the Usage section in the GitHub repository of Phantun.
Let's dive into setting up WireGuard with Phantun on your OpenWrt router. This guide uses placeholders for various values, so ensure you replace them with your specific details.
- Public IP-address of the Phantun server: 11.22.33.44, TCP port 443
- OpenWrt interface with (restricted) internet access: wan, gateway IP-address 192.168.69.1
- DNS server configured in the WireGuard user .conf file: 1.1.1.1
First, download the latest Phantun client from Phantun's GitHub Releases. For a WRT1900ACS, you'll need phantun_armv7-unknown-linux-musleabihf.zip. Use SCP (such as WinSCP) to transfer the phantun_client binary to /usr/sbin/phantun_client on your router. Ensure it's executable by running chmod +x /usr/sbin/phantun_client.
To have Phantun start automatically with the router, create an init script. SSH into your router and use a text editor (like nano/vi) or cat to create a new file at /etc/init.d/phantun_client. Make it executable and populate it with:
#!/bin/sh /etc/rc.common
START=95 # starts the script later on in the router's boot process
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /usr/sbin/phantun_client --local 127.0.0.1:51820 --remote 11.22.33.44:443 --ipv4-only
procd_set_param stdout 1 # forward stdout of Phantun to logd
procd_set_param stderr 1 # same for stderr
procd_set_param respawn # automatically restart Phantun if it crashes
procd_close_instance
}Then activate the script, either via OpenWrt's web interface (LuCI) at System > Startup > Initscripts, or by executing the command /etc/init.d/phantun_client enable.
Using LuCI
Navigate to Network > Interfaces and add a new interface. Name it wireguard and chose WireGuard VPN as protocol. Then transfer the data from the server's generated WireGuard user .conf file to the correct fields. Modify the following fields.
Under General Settings:
- Private Key: from config
- Public Key: from config, if none, enter a random character here, it will get automatically generated based on the private key
- IP Addresses: from config
Under Advanced Settings:
- MTU: 1428 (maximum supported MTU if interface MTU is 1500, ensure that the server has same MTU)
- Use custom DNS servers: from config, if none, leave empty
Under Firewall Settings:
- Create / Assign firewall-zone: wan
Under Peers: Add a new peer. Then configure the following.
- Description: client name of your choosing
- Public Key: from config
- Preshared Key: from config
- Allowed IPs: from config, should be 0.0.0.0/0 and ::0/0
- Route Allowed IPs: check
- Endpoint Host: 127.0.0.1 (localhost, IP-address of the internal Phantun connection)
- Endpoint Port: 51820
- Persistent Keep Alive: 25 (if behind a NAT)
If your WireGuard user .conf file has a DNS server listed, also add this address to the wan interface to avoid DNS leaking. Edit the wan interface, and under Advanced Settings > Use custom DNS servers, enter the DNS server of your WireGuard config.
Using CLI
Append the following to /etc/config/network. Note that many values are placeholders. See the LuCI section above for more details.
config interface 'wireguard'
option proto 'wireguard'
option private_key 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR'
list addresses '10.0.0.2/24'
option mtu '1428'
list dns '1.1.1.1'
option metric '1'
config wireguard_wireguard
option description 'abcd'
option public_key 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR'
option preshared_key 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR'
list allowed_ips '0.0.0.0/0'
list allowed_ips '::0/0'
option endpoint_host '127.0.0.1'
option endpoint_port '51820'
option persistent_keepalive '25'
option route_allowed_ips '1'And in the same file, append list network 'wireguard under config zone with option name 'wan'. If your WireGuard user .conf file has a DNS server listed, also add this address to the wan interface to avoid DNS leaking. Under config interface 'wan', append list dns '8.8.4.4'.
It's necessary to convert Phantun's physical address (192.168.200.2) to an address compatible with the WAN network, achievable through the use of masquerading.
Using LuCI
Navigate to Network > Firewall and add a new zone. Then configure the following.
Under General Settings:
- Name: phantun
- Input: reject
- Output: reject
- Intra zone forward: accept
- Masquerading: check
- MSS clamping: check
- Allow forward to destination zones: wan
Under Advanced Settings:
- Covered devices: tun0 (Phantun's tunnel)
Using CLI
Append the following to /etc/config/firewall.
config zone
option name 'phantun'
option input 'REJECT'
option output 'REJECT'
option forward 'ACCEPT'
list device 'tun0'
option masq '1'
option mtu_fix '1'
config forwarding
option src 'phantun'
option dest 'wan'Given that we've configured the allowed IPs as 0.0.0.0/0 and ::0/0 to route all internet traffic (or traffic to a broad range of networks) through the WireGuard tunnel, it's crucial to set up a specific route to the public IP of the Phantun server. Without this, OpenWrt might inadvertently route the Phantun tunnel's traffic through the WireGuard tunnel, leading to a recursive tunneling scenario.
Using LuCI
Navigate to Network > Routing > Static IPv4 Routes and add a new route. Then configure the following.
- Interface: wan
- Route type: unicast
- Target: 11.22.33.44/32
- Gateway: 192.168.69.1
Using CLI
Use the command ip route add 11.22.33.44 via 192.168.69.1 dev wan.
Then you can view the routes with the ip route command.
In my OpenWrt setup, I encountered an issue where, upon reboot, the routing table didn't update as expected. Instead of directing traffic through the wireguard interface, it persisted in routing through the wan interface. To address this and ensure lan traffic is no longer routed via the wan interface, we need to create a new firewall zone and set gateway metrics. The zones are designed to restrict lan traffic exclusively to WireGuard, while the gateway metrics play a crucial role in correcting the routing table. Moreover, this setup allows OpenWrt to maintain wan interface access for crucial NTP-server synchronization, a key component for establishing a connection with WireGuard.
Using LuCI
Navigate to Network > Firewall and add a new zone. Then configure the following.
Under General Settings:
- Name: vpn
- Input: reject
- Output: accept
- Intra zone forward: reject
- Masquerading: check
- MSS clamping: check
- Covered networks: wireguard
- Allow forward from source zones: lan
After that edit the wan zone and remove the following:
- Covered networks: wireguard
- Allow forward from source zones: lan
Next we want to configure the gateway metrics. Go to Network > Interfaces and edit the wireguard interface. Under Advanced Settings > Use gateway metric, enter 1. Then do the same for the wan interface but use a metric of 2.
Using CLI
Append the following to /etc/config/firewall.
config zone
option name 'vpn'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'wireguard'
option masq '1'
option mtu_fix '1'
config forwarding
option src 'lan'
option dest 'vpn'And in the same file, remove list network 'wireguard' under config zone with option name 'wan'. Then also remove the following.
config forwarding
option src 'lan'
option dest 'wan'Lastly, in /etc/config/network, append option metric '1' under config interface 'wireguard' and option metric '2' under config interface 'wan'.
After applying these configurations, reboot your router. You should now have a fully functional WireGuard connection over TCP with Phantun, securing your entire network's traffic.