This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
guides:wireguard_multilan_tunnels [2024/12/12 16:14] – techiem2 | guides:wireguard_multilan_tunnels [2024/12/17 08:20] (current) – [Route Services using NPM] techiem2 | ||
---|---|---|---|
Line 6: | Line 6: | ||
Why use a centralized server for connecting LANs rather than a site to site VPN?\\ | Why use a centralized server for connecting LANs rather than a site to site VPN?\\ | ||
- | 1. | + | - Not all routers/ |
- | 2. If your router is behind an ISP modem/ | + | |
Why use a centralized VPS to expose LAN services to the internet?\\ | Why use a centralized VPS to expose LAN services to the internet?\\ | ||
- | 1. | + | - As above, you may not have the ability to directly expose the ports on your home modem/ |
- | 2. Even if you can directly expose the ports, this adds a layer of security by not needing to publish the public IP of your LAN.\\ | + | |
- | 3. Your ISP may block ports on their side so even if you can expose on your modem/ | + | |
===== Basic Overview of Sample Setup ===== | ===== Basic Overview of Sample Setup ===== | ||
Line 59: | Line 59: | ||
==== Generate Key Pair ==== | ==== Generate Key Pair ==== | ||
Generate the public and private key for the machine:\\ | Generate the public and private key for the machine:\\ | ||
- | wg genkey | tee privatekey | wg pubkey > publickey\\ | + | < |
+ | wg genkey | tee privatekey | wg pubkey > publickey | ||
+ | </ | ||
==== Enable IP Forwarding ==== | ==== Enable IP Forwarding ==== | ||
Line 65: | Line 67: | ||
Edit / | Edit / | ||
Uncomment or add:\\ | Uncomment or add:\\ | ||
- | net.ipv4.ip_forward=1\\ | + | < |
+ | net.ipv4.ip_forward=1 | ||
+ | </ | ||
Reload the config:\\ | Reload the config:\\ | ||
- | sysctl --system\\ | + | < |
+ | sysctl --system | ||
+ | </ | ||
==== Create Config Files ==== | ==== Create Config Files ==== | ||
Create / | Create / | ||
=== VPS1 (Server) === | === VPS1 (Server) === | ||
+ | < | ||
+ | [Interface] | ||
+ | Address = 10.0.0.1/32 | ||
+ | ListenPort = 51820 | ||
+ | PrivateKey = <server private key> | ||
- | [Interface]\\ | + | # LAN1 WG PC (home) |
- | Address | + | [Peer] |
- | ListenPort = 51820\\ | + | PublicKey = <LAN1 WG PC Public Key> |
- | PrivateKey = <server private key>\\ | + | AllowedIPs |
- | # LAN1 WG PC (home)\\ | + | # LAN2 WG PC (work) |
- | [Peer]\\ | + | [Peer] |
- | PublicKey = <LAN1 WG PC Public Key>\\ | + | PublicKey = <LAN2 WG PC Public Key> |
- | AllowedIPs = 10.0.0.2/32, 192.168.100.0/24\\ | + | AllowedIPs = 10.0.0.3/32, 192.168.150.0/24 |
- | # LAN2 WG PC (work)\\ | + | # VPS2 |
- | [Peer]\\ | + | [Peer] |
- | PublicKey = <LAN2 WG PC Public Key>\\ | + | PublicKey = <VPS2 Public Key> |
- | AllowedIPs = 10.0.0.3/ | + | AllowedIPs = 10.0.0.10/ |
- | + | ||
- | # VPS2\\ | + | |
- | [Peer]\\ | + | |
- | PublicKey = <VPS2 Public Key>\\ | + | |
- | AllowedIPs = 10.0.0.10/ | + | |
- | + | ||
- | # VPS3\\ | + | |
- | [Peer]\\ | + | |
- | PublicKey = <VPS3 Public Key>\\ | + | |
- | AllowedIPs = 10.0.0.11/ | + | |
+ | # VPS3 | ||
+ | [Peer] | ||
+ | PublicKey = <VPS3 Public Key> | ||
+ | AllowedIPs = 10.0.0.11/ | ||
+ | </ | ||
=== LAN1 WG PC === | === LAN1 WG PC === | ||
- | [Interface]\\ | + | < |
- | Address = 10.0.0.2/32\\ | + | [Interface] |
- | PrivateKey = <LAN1 WG PC Private Key>\\ | + | Address = 10.0.0.2/ |
- | PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE\\ | + | PrivateKey = <LAN1 WG PC Private Key> |
- | PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE\\ | + | PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE |
+ | PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE | ||
- | # Server\\ | + | # Server |
- | [Peer]\\ | + | [Peer] |
- | PublicKey = <VPS1 Public Key>\\ | + | PublicKey = <VPS1 Public Key> |
- | Endpoint = <VPS1 Public IP>: | + | Endpoint = <VPS1 Public IP>: |
- | AllowedIPs = 10.0.0.0/ | + | AllowedIPs = 10.0.0.0/ |
- | PersistentKeepalive = 25\\ | + | PersistentKeepalive = 25 |
+ | </ | ||
=== LAN2 WG PC === | === LAN2 WG PC === | ||
- | [Interface]\\ | + | < |
- | Address = 10.0.0.3/32\\ | + | [Interface] |
- | PrivateKey = <LAN2 WG PC Private Key>\\ | + | Address = 10.0.0.3/ |
- | PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE\\ | + | PrivateKey = <LAN2 WG PC Private Key> |
- | PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE\\ | + | PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE |
- | + | PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <LAN interface, i.e. eth0> -j MASQUERADE | |
- | # Server\\ | + | |
- | [Peer]\\ | + | |
- | PublicKey = <VPS1 Public Key>\\ | + | |
- | Endpoint = <VPS1 Public IP>: | + | |
- | AllowedIPs = 10.0.0.0/ | + | |
- | PersistentKeepalive = 25\\ | + | |
+ | # Server | ||
+ | [Peer] | ||
+ | PublicKey = <VPS1 Public Key> | ||
+ | Endpoint = <VPS1 Public IP>: | ||
+ | AllowedIPs = 10.0.0.0/ | ||
+ | PersistentKeepalive = 25 | ||
+ | </ | ||
=== VPS2 === | === VPS2 === | ||
- | [Interface]\\ | + | < |
- | Address = 10.0.0.10/ | + | [Interface] |
- | PrivateKey = <VPS2 Private Key>\\ | + | Address = 10.0.0.10/ |
- | + | PrivateKey = <VPS2 Private Key> | |
- | # Server\\ | + | |
- | [Peer]\\ | + | |
- | PublicKey = <VPS1 Public Key>\\ | + | |
- | Endpoint = <VPS1 Public IP>: | + | |
- | AllowedIPs = 10.0.0.0/ | + | |
- | PersistentKeepalive = 25\\ | + | |
+ | # Server | ||
+ | [Peer] | ||
+ | PublicKey = <VPS1 Public Key> | ||
+ | Endpoint = <VPS1 Public IP>: | ||
+ | AllowedIPs = 10.0.0.0/ | ||
+ | PersistentKeepalive = 25 | ||
+ | </ | ||
=== VPS3 === | === VPS3 === | ||
- | [Interface]\\ | + | < |
- | Address = 10.0.0.11/ | + | [Interface] |
- | PrivateKey = <VPS3 Private Key>\\ | + | Address = 10.0.0.11/ |
- | + | PrivateKey = <VPS3 Private Key> | |
- | # Server\\ | + | |
- | [Peer]\\ | + | |
- | PublicKey = <VPS1 Public Key>\\ | + | |
- | Endpoint = <VPS1 Public IP>: | + | |
- | AllowedIPs = 10.0.0.0/ | + | |
- | PersistentKeepalive = 25\\ | + | |
+ | # Server | ||
+ | [Peer] | ||
+ | PublicKey = <VPS1 Public Key> | ||
+ | Endpoint = <VPS1 Public IP>: | ||
+ | AllowedIPs = 10.0.0.0/ | ||
+ | PersistentKeepalive = 25 | ||
+ | </ | ||
=== A Note on AllowedIPs === | === A Note on AllowedIPs === | ||
The AllowedIPs directive specifies what networks the machine will allow to enter the Wireguard interface.\\ | The AllowedIPs directive specifies what networks the machine will allow to enter the Wireguard interface.\\ | ||
Line 160: | Line 171: | ||
You should only need to do this on the VPSs, unless you run local firewalls on the LAN WG PCs as well.\\ | You should only need to do this on the VPSs, unless you run local firewalls on the LAN WG PCs as well.\\ | ||
=== / | === / | ||
- | net eth0 dhcp, | + | < |
- | vpn wg0 | + | net eth0 dhcp, |
+ | vpn wg0 | ||
+ | </ | ||
=== / | === / | ||
- | fw firewall\\ | + | < |
- | net ipv4\\ | + | fw firewall |
- | vpn ipv4\\ | + | net |
+ | vpn ipv4 | ||
+ | </ | ||
=== / | === / | ||
- | $FW | + | < |
- | $FW | + | $FW |
- | vpn | + | $FW |
- | net | + | vpn |
- | all | + | net |
+ | all | ||
+ | </ | ||
=== / | === / | ||
- | ?SECTION NEW\\ | + | < |
- | # Wireguard\\ | + | ?SECTION NEW |
- | ACCEPT | + | # Wireguard |
+ | ACCEPT | ||
+ | </ | ||
==== Test the Setup ==== | ==== Test the Setup ==== | ||
Make sure you've restarted the firewall services if necessary, then start Wireguard: | Make sure you've restarted the firewall services if necessary, then start Wireguard: | ||
- | wg-quick up wg0\\ | + | < |
You should see it bring up the interface and add routes and whatnot.\\ | You should see it bring up the interface and add routes and whatnot.\\ | ||
To view the status run:\\ | To view the status run:\\ | ||
- | wg show\\ | + | < |
On clients this should show the connection information and stats.\\ | On clients this should show the connection information and stats.\\ | ||
On the server it should have a section for each client. | On the server it should have a section for each client. | ||
Line 189: | Line 208: | ||
Make sure you can ping the Wireguard IPs back and forth from clients to server and clients to other clients.\\ | Make sure you can ping the Wireguard IPs back and forth from clients to server and clients to other clients.\\ | ||
Once you have verified, you can configure the system to automatically start the connection on boot" | Once you have verified, you can configure the system to automatically start the connection on boot" | ||
- | systemctl enable wg-quick@wg0\\ | + | < |
==== Enable Cross LAN Routing ==== | ==== Enable Cross LAN Routing ==== | ||
Line 197: | Line 216: | ||
In our case, LAN1 needs access to Wireguard Network and LAN2, and LAN2 needs access to Wireguard network and LAN1.\\ | In our case, LAN1 needs access to Wireguard Network and LAN2, and LAN2 needs access to Wireguard network and LAN1.\\ | ||
=== LAN1 Routes === | === LAN1 Routes === | ||
+ | < | ||
10.0.0.0/24 GW 192.168.100.4 | 10.0.0.0/24 GW 192.168.100.4 | ||
192.168.150.0/ | 192.168.150.0/ | ||
+ | </ | ||
=== LAN2 Routes === | === LAN2 Routes === | ||
+ | < | ||
10.0.0.0/24 GW 192.168.150.4 | 10.0.0.0/24 GW 192.168.150.4 | ||
192.168.100.0/ | 192.168.100.0/ | ||
+ | </ | ||
If everything is correct, machines on each LAN should be able to access all machines on the Wireguard network as well as all machines on the other LAN. | If everything is correct, machines on each LAN should be able to access all machines on the Wireguard network as well as all machines on the other LAN. | ||
- | ==== Exposing External Services ==== | + | ===== Exposing External Services ===== |
+ | Now that we have a nice hub and spoke Wireguard network, we want to expose some services on LAN1 to the outside world.\\ | ||
+ | We will do this using Nginx Proxy Manager (NPM).\\ | ||
+ | This is a relatively easy to setup and use reverse proxy program.\\ | ||
+ | Side Note: If all you want to expose are http/https services, you may want to explore Cloudflare Tunnels. | ||
+ | ==== Install NPM, but with a twist ==== | ||
+ | Pull up the [[https:// | ||
+ | - Remove the ports: section.\\ | ||
+ | - In it's place add: network_mode: | ||
+ | This will cause the docker container to use the host network instead of the docker bridge network.\\ | ||
+ | If you use the docker bridge network, you'll have to:\\ | ||
+ | - Figure out how to get it working properly with your firewall.\\ | ||
+ | - Stop the container, edit the configuration.yml file, and recompose every time you want to add a new port.\\ | ||
+ | |||
+ | ==== Route Services using NPM ==== | ||
+ | NPM is fairly straightforward to use, but there' | ||
+ | 1. Each port you want NPM to handle needs to be open on the firewall, so you need to add the appropriate rules.\\ | ||
+ | Web hosting is the obvious example (and primary focus of NPM)\\ | ||
+ | Another would be opening an OpenVPN server on your LAN for remote connections by your phone/ | ||
+ | Shorewall example rules:\\ | ||
+ | < | ||
+ | ACCEPT net fw tcp 80 | ||
+ | ACCEPT net fw tcp 443 | ||
+ | ACCEPT net fw udp 1194 | ||
+ | </ | ||
+ | 2. Web services (Proxy Hosts) need a hostname and ideally an SSL Certificate.\\ | ||
+ | In my case I have a specific domain that I use for external access services, but you could just use subdomains of any domain you control.\\ | ||
+ | The general process is to point a subdomain to the IP of the VPS, create the forwarding host in NPM, and have NPM use LetsEncrypt to generate an SSL certificate for it.\\ | ||
+ | The LetsEncrypt client supports a number of verification methods, including DNS based verification. | ||
+ | Since I use a dedicated domain for my public access hosts, I moved the DNS management of that domain to Cloudflare and had NPM use DNS verification with LetsEncrypt via the Cloudflare API plugin to generate a wildcard cert for my domain so I don't have to generate a new cert for each subdomain - I just add the DNS entry for the new subdomain then configure the host in NPM using the existing certificate.\\ | ||
+ | 3. For non-http/ | ||
+ | So for our example lets create a Proxy host using the domain home.mydomain.com, | ||
+ | - Login to the NPM web interface. | ||
+ | - Click Proxy Hosts\\ | ||
+ | - Click Add Proxy Host\\ | ||
+ | - Domain Name: home.mydomain.com\\ | ||
+ | - Scheme: http or https, whichever your internal server is running on.\\ | ||
+ | - Forward Hostname/ | ||
+ | - Forward Port: Port your server listens on, so likely 80 (http) or 443 (https)\\ | ||
+ | - Turn on Block Common Exploits, and if needed, Websockets Support\\ | ||
+ | - Switch to the SSL Tab\\ | ||
+ | - Select an existing certificate that covers that hostname or Request a new SSL Certificate.\\ | ||
+ | - Check Force SSL and HSTS Enabled.\\ | ||
+ | - If requesting a new cert, select Use DNS Challenge if you are using that, otherwise it will use the http verification method.\\ | ||
+ | - If requesting a new cert, agree to the LetsEncrypt terms.\\ | ||
+ | - Hit Save.\\ | ||
+ | You can also manage and request certs from the SSL Certificates section.\\ | ||
+ | If everything worked correctly and is configured correctly, you should be able to browse to home.mydomain.com from outside your LAN.\\ | ||
+ | Now for the OpenVPN connection: | ||
+ | Let's say our OpenVPN server is on Lan1 at 192.168.100.15.\\ | ||
+ | - Go to Hosts -> Streams (or Dashboard -> Streams).\\ | ||
+ | - Click Add Stream.\\ | ||
+ | - Incoming Port: 1194\\ | ||
+ | - Forward Host: 192.168.100.15\\ | ||
+ | - Forward Port: 1194\\ | ||
+ | - Uncheck TCP and check UDP.\\ | ||
+ | - Click Save.\\ | ||
+ | If everything is configured correctly, your OpenVPN client should now be able to connect from outside your network by pointing it to the VPS IP address (or an associated hostname).\\ | ||
+ | ===== Wrapup ===== | ||
+ | So that's a general guide to how I set this up for myself. | ||
+ | It took me a few days and lots of searching and testing and pestering friends to get it all working how I wanted, so I thought a write up would be helpful. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||