URI:
   DIR <- Back
       
       
       # Wireguard on OpenBSD for use as a mobile VPN
       
       Last modification on 2026-03-29
       
       Wireguard is a fast, modern and secure VPN tunnel.
       
  HTML Below is a guide to setup »Wireguard« on the OpenBSD
       operating system intended for use as a mobile VPN.
       
       It describes using the OpenBSD Wireguard wg(4) kernel driver using ifconfig,
       not the userland application, and will focus on setting up a IPv4 tunnel.
       
       It is however recommended to install wireguard-tools, because it contains
       useful tools to generate a private and public key (wg genkey, wg pubkey).
       
       To install the wireguard-tools package on OpenBSD:
       
               # pkg_add wireguard-tools
       
       
       ## Enable IPv4 traffic forwarding
       
       To enable traffic forwarding for IPv4 run:
       
               # sysctl net.inet.ip.forwarding=1
       
       To make it persistent add the above lines to the file /etc/sysctl.conf.  These
       sysctl lines are loaded on boot time.
       
       
       ## Server config: /etc/hostname.wg0
       
       This is an example config for the wg0 network interface.  It is stored at
       /etc/hostname.wg0:
       
               wgport 51820 wgkey 'private_key_here'
               inet 10.1.2.1/24
               up
               
               # peer: phone
               wgpeer 'pubkey' wgaip 10.1.2.2/32 wgdescr 'phone' wgpsk 'psk_here'
       
       
       ## Generating a private key
       
       Using wireguard-tools wg command:
       
               $ wg genkey
       
       Replace private_key_here with the generated text.
       
       To generate both a private and public key to the files private.key and
       public.key:
       
               $ wg genkey | tee private.key | wg pubkey > public.key
       
       **!!! Keep the private key secure. Do not share it with anyone!!!**
       
       
       ## Generate a separate preshared key (PSK).
       
       Using a preshared key (PSK) is optional, but recommended. This is used in the
       handshake to guard against future compromise of the peers' encrypted tunnel if
       a quantum-computational attack on their Diffie-Hellman exchange becomes
       feasible.
       
       Using wireguard-tools wg command:
       
               $ wg genpsk
       
       The PSK can be shared with a known client when configuring the clients. **Make sure
       to share it via a safe channel**.
       
       To configure or restart the wg0 interface using the configuration in
       /etc/hostname.wg0:
       
               # sh /etc/netstart wg0
       
       To show general info of the interface run the command (requires root
       permissions to view all information):
       
               # ifconfig wg0
       
       In the ifconfig wg0 output it should list the server public key as:
       
               wgpubkey server_pubkey_here
       
       
       ## Full example of a client config: wg-client.conf
       
               [Interface]
               Address = 10.1.2.2/32
               DNS = 10.1.2.1
               PrivateKey = CHBzstIHCi7+YOOa2MN0RXhkPAmJwIXQW0e6/n6+Pno=
               
               [Peer]
               AllowedIPs = 0.0.0.0/0
               Endpoint = example.org:51820
               PreSharedKey = 8ao/EMExyPAHrT3ShX+lnA0u7jUmo7MhrT0GjDcrIJA=
               PublicKey = Rny+AW4EPqPPxfO+8O+QdlkIrWbZRGQ6u6Fje5pUOFM=
       
       **Of course do not copy-paste this private key and PSK. Generate your own ;)**
       
       
       ## pf(4) firewall rules
       
       Below is a fragment of the firewall rules required for Wireguard.
       These rules assume a simple VPS with a vio network interface connected to the
       interwebs (no double NAT or other weird complex things ;)).
       
       pf.conf:
       
               # wireguard
               pass out quick on egress inet from (wg0:network) nat-to (vio0:0)
               pass in quick on wg0 from any to any
               pass in quick on wg0 proto udp from any to any port 51820
               # allow all on wireguard
               pass quick on wg0
       
       
       ## Mobile VPN application
       
  HTML For Android download the APK from »https://www.wireguard.com/install/«.
       There are also other versions available on the page.
       
       ## Android Wireguard settings
       
       ## Adding a tunnel
       
       In the Wireguard application press the plus (+) button in the bottom left of
       the screen to add a tunnel.
       
       
       ## Option: "Scan from QR code"
       
       ### Generate a QR code image from a client config
       
       Install the libqrencode package for the qrencode program:
       
               # pkg_add libqrencode
       
       Generate a QR code PNG image from a client config:
       
               $ qrencode -o qr.png < wg-client.conf
       
       This QR code simply contains the full text from the wg-client.conf. It can be
       scanned from the Android Wireguard application.  If it contains sensitive
       information such as the private key make sure to share the image in a safe way
       and/or destroy it immediately.
       
   IMG QR code image
       
       If the QR code contains a private key, make sure to destroy it "Inspector Gadget"-style.
       
   IMG inspector Gadget reading self-destruct message
       
   BIN Inspector Gadget, self-destruct video clip
       
       Now scan the generated image to import the config.
       
       
       ### Option: "Import from file or archive"
       
       Import a text .conf file or archive (ZIP) file containing one or more configs.
       
  TEXT Example conf file: »client-example.conf«.  
   BIN Example ZIP file: »client-example.zip«.
       
       
       ### Option: "Create from scratch"
       
       Generating the private key on the device itself and sharing the **public** key
       and PSK is probably the safest option.  Although sharing the public key text
       from a mobile device can be a bit annoying.
       
       
       ## Android settings
       
       Only allow connections and DNS using VPN:
       
       * Settings -> VPN -> Network & Internet:
         Make sure Wireguard is set and enabled under VPN.
       
       VPN settings, open Wireguard cogwheel:
       * Enable: Always on VPN option, with the description: "Stay connected to VPN at all times".
       * Enable: Block connections without VPN.
       
       Other recommendations:
       
       * Under Wi-Fi -> Privacy.
         * Use randomized MAC.
         * Disable "Send device name".
       * Set a secure and privacy-respecting DNS server.
       
       
       ## Wireguard persistent keepalive setting
       
       If the interface very rarely sends traffic, but it might at anytime receive
       traffic from a peer, and it is behind NAT, the interface might benefit from
       having a persistent keepalive interval of 25 seconds.
       
       If it is not needed, then it is recommended to not enable it, which is the
       default.
       
       This option is called PersistentKeepalive in Wireguard conf and is called
       wgpka for OpenBSD ifconfig, see the ifconfig(8) man page WIREGUARD section.
       
       
       ## Debugging tips
       
       For the Wireguard Android application you can find a textual log:
       
       * Open the Wireguard application.
       * At the top right select the 3 dots settings thingy.
       * Select the menu labeled "View application log".
       
       On the OpenBSD server you can run enable run-time debugging on the wg0 interface:
       
               # ifconfig wg0 debug
       
       
       ## Bonus: example using wg-quick from wg-tools
       
       Using the wg-quick program from wg-tools you can also quickly setup a client.
       This will setup the DNS, routing and interface. It can setup and restore the
       DNS and routing settings easily.
       
       As root, to setup the interface:
       
               # wg-quick up absolute/path/to/config/wg-client.conf
       
       As root, to restore the interface:
       
               # wg-quick down absolute/path/to/config/wg-client.conf
       
       
       ## Bonus: generating a private key using only OpenSSL commands
       
       Generate a private key:
       
               $ openssl genpkey -algorithm X25519 -outform DER -out private.der
       
       Now extract the last 32 bytes which has part of the actual private key (the
       first ASN.1 DER encoded bytes contain metadata information). Convert the actual
       key data to base64.
       
       Run:
       
               $ tail -c 32 private.der | openssl enc -a -A > private.key
       
       Derive public key:
       
               $ openssl pkey -inform DER -in private.der -pubout -outform DER -out public.der
       
       Convert public key to Wireguard format:
       
               $ tail -c 32 public.der | openssl enc -a -A > public.key
       
       Or even the magical voodoo commands:
       
               $ openssl rand -base64 32 > private.key
               $ (printf '\060\056\002\001\000\060\005\006\003\053\145\156\004\042\004\040';openssl enc -d -a -A < private.key) | \
                 openssl pkey -inform DER -pubout -outform DER | \
                       tail -c 32 | \
                       openssl enc -a -A > public.key
       
       
       ## References
       
  HTML * Wireguard:
  HTML   * Wireguard quickstart page:
           This uses the userland Wireguard programs and config. But it contains
           helpful information.  
  HTML   * wg(8) man page.
  HTML   * wg-quick(8) man page.
  HTML * OpenBSD operating system:
  HTML   * wg(4) driver man page.
  HTML   * ifconfig(8) man page WIREGUARD section.
  HTML   * pf.conf(5) file format.