Skip to content

Instantly share code, notes, and snippets.

@pamolloy
Last active January 23, 2024 07:28
Show Gist options
  • Save pamolloy/059c552b814b0dddfcdc0cec2bbe5872 to your computer and use it in GitHub Desktop.
Save pamolloy/059c552b814b0dddfcdc0cec2bbe5872 to your computer and use it in GitHub Desktop.
Ubiquiti USG configuration for Wireguard

Download the latest ugw3 package from https://github.com/Lochnair/vyatta-wireguard/releases and install it on your USG using dpkg -i wireguard-ugw3-<version>.deb.

cd /config/auth
umask 077
mkdir wireguard
cd wireguard
wg genkey > wg_private.key
wg pubkey < wg_private.key > wg_public.key

Copy example config.gateway.json to /var/lib/unifi/data/sites/default on the host running the Controller. Then through the Controller Web UI navigate to Devices, click on the USG row and then in the Properties window navigate to Config > Manage Device and click Provision.

To allow remote access navigate to Settings > Routing & Firewall > Firewall > WAN LOCAL and create a new rule to accept UDP traffic to port 51820.

Note that the mask associated with the allowed-ips is not a netmask! I also found that provisioning failed with a /32 mask with only some very vague errors in /var/log/messages.

See also

{
"firewall": {
"group": {
"network-group": {
"remote_user_vpn_network": {
"description": "Remote User VPN subnets",
"network": [
"10.2.1.0/24"
]
}
}
}
},
"interfaces": {
"wireguard": {
"wg0": {
"address": [
"10.2.1.1/24"
],
"firewall": {
"in": {
"name": "LAN_IN"
},
"local": {
"name": "LAN_LOCAL"
},
"out": {
"name": "LAN_OUT"
}
},
"listen-port": "51820",
"mtu": "1352",
"peer": [{
"ANDROID-PHONE-PUBLIC-KEY": {
"allowed-ips": [
"10.2.1.5/32"
],
"persistent-keepalive": 25
}
}],
"private-key": "/config/auth/wireguard/wg_private.key",
"route-allowed-ips": "true"
}
}
}
}
@tomaspapan
Copy link

Thank you for the guide. Did you manage to generate port forwarding rules also for wg0 interface automatically? I'm facing problem that I can connect to VPN, everything works, but clients from VPN can not access forwarded ports on WAN, I've checked iptables -L -v -n -t nat table to see that those rules are missing in UBNT_PFOR_SNAT_RULES chain. I can add them manually, just wondering if anyone solve this differently.

@Rar9
Copy link

Rar9 commented Jul 11, 2019

i believe on newer controller we first need to setup al Firewall GROUP to assing the PORT.
This we then can use in the WAN LOCAL as destination.

Is this right?

Do we need to define a Controller NETWORK? or will this be done trough Gateway.config.json?

If so could this IP range be the Same as the UNIFI VPN L2TP uses?

@johnyvella
Copy link

I have an issue when connecting to the wireguard VPN from a client (windows or android) I am unable to access internet, only local network. I havent seen that there is a need to configure anything else in firewall though. Any ideas?

@Ramblurr
Copy link

This config has worked for me, however I also set MTU to 1500, and route-allowed-ips to false.

Using wireguard on android, I can connect to my home LAN successfully, as well as browse the WAN (routed via the LAN).

I run the controller in a docker container (linuxserver/unifi-controller) and I placed the config json inside the data volume at /config/data/sites/[site id], as seen from the container. Seen from the host the path is /var/lib/docker/volumes/unifi_data/_data/data/sites/[site id]. Note, adding it to the default site did not work for me.

Many props to @pamolloy for the concise guide.

@anthr76
Copy link

anthr76 commented Nov 6, 2019

Using this example configuration I'm able to establish handshakes between my iPhone and my USG over LTE. Though my iPhone is unable to reach devices within my LAN, and my iPhones IP is giving me the carriers so none of my traffic is being routed. Would anyone know why?

@Cranial
Copy link

Cranial commented Nov 6, 2019

Using this example configuration I'm able to establish handshakes between my iPhone and my USG over LTE. Though my iPhone is unable to reach devices within my LAN, and my iPhones IP is giving me the carriers so none of my traffic is being routed. Would anyone know why?

Can you share your config on both ends? Don't forget to obfuscate any keys or WAN IPs.

@anthr76
Copy link

anthr76 commented Nov 6, 2019

Using this example configuration I'm able to establish handshakes between my iPhone and my USG over LTE. Though my iPhone is unable to reach devices within my LAN, and my iPhones IP is giving me the carriers so none of my traffic is being routed. Would anyone know why?

Can you share your config on both ends? Don't forget to obfuscate any keys or WAN IPs.

Here's my config.gateway.json on my Cloud Controller

{
	"firewall": {
		"group": {
			"network-group": {
				"remote_user_vpn_network": {
					"description": "Remote User VPN subnets",
					"network": [
						"172.255.255.0/24"
					]
				}
			}
		}
	},
	"interfaces": {
		"wireguard": {
			"wg0": {
				"address": [
					"172.255.255.1/24"
				],
				"firewall": {
					"in": {
						"name": "LAN_IN"
					},
					"local": {
						"name": "LAN_LOCAL"
					},
					"out": {
						"name": "LAN_OUT"
					}
				},
				"listen-port": "443",
				"mtu": "1352",
				"peer": [{
						"--pubkey--": {
							"allowed-ips": [
								"172.255.252.2/32"
							],
							"persistent-keepalive": 60
						}
					},
					{
						"--pubkey--": {
							"allowed-ips": [
								"172.255.252.3/32"
							],
							"persistent-keepalive": 60
						}
					}
				],
				"private-key": "/config/auth/wg.key",
				"route-allowed-ips": "true"
			}
		}
	}
}

My peer configuration on iPhone

[Interface]
PrivateKey = OMITTED
DNS = 1.1.1.1, 1.0.0.1
MTU = 1352

[Peer]
PublicKey = <PubKey of USG>
Endpoint = FQDN:443
PersistentKeepalive = 60

I have on the Unifi interface:

https://i.imgur.com/n6h6AQs.png This is on WAN_LOCAL

Besides that I don't think anything else was touched.

My network subnets are

172.160.100.1 - LAN
172.160.101.1 - IoT
172.160.10.1 - Servers

None of these are reachable on my iPhone although the wireguard app shows packets being transferred. My IP on my phone also remains the carrier IP and not my USGs ISPs IP.

@entrhopi
Copy link

@tomaspapan commented on 26 Jun
Thank you for the guide. Did you manage to generate port forwarding rules also for wg0 interface automatically? I'm facing problem that I can connect to VPN, everything works, but clients from VPN can not access forwarded ports on WAN, I've checked iptables -L -v -n -t nat table to see that those rules are missing in UBNT_PFOR_SNAT_RULES chain. I can add them manually, just wondering if anyone solve this differently.

To everyone who is still wondering ... I managed to get the rules added to UBNT_PFOR_SNAT_RULES automatically by adding all the interfaces including the wg0 to the config.gateway.json
Note that you need to list all the interfaces you're currently using.

{
    "port-forward": {
        "lan-interface": [
            "eth0",
            "eth0.90",
            "wg0"
        ]
    }
}

@viennaa
Copy link

viennaa commented Jan 7, 2020

@anthr76 have you found a solution to this problem? Got the exact same. However, it is possible to SSH between peers.

Update: This thread pointed me in the right direction: https://www.reddit.com/r/WireGuard/comments/ag6g44/access_home_network_behind_nat_via_vps_and/ee4gqx7/

The problem in the configuration for me was the client. I had put allowed_ips to the wireguard interface ip I was connecting to (in your case 172.255.255.1/24). Removing this and making it completely open (0.0.0.0/0) resulted in the wanted behaviour. Local IPs are working and my external IP on the phone is the one from the wireguard server site.

@entrhopi
Copy link

entrhopi commented Jan 8, 2020

@anthr76 and @viennaa your client configuration file should look something like this:

[Interface]
PrivateKey = OMITTED
Address = 172.255.252.2/24
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = <PubKey of USG>
Endpoint = FQDN:443
AllowedIPs = 0.0.0.0/0

Use 0.0.0.0/0 if you want all traffic routed through you VPN. Or add a comma separated list of your internal networks if you want only internal traffic to be send:
AllowedIPs = 172.160.100.1/24, 172.160.101.1/24, 172.160.10.1/24

Also you maybe want to use the USG IP as your DNS Server to get the internal names queried.

Let me know if this works for you

@tchmnkyz
Copy link

tchmnkyz commented Feb 6, 2020

So i have a bit of a issue. For some reason when i connect to the wireguard client session, it does not seem as though the route is working correctly. I know the session is up from the logs.

here is the USG conf:

{
    "firewall": {
        "group": {
            "network-group": {
                "remote_user_vpn_network": {
                    "description": "Remote User VPN subnets",
                    "network": [
                        "10.13.41.0/24"
                    ]
                }
            }
        }
    },
    "interfaces": {
        "wireguard": {
            "wg0": {
                "description": "VPN for remote clients",
                "address": [
                    "10.13.41.1/24"
                ],
                "firewall": {
                    "in": {
                        "name": "LAN_IN"
                    },
                    "local": {
                        "name": "LAN_LOCAL"
                    },
                    "out": {
                        "name": "LAN_OUT"
                    }
                },
                "listen-port": "51820",
                "mtu": "1500",
                "peer": [{
                        "<-- KEY -->": {
                            "allowed-ips": [
                                "10.13.41.10/32"
                            ],
                            "persistent-keepalive": 60
                        }
                    }
                ],
                "private-key": "/config/auth/wireguard/wg_private.key",
                "route-allowed-ips": "false"
            }
        }
    }
}

and the session looks good:

interface: wg0
  public key: <-- KEY -->
  private key: (hidden)
  listening port: 51820

peer: <-- KEY -->
  endpoint: <-- IP -->:49591
  allowed ips: 10.13.41.10/32
  latest handshake: 53 seconds ago
  transfer: 1.67 KiB received, 3.55 KiB sent
  persistent keepalive: every 1 minute

but it just does not route the data for some reason...

@darellsison
Copy link

Is this for a client or for a server? Can i use this for my VPN Unlimited VPN provider? It has a wireguard config file how do i load that?

@CodeSapiens
Copy link

Perhaps you guys already knew this and you have purposely configured public address subnets within your internal networks for some specific reason. But if you didn't, you should know that the private "172" range is from 172.16.0.0 to 172.31.255.255, which is only a 20-bit block. Unlike the "10" range that goes from 10.0.0.0 to 10.255.255.255. What you guys have defined in the "172" ranges are not private networks, so you better have all your extra security layers well in place.

@Ramblurr
Copy link

@darellsison Wireguard doesn't use the client/server model.

However this config is for running wireguard node on your USG, so external devices can access your internal network.

Configured properly it would also allow external devices to tunnel through your network.

@ghostserverd
Copy link

Note that the link for releases on this guide is out of date. The new place to get the releases from is here

https://github.com/WireGuard/wireguard-vyatta-ubnt/releases

Be aware that any time you update your device (e.g. USG) you need to reinstall the module before it will provision properly.

@maletazul
Copy link

Hi all,

anyone set a site to site between 2 USG, i asking because i did not see anyone using endpoint in the json file, so vyatta release suporte that?
I try to use endpoint in json, and no USG provison error, but seams dont working.
any tips on that front ?

@ruchette
Copy link

I have the same problem. I try to configure wireguard to connect 2 USG. The wg0 (10.1.1.1) interface of the 1st USG communicates with the wg0 (10.1.1.2) interface of the 2nd USG and the ping works correctly. However, the subnets do not communicate with each other. Can someone publish the config.gateway.json files for this case? Or give some advice? Thanks in advance.

@BobbyBleacher
Copy link

Trying to get this setup for my Starlink connection since we're all walled behind a CGNAT now. Doesn't look like my USG wants to provision and keeps throwing errors. Should I not be copying the gateway file verbatim?

@simonkaiser9
Copy link

simonkaiser9 commented Apr 17, 2021

@ruchette That works for me by adding a static route to the UniFi controller on either side of the tunnel, which routes every request for the respective other subnet to the wireguard net first.

@ruchette
Copy link

@SymanK83 thanks for the help. Indeed, I managed to make it work. But I have a problem with the UNIFI controller. I have two sites, one where the controller is located and one remote, that I want to access via vpn. Once the vpn is installed and operational, the remote site is no longer seen by the UNIFI controller.
Now, I also have another problem. Since I upgraded my USG to version 4.4.55.5377096, it doesn't work anymore! The provisioning of the USG does not finish anymore.

@simonkaiser9
Copy link

@ruchette I have the exact same problem since yesterday and it seems to coincite with the UniFi controller update as well.
Deleting the static route made the provisioning work again, as the error message in the log looked as if the route-allowed-ips config for wireguard now clashes with the additional manually entered static route.
My error was the same as this one:

Lochnair/vyatta-wireguard#137

It‘s currently not working for me. We‘ll see what I can find.

@Tijn1974
Copy link

Question,

In LAN OUT I drop everything from the WireGuard VLAN to all internal IP (RC1819) and i have allow rules to allow communication to specific servers. This works.
But from the WireGuard client i can Web&SSH to all gateways. It dont matter if i Drop all Web/SSH to All Gateways.
I did try, WAN Local, LAN in, Lan Out, Lan Local. But nothing is blocking this traffic.

Has anyone a idea about how to block the gateways access?

@vettronics
Copy link

@simonkaiser9 @ruchette I have the same problem.
I have setup the USG as a Wireguard Client.
The connection is established. From the USG SSH command line I can ping the remote wireguard server and all devices in remote Lan.
I cannot ping the remote devices from any of my local lan pcs...
Local Lan 192.168.2.x ; Remote Lan 192.168.1.x
I can see the route is set on USG:
"192.168.1.0/24 dev wg0 scope link"

Help!! I have spent 2 days on this :$

@simonkaiser9
Copy link

@vettronics I am - to be quite honest - not one hundred percent sure why my setup is now working flawlessly, but I got rid of the static route and have "route-allowed-ips" set to "true" for wg0. Routing between my two connected sites works perfect right now. There are no additional routes configured...

@vettronics
Copy link

@simonkaiser9
Found out the problem :) (contribution from WireGuard/wireguard-vyatta-ubnt#109)
Besides having the routes I also needed to have the my local subnet on the allowedips of the remote server.

@cdoublejj
Copy link

Copy example config.gateway.json to /var/lib/unifi/data/sites/default on the host running the Controller.

thats assuming/presuming the host is running linux and not windows like my self with windows server.

this file path is invalid

@swinchen
Copy link

swinchen commented Sep 5, 2022

Copy example config.gateway.json to /var/lib/unifi/data/sites/default on the host running the Controller.

thats assuming/presuming the host is running linux and not windows like my self with windows server.

this file path is invalid

Well, that's your fault 🤕

@cdoublejj
Copy link

cdoublejj commented Sep 5, 2022

Copy example config.gateway.json to /var/lib/unifi/data/sites/default on the host running the Controller.
thats assuming/presuming the host is running linux and not windows like my self with windows server.
this file path is invalid

Well, that's your fault 🤕

If I could have chose Linux, I def would have. Freedom is better.

@smdx2
Copy link

smdx2 commented Mar 17, 2023

I really need help with this config... :(
I've managed to put wireguard running on my USG, I am able to connect from mobile phone to wireguard server on USG, from my USG I can ping both mobile phone, and internal network when I ssh to my USG, but I cannot access internal LAN resources via mobile phone when connected to wireguard server on USG.

Any hints?

My config.gateway.json file:

{
	"firewall": {
		"group": {
			"network-group": {
				"remote_user_vpn_network": {
					"description": "Remote User VPN subnets",
					"network": [
						"192.168.5.0/24"
					]
				}
			}
		}
	},
  "interfaces": {
    "wireguard": {
      "wg0": {
        "address": [
          "192.168.5.1/24"  
        ],
        "firewall": {
          "in": {
            "name": "LAN_IN"
          },
          "local": {
            "name": "LAN_LOCAL"
          },
          "out": {
            "name": "LAN_OUT"
          }
        },
        "listen-port": "51821",  
        "mtu": "1500",
        "peer": [{
          "public_key_of_android_phone": {   
            "allowed-ips": [
              "192.168.5.50/32"               
            ],
            "persistent-keepalive": 25
          }
        },
        {
          "public_key_of_another_device": {   
            "allowed-ips": [
              "192.168.5.51/32"
            ],
            "persistent-keepalive": 25
          }
        }],
        "private-key": "/config/auth/wireguard/wg_private.key",  
        "route-allowed-ips": "true"
      }
    }
  }
}

My wireguard configuration on mobile phone:
Interface:
public_key_of_android_phone
address: 192.168.5.50/32

peer:
endpoint: public_FQDN:52821
public_key_of_usg
allowed_ips: 0.0.0.0/0
keep-alive: 25s

output of route command on USG:
Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         (redacted) 0.0.0.0         UG    0      0        0 eth0
(redacted)     *               255.255.255.0   U     0      0        0 eth0
loopback        *               255.0.0.0       U     0      0        0 lo
192.168.0.0     *               255.255.254.0   U     0      0        0 eth1
192.168.2.0     *               255.255.255.0   U     0      0        0 eth1.2
192.168.5.0     *               255.255.255.0   U     0      0        0 wg0

output of wg command on USG:

root@USG:~# wg
interface: wg0
  public key: (redacted)
  private key: (redacted)
  listening port: 51821

peer: (redacted)
  endpoint: (redacted):1304
  allowed ips: 192.168.5.50/32
  latest handshake: 41 seconds ago
  transfer: 60.14 KiB received, 105.39 KiB sent
  persistent keepalive: every 25 seconds

Any help would be much appreciated.
I've seen other forums with information, but typically very old one...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment