Difference between revisions of "Wireguard"
(→todo) |
|||
(30 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | Wireguard is a godsend to IT admins trying to manage VPNs. | ||
+ | It is just as complex as it needs to be, to be a practical vpn, but no more. | ||
+ | Much faster than any other VPN I've ever used (roadwarrior scripts and things like sonicwalls global vpn client don't count, as they | ||
+ | just hide the underlying functionality from the admin, making it impossible to fix if things don't 'just work'.). | ||
+ | |||
wireguard has a few setup scenarios. each are unique. | wireguard has a few setup scenarios. each are unique. | ||
+ | ==windows client to owrt split tunnel== | ||
+ | ===windows=== | ||
+ | this setup assumes you are using it as a traditional vpn to access resources. not to hide your ip address / internet traffic. | ||
− | |||
− | |||
download, run installer, add empty tunnel | download, run installer, add empty tunnel | ||
<pre> | <pre> | ||
Line 12: | Line 18: | ||
[Peer] | [Peer] | ||
PublicKey = (find it on server) | PublicKey = (find it on server) | ||
− | AllowedIPs = (what you want to be able to connect to on vpn lan) | + | AllowedIPs = (what you want to be able to connect to on vpn lan)(usually its the vpn router's ip, and then the lan range behind the router) |
Endpoint = (ipaddress:port) | Endpoint = (ipaddress:port) | ||
</pre> | </pre> | ||
− | Optional: If you have a windows server w/dns (i.e. domain) use | + | Optional: If you have a windows server w/dns (i.e. domain) don't use the vpn router but the windows server as the DNS. However, you may want to also add some other dns (level 4 / google) as backups. e.g. |
<pre> | <pre> | ||
[Interface] | [Interface] | ||
Line 22: | Line 28: | ||
Address = | Address = | ||
DNS = (windows server and the subnet should be on allowed ips, if it isn't already), 4.2.2.2, 8.8.8.8 | DNS = (windows server and the subnet should be on allowed ips, if it isn't already), 4.2.2.2, 8.8.8.8 | ||
+ | </pre> | ||
+ | troubleshoot that with nslookup. You might think you can avoid this and hardcode the dns in window's /etc/hosts but that won't properly resolve the domain controller. and everytime you access a domain share you have to enter a password. bad idea. | ||
+ | ===owrt=== | ||
+ | <pre> | ||
+ | config interface 'vpn' | ||
+ | option proto 'wireguard' | ||
+ | option private_key | ||
+ | option listen_port someport | ||
+ | list addresses ipofvpnhost | ||
+ | |||
+ | config wireguard_vpn 'anyname' | ||
+ | list allowed_ips 'onlyoneip/32' | ||
+ | option public_key | ||
+ | option route_allowed_ips '1' | ||
+ | </pre> | ||
+ | only tricky thing here is you need route_allowed_ips so the client knows to look for it's specified allowedips on the vpn iface | ||
+ | the good news about this setup, is that owrt handles some of the routing / forwarding on its side. so you don't have to worry about a source nat command. you do have the follow the owrt install docs for wg though. | ||
+ | |||
+ | ==Tips/Troubleshooting== | ||
+ | ===Basics=== | ||
+ | tcpdump -ni eth1 dst/src <ip> | ||
+ | tcpdump -ni vpn | ||
+ | route | ||
+ | wg (make sure the keys line up) | ||
+ | Make sure the vpn network is added to the lan section of /etc/config/firewall. This is a mistake I used to make. | ||
+ | |||
+ | Imagine doing this on one of those intern designed tacked on guis from sophos or sonicwall. Pure torture. Literally | ||
+ | a layer of dogshit painted over the 'actually useful' command line tools. There is a reason starlink uses | ||
+ | Owrt, and not some busywork web gui bullshit. Trying to use the molasses packet capture on a sonicwall or sophos through the | ||
+ | web gui is demonic firewall design. "Some things exist on earth as an example of how it is 'not' supposed to be done". | ||
+ | ===Windows Firewall for SMB Shares=== | ||
+ | Windows and wireguard will set it as a public network where smb doesn't always work. | ||
+ | the network is not listed in settings. but its there in the firewall section of settings... | ||
+ | so you have to edit it via powershell. bad software design. (from W11 2023). | ||
+ | |||
+ | Get-NetConnectionProfile will list the networks (there are a bunch of windows Get- commands) | ||
+ | Set-NetConnectionProfile -InterfaceAlias 'wg0' -NetworkCategory 'Private' | ||
+ | note that the Alias may be different from wg0. | ||
+ | the samba error in mount.cifs in linux (if testing an smb share) is | ||
+ | mount error(115): Operation now in progress. | ||
+ | the smb error in windows. haha. there's no fucking error # in windows. just a | ||
+ | generic error message. | ||
+ | |||
+ | Finally, you have to make one other change: its a firewall error. as you can prove | ||
+ | because mount.cifs works with the firewall disabled. | ||
+ | Therefore, set these ports open: | ||
+ | UDP\137-138 and TCP\137,139,445. | ||
+ | in windows advanced firewall. it's two rules, so set | ||
+ | all the TCP ports open, then all the UDP ports open | ||
+ | |||
+ | ===DNS on owrt=== | ||
+ | If you see that DNS requests are being ignored from a client on the VPN (packets in tcpdump arrive but nothing happens) | ||
+ | yet dnsmasq is listening on all interfaces (which it does by default in owrt) look at logread, you might see the message "ignoring query from non-local network" from dnsmasq. | ||
+ | This is due to the | ||
+ | localservice setting in /etc/config/dhcp | ||
+ | "Accept DNS queries only from hosts whose address is on a local subnet, ie a subnet for which an interface exists on the server." | ||
+ | Change that from 1 to 0 and requests should go through. | ||
+ | |||
+ | I also found that while in the lan requests to <hostname> would work, through the vpn, only requests to <hostname.lan> would work. IP resolution, of course, always worked. (windows) | ||
+ | ===owrt settings=== | ||
+ | There are some other settings you must make sure to include in owrt. For example: | ||
+ | /etc/config/firewall must include vpn in its lan section, e.g.: | ||
+ | <pre> | ||
+ | config zone | ||
+ | option name lan | ||
+ | list network 'lan' | ||
+ | list network 'vpn' | ||
+ | option input ACCEPT | ||
+ | option output ACCEPT | ||
+ | option forward ACCEPT | ||
+ | </pre> | ||
+ | Also the SOURCE NAT / MASQUERADE rules that you are used to setting with VPNs are still required with openwrt. I.e. you are changing your vpn client to look like the router when routing packets, so that the packets go through properly. This is a form of NAT. It's a bit confusing as the firewall has changed over time in owrt, and the rule used to look like this with iptables (source nat not masquerade version): | ||
+ | iptables -t nat -A POSTROUTING -s myvpnclientipaddress/32 -o vpn -j SNAT --to-source vpnrouteripaddress | ||
+ | but now looks like this with nft (owrt >21 or so): | ||
+ | nft add rule inet fw4 srcnat oifname "vpn" ip saddr myvpnclientipaddress counter snat to vpnrouteripaddress | ||
+ | Because of the different tables between iptables to nft, postrouting in owrt is now changed to srcnat. | ||
+ | I usually put these in /etc/firewall.user (see [[openwrt]]). | ||
+ | |||
+ | ==todo== | ||
+ | ===alpine to owrt=== | ||
+ | ===debian to debian=== | ||
+ | follow https://wiki.debian.org/WireGuard | ||
+ | This will just work, though you will need some firewall rules for additional security. | ||
+ | ===debian to owrt=== | ||
+ | <pre> | ||
+ | debian client: | ||
+ | a file named /etc/wireguard/wg0.conf | ||
+ | [Interface] | ||
+ | PrivateKey = | ||
+ | ListenPort = | ||
+ | #Address = SEE NOTES BELOW | ||
+ | |||
+ | [Peer] | ||
+ | PublicKey = | ||
+ | PreSharedKey = | ||
+ | AllowedIPs = 0.0.0.0/0 #for routing all traffic, this may vary | ||
+ | Endpoint = | ||
+ | |||
+ | |||
+ | And 'try' the following. (read below for a trap) | ||
+ | in /etc/network/interfaces | ||
+ | auto wg0 | ||
+ | iface wg0 inet auto | ||
+ | address | ||
+ | netmask | ||
+ | pre-up wg-quick up $IFACE | ||
+ | post-down wg-quick down $IFACE | ||
+ | |||
+ | One day on debian bullseye 11.1 i was unable to get the above | ||
+ | section in network/interfaces working because the vpn server used a | ||
+ | ddns name, and for whatever reason dns wouldn't resolve. theres not | ||
+ | really a way to delay the setup of the wg0 interface, or set it as manual | ||
+ | in /etc/network/interfaces | ||
+ | (there is a manual option but that doesn't do what you think). | ||
+ | If you run into this trap, just use wg-quick manually. If you end up using | ||
+ | network interfaces, then the address must be specified in network interfaces but | ||
+ | if you only use wg-quick then you specify the address in the wg0. I would guess | ||
+ | this is only a problem if you use ddns in the server endpoint from the debian client, | ||
+ | and with an ip it's not going to be an issue. | ||
+ | |||
+ | for reference the wg-quick script does (when first going down, then up) | ||
+ | [#] ip link delete dev wg0 | ||
+ | [#] ip link add wg0 type wireguard | ||
+ | [#] wg setconf wg0 /dev/fd/63 | ||
+ | [#] ip -4 address add <wgip> dev wg0 | ||
+ | [#] ip link set mtu 1420 up dev wg0 | ||
+ | [#] ip -4 route add <route> dev wg0 | ||
+ | [#] ip -4 route add <route> dev wg0 | ||
+ | |||
+ | #note on listenport: the listen port can be set statically as above. | ||
+ | #or if you don't include it, wireguard will randomly choose a port (which it changes | ||
+ | periodically). I think. You may also be able to set the endpoint of clients (along with | ||
+ | their port) which means you get more security, but I can't test it at the moment as my | ||
+ | server is not a VPS but in an onsite device. I don't see anybody doing this but it may | ||
+ | work. I need to test this. Usually people only set the endpoint of the server. But why | ||
+ | not set both, for added security. | ||
+ | |||
+ | openwrt server: | ||
+ | config interface 'vpn' | ||
+ | option proto 'wireguard' | ||
+ | option private_key '' | ||
+ | option listen_port '' | ||
+ | list addresses 'wireguard outside ip' | ||
+ | |||
+ | config wireguard_vpn 'apeer' | ||
+ | option public_key | ||
+ | option preshared_key | ||
+ | option route_allowed_ips '1' | ||
+ | list allowed_ips '' | ||
+ | list allowed_ips '' | ||
+ | |||
+ | |||
+ | </pre> | ||
+ | |||
+ | ===windows to windows=== | ||
+ | ===owrt to debian=== | ||
+ | <pre> | ||
+ | CLIENT: openwrt | ||
+ | config interface 'vpn' | ||
+ | option proto 'wireguard' | ||
+ | option private_key ' | ||
+ | list addresses 'youraddress' | ||
+ | |||
+ | config wireguard_vpn | ||
+ | option description 'name' | ||
+ | option endpoint_host 'ipaddress' | ||
+ | option endpoint_port 'port' | ||
+ | list allowed_ips 'debiansubnetsyouwanttoaccess/24' | ||
+ | list allowed_ips 'debianvpnaddress/32' | ||
+ | option public_key ' | ||
+ | option preshared_key ' | ||
+ | option route_allowed_ips '1' | ||
+ | |||
+ | the allowed ips and route allowed ips are important here. if this was a fullon vpn, the allowed ips would be 0.0.0.0/0 | ||
+ | |||
+ | SERVER: debian 10 | ||
+ | ==================== | ||
+ | (etc network interfaces) | ||
+ | (note: see debian wiki for an alternative configuration) | ||
+ | auto wg-p2p | ||
+ | iface wg-p2p inet static | ||
+ | address anyip | ||
+ | netmask 255.255.255.0 | ||
+ | pre-up wg-quick up $IFACE | ||
+ | post-down wg-quick down $IFACE | ||
+ | |||
+ | (/etc/wireguard/wg-p2p.conf) | ||
+ | |||
+ | [Interface] | ||
+ | PrivateKey = | ||
+ | ListenPort = portnumber | ||
+ | |||
+ | [Peer] | ||
+ | PublicKey = | ||
+ | PreSharedKey = | ||
+ | AllowedIPs = owrtvpn/32 | ||
+ | |||
+ | with these two settings, the iface will be visible on the specified udp port | ||
+ | |||
+ | and ping between will work. this is p2p. | ||
+ | if ping doesnt work, make sure there are routes between each box on the vpn interface | ||
+ | |||
+ | next | ||
+ | |||
+ | DEBIAN requires firewall rules | ||
+ | AND | ||
+ | ipv4 forwarding enabled. | ||
+ | |||
+ | its NOT masquerade | ||
+ | it's this: | ||
+ | iptables-legacy -t nat -A POSTROUTING -s vpnsubnet/24 -o vpsoutputiface -j SNAT --to-source vpswanip | ||
+ | the outputiface is eth0 or eth1 | ||
+ | convert to nft with iptables-translate if necessary | ||
+ | |||
+ | in my VPS, ipv4 forwarding was not enabled by default. TRAP. | ||
+ | so do that right too. | ||
+ | |||
+ | vpns will bite you here: | ||
+ | |||
+ | firewall rules must change traffic from vpn to appear like its coming from vps. yes, even wireguard (sometimes... depends what distro you use) | ||
+ | forwarding must be enabled (depends upon distro again, but don't forget this) | ||
+ | wireguard: routes must be properly setup | ||
+ | wireguard: ping to start interface conversation from client. when in doubt use tcpdump. | ||
+ | |||
+ | |||
+ | firewall on client owrt: must add vpn to WAN (not lan zone) to minimize setup (i.e. so you don't make its own interface) | ||
+ | once you do this last step, clients will be able to connect in the client pool. not just the owrt router. | ||
+ | |||
+ | Troubleshooting: | ||
+ | make sure docker isn't causing trouble. if you install docker, it disables the | ||
+ | default forwarding policy of accept. (makes it reject). | ||
</pre> | </pre> |
Latest revision as of 01:44, 26 September 2024
Wireguard is a godsend to IT admins trying to manage VPNs. It is just as complex as it needs to be, to be a practical vpn, but no more. Much faster than any other VPN I've ever used (roadwarrior scripts and things like sonicwalls global vpn client don't count, as they just hide the underlying functionality from the admin, making it impossible to fix if things don't 'just work'.).
wireguard has a few setup scenarios. each are unique.
windows client to owrt split tunnel
windows
this setup assumes you are using it as a traditional vpn to access resources. not to hide your ip address / internet traffic.
download, run installer, add empty tunnel
[Interface] PrivateKey = (it should auto populate this for you)(public key is above in text field) Address = (the ip you want on the vpn net/32 for one ip) [Peer] PublicKey = (find it on server) AllowedIPs = (what you want to be able to connect to on vpn lan)(usually its the vpn router's ip, and then the lan range behind the router) Endpoint = (ipaddress:port)
Optional: If you have a windows server w/dns (i.e. domain) don't use the vpn router but the windows server as the DNS. However, you may want to also add some other dns (level 4 / google) as backups. e.g.
[Interface] PrivateKey = Address = DNS = (windows server and the subnet should be on allowed ips, if it isn't already), 4.2.2.2, 8.8.8.8
troubleshoot that with nslookup. You might think you can avoid this and hardcode the dns in window's /etc/hosts but that won't properly resolve the domain controller. and everytime you access a domain share you have to enter a password. bad idea.
owrt
config interface 'vpn' option proto 'wireguard' option private_key option listen_port someport list addresses ipofvpnhost config wireguard_vpn 'anyname' list allowed_ips 'onlyoneip/32' option public_key option route_allowed_ips '1'
only tricky thing here is you need route_allowed_ips so the client knows to look for it's specified allowedips on the vpn iface the good news about this setup, is that owrt handles some of the routing / forwarding on its side. so you don't have to worry about a source nat command. you do have the follow the owrt install docs for wg though.
Tips/Troubleshooting
Basics
tcpdump -ni eth1 dst/src <ip> tcpdump -ni vpn route wg (make sure the keys line up)
Make sure the vpn network is added to the lan section of /etc/config/firewall. This is a mistake I used to make.
Imagine doing this on one of those intern designed tacked on guis from sophos or sonicwall. Pure torture. Literally a layer of dogshit painted over the 'actually useful' command line tools. There is a reason starlink uses Owrt, and not some busywork web gui bullshit. Trying to use the molasses packet capture on a sonicwall or sophos through the web gui is demonic firewall design. "Some things exist on earth as an example of how it is 'not' supposed to be done".
Windows and wireguard will set it as a public network where smb doesn't always work. the network is not listed in settings. but its there in the firewall section of settings... so you have to edit it via powershell. bad software design. (from W11 2023).
Get-NetConnectionProfile will list the networks (there are a bunch of windows Get- commands) Set-NetConnectionProfile -InterfaceAlias 'wg0' -NetworkCategory 'Private'
note that the Alias may be different from wg0. the samba error in mount.cifs in linux (if testing an smb share) is mount error(115): Operation now in progress. the smb error in windows. haha. there's no fucking error # in windows. just a generic error message.
Finally, you have to make one other change: its a firewall error. as you can prove because mount.cifs works with the firewall disabled. Therefore, set these ports open:
UDP\137-138 and TCP\137,139,445.
in windows advanced firewall. it's two rules, so set all the TCP ports open, then all the UDP ports open
DNS on owrt
If you see that DNS requests are being ignored from a client on the VPN (packets in tcpdump arrive but nothing happens) yet dnsmasq is listening on all interfaces (which it does by default in owrt) look at logread, you might see the message "ignoring query from non-local network" from dnsmasq. This is due to the localservice setting in /etc/config/dhcp "Accept DNS queries only from hosts whose address is on a local subnet, ie a subnet for which an interface exists on the server." Change that from 1 to 0 and requests should go through.
I also found that while in the lan requests to <hostname> would work, through the vpn, only requests to <hostname.lan> would work. IP resolution, of course, always worked. (windows)
owrt settings
There are some other settings you must make sure to include in owrt. For example: /etc/config/firewall must include vpn in its lan section, e.g.:
config zone option name lan list network 'lan' list network 'vpn' option input ACCEPT option output ACCEPT option forward ACCEPT
Also the SOURCE NAT / MASQUERADE rules that you are used to setting with VPNs are still required with openwrt. I.e. you are changing your vpn client to look like the router when routing packets, so that the packets go through properly. This is a form of NAT. It's a bit confusing as the firewall has changed over time in owrt, and the rule used to look like this with iptables (source nat not masquerade version):
iptables -t nat -A POSTROUTING -s myvpnclientipaddress/32 -o vpn -j SNAT --to-source vpnrouteripaddress
but now looks like this with nft (owrt >21 or so):
nft add rule inet fw4 srcnat oifname "vpn" ip saddr myvpnclientipaddress counter snat to vpnrouteripaddress
Because of the different tables between iptables to nft, postrouting in owrt is now changed to srcnat. I usually put these in /etc/firewall.user (see openwrt).
todo
alpine to owrt
debian to debian
follow https://wiki.debian.org/WireGuard This will just work, though you will need some firewall rules for additional security.
debian to owrt
debian client: a file named /etc/wireguard/wg0.conf [Interface] PrivateKey = ListenPort = #Address = SEE NOTES BELOW [Peer] PublicKey = PreSharedKey = AllowedIPs = 0.0.0.0/0 #for routing all traffic, this may vary Endpoint = And 'try' the following. (read below for a trap) in /etc/network/interfaces auto wg0 iface wg0 inet auto address netmask pre-up wg-quick up $IFACE post-down wg-quick down $IFACE One day on debian bullseye 11.1 i was unable to get the above section in network/interfaces working because the vpn server used a ddns name, and for whatever reason dns wouldn't resolve. theres not really a way to delay the setup of the wg0 interface, or set it as manual in /etc/network/interfaces (there is a manual option but that doesn't do what you think). If you run into this trap, just use wg-quick manually. If you end up using network interfaces, then the address must be specified in network interfaces but if you only use wg-quick then you specify the address in the wg0. I would guess this is only a problem if you use ddns in the server endpoint from the debian client, and with an ip it's not going to be an issue. for reference the wg-quick script does (when first going down, then up) [#] ip link delete dev wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add <wgip> dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] ip -4 route add <route> dev wg0 [#] ip -4 route add <route> dev wg0 #note on listenport: the listen port can be set statically as above. #or if you don't include it, wireguard will randomly choose a port (which it changes periodically). I think. You may also be able to set the endpoint of clients (along with their port) which means you get more security, but I can't test it at the moment as my server is not a VPS but in an onsite device. I don't see anybody doing this but it may work. I need to test this. Usually people only set the endpoint of the server. But why not set both, for added security. openwrt server: config interface 'vpn' option proto 'wireguard' option private_key '' option listen_port '' list addresses 'wireguard outside ip' config wireguard_vpn 'apeer' option public_key option preshared_key option route_allowed_ips '1' list allowed_ips '' list allowed_ips ''
windows to windows
owrt to debian
CLIENT: openwrt config interface 'vpn' option proto 'wireguard' option private_key ' list addresses 'youraddress' config wireguard_vpn option description 'name' option endpoint_host 'ipaddress' option endpoint_port 'port' list allowed_ips 'debiansubnetsyouwanttoaccess/24' list allowed_ips 'debianvpnaddress/32' option public_key ' option preshared_key ' option route_allowed_ips '1' the allowed ips and route allowed ips are important here. if this was a fullon vpn, the allowed ips would be 0.0.0.0/0 SERVER: debian 10 ==================== (etc network interfaces) (note: see debian wiki for an alternative configuration) auto wg-p2p iface wg-p2p inet static address anyip netmask 255.255.255.0 pre-up wg-quick up $IFACE post-down wg-quick down $IFACE (/etc/wireguard/wg-p2p.conf) [Interface] PrivateKey = ListenPort = portnumber [Peer] PublicKey = PreSharedKey = AllowedIPs = owrtvpn/32 with these two settings, the iface will be visible on the specified udp port and ping between will work. this is p2p. if ping doesnt work, make sure there are routes between each box on the vpn interface next DEBIAN requires firewall rules AND ipv4 forwarding enabled. its NOT masquerade it's this: iptables-legacy -t nat -A POSTROUTING -s vpnsubnet/24 -o vpsoutputiface -j SNAT --to-source vpswanip the outputiface is eth0 or eth1 convert to nft with iptables-translate if necessary in my VPS, ipv4 forwarding was not enabled by default. TRAP. so do that right too. vpns will bite you here: firewall rules must change traffic from vpn to appear like its coming from vps. yes, even wireguard (sometimes... depends what distro you use) forwarding must be enabled (depends upon distro again, but don't forget this) wireguard: routes must be properly setup wireguard: ping to start interface conversation from client. when in doubt use tcpdump. firewall on client owrt: must add vpn to WAN (not lan zone) to minimize setup (i.e. so you don't make its own interface) once you do this last step, clients will be able to connect in the client pool. not just the owrt router. Troubleshooting: make sure docker isn't causing trouble. if you install docker, it disables the default forwarding policy of accept. (makes it reject).