Step-by-step VyOS Wireguard Configuration

A step-by-step recipe for VyOS configuration.

Best Practices

  1. Ensure hardware has a serial port
  2. Ensure you have out-of-band serial port access
  3. Always update install-image-existing script before installing new version

Forward some ports (vyos 1.5)

  1. Forward tcp/80 and tcp/443 on eth0.100 to 10.3.20.101
     set nat destination rule 10 description 'Port Forward: HTTP to 10.3.20.101'
     set nat destination rule 10 destination port '80'
     set nat destination rule 10 inbound-interface name 'eth0.100'
     set nat destination rule 10 protocol 'tcp'
     set nat destination rule 10 translation address '10.3.20.101'
     set nat destination rule 20 description 'Port Forward: HTTPS to 10.3.20.101'
     set nat destination rule 20 destination port '443'
     set nat destination rule 20 inbound-interface name 'eth0.100'
     set nat destination rule 20 protocol 'tcp'
     set nat destination rule 20 translation address '10.3.20.101'
    
  2. Open firewall to permit traffic. Note the firewall rules apply to the translated IP address and port since firewall rules apply after NAT destination rules.
     set firewall ipv4 name WAN_IN default-action 'drop'
     set firewall ipv4 name WAN_IN description 'WAN to internal'
     set firewall ipv4 name WAN_IN enable-default-log
     set firewall ipv4 name WAN_IN rule 2 action 'accept'
     set firewall ipv4 name WAN_IN rule 2 description 'Allow established/related'
     set firewall ipv4 name WAN_IN rule 2 state 'established'
     set firewall ipv4 name WAN_IN rule 2 state 'related'
     set firewall ipv4 name WAN_IN rule 10 action 'accept'
     set firewall ipv4 name WAN_IN rule 10 destination address '10.3.20.101'
     set firewall ipv4 name WAN_IN rule 10 destination port '80'
     set firewall ipv4 name WAN_IN rule 10 protocol 'tcp'
     set firewall ipv4 name WAN_IN rule 10 state 'new'
     set firewall ipv4 name WAN_IN rule 20 action 'accept'
     set firewall ipv4 name WAN_IN rule 20 destination address '10.3.20.101'
     set firewall ipv4 name WAN_IN rule 20 destination port '443'
     set firewall ipv4 name WAN_IN rule 20 protocol 'tcp'
     set firewall ipv4 name WAN_IN rule 20 state 'new'
    
  3. Attach WAN_IN to eth0.100 interface
     set firewall ipv4 forward filter rule 5 action 'jump'
     set firewall ipv4 forward filter rule 5 inbound-interface name 'eth0.100'
     set firewall ipv4 forward filter rule 5 jump-target 'WAN_IN'
    

Wireguard roadwarrior configuration

Since this is my home router, I want remote administration capabilities for while I’m travelling.

  1. First, generate a public/private key for the wireguard server to use. The server will store it’s private key, and the public key will be included in client devices to connect to this wireguard server.
     $ generate pki wireguard key-pair install interface wg01
    
     You are not in configure mode, commands to install manually from configure mode:
     set interfaces wireguard wg11 private-key 'eKGOqwZ07a7d9dlSWtydVQyqF1+44bJcgtp3JJrG6Fc=' (only stored on server)
     Corresponding public-key to use on peer system is: 'dAH7uVduQHnV6bAl7TVMEEdYT4xIzL8TubZScK+X/TM=' (stored on clients)
    
  2. Now, enter configure mode, and set the private key on the wireguard server.

     $ configure
     # set interfaces wireguard wg01 private-key 'eKGOqwZ07a7d9dlSWtydVQyqF1+44bJcgtp3JJrG6Fc='
    
  3. Pick a subnet/address range for the wireguard server to use to talk to it’s clients. My internal network is 10.10.x.x/16, so I’m going to use 10.11.0.1/24 so it’s not conflicting. (And clients will use 10.11.0.2, 10.11.0.3, etc.). I’m using udp/51820 as the wireguard server port.
     # set interfaces wireguard wg01 address '10.11.0.1/24'
     # set interfaces wireguard wg01 description 'remote admin'
     # set interfaces wireguard wg01 port '51820'
    
  4. Permit the wireguard server traffic through. Pick a rule number that is not already in use. If you’ve been following this guide you can use
     # set firewall name WAN_LOCAL rule 200 action 'accept'
     # set firewall name WAN_LOCAL rule 200 description 'Allow wg'
     # set firewall name WAN_LOCAL rule 200 destination port '51820'
     # set firewall name WAN_LOCAL rule 200 protocol 'udp'
    
  5. To configure a client/’peer’ device that is allowed to connect to this server, we need a (another) private/public key pair. The private key will only exist on the client (that’s how it identifies itself) and the public key will be stored on the server so it can uniquely identify this client. We’ll generate both of these on the server, for ease, but for better security you can obviously create this public/private key directly on the client and only transfer the public key to the server.
     # run generate pki wireguard key-pair
    
     Private key: qOs9mxFSLpBxeM7t8bx7EbDVrJj5DLxCN1HXiUQH8Vc=  (only stored on client)
     Public key: G4x3ZMaj4X2qp7yiBJaIZgCZaQJJx6fM6nFGY9fqGhY=  (stored on server)
    
  6. On the wireguard server, configure this peer that is allowed to connect. To do this, we specify a unique client name (justin, in this case), the IP it should use on the wireguard subnet (one that is not already assigned), the client’s public key, and save the configuration.

     # set interfaces wireguard wg01 peer justin allowed-ips '10.11.0.2/32'
     # set interfaces wireguard wg01 peer justin public-key 'G4x3ZMaj4X2qp7yiBJaIZgCZaQJJx6fM6nFGY9fqGhY='
     # commit
     # save
    
  7. On the wireguard client, create the .conf file with the client’s private key, the address it should use on the wireguard subnet, which DNS server should be used while connected to the tunnel, along with the server’s public key, and hostname where the server can be found. Finally, we specify the IP range of the network on the other side of the VPN (the internal network subnet, in this case).

     [Interface]
     PrivateKey = qOs9mxFSLpBxeM7t8bx7EbDVrJj5DLxCN1HXiUQH8Vc=
     Address = 10.11.0.2/32
     DNS = 1.1.1.1
    
     [Peer]
     PublicKey = dAH7uVduQHnV6bAl7TVMEEdYT4xIzL8TubZScK+X/TM=
     Endpoint = server.example.com:51820
     AllowedIPs = 10.10.0.0/16
    
  8. Repeat steps 5-7 as needed, for additional clients.

Recovering from Failed Upgrade

I upgraded a 1.4-rolling image (20230801) to a 1.5-rolling (20231219) image and the new system image failed to migrate/upgrade the configuration:

[   31.808635] vyos-router[1031]: Mounting VyOS Config...done.
[   33.450633] vyos-router[1031]: Starting VyOS router: migrate
[   33.450932] vyos-router[1456]: Migration script error: /opt/vyatta/etc/config-migrate/migrate/cluster/1-to-2: [Errno 1] failed to run command: ['/opt/vyatta/etc/config-migrate/migrate/cluster/1-to-2', '/opt/vyatta/etc/config/config.boot']
[   33.450985] vyos-router[1456]: returned:
[   33.451036] vyos-router[1456]: exit code: 1.
[   33.800656] vyos-router[1031]:  configure failed!
[   34.429891] vyos-config[1037]: Configuration error
  1. Reboot back into old image (reboot system, pick old version from GRUB)
  2. Login, then delete the new image
     show system image
     delete system image <new-image>
    
  3. Follow instructions below for Updating System Image

Updating System Image

  1. Update the install-image-existing script first
     wget "https://raw.githubusercontent.com/vyos/vyatta-cfg-system/current/scripts/install/install-image-existing"
     sudo cp install-image-existing /opt/vyatta/sbin/
    
  2. Add new system image again add system image https://github.com/vyos/vyos-rolling-nightly-builds/releases/download/1.5-rolling-202312191154/vyos-1.5-rolling-202312191154-amd64.iso
  3. Reboot