Setting Up WireGuard and DuckDNS on a Raspberry Pi

DevOpshelianDevOpshelian
5 min read

In this guide, we’ll walk you through setting up WireGuard on a Raspberry Pi, combined with DuckDNS for dynamic DNS management. This will allow you to create a secure VPN server that you can access from anywhere, even when your public IP address changes regularly.

Prerequisites

  • Raspberry Pi: Any model with Raspberry Pi OS installed.

  • DuckDNS account: A free dynamic DNS service to handle IP changes.

  • WireGuard: A lightweight, high-performance VPN.

  • Publicly accessible IP: Required to expose your Raspberry Pi to the internet, but we’ll cover how DuckDNS helps with this.

  • CGNAT consideration: If you're behind CGNAT, like some ISPs provide, this guide assumes you’ll have to work around it, possibly with services like Tailscale or reverse proxy solutions.

Step 1: Set Up DuckDNS on Raspberry Pi

Since most ISPs assign dynamic IPs, we need to ensure that your Raspberry Pi's changing public IP can be accessed consistently. DuckDNS provides an easy, free solution for dynamic DNS.

  1. Create a DuckDNS account:

    • Go to DuckDNS, sign in, and create a subdomain.

    • You will get a unique token and your chosen subdomain, for example, myvpn.duckdns.org.

  2. Install DuckDNS on Raspberry Pi: We’ll create a simple cron job that periodically updates DuckDNS with your current IP.

    Open the terminal and type the following commands:

     sudo apt update && sudo apt install curl -y
    

    Create a new script to update DuckDNS:

     nano ~/duckdns.sh
    

    Inside the script, paste the following (replace <your_token> and <your_subdomain> with your actual token and subdomain):

     echo url="https://www.duckdns.org/update?domains=<your_subdomain>&token=<your_token>&ip=" | curl -k -o ~/duckdns.log -K -
    

    Save and close the file by pressing CTRL + X, then Y, and Enter.

  3. Set up cron job: We’ll now set a cron job to run this script every 5 minutes.

     crontab -e
    

    Add the following line to the file:

     */5 * * * * ~/duckdns.sh >/dev/null 2>&1
    

    This will update DuckDNS every 5 minutes with your current public IP.

Step 2: Install WireGuard on Raspberry Pi

WireGuard is a fast, modern VPN that is simpler to configure and deploy than older protocols.

  1. Install WireGuard: On your Raspberry Pi, install WireGuard using the following commands:

     sudo apt update && sudo apt install wireguard -y
    
  2. Generate Keys: You’ll need a public and private key pair for your server and each peer. Run the following commands to generate them:

     wg genkey | tee privatekey | wg pubkey > publickey
    

    This creates two files:

    • privatekey contains your server’s private key.

    • publickey contains your server’s public key.

Make sure to keep the private key safe!

  1. Configure WireGuard: Create a new WireGuard configuration file:

     sudo nano /etc/wireguard/wg0.conf
    

    Here’s a basic configuration file:

     [Interface]
     PrivateKey = <your_private_key>
     Address = 10.13.13.1/24   # This is the VPN subnet
     ListenPort = 51820
     PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
     PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
    
     [Peer]
     PublicKey = <peer_public_key>
     AllowedIPs = 10.13.13.3/32   # This is the peer’s VPN address
    

    Replace <your_private_key> with the private key you generated, and set the peer’s public key in the [Peer] section.

  2. Enable and Start WireGuard:

     sudo wg-quick up wg0
    

    To make sure WireGuard starts on boot, enable the service:

     sudo systemctl enable wg-quick@wg0
    

Step 3: Port Forwarding on Your Router

You’ll need to forward the WireGuard port (51820 by default) on your router. If your router is behind CGNAT, this may not be possible directly. In such cases, consider using a service like Tailscale, which doesn’t require port forwarding, or a reverse proxy that supports WireGuard.

  1. Log in to your router’s settings.

  2. Navigate to the port forwarding section and forward UDP port 51820 to your Raspberry Pi’s local IP address.

  3. Test connectivity using telnet or nc to ensure the port is open.

Step 4: Set Up WireGuard Clients

Once your Raspberry Pi VPN server is set up, you can connect clients like laptops, phones, or tablets.

  1. Generate client keys (on the Raspberry Pi or client device):

     wg genkey | tee client_privatekey | wg pubkey > client_publickey
    
  2. Add the client configuration: Edit the wg0.conf file on your Raspberry Pi and add a new [Peer] section for each client:

     [Peer]
     PublicKey = <client_public_key>
     AllowedIPs = 10.13.13.3/32   # Client VPN IP
    
  3. Client Configuration: On your client device, create a configuration file. Here’s an example for iOS or Android using the WireGuard app:

     [Interface]
     PrivateKey = <client_private_key>
     Address = 10.13.13.3/32
    
     [Peer]
     PublicKey = <server_public_key>
     Endpoint = myvpn.duckdns.org:51820
     AllowedIPs = 0.0.0.0/0, ::/0
    

    Replace <client_private_key> with the key generated for the client, and <server_public_key> with your Raspberry Pi’s public key.

Step 5: Testing the VPN

Once everything is set up, you can test the VPN by connecting to it from your client devices. Make sure to check that you can access your Raspberry Pi and any other services you’ve configured through the VPN.

To verify connectivity, you can use ping or try accessing services hosted on the Raspberry Pi, such as Docker containers you’ve set up.

Conclusion

Setting up WireGuard on a Raspberry Pi, combined with DuckDNS for dynamic DNS, allows you to maintain a secure VPN server that’s accessible regardless of your changing IP address. With a streamlined configuration process and a lightweight footprint, WireGuard is an excellent choice for Raspberry Pi VPN setups.

By following this guide, you should have a fully functioning WireGuard VPN server, protected by DuckDNS, and accessible remotely from anywhere.

0
Subscribe to my newsletter

Read articles from DevOpshelian directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

DevOpshelian
DevOpshelian