├── .github
└── FUNDING.yml
├── LICENSE
├── README.md
├── example-full
├── README.md
├── home-server
│ ├── home-server.key
│ ├── home-server.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── laptop
│ ├── laptop.key
│ ├── laptop.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── phone
│ ├── phone.key
│ ├── phone.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── public-server1
│ ├── public-server1.key
│ ├── public-server1.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
└── public-server2
│ ├── public-server2.key
│ ├── public-server2.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── example-internet-browsing-vpn
├── laptop
│ ├── laptop.key
│ ├── laptop.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── phone
│ ├── phone.key
│ ├── phone.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
└── server
│ ├── server.key
│ ├── server.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── example-iptables
└── iptables.sh
├── example-lan-briding
├── montreal
│ ├── montreal.key
│ ├── montreal.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
├── newyork
│ ├── newyork.key
│ ├── newyork.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
└── vancouver
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ ├── vancouver.key
│ ├── vancouver.key.pub
│ └── wg0.conf
├── example-simple-client-to-server
├── client
│ ├── client.key
│ ├── client.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
└── server
│ ├── server.key
│ ├── server.key.pub
│ ├── setup.sh
│ ├── start.sh
│ ├── stop.sh
│ └── wg0.conf
└── example-simple-server-to-server
├── server1
├── server1.key
├── server1.key.pub
├── setup.sh
├── start.sh
├── stop.sh
└── wg0.conf
└── server2
├── server2.key
├── server2.key.pub
├── setup.sh
├── start.sh
├── stop.sh
└── wg0.conf
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: zx2c4
4 | patreon: zx2c4
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 ~ 2023 Nick Sweeting
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Some Unofficial WireGuard Documentation
4 |
5 |
6 |
7 |
8 | API reference guide for WireGuard including Setup, Configuration, and Usage, with examples.
9 |
10 |
11 | All credit goes to the WireGuard project, [zx2c4](https://www.zx2c4.com/) and the [open source contributors](https://github.com/WireGuard/WireGuard/graphs/contributors) for the original software,
this is my solo unofficial attempt at providing more comprehensive documentation, API references, and examples.
12 |
13 |
14 |
15 | Source for these docs, example code, and issue tracker: https://github.com/pirate/wireguard-docs
16 | Nicer HTML page version: https://docs.sweeting.me/s/wireguard
17 |
18 |
19 |
20 |
21 |
22 | ---
23 |
24 | [WireGuard](https://www.wireguard.com/) is an open-source VPN solution written in C by [Jason Donenfeld](https://www.jasondonenfeld.com) and [others](https://github.com/WireGuard/WireGuard/graphs/contributors), aiming to fix many of the problems that have plagued other modern server-to-server VPN offerings like IPSec/IKEv2, OpenVPN, or L2TP. It shares some similarities with other modern VPN offerings like [Tinc](https://www.tinc-vpn.org/) and [MeshBird](https://github.com/meshbird/meshbird), namely good cipher suites and minimal config. As of 2020-01 [it's been merged into the 5.6 version of the Linux kernel](https://arstechnica.com/gadgets/2020/01/linus-torvalds-pulled-wireguard-vpn-into-the-5-6-kernel-source-tree/), meaning it will ship with most Linux systems out-of-the-box.
25 |
26 | **Official Links**
27 |
28 | - Homepage: https://www.wireguard.com
29 | - Install: https://www.wireguard.com/install/
30 | - QuickStart: https://www.wireguard.com/quickstart/
31 | - Manpages: [`wg`](https://manpages.debian.org/testing/wireguard-tools/wg.8.en.html), [`wg-quick`](https://manpages.debian.org/unstable/wireguard-tools/wg-quick.8.en.html)
32 | - Main Git repo: https://git.zx2c4.com/WireGuard/
33 | - GitHub Mirror: https://github.com/WireGuard/WireGuard
34 | - Mailing List: https://lists.zx2c4.com/mailman/listinfo/wireguard
35 |
36 | **WireGuard Goals**
37 |
38 | - strong, modern security by default
39 | - minimal config and key management
40 | - fast, both low-latency and high-bandwidth
41 | - simple internals and small protocol surface area
42 | - simple CLI and seamless integration with system networking
43 |
44 |
45 |
46 | It's also fast as hell. I routinely get sub 0.5ms pings and 900mbps+ on good connections.
47 | (See https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/)
48 |
49 |
50 |
51 | ---
52 |
53 | # Table of Contents
54 |
55 | See https://github.com/pirate/wireguard-docs for example code and documentation source.
56 |
57 |
134 |
135 |
136 | # Intro
137 |
138 | Whether living behind the Great Wall of China or just trying to form a network between your servers, WireGuard is a great option and serves as a "lego block" for building networks (much in the same way that ZFS is a lego block for building filesystems).
139 |
140 | ## WireGuard Overview
141 |
142 | - minimal config, low tunable surface area and sane defaults
143 | - minimal key management work needed, just 1 public & 1 private key per host
144 | - behaves like a normal ethernet interface, behaves well with standard kernel packet routing rules
145 | - ability to easily create a LAN like 192.0.2.0/24 between all servers, or more complex networks using custom routes
146 | - ability to some traffic or all traffic to/through arbitrary hosts on the VPN LAN
147 | - robust automatic reconnects after reboots / network downtime / NAT connection table drops
148 | - fast (low latency and line-rate bandwidth)
149 | - modern encryption, secure by default with forward secrecy & resilience to downgrade attacks
150 | - ideally support for any type of Level 2 and control traffic, e.g. ARP/DHCP/ICMP (or ideally raw ethernet frames), not just TCP/HTTP
151 | - ability to join the VPN from Ubuntu, FreeBSD, iOS, MacOS, Windows, Android (via open-source apps or natively)
152 | - supports both running on the host routing traffic for docker or running in a docker container routing for the host
153 |
154 | **Things WireGuard does not do:**
155 |
156 | - form a self-healing mesh network where nodes automatically gossip with neighbors
157 | - break through double NATs with a signalling server (WebRTC-style)
158 | - handle automatically distributing & revoking keys through a central authority
159 | - allow sending raw layer-2 ethernet frames (it's at the IP layer)
160 |
161 | But you can write your own solutions for these problems using WireGuard under the hood (like [Tailscale](https://github.com/tailscale/tailscale) or [AltheaNet](https://althea.net/)).
162 |
163 | ## List of Other VPN Solutions
164 |
165 | - [WireGuard](https://www.wireguard.com/)
166 | - [IPSec (IKEv2)](https://github.com/jawj/IKEv2-setup)/strongSwan: in my experience, there was lots of brittle config that was different for each OS, the NAT busting setup is very manual and involves updating the central server and starting all the others in the correct order, it wasn't great at becoming stable again after network downtime, had to be manually restarted often. your mileage may vary.
167 | - [OpenVPN](https://openvpn.net/vpn-server-resources/site-to-site-routing-explained-in-detail/): can work over UDP or be disguised as HTTPS traffic over TCP
168 | - StealthVPN: haven't tried it, should I?
169 | - [DsVPN](https://github.com/jedisct1/dsvpn): I think it does TCP-over-TCP which usually doesn't end well...
170 | - [SoftEther](https://www.softether.org/) ([SSTP](https://en.wikipedia.org/wiki/Secure_Socket_Tunneling_Protocol)): haven't tried it yet, should I? (also does TCP-over-TCP?)
171 | - L2TP: somewhat outdated
172 | - PPTP: ancient, inflexible, insecure, doesn't solve all the requirements
173 | - SOCKS/SSH: good for proxying single-port traffic, not a full networking tunnel or VPN
174 |
175 | ### Mesh VPN Solutions
176 |
177 | - [TINC](https://www.tinc-vpn.org/): haven't tried it yet, but it doesn't work on iOS, worst case scenario I could live
178 | - [VPNCloud](https://github.com/dswd/vpncloud): similar properties to WireGuard, with more auto-mesh features
179 | - [cjdns](https://github.com/cjdelisle/cjdns): haven't tried it yet, should I?
180 | - [ZeroTier](https://www.zerotier.com): haven't tried it yet, should I?
181 | - [MeshBird](https://github.com/meshbird/meshbird): "Cloud native" VPN/networking layer
182 | - [Yggdrasil Network](https://yggdrasil-network.github.io/): Yggdrasil is a self-arranging IPv4/IPv6 mesh VPN (haven't tried it yet)
183 |
184 | ### VPN Setup Tools
185 |
186 | - [Algo](https://github.com/trailofbits/algo) WireGuard setup tool
187 | - [Striesand](https://github.com/StreisandEffect/streisand) Multi-protocol setup tool
188 | - [IKEv2-setup](https://github.com/jawj/IKEv2-setup) IKEv2 server setup script
189 | - [WireGuard-Manager](https://github.com/complexorganizations/wireguard-manager) WireGuard setup tool, all in one
190 |
191 | ---
192 |
193 | # WireGuard Documentation
194 |
195 | ---
196 |
197 | ## Glossary
198 |
199 | ### Example Strings
200 |
201 | These are demo hostnames, domain names, IP addresses, and ranges used in the documentation and example configs.
202 | Replace them with your preferred values when doing your own setup.
203 |
204 | - Example domain: `example-vpn.dev` can be replaced with any publicly accessible domain you control
205 | - Example hostnames: `public-server1`, `public-server2`, `home-server`, `laptop`, `phone` can be changed to your device hostnames
206 | - IP addresses & ranges: `192.0.2.1/24`, `192.0.2.3`, `192.0.2.3/32`, `2001:DB8::/64` can be replaced with your preferred subnets and addresses (e.g. `192.168.5.1/24`)
207 |
208 | Wherever you see these strings below, they're just being used as placeholder values to illustrate an example and have no special meaning.
209 |
210 | **Make sure to change the IP addresses in your configs!** The blocks used in these docs
211 | are reserved for example purposes by the IETF and should never be used in real network setups.
212 |
213 | - **`192.0.2.0/24`** (TEST-NET-1) IPv4 example range [RFC5737](https://tools.ietf.org/html/rfc5737)
214 | - **`2001:DB8::/32`** IPv6 example range [RFC3849](https://tools.ietf.org/html/rfc3849)
215 |
216 | You can use any private range you want for your own setups, e.g. `10.0.44.0/24`, just make sure
217 | they don't conflict with any of the LAN subnet ranges your peers are on.
218 |
219 | ### Peer/Node/Device
220 |
221 | A host that connects to the VPN and registers a VPN subnet address such as `192.0.2.3` for itself. It can also optionally route traffic for more than its own address(es) by specifying subnet ranges in comma-separated CIDR notation.
222 |
223 | ### Bounce Server
224 |
225 | A publicly reachable peer/node that serves as a fallback to relay traffic for other VPN peers behind NATs. A bounce server is not a special type of server, it's a normal peer just like all the others, the only difference is that it has a public IP and has kernel-level IP forwarding turned on which allows it to bounce traffic back down the VPN to other clients.
226 |
227 | See more: https://tailscale.com/blog/how-nat-traversal-works/ (Tailscale uses Wireguard under the hood)
228 |
229 | ### Subnet
230 |
231 | A group of IPs separate from the public internet, e.g. 192.0.2.1-255 or 192.168.1.1/24. Generally behind a NAT provided by a router, e.g. in office internet LAN or a home Wi-Fi network.
232 |
233 | ### CIDR Notation
234 |
235 | A way of defining a subnet and its size with a "mask", a smaller mask = more address bits usable by the subnet & more IPs in the range. Most common ones:
236 | + `192.0.2.1/32` (a single IP address, `192.0.2.1`) netmask = `255.255.255.255`
237 | + `192.0.2.1/24` (255 IPs from `192.0.2.0`-`192.0.2.255`) netmask = ` 255.255.255.0`
238 | + `192.0.2.1/16` (65,536 IPs from `192.0.0.0` - `192.0.255.255`) netmask = `255.255.0.0`
239 | + `192.0.2.1/8` (16,777,216 IPs from `192.0.0.0` - `192.255.255.255`) netmask = `255.0.0.0`
240 | + `0.0.0.1/0` (4,294,967,296 IPs from `0.0.0.0` - `255.255.255.255`) netmask = `0.0.0.0`
241 | + IPv6 CIDR notation is also supported e.g. `2001:DB8::/64`
242 |
243 | https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
244 |
245 | To people just getting started `192.0.2.1/32` may seem like a weird and confusing way to refer to a single IP. This design is nice though because it allows peers to expose multiple IPs if needed without needing multiple notations. Just know that anywhere you see something like `192.0.2.3/32`, it really just means `192.0.2.3`.
246 |
247 | ### NAT
248 | A subnet with private IPs provided by a router standing in front of them doing Network Address Translation, individual nodes are not publicly accessible from the internet, instead the router keeps track of outgoing connections and forwards responses to the correct internal IP (e.g. standard office networks, home Wi-Fi networks, free public Wi-Fi networks, etc)
249 |
250 | ### Public Endpoint
251 |
252 | The publicly accessible address:port for a node, e.g. `123.124.125.126:1234` or `some.domain.tld:1234` (must be accessible via the public internet, generally can't be a private IP like `192.0.2.1` or `192.168.1.1` unless it's directly accessible using that address by other peers on the same subnet).
253 |
254 |
255 | ### Private key
256 | A WireGuard private key for a single node, generated with:
257 | `wg genkey > example.key`
258 | (never leaves the node it's generated on)
259 |
260 | ### Public key
261 | A WireGuard public key for a single node, generated with:
262 | `wg pubkey < example.key > example.key.pub `
263 | (shared with other peers)
264 |
265 | ### DNS
266 |
267 | Domain Name Server, used to resolve hostnames to IPs for VPN clients, instead of allowing DNS requests to leak outside the VPN and reveal traffic. Leaks are testable with http://dnsleak.com.
268 |
269 | ---
270 |
271 | ## How WireGuard Works
272 |
273 | ### How Public Relay Servers Work
274 |
275 | Public relays are just normal VPN peers that are able to act as an intermediate relay server between any VPN clients behind NATs, they can forward any VPN subnet traffic they receive to the correct peer at the system level (WireGuard doesn't care how this happens, it's handled by the kernel `net.ipv4.ip_forward = 1` and the iptables routing rules).
276 |
277 | If all peers are publicly accessible, you don't have to worry about special treatment to make one of them a relay server, it's only needed if you have any peers connecting from behind a NAT.
278 |
279 | Each client only needs to define the publicly accessible servers/peers in its config, any traffic bound to other peers behind NATs will go to the catchall VPN subnet (e.g. `192.0.2.1/24`) in the public relays `AllowedIPs` route and will be forwarded accordingly once it hits the relay server.
280 |
281 | In summary: only direct connections between clients should be configured, any connections that need to be bounced should not be defined as peers, as they should head to the bounce server first and be routed from there back down the vpn to the correct client.
282 |
283 | ### How WireGuard Routes Packets
284 |
285 | More complex topologies are definitely achievable, but these are the basic routing methods used in typical WireGuard setups:
286 |
287 | - **Direct node-to-node**
288 | In the simplest case, the nodes will either be on the same LAN or both be publicly accessible. Define directly accessible nodes with hardcoded `Endpoint` addresses and ports so that WireGuard can connect straight to the open port and route UDP packets without intermediate hops.
289 | - **Node behind local NAT to public node**
290 | When 1 of the 2 parties is behind remote NAT (e.g. when a laptop behind NAT connects to `public-server2`), define the publicly accessible node with a hardcoded `Endpoint` and the NAT-ed node without. The connection will be opened from NAT client -> public client, then traffic will route directly between them in both directions as long as the connection is kept alive by outgoing `PersistentKeepalive` pings from the NAT-ed client.
291 | - **Node behind local NAT to node behind remote NAT (via relay)**
292 | Most of the time when both parties are behind NATs, the NATs do source port randomization making direct connections infeasible, so they will both have to open a connection to `public-server1`, and traffic will forward through the intermediary bounce server as long as the connections are kept alive.
293 | - **Node behind local NAT to node behind remote NAT (via UDP NAT hole-punching)**
294 | While sometimes possible, it's generally infeasible to do direct NAT-to-NAT connections on modern networks, because most NAT routers are quite strict about randomizing the source port, making it impossible to coordinate an open port for both sides ahead of time. Instead, a signaling server (STUN) must be used that stands in the middle and communicates which random source ports are assigned to the other side. Both clients make an initial connection to the public signaling server, then it records the random source ports and sends them back to the clients. This is how WebRTC works in modern P2P web apps. Even with a signalling server and known source ports for both ends, sometimes direct connections are not possible because the NAT routers are strict about only accepting traffic from the original destination address (the signalling server), and will require a new random source port to be opened to accept traffic from other IPs (e.g. the other client attempting to use the originally communicated source port). This is especially true for "carrier-grade NATs" like cellular networks and some enterprise networks, which are designed specifically to prevent this sort of hole-punching connection. See the full section below on [**NAT to NAT Connections**](#NAT-to-NAT-Connections) for more information.
295 |
296 | More specific (also usually more direct) routes provided by other peers will take precedence when available, otherwise traffic will fall back to the least specific route and use the `192.0.2.1/24` catchall to forward traffic to the bounce server, where it will in turn be routed by the relay server's system routing table (`net.ipv4.ip_forward = 1`) back down the VPN to the specific peer that's accepting routes for that traffic. WireGuard does not automatically find the fastest route or attempt to form direct connections between peers if not already defined, it just goes from the most specific route in `[Peers]` to least specific.
297 |
298 | You can figure out which routing method WireGuard is using for a given address by measuring the ping times to figure out the unique length of each hop, and by inspecting the output of:
299 | ```bash
300 | wg show wg0
301 | ```
302 |
303 | ### What WireGuard Traffic Looks Like
304 |
305 | WireGuard uses encrypted UDP packets for all traffic, it does not provide guarantees around packet delivery or ordering, as that is handled by TCP connections within the encrypted tunnel.
306 |
307 | 
308 |
309 | Further reading:
310 |
311 | - https://www.wireshark.org/docs/dfref/w/wg.html
312 | - https://github.com/Lekensteyn/wireguard-dissector
313 | - https://nbsoftsolutions.com/blog/viewing-wireguard-traffic-with-tcpdump
314 |
315 | ### WireGuard Performance
316 |
317 | WireGuard claims faster performance than most other competing VPN solutions, though the exact numbers are sometimes debated and may depend on whether hardware-level acceleration is available for certain cryptographic ciphers.
318 |
319 | WireGuard's performance gains are achieved by handling routing at the kernel level, and by using modern cipher suites running on all cores to encrypt traffic. WireGuard also gains a significant advantage by using UDP with no delivery/ordering guarantees (compared to VPNs that run over TCP or implement their own guaranteed delivery mechanisms).
320 |
321 |
322 |
323 |
324 | Further reading:
325 |
326 | - https://www.wireguard.com/performance/
327 | - https://www.reddit.com/r/linux/comments/9bnowo/wireguard_benchmark_between_two_servers_with_10/
328 | - https://restoreprivacy.com/openvpn-ipsec-wireguard-l2tp-ikev2-protocols/
329 |
330 |
331 | ### WireGuard Security Model
332 |
333 | WireGuard uses the following protocols and primitives to secure traffic:
334 |
335 | - ChaCha20 for symmetric encryption, authenticated with Poly1305, using RFC7539’s AEAD construction
336 | - Curve25519 for ECDH
337 | - BLAKE2s for hashing and keyed hashing, described in RFC7693
338 | - SipHash24 for hashtable keys
339 | - HKDF for key derivation, as described in RFC5869
340 |
341 | > WireGuard's cryptography is essentially an instantiation of Trevor Perrin's Noise framework. It's modern and, again, simple. Every other VPN option is a mess of negotiation and handshaking and complicated state machines. WireGuard is like the Signal/Axolotl of VPNs, except it's much simpler and easier to reason about (cryptographically, in this case) than double ratchet messaging protocols.
342 | > It is basically the qmail of VPN software.
343 | > And it's ~4000 lines of code. It is plural orders of magnitude smaller than its competitors.
344 | >
345 | https://news.ycombinator.com/item?id=14599834
346 |
347 | Further reading:
348 |
349 | - https://www.wireguard.com/papers/wireguard.pdf
350 | - https://eprint.iacr.org/2018/080.pdf
351 | - https://courses.csail.mit.edu/6.857/2018/project/He-Xu-Xu-WireGuard.pdf
352 | - https://www.wireguard.com/talks/blackhat2018-slides.pdf
353 | - https://arstechnica.com/gadgets/2018/08/wireguard-vpn-review-fast-connections-amaze-but-windows-support-needs-to-happen/
354 |
355 |
356 | ### How WireGuard Manages Keys
357 |
358 | Authentication in both directions is achieved with a simple public/private key pair for each peer. Each peer generates these keys during the setup phase, and shares only the public key with other peers.
359 |
360 | No other certificates or pre-shared keys are needed beyond the public/private keys for each node.
361 |
362 | Key generation, distribution, and revocation can be handled in larger deployments using a separate service like Ansible or Kubernetes Secrets.
363 |
364 | Some services that help with key distribution and deployment:
365 |
366 | - https://pypi.org/project/wireguard-p2p/
367 | - https://github.com/trailofbits/algo
368 | - https://github.com/StreisandEffect/streisand
369 | - https://github.com/its0x08/wg-install
370 | - https://github.com/brittson/wireguard_config_maker
371 | - https://www.wireguardconfig.com
372 | - https://github.com/UrielCh/wireguard
373 |
374 | You can also read in keys from a file or via command if you don't want to hardcode them in `wg0.conf`, this makes managing keys via 3rd party service much easier:
375 |
376 | ```ini
377 | [Interface]
378 | ...
379 | PostUp = wg set %i private-key /etc/wireguard/wg0.key <(cat /some/path/%i/privkey)
380 | ```
381 |
382 | Technically, multiple servers can share the same private key as long as clients arent connected to two servers with the same key simulatenously.
383 | An example of a scenario where this is a reasonable setup is if you're using round-robin DNS to load-balance connections between two servers that are pretending to be a single server.
384 | Most of the time however, every peer should have its own public/private keypair so that peers can't read eachothers traffic and can be individually revoked.
385 |
386 | ---
387 |
388 | ## Usage
389 |
390 | ### QuickStart
391 |
392 | Overview of the general process:
393 |
394 | 1. Install `apt install wireguard` or `pkg/brew install wireguard-tools` on each node
395 | 2. Generate public and private keys locally on each node `wg genkey`+`wg pubkey`
396 | 3. Create a `wg0.conf` WireGuard config file on the main relay server
397 | - `[Interface]` Make sure to specify a CIDR range for the entire VPN subnet when defining the address the server accepts routes for `Address = 192.0.2.1/24`
398 | - `[Peer]` Create a peer section for every client joining the VPN, using their corresponding remote public keys
399 | 4. Create a `wg0.conf` on each client node
400 | - `[Interface]` Make sure to specify only a single IP for client peers that don't relay traffic `Address = 192.0.2.3/32`.
401 | - `[Peer]` Create a peer section for each public peer not behind a NAT, make sure to specify a CIDR range for the entire VPN subnet when defining the remote peer acting as the bounce server `AllowedIPs = 192.0.2.1/24`. Make sure to specify individual IPs for remote peers that don't relay traffic and only act as simple clients `AllowedIPs = 192.0.2.3/32`.
402 | 5. Start WireGuard on the main relay server with `wg-quick up /full/path/to/wg0.conf`
403 | 6. Start WireGuard on all the client peers with `wg-quick up /full/path/to/wg0.conf`
404 | 7. Traffic is routed from peer to peer using most specific route first over the WireGuard interface, e.g. `ping 192.0.2.3` checks for a direct route to a peer with `AllowedIPs = 192.0.2.3/32` first, then falls back to a relay server that's accepting IPs in the whole subnet
405 |
406 | ### Setup
407 |
408 | ```bash
409 | # install on Ubuntu
410 | sudo add-apt-repository ppa:wireguard/wireguard
411 | apt install wireguard
412 |
413 | # install on macOS
414 | brew install wireguard-tools
415 |
416 | # install on FreeBSD
417 | pkg install wireguard
418 |
419 | # install on iOS/Android using Apple App Store/Google Play Store
420 | # install on other systems using https://www.wireguard.com/install/#installation
421 | ```
422 |
423 | ```bash
424 | # to enable the kernel relaying/forwarding ability on bounce servers
425 | echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
426 | echo "net.ipv4.conf.all.proxy_arp = 1" | sudo tee -a /etc/sysctl.conf
427 | sudo sysctl -p /etc/sysctl.conf
428 |
429 | # to add iptables forwarding rules on bounce servers
430 | sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
431 | sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
432 | sudo iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
433 | sudo iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o eth0 -j MASQUERADE
434 | ```
435 |
436 | ### Config Creation
437 | ```bash
438 | nano wg0.conf # can be placed anywhere, must be referred to using absolute path (usually placed in /etc/wireguard/wg0.conf on most Linux systems)
439 | ```
440 |
441 | ### Key Generation
442 |
443 | ```bash
444 | # generate private key
445 | wg genkey > example.key
446 |
447 | # generate public key
448 | wg pubkey < example.key > example.key.pub
449 | ```
450 |
451 | ### Start / Stop
452 |
453 | ```bash
454 | wg-quick up /full/path/to/wg0.conf
455 | wg-quick down /full/path/to/wg0.conf
456 | # Note: you must specify the absolute path to wg0.conf, relative paths won't work
457 | # If wg0.conf is in /etc/wireguard you can use the simpler:
458 | wg-quick up wg0
459 | ```
460 |
461 | ```bash
462 | # start/stop VPN network interface
463 | ip link set wg0 up
464 | ip link set wg0 down
465 |
466 | # register/unregister VPN network interface
467 | ip link add dev wg0 type wireguard
468 | ip link delete dev wg0
469 |
470 | # register/unregister local VPN address
471 | ip address add dev wg0 192.0.2.3/32
472 | ip address delete dev wg0 192.0.2.3/32
473 |
474 | # register/unregister VPN route
475 | ip route add 192.0.2.3/32 dev wg0
476 | ip route delete 192.0.2.3/32 dev wg0
477 | ```
478 |
479 |
480 | ### Inspect
481 |
482 | #### Interfaces
483 |
484 | ```bash
485 | # show system LAN and WAN network interfaces
486 | ip address show
487 | # or if ip is not available:
488 | ifconfig
489 |
490 | # show system VPN network interfaces
491 | ip link show wg0
492 | # or
493 | ifconfig wg0
494 |
495 | # show WireGuard VPN interfaces
496 | wg show all
497 | wg show wg0
498 | ```
499 |
500 | #### Addresses
501 |
502 | ```bash
503 | # show public IP address
504 | ip address show eth0
505 | # or
506 | ifconfig eth0
507 | # or
508 | dig -4 +short myip.opendns.com @resolver1.opendns.com
509 |
510 | # show VPN IP address
511 | ip address show wg0
512 | ```
513 |
514 | #### Routes
515 |
516 | ```bash
517 | # show WireGuard routing table and peer connections
518 | wg show
519 | wg show wg0 allowed-ips
520 |
521 | # show system routing table
522 | ip route show table main
523 | ip route show table local
524 |
525 | # show system route to specific address
526 | ip route get 192.0.2.3
527 | ```
528 |
529 | #### Logs
530 |
531 | To enable additional logging run:
532 | ```bash
533 | modprobe wireguard
534 | echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
535 | ```
536 |
537 | To follow logs:
538 | ```bash
539 | dmesg -wH
540 | ```
541 |
542 | Systems with modern kernel and Safe Boot might require disabling Secure Boot DKMS Signature Verification to allow access to kernel logs.
543 | ```bash
544 | mokutil --disable-verification
545 | reboot
546 | ```
547 |
548 |
549 | ### Testing
550 |
551 | #### Ping Speed
552 | ```bash
553 | # check that the main relay server is accessible directly via public internet
554 | ping public-server1.example-vpn.dev
555 |
556 | # check that the main relay server is available via VPN
557 | ping 192.0.2.1
558 |
559 | # check that public peers are available via VPN
560 | ping 192.0.2.2
561 |
562 | # check that remote NAT-ed peers are available via VPN
563 | ping 192.0.2.3
564 |
565 | # check that NAT-ed peers in your local LAN are available via VPN
566 | ping 192.0.2.4
567 | ```
568 |
569 | #### Bandwidth
570 |
571 |
572 | ```bash
573 | # install iperf using your preferred package manager
574 | apt/brew/pkg/opkg install iperf
575 |
576 | # check bandwidth over public internet to relay server
577 | iperf -s # on public relay server
578 | iperf -c public-server1.example-vpn.dev # on local client
579 |
580 | # check bandwidth over VPN to relay server
581 | iperf -s # on public relay server
582 | iperf -c 192.0.2.1 # on local client
583 |
584 | # check bandwidth over VPN to remote public peer
585 | iperf -s # on remote public peer
586 | iperf -c 192.0.2.2 # on local client
587 |
588 | # check bandwidth over VPN to remote NAT-ed peer
589 | iperf -s # on remote NAT-ed peer
590 | iperf -c 192.0.2.3 # on local client
591 |
592 | # check bandwidth over VPN to local NAT-ed peer (on same LAN)
593 | iperf -s # on local NAT-ed peer
594 | iperf -c 192.0.2.4 # on local client
595 | ```
596 |
597 | #### DNS
598 |
599 | Check for DNS leaks using http://dnsleak.com, or by checking the resolver on a lookup:
600 | ```bash
601 | dig example.com A
602 | ```
603 |
604 | ---
605 |
606 | ## Config Reference
607 |
608 | ### Overview
609 |
610 | WireGuard config is in [INI syntax](https://en.wikipedia.org/wiki/INI_file), defined in a file usually called `wg0.conf`. It can be placed anywhere on the system, but is often placed in `/etc/wireguard/wg0.conf`.
611 |
612 | The config path is specified as an argument when running any `wg-quick` command, e.g:
613 | `wg-quick up /etc/wireguard/wg0.conf` (always specify the full, absolute path)
614 |
615 | The config file name must be in the format `${name of the new WireGuard interface}.conf`. WireGuard interface names are typically prefixed with `wg` and numbered starting at `0`, but you can use any name that matches the regex `^[a-zA-Z0-9_=+.-]{1,15}$`.
616 |
617 | Config files can opt to use the limited set of `wg` config options, or the more extended `wg-quick` options, depending on what command is preferred to start WireGuard. These docs recommend sticking to `wg-quick` as it provides a more powerful and user-friendly config experience.
618 |
619 | **Jump to definition:**
620 |
621 | ¶ `[Interface]`
622 | ¶ `# Name = node1.example.tld`
623 | ¶ `Address = 192.0.2.3/32`
624 | ¶ `ListenPort = 51820`
625 | ¶ `PrivateKey = localPrivateKeyAbcAbcAbc=`
626 | ¶ `DNS = 1.1.1.1,8.8.8.8`
627 | ¶ `Table = 12345`
628 | ¶ `MTU = 1420`
629 | ¶ `PreUp = /bin/example arg1 arg2 %i`
630 | ¶ `PostUp = /bin/example arg1 arg2 %i`
631 | ¶ `PreDown = /bin/example arg1 arg2 %i`
632 | ¶ `PostDown = /bin/example arg1 arg2 %i`
633 |
634 |
635 | ¶ `[Peer]`
636 | ¶ `# Name = node2-node.example.tld`
637 | ¶ `AllowedIPs = 192.0.2.1/24`
638 | ¶ `Endpoint = node1.example.tld:51820`
639 | ¶ `PublicKey = remotePublicKeyAbcAbcAbc=`
640 | ¶ `PersistentKeepalive = 25`
641 |
642 | ### `[Interface]`
643 |
644 | Defines the VPN settings for the local node.
645 |
646 | **Examples**
647 |
648 | * Node is a client that only routes traffic for itself and only exposes one IP
649 | ```ini
650 | [Interface]
651 | # Name = phone.example-vpn.dev
652 | Address = 192.0.2.5/32
653 | PrivateKey =
654 | ```
655 | * Node is a public bounce server that can relay traffic to other peers and exposes route for entire VPN subnet
656 | ```ini
657 | [Interface]
658 | # Name = public-server1.example-vpn.tld
659 | Address = 192.0.2.1/24
660 | ListenPort = 51820
661 | PrivateKey =
662 | DNS = 1.1.1.1
663 | ```
664 |
665 | #### `# Name`
666 |
667 | This is just a standard comment in INI syntax used to help keep track of which config section belongs to which node, it's completely ignored by WireGuard and has no effect on VPN behavior.
668 |
669 | NOTE: All comments, including `# Name`, are removed from the .conf files by certain operations and applications.
670 | If you need to identify peers, consider using a wireguard vanity key generator, such as
671 | [wireguard-vanity-keygen](https://github.com/axllent/wireguard-vanity-keygen) or
672 | [wireguard-vanity-address](https://github.com/warner/wireguard-vanity-address),
673 | which will allow you to include the host name in the public key of the host.
674 | The key generation can take minutes (4 characters), hours (5 characters) or longer,
675 | so consider using an abbreviation for hosts with longer names.
676 |
677 | #### `Address`
678 |
679 | Defines what address range the local node should route traffic for. Depending on whether the node is a simple client joining the VPN subnet, or a bounce server that's relaying traffic between multiple clients, this can be set to a single IP of the node itself (specified with CIDR notation), e.g. 192.0.2.3/32), or a range of IPv4/IPv6 subnets that the node can route traffic for.
680 |
681 | **Examples**
682 |
683 | * Node is a client that only routes traffic for itself
684 | `Address = 192.0.2.3/32`
685 |
686 | * Node is a public bounce server that can relay traffic to other peers
687 | When the node is acting as the public bounce server, it should set this to be the entire subnet that it can route traffic, not just a single IP for itself.
688 |
689 | `Address = 192.0.2.1/24`
690 |
691 | * You can also specify multiple subnets or IPv6 subnets like so:
692 | `Address = 192.0.2.1/24,2001:DB8::/64`
693 |
694 | #### `ListenPort`
695 |
696 | When the node is acting as a public bounce server, it should hardcode a port to listen for incoming VPN connections from the public internet. Clients not acting as relays should not set this value.
697 |
698 | **Examples**
699 |
700 | * Using default WireGuard port
701 | `ListenPort = 51820`
702 | * Using custom WireGuard port
703 | `ListenPort = 7000`
704 |
705 | #### `PrivateKey`
706 |
707 | This is the private key for the local node, never shared with other servers.
708 | All nodes must have a private key set, regardless of whether they are public bounce servers relaying traffic, or simple clients joining the VPN.
709 |
710 | This key can be generated with `wg genkey > example.key`
711 |
712 | **Examples**
713 |
714 | `PrivateKey = somePrivateKeyAbcdAbcdAbcdAbcd=`
715 |
716 | #### `DNS`
717 |
718 | The DNS server(s) to announce to VPN clients via DHCP, most clients will use this server for DNS requests over the VPN, but clients can also override this value locally on their nodes
719 |
720 | **Examples**
721 |
722 | * The value can be left unconfigured to use the system's default DNS servers
723 | * A single DNS server can be provided
724 | `DNS = 1.1.1.1`
725 | * or multiple DNS servers can be provided
726 | `DNS = 1.1.1.1,8.8.8.8`
727 |
728 | #### `Table`
729 |
730 | Optionally defines which routing table to use for the WireGuard routes, not necessary to configure for most setups.
731 |
732 | There are two special values: ‘off’ disables the creation of routes altogether, and ‘auto’ (the default) adds routes to the default table and enables special handling of default routes.
733 |
734 | https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
735 |
736 | **Examples**
737 |
738 | ```ini
739 | Table = 1234
740 | ```
741 |
742 | #### `MTU`
743 |
744 | Optionally defines the maximum transmission unit (MTU, aka packet/frame size) to use when connecting to the peer, not necessary to configure for most setups.
745 |
746 | The MTU is automatically determined from the endpoint addresses or the system default route, which is usually a sane choice.
747 |
748 | You should avoid setting this if at all possible. You almost certainly do not want 1500 here due to the encapsulation overhead.
749 |
750 | https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
751 | https://www.dropvps.com/blog/mtu-setting-wireguard/
752 |
753 | **Examples**
754 |
755 | ```ini
756 | MTU = 1420
757 | ```
758 |
759 |
760 | #### `PreUp`
761 |
762 | Optionally run a command before the interface is brought up.
763 | This option can be specified multiple times, with commands executed in the order they appear in the file.
764 |
765 | **Examples**
766 |
767 | * Add an IP route
768 | `PreUp = ip rule add ipproto tcp dport 22 table 1234`
769 |
770 | #### `PostUp`
771 |
772 | Optionally run a command after the interface is brought up.
773 | This option can appear multiple times, as with PreUp
774 |
775 | **Examples**
776 |
777 | * Read in a config value from a file or some command's output
778 | `PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command here)`
779 |
780 | * Log a line to a file
781 | `PostUp = echo "$(date +%s) WireGuard Started" >> /var/log/wireguard.log`
782 |
783 | * Hit a webhook on another server
784 | `PostUp = curl https://events.example.dev/wireguard/started/?key=abcdefg`
785 |
786 | * Add a route to the system routing table
787 | `PostUp = ip rule add ipproto tcp dport 22 table 1234`
788 |
789 | * Add an iptables rule to enable packet forwarding on the WireGuard interface
790 | `PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE`
791 |
792 | * Force WireGuard to re-resolve IP address for peer domain
793 | `PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i yes`
794 |
795 | #### `PreDown`
796 |
797 | Optionally run a command before the interface is brought down.
798 | This option can appear multiple times, as with PreUp
799 |
800 | **Examples**
801 |
802 | * Log a line to a file
803 | `PostDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log`
804 |
805 | * Hit a webhook on another server
806 | `PostDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg`
807 |
808 |
809 | #### `PostDown`
810 |
811 | Optionally run a command after the interface is brought down.
812 | This option can appear multiple times, as with PreUp
813 |
814 | **Examples**
815 |
816 | * Log a line to a file
817 | `PostDown = echo "$(date +%s) WireGuard Stopped" >> /var/log/wireguard.log`
818 |
819 | * Hit a webhook on another server
820 | `PostDown = curl https://events.example.dev/wireguard/stopped/?key=abcdefg`
821 |
822 | * Remove the iptables rule that forwards packets on the WireGuard interface
823 | `PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE`
824 |
825 |
826 | ### `[Peer]`
827 |
828 | Defines the VPN settings for a remote peer capable of routing traffic for one or more addresses (itself and/or other peers). Peers can be either a public bounce server that relays traffic to other peers, or a directly accessible client via LAN/internet that is not behind a NAT and only routes traffic for itself.
829 |
830 | All clients must be defined as peers on the public bounce server. Simple clients that only route traffic for themselves, only need to define peers for the public relay, and any other nodes directly accessible. Nodes that are behind separate NATs should _not_ be defined as peers outside of the public server config, as no direct route is available between separate NATs. Instead, nodes behind NATs should only define the public relay servers and other public clients as their peers, and should specify `AllowedIPs = 192.0.2.1/24` on the public server that accept routes and bounce traffic for the VPN subnet to the remote NAT-ed peers.
831 |
832 | In summary, all nodes must be defined on the main bounce server. On client servers, only peers that are directly accessible from a node should be defined as peers of that node, any peers that must be relayed by a bounce server should be left out and will be handled by the relay server's catchall route.
833 |
834 | In the configuration outlined in the docs below, a single server `public-server1` acts as the relay bounce server for a mix of publicly accessible and NAT-ed clients, and peers are configured on each node accordingly:
835 |
836 | - **in `public-server1` `wg0.conf` (bounce server)**
837 | `[peer]` list: `public-server2`, `home-server`, `laptop`, `phone`
838 |
839 | - **in `public-server2` `wg0.conf` (simple public client)**
840 | `[peer]` list: `public-server1`
841 |
842 | - **in `home-server` `wg0.conf` (simple client behind NAT)**
843 | `[peer]` list: `public-server1`, `public-server2`
844 |
845 | - **in `laptop` `wg0.conf` (simple client behind NAT)**
846 | `[peer]` list: `public-server1`, `public-server2`
847 |
848 | - **in `phone` `wg0.conf` (simple client behind NAT)**
849 | `[peer]` list: `public-server1`, `public-server2`
850 |
851 | **Examples**
852 |
853 | - Peer is a simple public client that only routes traffic for itself
854 | ```ini
855 | [Peer]
856 | # Name = public-server2.example-vpn.dev
857 | Endpoint = public-server2.example-vpn.dev:51820
858 | PublicKey =
859 | AllowedIPs = 192.0.2.2/32
860 | ```
861 |
862 | - Peer is a simple client behind a NAT that only routes traffic for itself
863 | ```ini
864 | [Peer]
865 | # Name = home-server.example-vpn.dev
866 | Endpoint = home-server.example-vpn.dev:51820
867 | PublicKey =
868 | AllowedIPs = 192.0.2.3/32
869 | ```
870 |
871 | - Peer is a public bounce server that can relay traffic to other peers
872 | ```ini
873 | [Peer]
874 | # Name = public-server1.example-vpn.tld
875 | Endpoint = public-server1.example-vpn.tld:51820
876 | PublicKey =
877 | # routes traffic to itself and entire subnet of peers as bounce server
878 | AllowedIPs = 192.0.2.1/24
879 | PersistentKeepalive = 25
880 | ```
881 |
882 | #### `# Name`
883 |
884 | This is just a standard comment in INI syntax used to help keep track of which config section belongs to which node, it's completely ignored by WireGuard and has no effect on VPN behavior.
885 |
886 | #### `Endpoint`
887 |
888 | Defines the publicly accessible address for a remote peer. This should be left out for peers behind a NAT or peers that don't have a stable publicly accessible IP:PORT pair. Typically, this only needs to be defined on the main bounce server, but it can also be defined on other public nodes with stable IPs like `public-server2` in the example config below.
889 |
890 | **Examples**
891 |
892 | - Endpoint is an IP address
893 | `Endpoint = 123.124.125.126:51820` (IPv6 is also supported)
894 | - Endpoint is a hostname/FQDN
895 | `Endpoint = public-server1.example-vpn.tld:51820`
896 |
897 | #### `AllowedIPs`
898 |
899 | This defines the IP ranges for which a peer will route traffic. On simple clients, this is usually a single address (the VPN address of the simple client itself). For bounce servers this will be a range of the IPs or subnets that the relay server is capable of routing traffic for. Multiple IPs and subnets may be specified using comma-separated IPv4 or IPv6 CIDR notation (from a single /32 or /128 address, all the way up to `0.0.0.0/0` and `::/0` to indicate a default route to send all internet and VPN traffic through that peer). This option may be specified multiple times.
900 |
901 | When deciding how to route a packet, the system chooses the most specific route first, and falls back to broader routes. So for a packet destined to `192.0.2.3`, the system would first look for a peer advertising `192.0.2.3/32` specifically, and would fall back to a peer advertising `192.0.2.1/24` or a larger range like `0.0.0.0/0` as a last resort.
902 |
903 | **Examples**
904 |
905 |
906 | - peer is a simple client that only accepts traffic to/from itself
907 | `AllowedIPs = 192.0.2.3/32`
908 |
909 | - peer is a relay server that can bounce VPN traffic to all other peers
910 | `AllowedIPs = 192.0.2.1/24`
911 |
912 | - peer is a relay server that bounces all internet & VPN traffic (like a proxy), including IPv6
913 | `AllowedIPs = 0.0.0.0/0,::/0`
914 |
915 | - peer is a relay server that routes to itself and only one other peer
916 | `AllowedIPs = 192.0.2.3/32,192.0.2.4/32`
917 |
918 | - peer is a relay server that routes to itself and all nodes on its local LAN
919 | `AllowedIPs = 192.0.2.3/32,192.168.1.1/24`
920 |
921 | #### `PublicKey`
922 |
923 | This is the public key for the remote node, shareable with all peers.
924 | All nodes must have a public key set, regardless of whether they are public bounce servers relaying traffic, or simple clients joining the VPN.
925 |
926 | This key can be generated with `wg pubkey < example.key > example.key.pub`.
927 | (see above for how to generate the private key `example.key`)
928 |
929 | **Examples**
930 |
931 | `PublicKey = somePublicKeyAbcdAbcdAbcdAbcd=`
932 |
933 | #### `PersistentKeepalive`
934 |
935 | If the connection is going from a NAT-ed peer to a public peer, the node behind the NAT must regularly send an outgoing ping in order to keep the bidirectional connection alive in the NAT router's connection table.
936 |
937 | **Examples**
938 |
939 | - local public node to remote public node
940 | This value should be left undefined as persistent pings are not needed.
941 |
942 | - local public node to remote NAT-ed node
943 | This value should be left undefined as it's the client's responsibility to keep the connection alive because the server cannot reopen a dead connection to the client if it times out.
944 |
945 | - local NAT-ed node to remote public node
946 | `PersistentKeepalive = 25` this will send a ping to every 25 seconds keeping the connection open in the local NAT router's connection table.
947 |
948 | ---
949 |
950 | ## Advanced Topics
951 |
952 | ### IPv6
953 |
954 | The examples in these docs primarily use IPv4, but WireGuard natively supports IPv6 CIDR notation and addresses everywhere that it supports IPv4, simply add them as you would any other subnet range or address.
955 |
956 | **Example**
957 |
958 | ```ini
959 | [Interface]
960 | Address = 192.0.2.3/24, 2001:DB8::/64
961 |
962 | [Peer]
963 | ...
964 | AllowedIPs = 0.0.0.0/0, ::/0
965 | ```
966 |
967 | ### Forwarding All Traffic
968 |
969 | If you want to forward *all* internet traffic through the VPN, and not just use it as a server-to-server subnet, you can add `0.0.0.0/0, ::/0` to the `AllowedIPs` definition of the peer you want to pipe your traffic through.
970 |
971 | Make sure to also specify an IPv6 catchall even when only forwarding IPv4 traffic in order to avoid leaking IPv6 packets outside the VPN, see:
972 | https://www.reddit.com/r/WireGuard/comments/b0m5g2/ipv6_leaks_psa_for_anyone_here_using_wireguard_to/
973 |
974 | **Example**
975 |
976 | ```ini
977 | [Interface]
978 | # Name = phone.example-vpn.dev
979 | Address = 192.0.2.3/32
980 | PrivateKey =
981 |
982 | [Peer]
983 | # Name = public-server1.example-vpn.dev
984 | PublicKey =
985 | Endpoint = public-server1.example-vpn.dev:51820
986 | AllowedIPs = 0.0.0.0/0, ::/0
987 | ```
988 |
989 | ### NAT To NAT Connections
990 |
991 | WireGuard can sometimes natively make connections between two clients behind NATs without the need for a public relay server, but in most cases this is not possible. NAT-to-NAT connections are only possible if at least one host has a stable, publicly-accessible IP address:port pair that can be hardcoded ahead of time, whether that's using a FQDN updated with Dynamic DNS, or a static public IP with a non-randomized NAT port opened by outgoing packets, anything works as long as all peers can communicate it beforehand and it doesn't change once the connection is initiated.
992 |
993 | A known port and address need to be configured ahead of time because WireGuard doesn't have a signalling layer or public STUN servers that can be used to search for other hosts dynamically. WebRTC is an example of a protocol that can dynamically configure a connection between two NATs, but it does this by using an out-of-band signaling server to detect the IP:port combo of each host. WireGuard doesn't have this, so it only works with a hardcoded `Endpoint` + `ListenPort` (and `PersistentKeepalive` so it doesn't drop after inactivity).
994 |
995 | Learn more from Tailscale's bible of NAT traversal: https://tailscale.com/blog/how-nat-traversal-works/
996 |
997 | #### Requirements for NAT-to-NAT setups
998 |
999 | - At least one peer has to have to have a hardcoded, directly-accessible `Endpoint` defined. If they're both behind NATs without stable IP addresses, then you'll need to use Dynamic DNS or another solution to have a stable, publicly accessibly domain/IP for at least one peer
1000 | - At least one peer has to have a hardcoded UDP `ListenPort` defined, and it's NAT router must not do UDP source port randomization, otherwise return packets will be sent to the hardcoded `ListenPort` and dropped by the router, instead of using the random port assigned by the NAT on the outgoing packet
1001 | - All NAT'ed peers must have `PersistentKeepalive` enabled on all other peers, so that they continually send outgoing pings to keep connections persisted in their NAT's routing table
1002 |
1003 | #### The hole-punching connection process
1004 |
1005 | 1. Peer1 sends a UDP packet to Peer2, it's rejected Peer2's NAT router immediately, but that's ok, the only purpose was to get Peer1's NAT to start forwarding any expected UDP responses back to Peer1 behind its NAT
1006 | 2. Peer2 sends a UDP packet to Peer1, it's accepted and forwarded to Peer1 as Peer1's NAT server is already expecting responses from Peer2 because of the initial outgoing packet
1007 | 3. Peer1 sends a UDP response to Peer2's packet, it's accepted and forwarded by Peer2's NAT server as it's also expecting responses because of the initial outgoing packet
1008 |
1009 | This process of sending an initial packet that gets rejected, then using the fact that the router has now created a forwarding rule to accept responses is called "UDP hole-punching".
1010 |
1011 | When you send a UDP packet out, the router (usually) creates a temporary rule mapping your source address and port to the destination address and port, and vice versa. UDP packets returning from the destination address and port (and no other) are passed through to the original source address and port (and no other). This is how most UDP applications function behind NATs (e.g. BitTorrent, Skype, etc). This rule will timeout after some minutes of inactivity, so the client behind the NAT must send regular outgoing packets to keep it open (see `PersistentKeepalive`).
1012 |
1013 | Getting this to work when both end-points are behind NATs or firewalls requires that both end-points send packets to each-other at about the same time. This means that both sides need to know each-other's public IP addresses and port numbers ahead of time, in WireGuard's case this is achieved by hard-coding pre-defined ports for both sides in `wg0.conf`.
1014 |
1015 | #### Drawbacks and limitations
1016 |
1017 | As of 2019, many of the old hole-punching methods used that used to work are no longer effective. One example was a novel method pioneered by [pwnat](https://github.com/samyk/pwnat) that faked an ICMP Time Exceeded response from outside the NAT to get a packet back through to a NAT'ed peer, thereby leaking its own source port. Hardcoding UDP ports and public IPs for both sides of a NAT-to-NAT connection (as described above) still works on a small percentage of networks. Generally the more "enterprisey" a network is, the less likely you'll be able to hole punch public UDP ports (commercial public Wi-Fi and cell data NATs often don't work for example).
1018 |
1019 | ##### Source port randomization
1020 |
1021 | NAT-to-NAT connections are not possible if all endpoints are behind NAT's with strict UDP source port randomization (e.g. most cellular data networks). Since neither side is able to hardcode a `ListenPort` and guarantee that their NAT will accept traffic on that port after the outgoing ping, you cannot coordinate a port for the initial hole-punch between peers and connections will fail. For this reason, you generally cannot do phone-to-phone connections on LTE/3g networks, but you might be able to do phone-to-office or phone-to-home where the office or home has a stable public IP and doesn't do source port randomization.
1022 |
1023 | ##### Using a signaling server
1024 |
1025 | NAT-to-NAT connections from behind NATs with strict source-port randomization is possible, you just need a signaling server to tell each side the other's IP:port tuple. Here are a few implementations that achieve this with WireGuard:
1026 |
1027 | - https://github.com/takutakahashi/wg-connect
1028 | - https://git.zx2c4.com/wireguard-tools/tree/contrib/nat-hole-punching/
1029 | - https://github.com/jwhited/wgsd
1030 |
1031 | ##### Dynamic IP addresses
1032 | Many users report having to restart WireGuard whenever a dynamic IP changes, as it only resolves hostnames on startup. To force WireGuard to re-resolve dynamic DNS `Endpoint` hostnames more often, you may want to use a `PostUp` hook to restart WireGuard every few minutes or hours.
1033 |
1034 |
1035 | #### Testing it out
1036 |
1037 | You can see if a hole-punching setup is feasible by using netcat on the client and server to see what ports and connection order work to get a bidirectional connection open: run `nc -v -u -p 51820 51820` (on peer1) and `nc -v -u -l 0.0.0.0 51820` (on peer2), then type in both windows to see if you can get bidirectional traffic going. If it doesn't work regardless of which peer sends the initial packet, then WireGuard won't be unable to work between the peers without a public relay server.
1038 |
1039 | NAT-to-NAT connections are often more unstable and have other limitations, which is why having a fallback public relay server is still advised.
1040 |
1041 | #### Further reading
1042 |
1043 | - https://github.com/samyk/pwnat
1044 | - https://en.wikipedia.org/wiki/UDP_hole_punching
1045 | - https://stackoverflow.com/questions/8892142/udp-hole-punching-algorithm
1046 | - https://stackoverflow.com/questions/12359502/udp-hole-punching-not-going-through-on-3g
1047 | - https://stackoverflow.com/questions/11819349/udp-hole-punching-not-possible-with-mobile-provider
1048 | - https://github.com/WireGuard/WireGuard/tree/master/contrib/examples/nat-hole-punching
1049 | - https://staaldraad.github.io/2017/04/17/nat-to-nat-with-wireguard/
1050 | - https://golb.hplar.ch/2019/01/expose-server-vpn.html
1051 | - https://www.jordanwhited.com/posts/wireguard-endpoint-discovery-nat-traversal/
1052 |
1053 | **Example**
1054 |
1055 | *Peer1:*
1056 | ```ini
1057 | [Interface]
1058 | ...
1059 | ListenPort 12000
1060 |
1061 | [Peer]
1062 | ...
1063 | Endpoint = peer2.example-vpn.dev:12000
1064 | PersistentKeepalive = 25
1065 | ```
1066 |
1067 | *Peer2:*
1068 | ```ini
1069 | [Interface]
1070 | ...
1071 | ListenPort 12000
1072 |
1073 | [Peer]
1074 | ...
1075 | Endpoint = peer1.example-vpn.dev:12000
1076 | PersistentKeepalive = 25
1077 | ```
1078 |
1079 | ### Dynamic IP Allocation
1080 |
1081 | *Note: this section is about dynamic peer IPs within the VPN subnet, not dynamic public `Endpoint` addresses*.
1082 |
1083 | Dynamic allocation of peer IPs (instead of only having fixed peers) is being developed, the WIP implementation is available here:
1084 | https://github.com/WireGuard/wg-dynamic
1085 |
1086 | You can also build a dynamic allocation system yourself by reading in IP values from files at runtime by using `PostUp` (see below).
1087 |
1088 | **Example**
1089 | ```ini
1090 | [Interface]
1091 | ...
1092 | PostUp = wg set %i allowed-ips /etc/wireguard/wg0.key <(some command)
1093 | ```
1094 |
1095 | ### Other WireGuard Implementations
1096 |
1097 | - https://git.zx2c4.com/wireguard-go/about/
1098 | A compliant userland WireGuard implementation written in Go.
1099 |
1100 | - https://git.zx2c4.com/wireguard-rs/about/
1101 | An incomplete, insecure userspace implementation of WireGuard written in Rust (not ready for the public).
1102 |
1103 | - https://git.zx2c4.com/wireguard-hs/about/
1104 | An incomplete, insecure userspace implementation of WireGuard written in Haskell (not ready for the public).
1105 |
1106 | - https://github.com/cloudflare/boringtun
1107 | A non-compliant, independent WireGuard implementation written in Rust (a separate fork written by CloudFlare).
1108 | See https://blog.cloudflare.com/boringtun-userspace-wireguard-rust/
1109 |
1110 | - Platform-specific WireGuard apps
1111 | https://git.zx2c4.com/wireguard-ios/about/
1112 | https://git.zx2c4.com/wireguard-android/about/
1113 | https://git.zx2c4.com/wireguard-windows/about/
1114 |
1115 | All of the userspace implementations are slower than the native C version that runs in kernel-land, but provide other benefits by running in userland (e.g. easier containerization, compatibility, etc.).
1116 |
1117 | ### WireGuard Setup Tools
1118 |
1119 | These are some GUI and CLI tools that wrap WireGuard to assist with config, deployment, key management, and connection.
1120 |
1121 | - https://github.com/weejewel/wg-easy
1122 | - https://github.com/seashell/drago
1123 | - https://github.com/gravitl/netmaker
1124 | - https://github.com/vx3r/wg-gen-web
1125 | - https://github.com/subspacecloud/subspace
1126 | - https://github.com/corrad1nho/qomui
1127 | - https://github.com/max-moser/network-manager-wireguard
1128 | - https://github.com/psyhomb/wireguard-tools
1129 | - https://github.com/its0x08/wg-install
1130 | - https://github.com/sowbug/mkwgconf
1131 | - https://github.com/brittson/wireguard_config_maker
1132 | - https://github.com/SirToffski/WireGuard-Ligase/
1133 | - https://pypi.org/project/wireguard-p2p/
1134 | - https://github.com/trailofbits/algo
1135 | - https://github.com/StreisandEffect/streisand
1136 | - https://www.veeam.com/blog/veeam-pn-v2-wireguard.html
1137 | - https://github.com/wg-dashboard/wg-dashboard
1138 | - https://www.wireguardconfig.com
1139 | - https://github.com/complexorganizations/wireguard-manager
1140 | - https://github.com/influxdata/wirey
1141 | - https://github.com/apognu/wgctl
1142 | - https://github.com/naggie/dsnet
1143 | - https://github.com/perara/wg-manager
1144 | - https://github.com/pivpn/pivpn
1145 | - https://github.com/BrunIF/wg-ccg
1146 | - https://github.com/freifunkMUC/wg-access-server
1147 | - https://github.com/firezone/firezone
1148 | - https://gitlab.com/BoostCookie/wgsetup
1149 |
1150 |
1151 | ### Config Shortcuts
1152 |
1153 | Credit for these shortcuts goes to:
1154 | https://www.ericlight.com/new-things-i-didnt-know-about-wireguard.html
1155 |
1156 | #### Sharing a single peers.conf file
1157 |
1158 | WireGuard will ignore a peer whose public key matches the interface's private key. So you can distribute a single list of peers everywhere, and only define the `[Interface]` separately on each server.
1159 |
1160 | See: https://lists.zx2c4.com/pipermail/wireguard/2018-December/003703.html
1161 |
1162 | You can combine this with `wg addconf` like this:
1163 |
1164 | * Each peer has its own `/etc/wireguard/wg0.conf` file, which only contains its `[Interface]` section.
1165 |
1166 | * Each peer also has a shared `/etc/wireguard/peers.conf` file, which contains all the peers.
1167 |
1168 | * The `wg0.conf` file also has a `PostUp` hook: `PostUp = wg addconf /etc/wireguard/peers.conf`.
1169 |
1170 | It's up to you to decide how you want to share the `peers.conf`, be it via a proper orchestration platform, something much more pedestrian like Dropbox, or something kinda wild like Ceph. I dunno, but it's pretty great that you can just wildly fling a peer section around, without worrying whether it's the same as the interface.
1171 |
1172 | #### Setting config values from files or command outputs
1173 |
1174 | You can set config values from arbitrary commands or by reading in values from files, this makes key management and deployment much easier as you can read in keys at runtime from a 3rd party service like Kubernetes Secrets or AWS KMS.
1175 |
1176 | See: https://lists.zx2c4.com/pipermail/wireguard/2018-December/003702.html
1177 |
1178 | **Example**
1179 |
1180 | You can read in a file as the `PrivateKey` by doing something like:
1181 |
1182 | `PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command)`
1183 |
1184 |
1185 | ### Containerization
1186 |
1187 | WireGuard can be run in Docker with varying degrees of ease. In the simplest case, `--privileged` and `--cap-add=all` arguments can be added to the docker commands to enable the loading of the kernel module.
1188 |
1189 | Setups can get somewhat complex and are highly dependent on what you're trying to achieve. You can have WireGuard itself run in a container and expose a network interface to the host, or you can have WireGuard running on the host exposing an interface to specific containers.
1190 |
1191 | See below for an example of a Docker container `vpn_test` routing all its traffic through a WireGuard relay server.
1192 |
1193 | #### Example Relay Server Setup
1194 |
1195 | ```yaml
1196 | version: '3'
1197 |
1198 | services:
1199 | wireguard:
1200 | image: linuxserver/wireguard
1201 | ports:
1202 | - 51820:51820/udp
1203 | cap_add:
1204 | - NET_ADMIN
1205 | - SYS_MODULE
1206 | volumes:
1207 | - /lib/modules:/lib/modules
1208 | - ./wg0.conf:/config/wg0.conf:ro
1209 | ```
1210 | **`wg0.conf`:**
1211 | ```ini
1212 | [Interface]
1213 | # Name = relay1.wg.example.com
1214 | Address = 192.0.2.1/24
1215 | ListenPort = 51820
1216 | PrivateKey = oJpRt2Oq27vIB5/UVb7BRqCwad2YMReQgH5tlxz8YmI=
1217 | DNS = 1.1.1.1,8.8.8.8
1218 | PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
1219 | PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
1220 |
1221 | [Peer]
1222 | # Name = peer1.wg.example.com
1223 | PublicKey = I+hXRAJOG/UE2IQvIHsou2zTgkUyPve2pzvHTnd/2Gg=
1224 | AllowedIPs = 192.0.2.2/32
1225 | ```
1226 |
1227 | #### Example Client Container Setup
1228 |
1229 | In this example *all* the traffic from inside the `speedtest` container will go through the wireguard VPN.
1230 | To only route some traffic, replace `0.0.0.0/0` in `wg0.conf` below with the subnet ranges you want to route via the VPN.
1231 |
1232 | **`docker-compose.yml`:**
1233 | ```yaml
1234 | version: '3'
1235 |
1236 | services:
1237 | wireguard:
1238 | image: linuxserver/wireguard
1239 | cap_add:
1240 | - NET_ADMIN
1241 | - SYS_MODULE
1242 | volumes:
1243 | - /lib/modules:/lib/modules
1244 | - ./wg0.conf:/config/wg0.conf:ro
1245 |
1246 | vpn_test:
1247 | image: curlimages/curl
1248 | entrypoint: curl -s http://whatismyip.akamai.com/
1249 | network_mode: 'service:wireguard'
1250 | ```
1251 | **`wg0.conf`:**
1252 | ```ini
1253 | [Interface]
1254 | # Name = peer1.wg.example.com
1255 | Address = 192.0.2.2/32
1256 | PrivateKey = YCW76edD4W7nZrPbWZxPZhcs32CsBLIi1sEhsV/sgk8=
1257 | DNS = 1.1.1.1,8.8.8.8
1258 |
1259 | [Peer]
1260 | # Name = relay1.wg.example.com
1261 | Endpoint = relay1.wg.example.com:51820
1262 | PublicKey = zJNKewtL3gcHdG62V3GaBkErFtapJWsAx+2um0c0B1s=
1263 | AllowedIPs = 192.0.2.1/24,0.0.0.0/0
1264 | PersistentKeepalive = 21
1265 | ```
1266 |
1267 | For more details see the Further Reading: Docker section below.
1268 |
1269 | ---
1270 |
1271 | # Further Reading
1272 |
1273 | ### Reference Docs
1274 |
1275 | - https://www.wireguard.com/install/#installation
1276 | - https://git.zx2c4.com/WireGuard/about/src/tools/man/wg.8
1277 | - https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
1278 | - https://wiki.archlinux.org/index.php/WireGuard / https://wiki.archlinux.org/title/WireGuard
1279 | - https://wiki.debian.org/Wireguard#Configuration
1280 | - https://docs.netgate.com/pfsense/en/latest/vpn/wireguard/index.html
1281 | - https://www.procustodibus.com/blog/2020/10/wireguard-topologies/
1282 |
1283 | ### Tutorials
1284 |
1285 | - https://www.wireguard.com/quickstart/
1286 | - https://www.stavros.io/posts/how-to-configure-wireguard/
1287 | - https://nbsoftsolutions.com/blog/wireguard-vpn-walkthrough
1288 | - https://networkhobo.com/building-a-wireguard-router/
1289 | - https://proprivacy.com/guides/wireguard-hands-on-guide
1290 | - https://angristan.xyz/how-to-setup-vpn-server-wireguard-nat-ipv6/
1291 | - https://medium.com/@headquartershq/setting-up-wireguard-on-a-mac-8a121bfe9d86
1292 | - https://grh.am/2018/wireguard-setup-guide-for-ios/
1293 | - https://techcrunch.com/2018/07/28/how-i-made-my-own-wireguard-vpn-server/
1294 | - https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/
1295 | - https://jrs-s.net/2018/08/05/routing-between-wg-interfaces-with-wireguard/
1296 | - https://www.stavros.io/posts/how-to-configure-wireguard/
1297 | - https://vincent.bernat.ch/en/blog/2018-route-based-vpn-wireguard
1298 | - https://staaldraad.github.io/2017/04/17/nat-to-nat-with-wireguard
1299 | - https://try.popho.be/wg.html
1300 | - https://docs.artemix.org/sysadmin/wireguard-management/
1301 | - https://github.com/adrianmihalko/raspberrypiwireguard
1302 | - https://www.ericlight.com/wireguard-part-one-installation.html
1303 | - https://www.ericlight.com/wireguard-part-two-vpn-routing.html
1304 | - https://www.ericlight.com/wireguard-part-three-troubleshooting.html
1305 | - https://wiki.dd-wrt.com/wiki/index.php/The_Easiest_Tunnel_Ever
1306 | - https://www.reddit.com/r/pihole/comments/bnihyz/guide_how_to_install_wireguard_on_a_raspberry_pi/
1307 | - https://jwillmer.de/blog/tutorial/wireguard-proxy-configuration
1308 | - https://www.maths.tcd.ie/~fionn/misc/wireguard.php
1309 | - https://www.linode.com/docs/networking/vpn/set-up-wireguard-vpn-on-debian/
1310 | - https://golb.hplar.ch/2019/01/expose-server-vpn.html
1311 | - https://medium.com/@jmarhee/configuring-and-managing-routes-between-multiple-networks-with-wireguard-61ad995c887c
1312 | - https://stanislas.blog/2019/01/how-to-setup-vpn-server-wireguard-nat-ipv6/
1313 |
1314 | ### Papers, Articles, and Talks
1315 |
1316 | - https://www.wireguard.com/papers/wireguard.pdf
1317 | - https://www.wireguard.com/presentations/
1318 | - https://eprint.iacr.org/2018/080.pdf
1319 | - https://courses.csail.mit.edu/6.857/2018/project/He-Xu-Xu-WireGuard.pdf
1320 | - https://arstechnica.com/gadgets/2018/08/wireguard-vpn-review-fast-connections-amaze-but-windows-support-needs-to-happen/
1321 | - https://www.wireguard.com/talks/blackhat2018-slides.pdf
1322 |
1323 | ### Related Projects
1324 |
1325 | - https://github.com/weejewel/wg-easy
1326 | - https://github.com/gravitl/netmaker
1327 | - https://github.com/complexorganizations/wireguard-manager
1328 | - https://github.com/subspacecloud/subspace
1329 | - https://github.com/trailofbits/algo
1330 | - https://github.com/StreisandEffect/streisand
1331 | - https://github.com/its0x08/wg-install
1332 | - https://github.com/sowbug/mkwgconf
1333 | - https://github.com/brittson/wireguard_config_maker
1334 | - https://github.com/SirToffski/WireGuard-Ligase/
1335 | - https://pypi.org/project/wireguard-p2p/
1336 | - https://github.com/cloudflare/boringtun
1337 | - https://git.zx2c4.com/wireguard-go/about/
1338 | - https://github.com/WireGuard/wg-dynamic
1339 | - https://github.com/WireGuard/wireguard-ios
1340 | - https://github.com/WireGuard/wireguard-windows
1341 | - https://github.com/WireGuard/wireguard-rs
1342 | - https://github.com/WireGuard/wireguard-go
1343 | - https://www.veeam.com/blog/veeam-pn-v2-wireguard.html
1344 | - https://github.com/wg-dashboard/wg-dashboard
1345 | - https://wirtbot.com
1346 | - https://github.com/seashell/drago
1347 | - https://www.wireguardconfig.com
1348 | - https://github.com/angristan/wireguard-install
1349 | - https://github.com/complexorganizations/wireguard-manager
1350 | - https://github.com/influxdata/wirey
1351 | - https://github.com/apognu/wgctl
1352 | - https://github.com/tailscale/tailscale
1353 | - https://github.com/pivpn/pivpn
1354 | - https://github.com/jwhited/wgsd
1355 | - https://github.com/freifunkMUC/wg-access-server
1356 | - https://github.com/firezone/firezone
1357 |
1358 | ### Docker
1359 |
1360 |
1361 | - https://blog.jessfraz.com/post/installing-and-using-wireguard/
1362 | - https://codeopolis.com/posts/installing-wireguard-in-docker/
1363 | - http://tiven.wang/articles/wireguard-setup-server-in-docker/
1364 | - https://github.com/activeeos/wireguard-docker
1365 | - https://github.com/cmulk/wireguard-docker
1366 | - https://github.com/ironhalik/docker-wireguard
1367 | - https://github.com/linuxserver/docker-wireguard
1368 | - https://github.com/squat/kilo
1369 | - https://github.com/gravitational/wormhole
1370 | - https://medium.com/@mdp/securing-docker-with-wireguard-82ad45004f4d
1371 | - https://nbsoftsolutions.com/blog/leaning-on-algo-to-route-docker-traffic-through-wireguard
1372 | - https://nbsoftsolutions.com/blog/routing-select-docker-containers-through-wireguard-vpn
1373 | - https://www.net.in.tum.de/fileadmin/bibtex/publications/theses/2018-pudelko-vpn-performance.pdf
1374 | - https://www.wireguard.com/#ready-for-containers
1375 | - https://discuss.linuxcontainers.org/t/solved-wireguard-in-macvlan-container-on-ubuntu-18-04/4445
1376 | - https://www.reddit.com/r/WireGuard/comments/gdhcej/trouble_tunneling_docker_containers_through_a/
1377 | - https://forums.unraid.net/topic/91367-partially-working-wireguard-docker/
1378 | - https://saasbootstrap.com/how-to-setup-a-vpn-with-wireguard-that-only-routes-traffic-from-a-specific-docker-container-or-specific-ip/
1379 |
1380 | ### Other
1381 |
1382 | - https://blog.cloudflare.com/boringtun-userspace-wireguard-rust/
1383 | - https://jrs-s.net/category/open-source/wireguard/
1384 | - https://restoreprivacy.com/openvpn-ipsec-wireguard-l2tp-ikev2-protocols/
1385 | - https://restoreprivacy.com/wireguard/
1386 | - https://www.ericlight.com/new-things-i-didnt-know-about-wireguard.html
1387 | - https://www.ericlight.com/tag/wireguard.html
1388 | - https://www.linode.com/docs/networking/vpn/set-up-wireguard-vpn-on-ubuntu/
1389 | - https://www.reddit.com/r/linux/comments/9bnowo/wireguard_benchmark_between_two_servers_with_10/
1390 | - https://www.wireguard.com/netns/
1391 | - https://www.wireguard.com/performance/
1392 | - https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/
1393 | - https://github.com/max-moser/network-manager-wireguard
1394 | - https://blog.linuxserver.io/2019/11/24/connect-an-ubuntu-client-to-opnsense-wireguard-tunnel-with-a-gui-toggle-in-gnome/
1395 | - https://im.salty.fish/index.php/archives/linux-networking-shallow-dive.html
1396 |
1397 |
1398 | ### Discussions
1399 |
1400 | - https://www.reddit.com/r/WireGuard
1401 | - https://lists.zx2c4.com/mailman/listinfo/wireguard
1402 | - https://www.reddit.com/r/VPN/comments/a914mr/can_you_explain_the_difference_between_openvpn/
1403 | - https://www.reddit.com/r/WireGuard/comments/b0m5g2/ipv6_leaks_psa_for_anyone_here_using_wireguard_to/?utm_source=reddit&utm_medium=usertext&utm_name=WireGuard&utm_content=t1_ep8tv0o
1404 | - https://www.reddit.com/r/VPN/comments/au4owb/how_secure_is_wireguard_vpn_protocol/
1405 | - https://www.reddit.com/r/WireGuard/comments/ap33df/wireguard_what_is_so_special_about_it_and_why/
1406 | - https://www.reddit.com/r/VPN/comments/9hgs2x/what_is_the_difference_between_wireguard_openvpn/
1407 | - https://www.reddit.com/r/WireGuard/comments/d3thxp/port_forwarding_on_the_router_with_wireguard_is/
1408 | - https://www.reddit.com/r/privacytoolsIO/comments/8l0vxt/what_do_you_think_guys_of_wireguard/
1409 | - https://community.ui.com/questions/Edgerouter-with-remote-Wireguard-access-issue/03e4f2e2-3871-437f-8632-3c5c7fb1c7a4
1410 | - https://discuss.linuxcontainers.org/t/solved-wireguard-in-macvlan-container-on-ubuntu-18-04/4445
1411 | - https://news.ycombinator.com/item?id=20036194
1412 | - https://news.ycombinator.com/item?id=17659983
1413 | - https://news.ycombinator.com/item?id=17846387
1414 |
1415 | For more detailed instructions, see the [QuickStart](#QuickStart) guide and API reference above. You can also download the complete example setup here: https://github.com/pirate/wireguard-example.
1416 |
1417 |
1418 | ---
1419 |
1420 |
1421 |
1422 | Suggest changes: https://github.com/pirate/wireguard-docs/issues
1423 |
1424 |
1425 |
--------------------------------------------------------------------------------
/example-full/README.md:
--------------------------------------------------------------------------------
1 | # Example Server-To-Server Config with Roaming Devices
2 |
3 | WARNING: **Make sure to change the IP addresses and ranges in your configs before running!**
4 | The blocks used in these examples are reserved for documentation purposes by the IETF and should never be used in real network setups.
5 |
6 | - **`192.0.2.0/24`** (TEST-NET-1) IPv4 example range [RFC5737](https://tools.ietf.org/html/rfc5737)
7 | - **`2001:DB8::/32`** IPv6 example range [RFC3849](https://tools.ietf.org/html/rfc3849)
8 |
9 | You can use any private range you want instead, e.g. `10.0.44.0/24`, just make sure
10 | it doesn't conflict with any of the LAN subnet ranges your peers are on.
11 |
12 | The complete example config for the setup below can be found here: https://github.com/pirate/wireguard-docs/tree/master/full-example (WARNING: do not use it on your devices without changing the public/private keys!).
13 |
14 | ## Overview
15 |
16 | ### Network Topology
17 |
18 | These 5 devices are used in our example setup to explain how WireGuard supports bridging across a variety of network conditions, they're all under an example domain `example-vpn.dev`, with the following short hostnames:
19 |
20 | - `public-server1` (not behind a NAT, acts as the main VPN bounce server)
21 | - `public-server2` (not behind a NAT, joins as a peer without bouncing traffic)
22 | - `home-server` (behind a NAT, joins as a peer without bouncing traffic)
23 | - `laptop` (behind NAT, sometimes shared w/ home-server/phone, sometimes roaming)
24 | - `phone` (behind NAT, sometimes shared w/ home-server/laptop, sometimes roaming)
25 |
26 | ### Explanation
27 |
28 | This VPN config simulates setting up a small VPN subnet `192.0.2.1/24` shared by 5 nodes. Two of the nodes (public-server1 and public-server2) are VPS instances living in a cloud somewhere, with public IPs accessible to the internet. home-server is a stationary node that lives behind a NAT with a dynamic IP, but it doesn't change frequently. Phone and laptop are both roaming nodes, that can either be at home in the same LAN as home-server, or out-and-about using public wifi or cell service to connect to the VPN.
29 |
30 | Whenever possible, nodes should connect directly to each other, depending on whether nodes are directly accessible or NATs are between them, traffic will route accordingly:
31 |
32 | ### The Public Relay
33 |
34 | `public-server1` acts as an intermediate relay server between any VPN clients behind NATs, it will forward any 192.0.2.1/24 traffic it receives to the correct peer at the system level (WireGuard doesn't care how this happens, it's handled by the kernel `net.ipv4.ip_forward = 1` and the iptables routing rules).
35 |
36 | Each client only needs to define the publicly accessible servers/peers in its config, any traffic bound to other peers behind NATs will go to the catchall `192.0.2.1/24` for the server and will be forwarded accordingly once it hits the main server.
37 |
38 | In summary: only direct connections between clients should be configured, any connections that need to be bounced should not be defined as peers, as they should head to the bounce server first and be routed from there back down the vpn to the correct client.
39 |
40 | ## Full Example Code
41 |
42 | To run this full example, simply copy the `full wg0.conf config file for node` section from each node onto each server, enable IP forwarding on the public relay, and then start WireGuard on all the machines.
43 |
44 | For more detailed instructions, see the [Quickstart](#Quickstart) guide and API reference above. You can also download the complete example setup here: https://github.com/pirate/wireguard-docs/tree/master/full-example (WARNING: do not use it on your devices without changing the public/private keys!).
45 |
46 | ## Node Config
47 |
48 | ### public-server1.example-vpn.tld
49 | * public endpoint: `public-server1.example-vpn.tld:51820`
50 | * own vpn ip address: `192.0.2.1`
51 | * can accept traffic for ips: `192.0.2.1/24`
52 | * priv key: ``
53 | * pub key: ``
54 | * setup required:
55 | 1. install wireguard
56 | 2. generate public/private keypair
57 | 3. create wg0.conf (see below)
58 | 4. enable kernel ip & arp forwarding, add iptables forwarding rules
59 | 5. start wireguard
60 | * config as remote peer:
61 | ```ini
62 | [Peer]
63 | # Name = public-server1.example-vpn.tld
64 | Endpoint = public-server1.example-vpn.tld:51820
65 | PublicKey =
66 | # routes traffic to itself and entire subnet of peers as bounce server
67 | AllowedIPs = 192.0.2.1/24
68 | PersistentKeepalive = 25
69 | ```
70 | * config as local interface:
71 | ```ini
72 | [Interface]
73 | # Name = public-server1.example-vpn.tld
74 | Address = 192.0.2.1/24
75 | ListenPort = 51820
76 | PrivateKey =
77 | DNS = 1.1.1.1
78 | ```
79 | * peers: public-server2, home-server, laptop, phone
80 | * full `wg0.conf` config file for node:
81 | ```ini
82 | [Interface]
83 | # Name = public-server1.example-vpn.tld
84 | Address = 192.0.2.1/24
85 | ListenPort = 51820
86 | PrivateKey =
87 | DNS = 1.1.1.1
88 |
89 | [Peer]
90 | # Name = public-server2.example-vpn.dev
91 | Endpoint = public-server2.example-vpn.dev:51820
92 | PublicKey =
93 | AllowedIPs = 192.0.2.2/32
94 |
95 | [Peer]
96 | # Name = home-server.example-vpn.dev
97 | Endpoint = home-server.example-vpn.dev:51820
98 | PublicKey =
99 | AllowedIPs = 192.0.2.3/32
100 |
101 | [Peer]
102 | # Name = laptop.example-vpn.dev
103 | PublicKey =
104 | AllowedIPs = 192.0.2.4/32
105 |
106 | [Peer]
107 | # phone.example-vpn.dev
108 | PublicKey =
109 | AllowedIPs = 192.0.2.5/32
110 | ```
111 |
112 | ### public-server2.example-vpn.dev
113 | * public endpoint: `public-server2.example-vpn.dev:51820`
114 | * own vpn ip address: `192.0.2.2`
115 | * can accept traffic for ips: `192.0.2.2/32`
116 | * priv key: ``
117 | * pub key: ``
118 | * setup required:
119 | 1. install wireguard
120 | 2. generate public/private keypair
121 | 3. create wg0.conf (see below)
122 | 4. confirm main public relay server is directly accessible
123 | 4. start wireguard
124 | * config as local interface:
125 | ```ini
126 | [Interface]
127 | # Name = public-server2.example-vpn.dev
128 | Address = 192.0.2.2/32
129 | ListenPort = 51820
130 | PrivateKey =
131 | DNS = 1.1.1.1
132 | ```
133 | * config as peer:
134 | ```ini
135 | [Peer]
136 | # Name = public-server2.example-vpn.dev
137 | Endpoint = public-server2.example-vpn.dev:51820
138 | PublicKey =
139 | AllowedIPs = 192.0.2.2/32
140 | ```
141 | * peers: public-server1
142 | * full `wg0.conf` config file for node:
143 | ```ini
144 | [Interface]
145 | # Name = public-server2.example-vpn.dev
146 | Address = 192.0.2.2/32
147 | ListenPort = 51820
148 | PrivateKey =
149 | DNS = 1.1.1.1
150 |
151 | [Peer]
152 | # Name = public-server1.example-vpn.tld
153 | Endpoint = public-server1.example-vpn.tld:51820
154 | PublicKey =
155 | # routes traffic to itself and entire subnet of peers as bounce server
156 | AllowedIPs = 192.0.2.1/24
157 | PersistentKeepalive = 25
158 | ```
159 |
160 | ### home-server.example-vpn.dev
161 | * public endpoint: (none, behind NAT)
162 | * own vpn ip address: `192.0.2.3`
163 | * can accept traffic for ips: `192.0.2.3/32`
164 | * priv key: ``
165 | * pub key: ``
166 | * setup required:
167 | 1. install wireguard
168 | 2. generate public/private keypair
169 | 3. create wg0.conf (see below)
170 | 4. confirm main public relay server is directly accessible
171 | 4. start wireguard
172 | * config as local interface:
173 | ```ini
174 | [Interface]
175 | # Name = home-server.example-vpn.dev
176 | Address = 192.0.2.3/32
177 | ListenPort = 51820
178 | PrivateKey =
179 | DNS = 1.1.1.1
180 | ```
181 | * config as peer:
182 | ```ini
183 | [Peer]
184 | # Name = home-server.example-vpn.dev
185 | Endpoint = home-server.example-vpn.dev:51820
186 | PublicKey =
187 | AllowedIPs = 192.0.2.3/32
188 | ```
189 | * peers: public-server1
190 | * full `wg0.conf` config file for node:
191 | ```ini
192 | [Interface]
193 | # Name = home-server.example-vpn.dev
194 | Address = 192.0.2.3/32
195 | ListenPort = 51820
196 | PrivateKey =
197 | DNS = 1.1.1.1
198 |
199 | [Peer]
200 | # Name = public-server1.example-vpn.tld
201 | Endpoint = public-server1.example-vpn.tld:51820
202 | PublicKey =
203 | # routes traffic to itself and entire subnet of peers as bounce server
204 | AllowedIPs = 192.0.2.1/24
205 | PersistentKeepalive = 25
206 | ```
207 |
208 | ### laptop.example-vpn.dev
209 | * public endpoint: (none, behind NAT)
210 | * own vpn ip address: `192.0.2.4`
211 | * can accept traffic for ips: `192.0.2.4/32`
212 | * priv key: ``
213 | * pub key: ``
214 | * setup required:
215 | 1. install wireguard
216 | 2. generate public/private keypair
217 | 3. create wg0.conf (see below)
218 | 4. confirm main public relay server is directly accessible
219 | 4. start wireguard
220 | * config as local interface:
221 | ```ini
222 | [Interface]
223 | # Name = laptop.example-vpn.dev
224 | Address = 192.0.2.4/32
225 | PrivateKey =
226 | DNS = 1.1.1.1
227 | ```
228 | * config as peer:
229 | ```ini
230 | [Peer]
231 | # Name = laptop.example-vpn.dev
232 | PublicKey =
233 | AllowedIPs = 192.0.2.4/32
234 | ```
235 | * peers: public-server1
236 | * full `wg0.conf` config file for node:
237 | ```ini
238 | [Interface]
239 | # Name = laptop.example-vpn.dev
240 | Address = 192.0.2.4/32
241 | PrivateKey =
242 | DNS = 1.1.1.1
243 |
244 | [Peer]
245 | # Name = public-server1.example-vpn.tld
246 | Endpoint = public-server1.example-vpn.tld:51820
247 | PublicKey =
248 | # routes traffic to itself and entire subnet of peers as bounce server
249 | AllowedIPs = 192.0.2.1/24
250 | PersistentKeepalive = 25
251 | ```
252 |
253 | ### phone.example-vpn.dev
254 | * public endpoint: (none, behind NAT)
255 | * own vpn ip address: `192.0.2.5`
256 | * can accept traffic for ips: `192.0.2.5/32`
257 | * priv key: ``
258 | * pub key: ``
259 | * setup required:
260 | 1. install wireguard
261 | 2. generate public/private keypair
262 | 3. create wg0.conf (see below)
263 | 4. confirm main public relay server is directly accessible
264 | 4. start wireguard
265 | * config as local interface:
266 | ```ini
267 | [Interface]
268 | # Name = phone.example-vpn.dev
269 | Address = 192.0.2.5/32
270 | PrivateKey =
271 | DNS = 1.1.1.1
272 | ```
273 | * config as peer:
274 | ```ini
275 | [Peer]
276 | # phone.example-vpn.dev
277 | PublicKey =
278 | AllowedIPs = 192.0.2.5/32
279 | ```
280 | * peers: public-server1
281 | * full `wg0.conf` config file for node:
282 | ```ini
283 | [Interface]
284 | # Name = phone.example-vpn.dev
285 | Address = 192.0.2.5/32
286 | PrivateKey =
287 | DNS = 1.1.1.1
288 |
289 | [Peer]
290 | # Name = public-server1.example-vpn.tld
291 | Endpoint = public-server1.example-vpn.tld:51820
292 | PublicKey =
293 | # routes traffic to itself and entire subnet of peers as bounce server
294 | AllowedIPs = 192.0.2.1/24
295 | PersistentKeepalive = 25
296 | ```
297 |
298 |
299 |
300 |
301 | Suggest changes: https://github.com/pirate/wireguard-docs/issues
302 |
303 |
304 |
--------------------------------------------------------------------------------
/example-full/home-server/home-server.key:
--------------------------------------------------------------------------------
1 | WN+bvd3PCWs5Pk3bvl7abWR0c1L6PCWKYRX56mjVYGo=
2 |
--------------------------------------------------------------------------------
/example-full/home-server/home-server.key.pub:
--------------------------------------------------------------------------------
1 | 8bSk5fATxg9qdxbK20iTGdrQ7SWvxIBhxdMo+W54pEg=
2 |
--------------------------------------------------------------------------------
/example-full/home-server/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on FreeBSD
4 | pkg install wireguard
5 |
6 | # install wireguard on Ubuntu
7 | #add-apt-repository ppa:wireguard/wireguard
8 | #apt update
9 | #apt install wireguard
10 |
--------------------------------------------------------------------------------
/example-full/home-server/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/home-server/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/home-server/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = home-server.example-vpn.dev
3 | Address = 10.0.44.3/32
4 | ListenPort = 51820
5 | PrivateKey = WN+bvd3PCWs5Pk3bvl7abWR0c1L6PCWKYRX56mjVYGo=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = public-server1.example-vpn.tld
10 | Endpoint = public-server1.example-vpn.tld:51820
11 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
12 | # routes traffic to itself and entire subnet of peers as bounce server
13 | AllowedIPs = 10.0.44.1/24
14 | PersistentKeepalive = 25
15 |
--------------------------------------------------------------------------------
/example-full/laptop/laptop.key:
--------------------------------------------------------------------------------
1 | OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
2 |
--------------------------------------------------------------------------------
/example-full/laptop/laptop.key.pub:
--------------------------------------------------------------------------------
1 | BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
2 |
--------------------------------------------------------------------------------
/example-full/laptop/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on Ubuntu
4 | #add-apt-repository ppa:wireguard/wireguard
5 | #apt update
6 | #apt install wireguard
7 |
8 | # install wireguard on macOS
9 | brew install wireguard-tools
10 |
--------------------------------------------------------------------------------
/example-full/laptop/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/laptop/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/laptop/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = laptop.example-vpn.dev
3 | Address = 10.0.44.4/32
4 | PrivateKey = OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
5 | DNS = 1.1.1.1
6 |
7 | [Peer]
8 | # Name = public-server1.example-vpn.tld
9 | Endpoint = public-server1.example-vpn.tld:51820
10 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
11 | # routes traffic to itself and entire subnet of peers as bounce server
12 | AllowedIPs = 10.0.44.1/24
13 | PersistentKeepalive = 25
14 |
--------------------------------------------------------------------------------
/example-full/phone/phone.key:
--------------------------------------------------------------------------------
1 | WH98AvjKKZ584ZLb69G912bNry2wOda9+kfzm+qbnUw=
2 |
--------------------------------------------------------------------------------
/example-full/phone/phone.key.pub:
--------------------------------------------------------------------------------
1 | VpjKa2MQKXuvttXRwJIe0LLYrtFYGQRTtmt8okUGm3A=
2 |
--------------------------------------------------------------------------------
/example-full/phone/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on iOS/Android
4 | echo "Use the iOS App Store / Google Play Store to install WireGuard on your mobile device"
5 |
--------------------------------------------------------------------------------
/example-full/phone/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Use the iOS/Android app to load the wg0.conf file and start Wireguard"
4 |
--------------------------------------------------------------------------------
/example-full/phone/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Use the iOS/Android app to load the wg0.conf file and stop Wireguard"
4 |
--------------------------------------------------------------------------------
/example-full/phone/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = phone.example-vpn.dev
3 | Address = 10.0.44.5/32
4 | PrivateKey = WH98AvjKKZ584ZLb69G912bNry2wOda9+kfzm+qbnUw=
5 | DNS = 1.1.1.1
6 |
7 | [Peer]
8 | # Name = public-server1.example-vpn.tld
9 | Endpoint = public-server1.example-vpn.tld:51820
10 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
11 | # routes traffic to itself and entire subnet of peers as bounce server
12 | AllowedIPs = 10.0.44.1/24
13 | PersistentKeepalive = 25
14 |
--------------------------------------------------------------------------------
/example-full/public-server1/public-server1.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-full/public-server1/public-server1.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-full/public-server1/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp = 1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-full/public-server1/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/public-server1/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/public-server1/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = public-server1.example-vpn.tld
3 | Address = 10.0.44.1/24
4 | ListenPort = 51820
5 | PrivateKey = 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = public-server2.example-vpn.dev
10 | Endpoint = public-server2.example-vpn.dev:51820
11 | PublicKey = SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
12 | AllowedIPs = 10.0.44.2/32
13 |
14 | [Peer]
15 | # Name = home-server.example-vpn.dev
16 | Endpoint = home-server.example-vpn.dev:51820
17 | PublicKey = 8bSk5fATxg9qdxbK20iTGdrQ7SWvxIBhxdMo+W54pEg=
18 | AllowedIPs = 10.0.44.3/32
19 |
20 | [Peer]
21 | # Name = laptop.example-vpn.dev
22 | PublicKey = BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
23 | AllowedIPs = 10.0.44.4/32
24 |
25 | [Peer]
26 | # Name = phone.example-vpn.dev
27 | PublicKey = VpjKa2MQKXuvttXRwJIe0LLYrtFYGQRTtmt8okUGm3A=
28 | AllowedIPs = 10.0.44.5/32
29 |
--------------------------------------------------------------------------------
/example-full/public-server2/public-server2.key:
--------------------------------------------------------------------------------
1 | eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
2 |
--------------------------------------------------------------------------------
/example-full/public-server2/public-server2.key.pub:
--------------------------------------------------------------------------------
1 | SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
2 |
--------------------------------------------------------------------------------
/example-full/public-server2/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
--------------------------------------------------------------------------------
/example-full/public-server2/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/public-server2/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-full/public-server2/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = public-server2.example-vpn.dev
3 | Address = 10.0.44.2/32
4 | ListenPort = 51820
5 | PrivateKey = eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = public-server1.example-vpn.tld
10 | Endpoint = public-server1.example-vpn.tld:51820
11 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
12 | # routes traffic to itself and entire subnet of peers as bounce server
13 | AllowedIPs = 10.0.44.1/24
14 | PersistentKeepalive = 25
15 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/laptop.key:
--------------------------------------------------------------------------------
1 | OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/laptop.key.pub:
--------------------------------------------------------------------------------
1 | BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on Ubuntu
4 | #add-apt-repository ppa:wireguard/wireguard
5 | #apt update
6 | #apt install wireguard
7 |
8 | # install wireguard on macOS
9 | brew install wireguard-tools
10 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/laptop/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = laptop.example-vpn.dev
3 | Address = 10.0.44.2/32
4 | PrivateKey = OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
5 | DNS = 1.1.1.1
6 |
7 | [Peer]
8 | # Name = server.example-vpn.tld
9 | Endpoint = server.example-vpn.tld:51820
10 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
11 | AllowedIPs = 0.0.0.0/0, ::/0
12 | PersistentKeepalive = 25
13 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/phone.key:
--------------------------------------------------------------------------------
1 | WH98AvjKKZ584ZLb69G912bNry2wOda9+kfzm+qbnUw=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/phone.key.pub:
--------------------------------------------------------------------------------
1 | VpjKa2MQKXuvttXRwJIe0LLYrtFYGQRTtmt8okUGm3A=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on iOS/Android
4 | echo "Use the iOS App Store / Google Play Store to install WireGuard on your mobile device"
5 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Use the iOS/Android app to load the wg0.conf file and start Wireguard"
4 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Use the iOS/Android app to load the wg0.conf file and stop Wireguard"
4 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/phone/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = phone.example-vpn.dev
3 | Address = 10.0.44.3/32
4 | PrivateKey = WH98AvjKKZ584ZLb69G912bNry2wOda9+kfzm+qbnUw=
5 | DNS = 1.1.1.1
6 |
7 | [Peer]
8 | # Name = server.example-vpn.tld
9 | Endpoint = server.example-vpn.tld:51820
10 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
11 | AllowedIPs = 0.0.0.0/0, ::/0
12 | PersistentKeepalive = 25
13 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/server.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/server.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp = 1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-internet-browsing-vpn/server/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = server.example-vpn.tld
3 | Address = 10.0.44.1/24
4 | ListenPort = 51820
5 | PrivateKey = 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
6 | DNS = 1.1.1.1
7 | PostUp = sysctl -w net.ipv4.ip_forward=1
8 | PostUp = sysctl -w net.ipv6.conf.all.forwarding=1
9 |
10 | [Peer]
11 | # Name = laptop.example-vpn.dev
12 | PublicKey = BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
13 | AllowedIPs = 10.0.44.2/32
14 |
15 | [Peer]
16 | # Name = phone.example-vpn.dev
17 | PublicKey = VpjKa2MQKXuvttXRwJIe0LLYrtFYGQRTtmt8okUGm3A=
18 | AllowedIPs = 10.0.44.3/32
19 |
--------------------------------------------------------------------------------
/example-iptables/iptables.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | IPT="/sbin/iptables"
3 |
4 | # Server IP
5 | SERVER_IP="$(ip addr show eth0 | grep 'inet ' | cut -f2 | awk '{ print $2}')"
6 |
7 | # Your DNS servers you use: cat /etc/resolv.conf
8 | DNS_SERVER="8.8.4.4 8.8.8.8"
9 |
10 | # Allow connections to this package servers
11 | PACKAGE_SERVER="ftp.us.debian.org security.debian.org"
12 |
13 | echo "flush iptable rules"
14 | $IPT -F
15 | $IPT -X
16 | $IPT -t nat -F
17 | $IPT -t nat -X
18 | $IPT -t mangle -F
19 | $IPT -t mangle -X
20 |
21 | echo "Set default policy to 'DROP'"
22 | $IPT -P INPUT DROP
23 | $IPT -P FORWARD DROP
24 | $IPT -P OUTPUT DROP
25 |
26 | ## This should be one of the first rules.
27 | ## so dns lookups are already allowed for your other rules
28 | for ip in $DNS_SERVER; do
29 | echo "Allowing DNS lookups (tcp, udp port 53) to server '$ip'"
30 | $IPT -A OUTPUT -p udp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
31 | $IPT -A INPUT -p udp -s $ip --sport 53 -m state --state ESTABLISHED -j ACCEPT
32 | $IPT -A OUTPUT -p tcp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
33 | $IPT -A INPUT -p tcp -s $ip --sport 53 -m state --state ESTABLISHED -j ACCEPT
34 | done
35 |
36 | echo "allow all and everything on localhost"
37 | $IPT -A INPUT -i lo -j ACCEPT
38 | $IPT -A OUTPUT -o lo -j ACCEPT
39 |
40 | for ip in $PACKAGE_SERVER; do
41 | echo "Allow connection to '$ip' on port 21"
42 | $IPT -A OUTPUT -p tcp -d "$ip" --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
43 | $IPT -A INPUT -p tcp -s "$ip" --sport 21 -m state --state ESTABLISHED -j ACCEPT
44 |
45 | echo "Allow connection to '$ip' on port 80"
46 | $IPT -A OUTPUT -p tcp -d "$ip" --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
47 | $IPT -A INPUT -p tcp -s "$ip" --sport 80 -m state --state ESTABLISHED -j ACCEPT
48 |
49 | echo "Allow connection to '$ip' on port 443"
50 | $IPT -A OUTPUT -p tcp -d "$ip" --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
51 | $IPT -A INPUT -p tcp -s "$ip" --sport 443 -m state --state ESTABLISHED -j ACCEPT
52 | done
53 |
54 | #######################################################################################################
55 | ## Global iptable rules. Not IP specific
56 |
57 | echo "Allowing new and established incoming connections to port 21, 80, 443"
58 | $IPT -A INPUT -p tcp -m multiport --dports 21,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
59 | $IPT -A OUTPUT -p tcp -m multiport --sports 21,80,443 -m state --state ESTABLISHED -j ACCEPT
60 |
61 | echo "Allow all outgoing connections to port 22"
62 | $IPT -A OUTPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
63 | $IPT -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
64 |
65 | echo "Allow outgoing icmp connections (pings,...)"
66 | $IPT -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
67 | $IPT -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
68 |
69 | echo "Allow outgoing connections to port 123 (ntp syncs)"
70 | $IPT -A OUTPUT -p udp --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT
71 | $IPT -A INPUT -p udp --sport 123 -m state --state ESTABLISHED -j ACCEPT
72 |
73 | # Log before dropping
74 | $IPT -A INPUT -j LOG -m limit --limit 12/min --log-level 4 --log-prefix 'IP INPUT drop: '
75 | $IPT -A INPUT -j DROP
76 |
77 | $IPT -A OUTPUT -j LOG -m limit --limit 12/min --log-level 4 --log-prefix 'IP OUTPUT drop: '
78 | $IPT -A OUTPUT -j DROP
79 |
80 | exit 0
81 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/montreal.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/montreal.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp = 1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/montreal/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = montreal.example-vpn.tld
3 | # LAN = 192.168.1.1/24
4 | Address = 10.0.44.1/24
5 | ListenPort = 51820
6 | PrivateKey = 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
7 | DNS = 1.1.1.1
8 | PostUp = sysctl -w net.ipv4.ip_forward=1
9 | PostUp = sysctl -w net.ipv6.conf.all.forwarding=1
10 | PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
11 | PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
12 |
13 |
14 | [Peer]
15 | # Name = newyork.example-vpn.dev
16 | # LAN = 192.168.2.1/24
17 | Endpoint = newyork.example-vpn.dev:51820
18 | PublicKey = SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
19 | AllowedIPs = 10.0.44.2/32, 192.168.2.1/24
20 |
21 | [Peer]
22 | # Name = vancouver.example-vpn.dev
23 | # LAN = 192.168.3.1/24
24 | Endpoint = vancouver.example-vpn.dev:51820
25 | PublicKey = 8bSk5fATxg9qdxbK20iTGdrQ7SWvxIBhxdMo+W54pEg=
26 | AllowedIPs = 10.0.44.3/32, 192.168.3.1/24
27 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/newyork.key:
--------------------------------------------------------------------------------
1 | eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/newyork.key.pub:
--------------------------------------------------------------------------------
1 | SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/newyork/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = newyork.example-vpn.dev
3 | # LAN = 192.168.2.1/24
4 | Address = 10.0.44.2/32
5 | ListenPort = 51820
6 | PrivateKey = eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
7 | DNS = 1.1.1.1
8 | PostUp = sysctl -w net.ipv4.ip_forward=1
9 | PostUp = sysctl -w net.ipv6.conf.all.forwarding=1
10 | PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
11 | PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
12 |
13 |
14 | [Peer]
15 | # Name = montreal.example-vpn.dev
16 | # LAN = 192.168.1.1/24
17 | Endpoint = montreal.example-vpn.dev:51820
18 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
19 | AllowedIPs = 10.0.44.1/32, 192.168.1.1/24
20 |
21 | [Peer]
22 | # Name = vancouver.example-vpn.dev
23 | # LAN = 192.168.3.1/24
24 | Endpoint = vancouver.example-vpn.dev:51820
25 | PublicKey = 8bSk5fATxg9qdxbK20iTGdrQ7SWvxIBhxdMo+W54pEg=
26 | AllowedIPs = 10.0.44.3/32, 192.168.3.1/24
27 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp =1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/vancouver.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/vancouver.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-lan-briding/vancouver/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = vancouver.example-vpn.tld
3 | # LAN = 192.168.3.1/24
4 | Address = 10.0.44.3/24
5 | ListenPort = 51820
6 | PrivateKey = WN+bvd3PCWs5Pk3bvl7abWR0c1L6PCWKYRX56mjVYGo=
7 | DNS = 1.1.1.1
8 | PostUp = sysctl -w net.ipv4.ip_forward=1
9 | PostUp = sysctl -w net.ipv6.conf.all.forwarding=1
10 | PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
11 | PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
12 |
13 |
14 | [Peer]
15 | # Name = montreal.example-vpn.dev
16 | # LAN = 192.168.1.1/24
17 | Endpoint = montreal.example-vpn.dev:51820
18 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
19 | AllowedIPs = 10.0.44.1/32, 192.168.1.1/24
20 |
21 | [Peer]
22 | # Name = newyork.example-vpn.dev
23 | # LAN = 192.168.2.1/24
24 | Endpoint = newyork.example-vpn.dev:51820
25 | PublicKey = SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
26 | AllowedIPs = 10.0.44.2/32, 192.168.2.1/24
27 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/client.key:
--------------------------------------------------------------------------------
1 | OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
2 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/client.key.pub:
--------------------------------------------------------------------------------
1 | BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
2 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard on Ubuntu
4 | #add-apt-repository ppa:wireguard/wireguard
5 | #apt update
6 | #apt install wireguard
7 |
8 | # install wireguard on macOS
9 | brew install wireguard-tools
10 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/client/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = laptop.example-vpn.dev
3 | Address = 10.0.44.2/32
4 | PrivateKey = OPmibSXYAAcMIYKNsWqr77zY06Kl750AEB1nWQi1T2o=
5 | DNS = 1.1.1.1
6 |
7 | [Peer]
8 | # Name = server.example-vpn.tld
9 | Endpoint = server.example-vpn.tld:51820
10 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
11 | AllowedIPs = 10.0.44.1/24
12 | PersistentKeepalive = 25
13 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/server.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/server.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp = 1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-client-to-server/server/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = public-server1.example-vpn.tld
3 | Address = 10.0.44.1/24
4 | ListenPort = 51820
5 | PrivateKey = 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = client.example-vpn.dev
10 | PublicKey = BV5DjXeCugIrjvEZLo4sZ0hN5wveFTH8kOfZ1AIQ5js=
11 | AllowedIPs = 10.0.44.2/32
12 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/server1.key:
--------------------------------------------------------------------------------
1 | 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
2 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/server1.key.pub:
--------------------------------------------------------------------------------
1 | q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
2 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
8 | # to enable kernel relaying/forwarding ability on bounce servers
9 | echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.conf
10 | echo "net.ipv4.conf.all.proxy_arp = 1" >>/etc/sysctl.conf
11 | sysctl -p /etc/sysctl.conf
12 |
13 | # to add iptables forwarding rules on bounce servers
14 | iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
15 | iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
16 | iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
17 | iptables -t nat -A POSTROUTING -s 10.0.44.0/24 -o eth0 -j MASQUERADE
18 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server1/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = server1.example-vpn.tld
3 | Address = 10.0.44.1/24
4 | ListenPort = 51820
5 | PrivateKey = 2P/3ll/TxGTjGqwcWnqJMnjwPqGw7oX1RaXlPfsf2FQ=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = server2.example-vpn.dev
10 | Endpoint = server2.example-vpn.dev:51820
11 | PublicKey = SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
12 | AllowedIPs = 10.0.44.2/32
13 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/server2.key:
--------------------------------------------------------------------------------
1 | eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
2 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/server2.key.pub:
--------------------------------------------------------------------------------
1 | SceMEaVZaZfOGtGXjMsoJjhwxKHkb++9wjxqN1vm32s=
2 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # install wireguard
4 | add-apt-repository ppa:wireguard/wireguard
5 | apt update
6 | apt install wireguard
7 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick up "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PEER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | wg-quick down "$PEER_DIR"/wg0.conf
5 | wg show
6 |
--------------------------------------------------------------------------------
/example-simple-server-to-server/server2/wg0.conf:
--------------------------------------------------------------------------------
1 | [Interface]
2 | # Name = server2.example-vpn.dev
3 | Address = 10.0.44.2/32
4 | ListenPort = 51820
5 | PrivateKey = eDwURfg8PhpUAdPp+OA9pQ5oZQYqGqY3LToUORMh220=
6 | DNS = 1.1.1.1
7 |
8 | [Peer]
9 | # Name = server1.example-vpn.tld
10 | Endpoint = server1.example-vpn.tld:51820
11 | PublicKey = q/+jwmL5tNuYSB3z+t9Caj00Pc1YQ8zf+uNPu/UE1wE=
12 | AllowedIPs = 10.0.44.1/24
13 |
--------------------------------------------------------------------------------