Skip to content

Instantly share code, notes, and snippets.

@adrianmihalko
Last active August 29, 2022 03:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrianmihalko/39f603cf06c6e5d8d7b2a3a7beebf765 to your computer and use it in GitHub Desktop.
Save adrianmihalko/39f603cf06c6e5d8d7b2a3a7beebf765 to your computer and use it in GitHub Desktop.
Selective routing trough VPN with Unifi USG.
I wanted to route only specific IPs trough a Wireguard interface. I am not expert in any way, but I am trying to explain you as best I can how I did it.
Setup a WG connection as usual on one of your device in your network (In my example I will call it "Ubuntu server", 192.168.1.54):
[Interface]
Address = something/24
PrivateKey = longprivatekeyR5FE=
Table = 43
PostUp = ip rule add from 192.168.1.91 table 43; iptables -w -A FORWARD -i %i -j ACCEPT; iptables -w -A FORWARD -o %i -j ACCEPT; iptables -w -t nat -A POSTROUTING -o ens160 -j MASQUERADE; iptables -t nat -A POSTROUTING -o %i -j MASQUERADE
PostDown = ip rule del from 192.168.1.91 table 43; iptables -w -D FORWARD -i %i -j ACCEPT; iptables -w -D FORWARD -o %i -j ACCEPT; iptables -w -t nat -D POSTROUTING -o ens160 -j MASQUERADE; iptables -t nat -D POSTROUTING -o %i -j MASQUERADE
[Peer]
Endpoint = mullvad.com:51820
PublicKey = longkeyqlVQ=
AllowedIPs = 0.0.0.0/0
---
Explanation:
Postup/Postdown commands are the interesting parts here. We are adding everything into table 43, so default route should be not overwritten on the device (note: we are not wanting to forward all traffic trough WG). We need to do some NAT and MASQUERADE to properly route the traffic in and out. Don't forget to replace interface name with your actual interface name (ens160 is my physical port on the server). Also replace 192.168.1.91 with IP you want to route trough WG interface. You want to add more IPs? Double the command.
Like this (even if you are not using Unifi / USG) you can set this device's IP (= of the "Ubuntu server" where WG is running: 192.168.1.54) as router/gateway of your client and voila, your client should be routed trough WG interface. All other traffic should be routed trough your normal network.
If you verified that it's working you are allowed ( :-D ) to continue. We are lazy AF and we are don't want to set IP of router/gateway manually on clients. We have expensive Unifi gear which of course don't support setting policy based routing trough web interface (promised for a couple of years), so we are diving into CLI.
First, I would suggest you to create an IP group (type Address IPv4) trough web interface:
Settings -> Routing & Firewall -> Firewall tab -> Groups tab
VPN-IP
if you want to specify what should be routed trough WG even more, create one more group for ports (type Port):
VPN-PORT
Like this, we can forward traffic which destination port is set in this group. Example you set here 80, 443, all your normal web traffic will be routed trough WG interface, but other traffic, example SSH will be routed your normal internet connection.
Let's SSH into USG. Find your groups's exotic name:
$ show firewall group
Name : 6029c6a2e4f9411eca9687e0
Type : port
Description: customized-VPN-PORT
References : LOAD_BALANCE-2501-destination
Members :
23
80
Name : 6029c3e9e4f9411eca96870f
Type : address
Family : IPv4
Description: customized-VPN-IP
References : LOAD_BALANCE-2501-source
Members :
192.168.1.91
From there it's pretty straight forward:
configure
set protocols static table 5 route 0.0.0.0/0 next-hop 192.168.1.54
set firewall modify LOAD_BALANCE rule 2501 action modify
set firewall modify LOAD_BALANCE rule 2501 modify table 5
set firewall modify LOAD_BALANCE rule 2501 source group address-group 6029c3e9e4f9411eca96870f
set firewall modify LOAD_BALANCE rule 2501 protocol tcp
set firewall modify LOAD_BALANCE rule 2501 destination group port-group 6029c6a2e4f9411eca9687e0
commit ; exit
You can skip the protocol tcp, desctination port-group lines if you want all traffic to be routed from IPs you specified in the VPN-IP group.
Verify if it works. Continue only if it works.
We want to keep this config accross restarts, so we need to add this into config.gateway.json (mine is located at /usr/lib/unifi/data/sites/default/config.gateway.json) launch force reprovision and verify again if it works.
In the future you should just add new IPs/ports to the group and it will work like magic.
Thanks for reading,
Adrian Mihalko
www.mihalkoe.eu
{
"firewall": {
"modify": {
"LOAD_BALANCE": {
"description": "LOAD_BALANCE",
"rule": {
"2501": {
"action": "modify",
"destination": {
"group": {
"port-group": "6029c6a2e4f9411eca9687e0"
}
},
"modify": {
"table": "5"
},
"protocol": "tcp",
"source": {
"group": {
"address-group": "6029c3e9e4f9411eca96870f"
}
}
}
}
}
}
},
"protocols": {
"static": {
"table": {
"5": {
"route": {
"0.0.0.0/0": {
"next-hop": {
"192.168.1.54": "''"
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment