Recently, I wanted to deploy my music download bot to the cloud, so I set up a server on Hetzner. The quality and speed are impressive—truly German engineering! I decided to configure a WireGuard connection between my local machine and Hetzner.

Despite having used WireGuard for a while, this was my first time setting it up properly. Previously, I only copied configurations from others while playing with DN42, without delving into the details. This time, I gained a deeper understanding.

Server Configuration (loosely termed as “server”)

Using Debian as an example:

Standard installation:

1
sudo apt update && apt install wireguard

Here’s the wg0.conf for the server:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Interface]
PrivateKey = <server private key>
ListenPort = 520
Address = 10.0.0.1/24, fd00::1/64
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <client public key>
AllowedIPs = 10.0.0.2/32, fd00::2/128

[Peer]
PublicKey = <client public key>
AllowedIPs = 10.0.0.3/32, fd00::3/128

Note: My choice of address wasn’t ideal as it conflicts with my campus network’s internal IP range.

Open the necessary ports to allow traffic through:

1
2
sudo iptables -A INPUT -p udp --dport 520 -j ACCEPT
sudo ip6tables -A INPUT -p udp --dport 520 -j ACCEPT

Verify the rules:

1
2
sudo iptables -L INPUT -n
sudo ip6tables -L INPUT -n

Expected output:

1
2
3
4
5
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     17   --  0.0.0.0/0            0.0.0.0/0            udp dpt:520
1
2
3
4
5
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520
ACCEPT     17   --  ::/0                 ::/0                 udp dpt:520

Start the WireGuard service:

1
2
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

Configuration Details

  • [Interface] Section

    • PrivateKey: Server’s private key for encryption.
    • ListenPort: The port WireGuard listens on for incoming connections.
    • Address: Server’s address in the virtual network (e.g., 10.0.0.1 for IPv4, fd00::1 for IPv6).
    • PostUp and PostDown: Commands to set up and tear down NAT rules for traffic routing.
  • [Peer] Section

    • PublicKey: Each peer’s public key for identity verification.
    • AllowedIPs: IP addresses allowed through this peer (e.g., 10.0.0.2/32 for client).

Role and Association of Addresses

  • Server’s Address: Defines the server’s IP in the WireGuard network.
  • Client’s Address: Defines the client’s IP in the WireGuard network.
  • Association: Server and client addresses should be in the same subnet for communication (e.g., 10.0.0.1/24 for server, 10.0.0.2/24 for client).

Client Configuration

On my Mac, install WireGuard from the App Store or the official website.

Client’s wg0.conf:

1
2
3
4
5
6
7
8
9
[Interface]
PrivateKey = <client private key>
Address = 10.0.0.2/24, fd00::2/64
DNS = 8.8.8.8, 2001:4860:4860::8888

[Peer]
PublicKey = <server public key>
Endpoint = <server IPv6 address>:520
AllowedIPs = 0.0.0.0/0, ::/0

The Endpoint specifies the server’s IPv6 address and port. AllowedIPs set to 0.0.0.0/0, ::/0 means all traffic routes through the WireGuard tunnel.

For more configurations, check this: WireGuard AllowedIPs Calculator.

Testing the Connection

Ensure the connection is established between the client and server. Use wg command to check WireGuard status:

1
sudo wg

You should see the connection details and active traffic.

Troubleshooting

I faced issues with the client not communicating via the VPS’s IPv6 address. Here are some troubleshooting steps:

  1. Check Server’s IPv6 Configuration: Ensure VPS has the correct IPv6 setup and can access external IPv6 addresses (use ping6).

  2. Check Routing Table: Use ip -6 route to verify VPS’s IPv6 routes.

  3. Firewall Settings: Ensure no firewall rules block IPv6 traffic:

    1
    2
    
    sudo ip6tables -A INPUT -p udp --dport 520 -j ACCEPT
    sudo ip6tables -A FORWARD -i wg0 -j ACCEPT
    
  4. IPv6 DNS Server: Ensure correct IPv6 DNS configuration (e.g., 2001:4860:4860::8888).

Conclusion

After some trial and error, I established a WireGuard connection between my Hetzner VPS and local machine, enabling traffic forwarding through the VPS. This process deepened my understanding of WireGuard configuration and principles. There’s still much to learn!

WireGuard AllowedIPs Calculator