In this post, I’ll share how I set up a WireGuard VPN over TCP using udp2raw
, which provides secure access to corporate networks and serves as a fallback for internet access when customer networks impose heavy restrictions. Inspired by Pro Custodibus, this solution enables IoT gateways to seamlessly connect to both the company’s internal services and the broader internet under constrained conditions.
Scenario Overview
The architecture for this setup is illustrated below:
Key Features of the Solution:
- Access to Corporate Networks: IoT Gateways securely connect to the corporate network for accessing internal services.
- Fallback Internet Access: When the customer’s network restricts internet access but allows TCP connections to the company infrastructure, the IoT Gateway routes its internet traffic through the company’s network.
How It Works:
- Endpoint A (Client): An IoT Gateway connects through the restrictive customer network.
- Endpoint B (Server): The WireGuard server is accessible via a public IP (
134.122.74.29
) on TCP port55055
. - Traffic flows through a TCP tunnel created with
udp2raw
, enabling the gateway to securely access the corporate network or relay internet traffic via the company’s infrastructure.
This dual-purpose setup ensures robust connectivity for IoT devices even in challenging environments.
Video Demonstration (in Spanish)
I’ve created a video demonstration in Spanish showcasing the entire setup and functionality of this scenario. The video walks through the following steps:
- Explaining the problem and network constraints.
- Demonstrating the configuration of both endpoints (client and server).
- Showing the connection initiation and testing, including how traffic flows through the VPN tunnel.
- Verifying fallback internet access through the company network.
This video is ideal for those who prefer visual explanations or need extra guidance in implementing this solution.
Configuration Files
1. Endpoint B (server, /etc/wireguard/wg0.conf
)
This configuration allows Endpoint B to act as a gateway for both corporate access and fallback internet connectivity:
# local settings for Endpoint B
[Interface]
PrivateKey = EMqyADu4Xeu95ZpNZE97FET5eKzN1WSwBkeBWtX1yGg=
Address = 192.168.111.1/32
ListenPort = 51822
# receive wg through udp2raw
MTU = 1342
PreUp = udp2raw -s -l 134.122.74.29:55055 -r 127.0.0.1:51822 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true
# Enable NAT for traffic forwarding (corporate and fallback internet access)
PreUp = echo 1 > /proc/sys/net/ipv4/ip_forward || true
PreUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE || true
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE || true
# remote settings for Endpoint A
[Peer]
PublicKey = Xt70DJy8ldPcDNW4YM2Dt94n16pTQKFxhmvpgKvJyng=
AllowedIPs = 192.168.111.2/32
PersistentKeepalive = 120
Key Points:
- NAT Rules: These rules enable traffic originating from Endpoint A to use Endpoint B for accessing the internet.
- MTU Adjustment: The MTU is set to 1342 to prevent fragmentation issues over the TCP tunnel.
Assumptions:
- eth0, is the name of the interface for reaching Internet.
- 192.168.111.0/24 is available for point-to-point connections in the tunnels.
ud2raw
is in PATH.- Don’t re-use my pub and private keys. Neither the pre-shared key of used by
udp2raw
.
Endpoint A (client, /etc/wireguard/wg0.conf
)
This configuration sets up Endpoint A to route all traffic (corporate and internet) through Endpoint B:
[Interface]
PrivateKey = yAxByb468bAuMdg5S6AlfYkxbeYDOMEKxdaJ7d2p83g=
Address = 192.168.111.2/32
# Route configuration for public IP
PreUp = ip route del default || true
PreUp = ip route add 134.122.74.29 via 10.2.0.1 dev eth0 || true
PostDown = ip route del 134.122.74.29 via 10.2.0.1 dev eth0 || true
PostDown = ip route add default via 10.2.0.1 || true
MTU = 1342
PreUp = udp2raw -c -l 127.0.0.1:50001 -r 134.122.74.29:55055 -k "The2password." -a >/var/log/udp2raw.log 2>&1 &
PostDown = killall udp2raw || true
[Peer]
PublicKey = VUN2JqZiGQ1V46PDoFECw/nMs3/o6n8PvGMV+ad+Hww=
Endpoint = 127.0.0.1:50001
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 120
Key Points:
- Fallback Internet Routing: The
AllowedIPs = 0.0.0.0/0
directive ensures all traffic is routed through Endpoint B, including internet traffic. - Dynamic Route Adjustments: The
PreUp
andPostDown
commands manage routes for efficient fallback connectivity.
Here’s the improved Implementation Steps section based on your feedback and expertise in WireGuard and udp2raw
:
Implementation Steps
This section outlines the precise steps required to set up the WireGuard VPN over TCP using udp2raw
. Follow these instructions carefully for both Endpoint A (client) and Endpoint B (server).
1. Pre-requisites
- WireGuard Installation: Ensure WireGuard is installed on both systems. This can usually be done via the package manager of your operating system (e.g.,
apt install wireguard
for Debian-based distributions). - udp2raw Binary: Download the appropriate
udp2raw
binary from its GitHub Releases Page. Binaries are available for various architectures. For simplicity:- Extract the binary from the tarball (e.g.,
udp2raw_amd64
for most x86_64 systems). - Place the binary in a directory accessible from your
PATH
(e.g.,/usr/local/bin
). - Verify the installation:
which udp2raw udp2raw -h # Should display the help menu
- Extract the binary from the tarball (e.g.,
2. Prepare the Configuration Files
The configuration files should be located at /etc/wireguard/wg0.conf
. Each endpoint has its own specific configuration:
- Endpoint A: Use the
wg0.conf
provided earlier, replacing placeholders like keys and IPs as needed. - Endpoint B: Use the
wg0.conf
provided earlier.
Ensure both files reflect the IP addresses, MTU settings, and public/private keys accurately.
3. Generate WireGuard Keys
WireGuard requires public-private key pairs for secure communication. Generate them as follows:
- Generate the Private Key:
wg genkey > privatekey
- Generate the Public Key from the private key:
cat privatekey | wg pubkey > publickey
- Place the private key in the
[Interface]
section of the respective configuration file (PrivateKey = ...
) and the corresponding public key of the peer in the[Peer]
section (PublicKey = ...
).
Note: Never share your private keys.
4. Start the VPN Tunnel
- Start the Server First (Endpoint B):
- Bring up the WireGuard interface using
wg-quick
:sudo wg-quick up wg0
- Verify that the interface is active:
wg show
- Bring up the WireGuard interface using
- Start the Client (Endpoint A):
- Bring up the client WireGuard interface:
sudo wg-quick up wg0
- Verify that the interface is active:
wg show
- Bring up the client WireGuard interface:
5. Test the Connection
Once both endpoints are active, initiate traffic from Endpoint A to Endpoint B. This step ensures the udp2raw
TCP socket is properly established and functioning:
- Ping Endpoint B’s WireGuard IP:
ping 192.168.111.1
- If the ping succeeds, the connection is working as expected.
- If it fails, check the logs for
udp2raw
and WireGuard on both endpoints for errors:less /var/log/udp2raw.log
- Once the initial handshake completes, the tunnel will remain active as long as
PersistentKeepalive
is configured in the client configuration (e.g.,PersistentKeepalive = 120
).
6. Validate Fallback Internet Access
To confirm the fallback internet routing through Endpoint B:
- On Endpoint A, run a test to confirm external connectivity:
curl -I https://www.google.com
- If the response headers are received, the internet routing through Endpoint B is functioning.
- Verify that the traffic is routed through the WireGuard tunnel:
traceroute google.com
- If fallback internet access fails, ensure that NAT is correctly configured on Endpoint B:
iptables -t nat -L -n
7. Troubleshooting
- Log Files:
- Check the
udp2raw
logs on both endpoints for issues (e.g., MTU mismatches, handshake failures). - Review WireGuard logs for additional details.
- Check the
- MTU Issues:
- If large packets fail but small packets (e.g.,
ping
) succeed, reduce the MTU (e.g., to 1280).
- If large packets fail but small packets (e.g.,
8. Automate Startup
To ensure the VPN starts automatically on boot:
- Enable the WireGuard service:
sudo systemctl enable wg-quick@wg0
- Add
udp2raw
commands to a systemd service or thePreUp
directive inwg0.conf
(as shown in the configuration files).
With these steps, you now have a fully operational WireGuard tunnel over TCP, enabling secure communication between endpoints and fallback internet connectivity via the company’s infrastructure.
Conclusion
This configuration provides a robust solution for IoT Gateways operating in restrictive environments. By leveraging udp2raw
, WireGuard traffic is tunneled over TCP, enabling:
- Seamless Corporate Access.
- Fallback Internet Connectivity through the company network when customer environments impose constraints.
This versatile setup ensures uninterrupted operations and secure communications for IoT devices. Explore the Pro Custodibus guide and udp2raw GitHub repository for additional insights.