
Wireguard-docs: Setup, usage, configuration, and a full example - axiomdata316
https://github.com/pirate/wireguard-docs
======
nikisweeting
Goddamn it, this happens literally every time I post my projects to HN :(

I posted the link myself to my repo, 0 points 14 hours later someone else
posts it: 260+ points

No hate towards you axiomdata316, thanks for posting it, I'm just childishly
complaining about the unfairness of fake internet points :p

~~~
axiomdata316
Lol. I know what you mean. Congrats on all the attention you're getting
however. BTW I went to your original post and gave you a point. ;-)

~~~
swrobel
If anyone else wants to...
[https://news.ycombinator.com/item?id=20031254](https://news.ycombinator.com/item?id=20031254)

------
jchook
Gotta say, if you just want a VPN to work now, definitely check out Algo or
Streisand.

You can get a VPN running in an hour or less. Algo even supports wireguard.

I currently have two VPNs — Algo Wireguard & iVPN.

Anecdotally the wireguard VPN rocks— crazy fast in every way, including
connection/disconnection.

Sometimes YouTube is slow.. I just hop on WG and it’s fast again. I’ve
achieved faster downloads via WG than my bare internet connection (thanks
Linode!)

However, some points to consider:

1\. If you use a VPS to host your own VPN.. you don’t gain privacy. Usually
your IP can (mostly) still identify you. And your VPS company will hold you
accountable for your traffic eg DMCA.

2\. OpenVPN never borks my resolv.conf but Wireguard often leaves my DNS
resolution in a state of confusion.

~~~
nsomaru
My default-config Streisand server was compromised according to Vultr. Just a
heads up because VPNs can’t really afford this.

~~~
NamTaf
Per the sibling comments, I'd definitely like to know more detail. I rely on
Streisand when in China and so if it's something to do with Streisand itself
then I want to be aware of that.

------
oedmarap
For anyone wanting to get WireGuard up and running in a few minutes with zero
hassle, I usually use this excellent bash script [0] as my goto.

Can be edited for DNS/subnet config, generates .conf files as needed and also
handles QR code generation for adding mobile devices. Pair this with a $5 DO
droplet and you're all set.

[0] [https://github.com/its0x08/wg-install](https://github.com/its0x08/wg-
install)

~~~
groovybits
I typically use Algo for this

[https://github.com/trailofbits/algo](https://github.com/trailofbits/algo)

------
snvzz
My first thought is usually to check the Arch Wiki[0]. As usual, it does not
disappoint.

[0]:
[https://wiki.archlinux.org/index.php/WireGuard](https://wiki.archlinux.org/index.php/WireGuard)

~~~
nikisweeting
I love the Arch wiki, used it as a reference for a lot of my setup while I was
writing these docs. Also linked to it at the bottom under _Further Reading_.

------
syedamer
Beware all examples in this don't cover ipv6. Should you have an ipv6 address,
you are not using the vpn for most of your connections.

Sadly most Wireguard howtos don't cover ipv6.

~~~
StavrosK
If you give me some sample config I can add it to my howto here:
[https://www.stavros.io/posts/how-to-configure-
wireguard/](https://www.stavros.io/posts/how-to-configure-wireguard/)

~~~
tgragnato
I based my configuration on yours. You just need to add another 'Address =
<IPv6>' (client and server), and add ip6tables.

The address is going to be static: I'm not aware of a way to simulate privacy
extensions with Wireguard. A workaround is to assign ULAs and apply NAT.

~~~
StavrosK
I see, thank you. Unfortunately I don't have IPv6 on my network and don't know
the IPv6 local addresses and ip6tables config, if you could give me the actual
config you used I'd appreciate it, especially if it works with both IPv4 and
IPv6 together.

~~~
tgragnato
Sure

\------------------

[Interface] Address = 172.16.31.1/24 Address = 2001:__::1/64 PrivateKey = __
ListenPort = 443

[Peer] PublicKey = __ PresharedKey = __ AllowedIPs = 172.16.31.2/32,
2001:__::2/128

[Peer] PublicKey = __ PresharedKey = __ AllowedIPs = 172.16.31.3/32,
2001:__::3/128

[...]

\------------------

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j
ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A
FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT PostDown =
iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT;
iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i
%i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT

\------------------

[Interface] Address = 172.16.31.2/24 Address = 2001:__::2/64 PrivateKey = __
DNS = 172.16.31.1, 2001:__::1 [Peer] PublicKey = __ PresharedKey = __
AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = <server_ip>:443 PersistentKeepalive =
25

\------------------

~~~
StavrosK
This is extremely helpful, thanks!

------
sowbug
Author, if you're reading this: thank you.

This weekend I wrote a simple tool to manage a client/server-style Wireguard
setup. It's a little less tedious than copying and pasting "wg genkey" and "wg
pubkey" output as you're setting up new clients. It's not quite easy enough
for someone to use without prior Wireguard setup knowledge, but if you've
gotten your first client-server pair running, then you'll recognize where this
tool fits into the rest of your workflow.

Hope it helps someone.

~~~
davidcollantes
Where is the tool you build?

~~~
garblegarble
I'm not the person you're replying to, but I think this is what they were
referring to from their github:
[https://github.com/sowbug/mkwgconf](https://github.com/sowbug/mkwgconf)

~~~
sowbug
Aaaaand I'm awake after a good night's sleep and far past the edit window for
my original comment. Thank you for that link; yes, it's the one I meant to
post. Sigh.

~~~
nikisweeting
Thanks for this tool, I just added it to the docs:

[https://github.com/pirate/wireguard-
docs/commit/faaf447868a5...](https://github.com/pirate/wireguard-
docs/commit/faaf447868a597825f9889b6999c8c41764901f9)

------
puzzlingcaptcha
>IPSec (IKEv2)/strongSwan: lots of brittle config that's different for each
OS, NAT busting setup is very manual and involves updating the central server
and starting all the others in the correct order, not great at reconnecting
after network downtime, had to be manually restarted often

I don't follow, NAT traversal is integral to IKEv2 and pretty much "just
works" [1]. Reconnecting after network downtime is not an issue either, with
either on demand connection setup (auto=add) or pretty standard ifupdown
scripts/networkmanager. I don't believe I had to restart my strongswan daemons
in the past few months either...

I also disagree that config is 'brittle'. Quite to the contrary, I think
strongswan with its exhaustive documentation and a complete test suite which
provides configuration for _every host_ in every scenario in the test suite is
a great accomplishment and an incredibly useful resource [example: 2].

I think wireguard has a great niche to fill as OpenVPN replacement (which has
a lot of issues) but some of its supposed benefits over ipsec are a bit
overblown and a confluence of 'I couldn't be bothered to read the manual',
failure to understand a difference between host-based and policy-based routing
[3] and a pinch of hype-driven development.

[1]
[https://wiki.strongswan.org/projects/strongswan/wiki/NatTrav...](https://wiki.strongswan.org/projects/strongswan/wiki/NatTraversal)

[2] [https://www.strongswan.org/testing/testresults/ikev2/rw-
cert...](https://www.strongswan.org/testing/testresults/ikev2/rw-
cert/index.html)

[3]
[https://wiki.strongswan.org/projects/strongswan/wiki/Introdu...](https://wiki.strongswan.org/projects/strongswan/wiki/IntroductionTostrongSwan)

~~~
zymhan
> OpenVPN replacement (which has a lot of issues)

Care to elaborate?

~~~
anilakar
This. I'm using OpenVPN for ethernet bridging, which Wireguard cannot do.

~~~
amaccuish
I've done bridging over wireguard. You just set up a gretap tunnel to run over
the wireguard tunnel.

------
ktta
> ZeroTier: haven't tried it yet, sould I?

Yes. If connectivity to clients behind NAT is important and you don't want to
waste effort creating a 'bounce off' server.

ZeroTier makes it really easy to setup a private VPN with minimal config. The
real value add with it is the work that's done regarding hole punching and if
you have a carrier grade NAT that is tough to get through, it will relay your
traffic (albeit at a throttled speed) which can be a great time saver.

The other thing is their online 'Central' where you can add/remove devices,
assign IP addresses, set flow rules and more. I really like their service and
the best part of it compared to my WireGuard server is I don't have to worry
about downtime due to some problem with my server.

------
alels
I looked a bit into Wireguard.

But it seems it's only really useful with static IPs.

Say my "Server" is behind a DDns Hostname and i want to connect to it from my
Phone.

So my problem is. I allow incoming from 0.0.0.0 but on my mobile the DDns
Hostname gets compiled to a specific IP.

OpenVpn has no problem with this setup. Is it solvable with Wireguard?

wg-dynamic seems to tackle this but wasn't really ready last time i checked

~~~
mtmsr
Wireguard comes with an example script [1] that does DNS updates for peers,
which works well for me in a cron job. Archwiki also has an example for
systemd timers [2]. But if your question is specifically about phones, then
this might get a bit more complicated to set up.

[1]
[https://git.zx2c4.com/WireGuard/tree/contrib/examples/rereso...](https://git.zx2c4.com/WireGuard/tree/contrib/examples/reresolve-
dns/reresolve-dns.sh)

[2]
[https://wiki.archlinux.org/index.php/WireGuard#Endpoint_with...](https://wiki.archlinux.org/index.php/WireGuard#Endpoint_with_changing_IP)

------
genghizkhan
I wish there was good documentation/a tutorial which shows one how to use
systemd-networkd and nftables to manage wireguard interfaces. The Arch Wiki
has some documentation[0], but I've never been able to get it past the initial
handshake (which always succeeds) and no one on the IRC channel was able to
help me out.

I don't want to ask for hand-holding, but some more comprehensive and
accessible documentation might help me troubleshoot it better.

[0]
[https://wiki.archlinux.org/index.php/WireGuard#Using_systemd...](https://wiki.archlinux.org/index.php/WireGuard#Using_systemd-
networkd)

~~~
mahkoh
If you want to enable forwarding then set the sysctl [0] and masquerade [1].
nftables also has a `log` rule which might be useful for debugging.

If you can't even connect to services on the peer then first delete all
iptables and nftables rules and try again.

[0]
[https://wiki.archlinux.org/index.php/WireGuard#Server](https://wiki.archlinux.org/index.php/WireGuard#Server)

[1]
[https://wiki.archlinux.org/index.php/Nftables#Masquerading](https://wiki.archlinux.org/index.php/Nftables#Masquerading)

~~~
genghizkhan
Thank you, kind stranger! I know what tomorrow's project is going to be!

------
voltagex_
This is really good. I hope the author considered getting this pushed
upstream.

~~~
baobrien
If the author hasn't reached out, @zx2c4 will probably see this post. He's
pretty active on wireguard-related HN posts.

~~~
nikisweeting
I've already emailed him to discuss it :)

------
apexalpha
Use this as a permanent VPN on my phone to my home. It only forwards requests
in the 192.168.1.0/24 range and that includes all DNS requests that go to my
pihole. All regular traffic is unaffected as my upload at home is slower than
my 4G download speed and I don't want to limit it.

Can recommend this setup to everyone, especially on devices with spotty
connections like a phone.

------
sirtoffski
That's awesome! My suggestions:

* I'd include this research paper. It's the "first mechanised cryptographic proof of WG protocol" : [https://hal.inria.fr/hal-02100345/document](https://hal.inria.fr/hal-02100345/document)

Self-plug right here. There are a ton of bash scripts to install and configure
WireGuard. Here's mine: [https://github.com/SirToffski/WireGuard-
Ligase/](https://github.com/SirToffski/WireGuard-Ligase/)

It will configure server and clients independent of the OS it's running at.
Steps to install WG are provided in the Wiki. On Ubuntu server with pre-
installed WG, the quick setup option will make a ready to use server. You can
quickly edit the variables to change things up.

Cheers!

------
graystevens
Looks like a great write up, very thorough. I wrote up a quick guide how to
make the mobile setup a little easier with QR codes within the WireGuard
mobile apps - when I get the time I’ll submit a pull request to get something
included. [https://grh.am/2018/wireguard-setup-guide-for-
ios/](https://grh.am/2018/wireguard-setup-guide-for-ios/)

~~~
nikisweeting
Thanks! Just added this link under the _Further Reading_ section.

------
anilakar
Wireguard is a great solution for a secure, high-performance data pipe.
However, it only supports layer 3 static routing by itself, which by itself
fits none of my typical use cases.

If you're willing to think of it as a secure control plane where the
cryptographic identities of peers are mapped to IP addresses, you can run
other tried-and-tested but insecure tunnels over it.

------
sysashi
Thanks for the docs, very helpful! I'm following Wireguard project and trying
to gather all the bits sometimes takes time.

I'm also making a simple program for myself and friend that is able to talk to
hosting providers via API, spawn a vps and just installs prebuild image with
Wireguard, Pihole and Cloudflared installed and configured + UI to add /
remove clients.

------
josteink
This looks like a very comprehensive guide with lots of practical examples.
Good job!

What I cannot see explicitly mentioned anywhere, is a full example of how to
set up a central wireguard server which routes client traffic from the VPN
subnet out to the Internet.

Is this done automatically/implicitly? If so how? I don’t see enough commands
to make this happen.

Am I just stupid? What am I missing?

~~~
nikisweeting
Just add `,0.0.0.0/0` to AllowedIPs on the central server, and `,0.0.0.0/0` on
the peer definition for the central server on all the clients.

I'll add an example to the docs as well.

~~~
nikisweeting
Added here: [https://github.com/pirate/wireguard-docs#Forwarding-All-
Traf...](https://github.com/pirate/wireguard-docs#Forwarding-All-Traffic)

------
moreorless
This is great, but if you want something with a web-frontend for creating
users, Veeam has a nice free tool for that.

[https://www.veeam.com/powered-network.html](https://www.veeam.com/powered-
network.html)

------
darkpuma
Superb, just what I was looking for. The official documentation really is
spartan.

------
ac130kz
I've been waiting for UDP support/tunnelling for so long that it makes me
think about writing my it on my own.

------
exabrial
I'd like a tutorial on getting wireguard running with systemd for
debian/ubuntu based systems!

------
cm2187
Is wireguard also able to reach 1gbps on Windows? (Windows performance was my
main beef with OpenVPN).

------
the_common_man
Can wireguard be run in docker?

~~~
MertsA
The wireguard kernel implementation can't but AFAIK you should be able to run
a userspace implementation like the rust version just fine.

~~~
FredFS456
The Rust implementation is very incomplete, I believe you'll have better luck
with the Go userspace implementation.

------
yourfate
I'm using it with mullvad, works great on desktop and iOS.

------
moviuro
It's seriously weird that `Address=10.0.1.2/32` works at all. An Address
should have a correct subnet mask (like your IP at home might be
192.168.1.25/24, not 192.168.1.25/32).

The documentation is complete, but I think the most important topic is
`AllowedIPs`. The rest is pretty standard and unsurprising (if you have any
networking knowledge at all). I had written a bit about AllowedIPs when I
switched to WG myself:
[https://try.popho.be/wg.html](https://try.popho.be/wg.html) , with examples
too.

~~~
alias_neo
You're aware that /32 is the correct way of specifying one, single IPv4
address using this notation?

There is nothing weird about it at all.

If you've used IPv6 you'll see the equivalent /128 for a single address.

~~~
moviuro
Try setting 192.168.1.25/32 on your eth0 interface, you're in for a bad time.

~~~
Hikikomori
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP
group default qlen 1000

    
    
        inet 192.168.101.12/24 brd 192.168.101.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet 192.168.1.25/32 scope global eth0
           valid_lft forever preferred_lft forever
        inet 192.168.1.32/31 scope global eth0
           valid_lft forever preferred_lft forever
    

Seems to work fine, added a /31 just for fun.

~~~
moviuro
if you remove the /24 you'll have a nice surprise

~~~
Hikikomori
Not really a surprise. The point is that it is a completely valid address to
use, and in this case it just defines a range. /32 are commonly used in
routers (even servers in some cases) and /31 for linknets.

------
nprateem
Could Wireguard have been written in Rust or does it require C for some
reason? We've seen CVEs in major libraries (e.g. openssl) and some of the
guarantees Rust provides would prevent certain classes of vulnerabilities.

Has the author not learnt from the past or does it actually need to be written
in C for some reason?

~~~
moreentropy
You don't seem to have spent a single minute researching before posting :/

The original implementation is a kernel module. You can find a bunch of
(excellent) talks online by wireguard's author which all have a focus on
security aspects and avoiding vulnerabilities. Besides, Go and Rust (3rd pty)
implementations exist.

~~~
nprateem
> You don't seem to have spent a single minute researching before posting

Correct. This is a discussion site after all.

> The original implementation is a kernel module

How does that make it safer if it's written in C? Of course no one likes to
think they're writing vulnerable code...

~~~
rswail
If you want a module to be accepted in to the Linux kernel upstream, then you
have to comply with the kernel's rules.

The kernel uses various C macros and GCC extensions. Ensuring that a module
written in another language was compatible, even given that it would need to
be built outside the normal tree would make its maintenance within the kernel
tree impossible.

In terms of being written in C++/Rust/whatever, as an external module that
complies with the kernel ABI (not guaranteed between kernel releases), go for
it.

But if you want to have your protocol/module in the standard kernel tree, C is
your choice.

~~~
cesarb
> the kernel ABI (not guaranteed between kernel releases)

Even within a single release, the kernel ABI varies depending on several
kernel configuration options (for instance, CONFIG_SMP).

