summaryrefslogtreecommitdiff
path: root/content/wireguard.md
blob: c0d1879a274819eac375c8db860673852181c261 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
---
title: Wireguard
date: 2022-07-26T00:00:00.000Z
icon: wireguard.svg
tags:
  - service
short_desc: "Fast, Modern, Secure VPN Tunnel"
---

Looking for lightweight privacy on the go? Then consider hosting a WireGuard VPN service.
In addition to this setup guide, we'll also demonstrate how to tunnel
your WireGuard traffic through a TLS WebSocket connection to circumvent some
deep packet inspection systems.

As an example, we'll be using a virtual 172.16.0.0/24 network, but any private ip range will suffice.

## Installation

### On the Server

Install the WireGuard management tools:

    apt install wireguard

Enable IPv4 forwarding by uncommenting the following line in `/etc/sysctl.d/99-sysctl.conf`

    net.ipv4.ip_forward=1

Run the following command to apply the change:

    sysctl -w net.ipv4.ip_forward=1

### On the Client

Use your package manager to install the WireGuard Management Tools.
On Arch and Fedora based distros the package is `wireguard-tools`. For Debian based, it's listed above.

Create the public and private keys for your machine:

    sudo bash -c "umask 077 ; wg genkey > /etc/wireguard/client_priv.key"
    sudo bash -c "wg pubkey < /etc/wireguard/client_priv.key > /etc/wireguard/client_pub.key"

### Back to the Server

Generate the public and private keys for your server:

    umask 077 ; wg genkey > /etc/wireguard/server_priv.key
    wg pubkey < /etc/wireguard/server_priv.key > /etc/wireguard/server_pub.key

Create a WireGuard configuration file `/etc/wireguard/wg0.conf`, where `wg0` is the name of the network interface:

    [Interface]
    Address = 172.16.0.1/24
    ListenPort = 51820
    PrivateKey = (server's private key goes here)
    # Firewall rules
    PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

    [Peer]
    # Client #1 details
    PublicKey = (client's public key goes here)
    # Traffic to route to this client
    AllowedIPs = 172.16.0.2/32

Paste the server's private key and client's public key on their respective
lines, each being around 45 characters with an equal sign at the end.

#### Note on extra peers

In our example, the subnet could recognize up to 254 other peers. Add the new
peer's info below the first peer and update the `AllowedIPS` line to the next virtual
ip. Don't change the `32`: this ensures everyone's tunnel is isolated.
Use this optionally for extra devices or for friends.

Enable and start the WireGuard service:

    systemctl enable --now wg-quick@wg0.service

Change `wg0` to match the name of the config file if you called it something different.

### Back to the Client

Create another WireGuard configuration file in `/etc/wireguard/myvpn.conf`:

    [Interface]
    Address = 172.16.0.2/24
    PrivateKey = (client's private key goes here)
    # Set to your desired DNS server
    # DNS = 9.9.9.9

    [Peer]
    PublicKey = (server's public key goes here)
    # Endpoint (server) can be a domain name or IP address
    Endpoint = (server's IP address goes here):51820
    # Traffic to route to server
    AllowedIPs = 0.0.0.0/0, ::/0

Fill in your information where needed. Remember to use your server's public ip address, not the wireguard one.

Start WireGuard:

    sudo wg-quick up myvpn

If you cannot ping `172.16.0.1` or reach the Internet, and have meticulously followed this guide so far,
there's a good chance you're behind a corporate firewall. Read on.

## WebSocket Tunnel

#### Note on TLS

If your server hosts a website with https, you won't be able to use port 443 to
obfuscate your WireGuard packets as TLS traffic. You may use some other innocuous
port, but there's no guarantee you'll punch through the picky firewall.

### On the Server

Download and install wstunnel:

    wget https://github.com/erebe/wstunnel/releases/download/v4.0/wstunnel-x64-linux
    mv wstunnel-x64-linux /usr/local/bin/wstunnel
    chmod uo+x /usr/local/bin/wstunnel
    setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/wstunnel

Make a new systemd service config file, `/etc/systemd/system/wstunnel.service`:

    [Unit]
    Description=Tunnel WireGuard UDP over websocket
    After=network.target

    [Service]
    Type=simple
    User=nobody
    ExecStart=/usr/local/bin/wstunnel -v --server wss://0.0.0.0:443 --restrictTo=127.0.0.1:51820
    Restart=no

    [Install]
    WantedBy=multi-user.target

Enable and start wstunnel:

    systemctl enable --now wstunnel

### On the Client

Download and install wstunnel and a helper script:

    wget https://github.com/erebe/wstunnel/releases/download/v4.0/wstunnel-x64-linux
    sudo mv wstunnel-x64-linux /usr/local/bin/wstunnel
    sudo chmod +x /usr/local/bin/wstunnel
    wget https://raw.githubusercontent.com/jnsgruk/wireguard-over-wss/master/wstunnel.sh
    sudo mv wstunnel.sh /etc/wireguard/wstunnel.sh
    sudo chmod +x /etc/wireguard/wstunnel.sh

Create the wstunnel configuration file, `/etc/wireguard/myvpn.wstunnel`:

    REMOTE_HOST=(server's IP address goes here)
    REMOTE_PORT=51820
    # Use the following line if you're connecting to your VPN server using a domain name.
    # UPDATE_HOSTS='/etc/hosts'

Edit `/etc/wireguard/myvpn.conf`. Change the `Endpoint` line to `127.0.0.1:51820` and add these four lines to the `[Interface]` section:

    Table = off
    PreUp = source /etc/wireguard/wstunnel.sh && pre_up %i
    PostUp = source /etc/wireguard/wstunnel.sh && post_up %i
    PostDown = source /etc/wireguard/wstunnel.sh && post_down %i

Start WireGuard again:

    sudo wg-quick up myvpn

To disconnect, type `down` instead of `up`. And just like that, you now host a WireGuard VPN server!