https://www.wireguard.com/img/wireguard.svg

Wireguard to nowoczesny, szybki i ultra lekki VPN. Twórcy założyli sobie, że ma działać zarówno na urządzeniach o małej mocy obliczeniowej, jak i na super nowoczesnych komputerach. Nie będę się skupiać na niuansach działania samego VPN. Niniejszy artykuł ma przybliżyć samą instalację oraz konfigurację.

Należy mieć również na uwadze, że projekt dynamicznie się rozwija, dlatego musimy się liczyć z bardzo częstymi aktualizacjami.

Projekt oficjalnie został włączony do jądra Linuksa od wersji 5.6. Jeżeli mamy tę wersję, to i proces instalacji możemy spokojnie pominąć.

Instalacja

Sam proces instalacji jest bardzo ładnie opisany na stronie projektu https://www.wireguard.com/install/. Odnajdziemy tam instrukcje instalacji dla wszystkich dominujących systemów operacyjnych na rynku (Windows, Mac, Android, Linux, BSD). Dlatego doszedłem do wniosku, iż nie będę tego wszystkiego powielać, aczkolwiek, zaprezentuje, jak przebiegał proces instalacji w moim przypadku. Cała instalacja odbyła się na tymczasowo uworzonym VPS-ie o adresie IP: 80.211.241.78. Nasz serwer oparty jest na Debian 10. Jako klient posłuży mój desktop z zainstalowanym Linux-em.

# apt update && apt upgrade
# apt install build-essentials libmnl-dev linux-headers-$(uname -r)
# git clone https://git.zx2c4.com/WireGuard
Cloning into 'WireGuard'...
remote: Enumerating objects: 11070, done.
remote: Counting objects: 100% (11070/11070), done.
remote: Compressing objects: 100% (2712/2712), done.
remote: Total 11070 (delta 8284), reused 10837 (delta 8119)
Receiving objects: 100% (11070/11070), 2.33 MiB | 2.14 MiB/s, done.
Resolving deltas: 100% (8284/8284), done.
[root@wireguard ~]# cd WireGuard/src
root@wireguard:~# git clone https://git.zx2c4.com/WireGuard
Cloning into 'WireGuard'...
warning: redirecting to https://git.zx2c4.com/wireguard-monolithic-historical/
remote: Enumerating objects: 17, done.
remote: Counting objects: 100% (17/17), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 11550 (delta 0), reused 0 (delta 0), pack-reused 11533
Receiving objects: 100% (11550/11550), 2.39 MiB | 4.19 MiB/s, done.
Resolving deltas: 100% (8638/8638), done.
root@wireguard:~# cd WireGuard/src/
root@wireguard:~/WireGuard/src# make
/bin/sh: 1: bc: not found
  CC [M]  /root/WireGuard/src/main.o
  CC [M]  /root/WireGuard/src/noise.o
  CC [M]  /root/WireGuard/src/device.o
  CC [M]  /root/WireGuard/src/peer.o
  CC [M]  /root/WireGuard/src/timers.o
  CC [M]  /root/WireGuard/src/queueing.o
  CC [M]  /root/WireGuard/src/send.o
  CC [M]  /root/WireGuard/src/receive.o
  CC [M]  /root/WireGuard/src/socket.o
  CC [M]  /root/WireGuard/src/peerlookup.o
  CC [M]  /root/WireGuard/src/allowedips.o
  CC [M]  /root/WireGuard/src/ratelimiter.o
  CC [M]  /root/WireGuard/src/cookie.o
  CC [M]  /root/WireGuard/src/netlink.o
  CC [M]  /root/WireGuard/src/crypto/zinc/chacha20/chacha20.o
  PERLASM /root/WireGuard/src/crypto/zinc/chacha20/chacha20-x86_64.S
  AS [M]  /root/WireGuard/src/crypto/zinc/chacha20/chacha20-x86_64.o
  CC [M]  /root/WireGuard/src/crypto/zinc/poly1305/poly1305.o
  PERLASM /root/WireGuard/src/crypto/zinc/poly1305/poly1305-x86_64.S
  AS [M]  /root/WireGuard/src/crypto/zinc/poly1305/poly1305-x86_64.o
  CC [M]  /root/WireGuard/src/crypto/zinc/chacha20poly1305.o
  CC [M]  /root/WireGuard/src/crypto/zinc/blake2s/blake2s.o
  AS [M]  /root/WireGuard/src/crypto/zinc/blake2s/blake2s-x86_64.o
  CC [M]  /root/WireGuard/src/crypto/zinc/curve25519/curve25519.o
  LD [M]  /root/WireGuard/src/wireguard.o
  Building modules, stage 2.
/bin/sh: 1: bc: not found
  MODPOST 1 modules
  CC      /root/WireGuard/src/wireguard.mod.o
  LD [M]  /root/WireGuard/src/wireguard.ko
  CC      /root/WireGuard/src/tools/wg.o
  CC      /root/WireGuard/src/tools/config.o
  CC      /root/WireGuard/src/tools/show.o
  CC      /root/WireGuard/src/tools/terminal.o
  CC      /root/WireGuard/src/tools/ipc.o
  CC      /root/WireGuard/src/tools/mnlg.o
  CC      /root/WireGuard/src/tools/encoding.o
  CC      /root/WireGuard/src/tools/curve25519.o
  CC      /root/WireGuard/src/tools/setconf.o
  CC      /root/WireGuard/src/tools/genkey.o
  CC      /root/WireGuard/src/tools/showconf.o
  CC      /root/WireGuard/src/tools/pubkey.o
  CC      /root/WireGuard/src/tools/set.o
  LD      /root/WireGuard/src/tools/wg
root@wireguard:~/WireGuard/src# make install
  INSTALL /root/WireGuard/src/wireguard.ko
  DEPMOD  4.19.0-8-amd64
Warning: modules_install: missing 'System.map' file. Skipping depmod.
depmod -a 4.19.0-8-amd64
'wg' -> '/usr/bin/wg'
'man/wg.8' -> '/usr/share/man/man8/wg.8'
'completion/wg.bash-completion' -> '/usr/share/bash-completion/completions/wg'
'wg-quick/linux.bash' -> '/usr/bin/wg-quick'
install: creating directory '/etc/wireguard'
'man/wg-quick.8' -> '/usr/share/man/man8/wg-quick.8'
'completion/wg-quick.bash-completion' -> '/usr/share/bash-completion/completions/wg-quick'

Konfiguracja

Konfiguracje zaczynamy od wygenerowanie kluczy: prywatnego oraz publicznego. Klucze mają postać base64. Operację tą wykonujemy na każdym z urządzeń tj. serwerze, jaki i klientach. Należy pamiętać, że pomiędzy urządzeniami wymieniamy się tylko kluczami publicznymi. Klucze prywatne jak sama nazwa wskazuje, są prywatne i takie powinny pozostać. Oczywiście na potrzebę tego artykułu będą podane.

Serwer

Klucz prywatny:

[root@wireguard wg-keys]# umask 077
[root@wireguard wg-keys]# wg genkey > privatekey.wg
[root@wireguard wg-keys]# cat privatekey.wg
8NFVDOg+xJ+wo5SSOckwundt+S9U1UibGS1/QAFmnXU=

Klucz publiczny:

[root@wireguard wg-keys]# wg pubkey < privatekey.wg > publickey.wg
[root@wireguard wg-keys]# cat publickey.wg
rFru+bSvHb6TMt+aWo+dEVUvOB5S3YQDSrA4tQkqQSQ=

Po wygenerowaniu kluczy możemy przystąpić do konfiguracji interfejsu sieciowego.

Tworzymy nowy interfejs sieciowy typu wireguard, nazwiemy go wg0:

[root@wireguard wg-keys]#ip link add dev wg0 type wireguard

Następnie przypisujemy do niego adres IP (ten wewnątrz, oczywiście możecie sobie wybrać dowolną klasę adresów IP. Ja wybrałem IP z klasy A:

[root@wireguard wg-keys]# ip address add dev wg0 10.0.0.1/24

Mając tak utworzony interfejs sieciowy, możemy przejść do konfiguracji właściwej. Do tego służy komenda wg:

root@wireguard wg-keys]# wg set wg0 listen-port 51820 private-key privatekey.wg
  • set wg0 - Podajemy nazwę interfejsu sieciowego, jak pamiętamy nasz nazywa się wg0
  • listen-port 51820 - port UDP na którym będziemy nasłuchiwać, w tym przypadku używamy domyślnego
  • private-key privatekey.wg - plik z naszym kluczem prywatnym

Kolejnym krokiem jest dodanie klientów (naszych urządzeń), które będą miały prawo łączyć się do serwera VPN. Aby to zrobić, potrzebujemy klucze publiczne naszych urządzeń. (Klucz publiczny, który wygenerowałem na moim komputerze ma postać 'AhC5QJv8PR9RyJ/JtwgRwaU7UJDTzQ0UXfxVvhcfN0Q='. Warto też dodać, że adres IP pierwszego naszego klienta wewnątrz sieci VPN, musi być 10.0.0.2).

root@wireguard wg-keys# wg set wg0 peer "AhC5QJv8PR9RyJ/JtwgRwaU7UJDTzQ0UXfxVvhcfN0Q=" allowed-ips 10.0.0.2/32

Podstawową konfigurację mamy już ukończoną. Teraz pozostaje nam tylko „podnieść” nasz nowy interfejs sieciowy wg0. Dzięki czemu zacznie „oczekiwać” nowych połączeń.

root@wireguard wg-keys# ip link set dev wg0 up

Klient

Proces generowania kluczy, jak wspomniałem wcześniej, jest identyczny z procesem po stronie serwera. Na potrzebę tego artykułu pokażę tylko ich zawartość:

dawid@arch:~/.ssh$  cat privatekey.wg
mIhFAH5LXgtMkalWsmFwEJCu3T/QRHkNOLSk0ZrjuWI=
dawid@arch:~/.ssh$  cat publickey.wg
AhC5QJv8PR9RyJ/JtwgRwaU7UJDTzQ0UXfxVvhcfN0Q=

Podobnie ma się konfiguracja nowego interfejsu sieciowego. W tym przypadku nazwę go sobie wg0-client tak, aby móc łatwo odróżnić, do czego służy:

dawid@arch:~/.ssh$ sudo ip link add dev wg0-client type wireguard
dawid@arch:~/.ssh$ sudo ip address add dev wg0-client 10.0.0.2/24
dawid@arch:~/.ssh$ sudo wg set wg0-client private-key privatekey.wg peer "rFru+bSvHb6TMt+aWo+dEVUvOB5S3YQDSrA4tQkqQSQ=" allowed-ips 0.0.0.0/0 endpoint 80.211.241.78:51820 persistent-keepalive 21
dawid@arch:~/.ssh$ sudo ip link set dev wg0-client up

Kilka słów wyjaśnienia:

  • Ares IP klienta 10.0.0.2 wewnątrz naszej sieci VPN
  • peer "rFru+bSvHb6TMt+aWo+dEVUvOB5S3YQDSrA4tQkqQSQ=" - tym razem podajemy klucz publiczny serwera
  • endpoint 80.211.241.78:51820 - adres IP oraz port naszego serwera VPN
  • persistent-keepalive 21 - co ile sekund mają być wysyłane pakiety podtrzymujące połączenie, głównie ma to zastosowanie, kiedy nasz klient jest za NAT-em.

Ostatnia komenda sudo ip link set dev wg0-client up nawiązuję połączenie sieciowe do serwera VPN. Jeżeli nasza konfiguracja jest poprawna, połączenie powinno być ustawione. Aby to sprawdzić, możemy użyć komendy ping, bądź wpisując samą komendę wg. Poniżej przykład:

dawid@arch:~/.ssh$  ping -c 4 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=11.4 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=11.5 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=11.3 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=11.6 ms

--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 11.289/11.446/11.574/0.108 ms
dawid@arch:~/.ssh$  sudo wg
interface: wg0-client
  public key: AhC5QJv8PR9RyJ/JtwgRwaU7UJDTzQ0UXfxVvhcfN0Q=
  private key: (hidden)
  listening port: 50182

peer: rFru+bSvHb6TMt+aWo+dEVUvOB5S3YQDSrA4tQkqQSQ=
  endpoint: 80.211.241.78:51820
  allowed ips: 0.0.0.0/0
  latest handshake: 37 seconds ago
  transfer: 6.93 KiB received, 34.59 KiB sent
  persistent keepalive: every 21 seconds

Taka konfiguracja nie jest stała, po restarcie serwera czy klienta zostanie usunięta. Na szczęście twórcy WireGuard przygotowali skrypt wg-quick który zapisze/ułatwi korzystanie z VPN-a. Dodatkowo skrypt automatycznie konfiguruje nam VPN-a jako "bramę" na świat. Oznacza to, że cały ruch internetowy będzie przechodził przez naszego VPN-a.

Aby zapisać już istniejącą konfigurację musimy wykonać kilka czynności:

Po stronie klienta:

Tworzymy plik o nazwie tak jak interfejs sieciowy + rozszerzenie conf. W naszym przypadku będzie to

dawid@arch:~/ sudo touch /etc/wireguard/wg0-client.conf

Następnie zapisujemy konfigurację to tego pliku używając polecenia

dawid@arch:~/ sudo wg-quick save wg0-client.conf

Po stronie serwera

Tworzymy plik o nazwie tak jak interfejs sieciowy + rozszerzenie conf. W naszym przypadku będzie to

root@wireguard wg-keys# touch /etc/wireguard/wg0.conf

Następnie zapisujemy konfigurację to tego pliku używając polecenia

root@wireguard wg-keys# sudo wg-quick save wg0.conf

Dodatkowo włączamy możliwość przekazywanie protokołu IPv4. W pliku /etc/sysctl.conf doajemy/bądz usuwamy komentarz z linii net.ipv4.ip_forward=1. Po restarcie serwera będzie automatycznie włączane.

Aby teraz nie restartować serwera uruchamiamy komendę:

[root@wireguard ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

Jeszcze na koniec edytujemy plik /etc/wireguard/wg0.conf naszym ulubionym edytorem i dodajemy 2 wpisy PostUp oraz PostDown pod sekcją [Interface]. Posłużą one do przekazywania pakietów pomiędzy interfejsami sieciowymi, tak zwany NAT

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = 8NFVDOg+xJ+wo5SSOckwundt+S9U1UibGS1/QAFmnXU=
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]
PublicKey = AhC5QJv8PR9RyJ/JtwgRwaU7UJDTzQ0UXfxVvhcfN0Q=
AllowedIPs = 10.0.0.2/32

Teraz tylko na sam koniec pozostał nam restart naszych interfejsów sieciowych już za pomocą komendy wg-quick:

#serwer
root@wireguard wg-keys#  wg-quick down wg0.conf
root@wireguard wg-keys#  wg-quick up wg0.conf
#klient
dawid@arch:~/ sudo wg-quick down wg0-client.conf
dawid@arch:~/ sudo wg-quick up wg0-client.conf
#Sprawdzenie naszego IP
dawid@arch:~$  curl -s http://whatismyip.akamai.com/
80.211.241.78

Jak widzimy nasz "nowy" adres IP jest taki sam jak serwera.

Previous Post