User:Wacek/brudnopis WireGuard

From ArchWiki

Ze strony głównej projektu WireGuard

WireGuard to niezwykle prosta, ale szybka i nowoczesna sieć VPN, która wykorzystuje najnowocześniejszą kryptografię. Ma być szybszy, prostszy, szczuplejszy i bardziej przydatny niż IPsec. Ma być znacznie wydajniejszy niż OpenVPN. WireGuard został zaprojektowany jako VPN ogólnego przeznaczenia do pracy na wbudowanych interfejsach i superkomputerach, przystosowany do wielu różnych okoliczności. Początkowo wydany dla jądra Linuksa, jest teraz wieloplatformowy (Windows, macOS, BSD, iOS, Android) i szeroko stosowany.
Warning: WireGuard nie przeszedł odpowiedniego stopnia audytu bezpieczeństwa, a protokół nadal może ulec zmianie [1].

Instalacja

Install wireguard-tools i jeden lub więcej odpowiednich modułów jądra:

Note: WireGuard został połączony z Linuksem 5.6. [2]
Tip: zarówno systemd-networkd jak i NetworkManager mają natywne wsparcie dla konfiguracji interfejsów WireGuard, wymagają tylko modułu jądra.

Używanie

Poniższe polecenia pokazują, jak skonfigurować podstawowy tunel między dwoma równorzędnymi urządzeniami z następującymi ustawieniami:

This article or section needs expansion.

Reason: Add Peer C to better demonstrate routing and PSK, and add IPv6. (Discuss in User talk:Wacek/brudnopis WireGuard)
Peer A Peer B
Zewnętrzny adres IP 198.51.100.101 203.0.113.102
Wewnętrzny adres IP 10.0.0.1/24 10.0.0.2/24
Port nasłuchowy WireGuard UDP/51871 UDP/51902

Adresy zewnętrzne powinny już istnieć. Na przykład, peer A powinien mieć możliwość pingowania peer B poprzez ping ping 203.0.113.102 i odwrotnie. Adresy wewnętrzne będą nowymi adresami utworzonymi za pomocą poniższych poleceń ip(8) i będą udostępniane wewnętrznie w nowej sieci WireGuard za pomocą wg(8). /24 w adresach IP to CIDR.

Generowanie klucza

Aby utworzyć klucz prywatny:

$ umask 077
$ wg genkey > privatekey

Aby utworzyć klucz publiczny:

$ wg pubkey < privatekey > publickey

Możesz to zrobić jednocześnie:

$ umask 077; wg genkey | tee privatekey | wg pubkey > publickey

Można również wygenerować wstępny klucz, aby dodać dodatkową warstwę kryptografii z kluczem symetrycznym, aby zmieszać ją z już istniejącą kryptografią z kluczem publicznym, aby uzyskać odporność post kwantową.

This article or section needs expansion.

Reason: A pre-shared key should be created for each peer pair. E.g. with peers A, B and C, there should be three pre-shared keys, peer_A-peer_B-psk for the connection between Peer A and Peer B, peer_A-peer_C-psk for the connection between Peer A and Peer C and peer_B-peer_C-psk for the connection between Peer B and Peer C. (Discuss in User talk:Wacek/brudnopis WireGuard)
# wg genpsk > preshared

Konfiguracja peer A

Ten element równorzędny będzie nasłuchiwał na porcie UDP 51871 i zaakceptuje połączenie z elementem równorzędnym B, łącząc swój klucz publiczny zarówno z wewnętrznym, jak i zewnętrznym adresem IP.

# ip link add dev wg0 type wireguard
# ip addr add 10.0.0.1/24 dev wg0
# wg set wg0 listen-port 51871 private-key ./privatekey
# wg set wg0 peer PEER_B_PUBLIC_KEY persistent-keepalive 25 allowed-ips 10.0.0.2/32 endpoint 203.0.113.102:51902
# ip link set wg0 up

PEER_B_PUBLIC_KEY powinien mieć ten sam format co EsnHH9m6RthHSs+sd9uM6eCHe/mMVFaRh93GYadDDnM=. Słowo kluczowe allowed-ips to lista adresów, do których uczestnik A będzie mógł wysyłać ruch; allowed-ips 0.0.0.0/0 pozwoliłoby na wysyłanie ruchu na dowolny adres IPv4, ::/0 pozwala na wysyłanie ruchu na dowolny adres IPv6.

Konfiguracja peer B

Jak w przypadku peera A, podczas gdy demon wireguard nasłuchuje na porcie UDP 51902 i akceptuje połączenie tylko z peer A.

# ip link add dev wg0 type wireguard
# ip addr add 10.0.0.2/24 dev wg0
# wg set wg0 listen-port 51902 private-key ./privatekey
# wg set wg0 peer PEER_A_PUBLIC_KEY persistent-keepalive 25 allowed-ips 10.0.0.1/32 endpoint 198.51.100.101:51871
# ip link set wg0 up

Basic checkups

Wywołanie polecenia wg(8) bez parametru da szybki przegląd bieżącej konfiguracji.

Na przykład po skonfigurowaniu elementu równorzędnego A możemy zobaczyć jego tożsamość i powiązane elementy równorzędne:

[user@peer-a]# wg
interface: wg0
  public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
  private key: (hidden)
  listening port: 51871

peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
  endpoint: 203.0.113.102:51902
  allowed ips: 10.0.0.2/32

W tym momencie można było dojść do końca tunelu:

[user@peer-a]$ ping 10.0.0.2

Trwała konfiguracja

Konfigurację można zapisać za pomocą showconf:

# wg showconf wg0 > /etc/wireguard/wg0.conf
# wg setconf wg0 /etc/wireguard/wg0.conf

Przykładowa konfiguracja równorzędna

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY

[Peer]
PublicKey = SERVER_PUBLICKEY
AllowedIPs = 10.0.0.0/24, 10.123.45.0/24, 1234:4567:89ab::/48
Endpoint = SERVER_ENDPOINT:51871
PersistentKeepalive = 25

Przykładowa konfiguracja dla systemd-networkd

Zobacz #Using systemd-networkd.

Szczególny przypadek użycia: serwer VPN

Note: Używa się tutaj terminów „serwer” i „klient” specjalnie dla nowych użytkowników WireGuard i dla obecnych użytkowników OpenVPN, aby pomóc w zapoznaniu się z konstrukcją plików konfiguracyjnych. Dokumentacja WireGuard po prostu odnosi się do obu tych pojęć jako „peerów”.

Celem tej sekcji jest skonfigurowanie „serwera” WireGuard i ogólnych „klientów”, aby umożliwić dostęp do zasobów serwerowych / sieciowych przez zaszyfrowany i zabezpieczony tunel, taki jak OpenVPN i inne. Serwer działa na systemie Linux, a klienci mogą uruchamiać dowolną liczbę platform (WireGuard Project oferuje aplikacje na platformy iOS i Android oprócz Linux, Windows i MacOS). Zobacz oficjalny install link projektu, aby uzyskać więcej.

Tip: Zamiast używać wireguard-tools do konfiguracji serwer / klient, można użyć natywnej obsługi WireGuard systemd-networkd.

serwer

Na komputerze równorzędnym, który będzie działał jako „serwer”, najpierw włącz przekazywanie IPv4 za pomocą sysctl:

# sysctl -w net.ipv4.ip_forward=1

Aby zmienić na stałe, dodaj net.ipv4.ip_forward = 1 do /etc/sysctl.d/99-sysctl.conf.

Prawidłowo skonfigurowany firewall jest WYSOKIE zalecany dla każdego urządzenia podłączonego do Internetu.

Jeśli na serwerze skonfigurowano publiczny adres IP, należy:

  • Zezwalaj na ruch UDP na określonych portach, na których WireGuard będzie działał (na przykład zezwalając na ruch na 51820/udp).
  • Skonfiguruj zasady przekazywania dla zapory, jeśli nie są one zawarte w konfiguracji WireGuard dla samego interfejsu /etc/wireguard/wg0.conf. Poniższy przykład powinien zawierać reguły iptables i działać bez zmian.

Jeśli serwer znajduje się za NAT, należy przekazać określone porty, na których będzie działać WireGuard (na przykład 51820/UDP) z routera na serwer WireGuard.

Generowanie klucza

Wygeneruj pary kluczy dla serwera i dla każdego klienta, jak wyjaśniono w #Generowanie klucza.

Konfiguracja serwera

Utwórz plik konfiguracyjny „serwer”:

/etc/wireguard/wg0.conf
[Interface]
Address = 10.200.200.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

# note - substitute eth0 in the following lines to match the Internet-facing interface
# if the server is behind a router and receive traffic via NAT, this iptables rules are not needed
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# foo
PublicKey = PEER_FOO_PUBLIC_KEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.200.2/32

[Peer]
# bar
PublicKey = PEER_BAR_PUBLIC_KEY
AllowedIPs = 10.200.200.3/32

Dodatkowe elementy równorzędne ("clients") mogą być wyświetlane w tym samym formacie, w zależności od potrzeb. Każdy peer wymaga ustawienia PublicKey Jednak określenie PresharedKey jest opcjonalne.

Zauważ, że Address ma maskę „/24”, a klienci na dozwolonych AllowedIPs „/32”. Klient używa tylko swojego adresu IP, a serwer odsyła tylko odpowiedni adres.

Interfejsem można zarządzać ręcznie za pomocą wg-quick(8) lub usługi systemowej zarządzanej przez systemctl(1).

Interfejs można wywołać za pomocą wg-quick up wg0 odpowiednio poprzez uruchomienie i potencjalnie włączenie interfejsu za pośrednictwem wg-quick@interface.service, np. wg-quick@wg0.service Aby zamknąć interfejs, użyj wg-quick down wg0 odpowiednio stop wg-quick@interface.service.

Konfiguracja klienta

Utwórz odpowiednie pliki konfiguracyjne „klienta”:

foo.conf
[Interface]
Address = 10.200.200.2/24
PrivateKey = PEER_FOO_PRIVATE_KEY
DNS = 10.200.200.1

[Peer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = my.ddns.example.com:51820
bar.conf
[Interface]
Address = 10.200.200.3/24
PrivateKey = PEER_BAR_PRIVATE_KEY
DNS = 10.200.200.1

[Peer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = my.ddns.example.com:51820

Używając catch-all AllowedIPs = 0.0.0.0/0, ::/0 przekieruje cały ruch IPv4 (0.0.0.0/0) i IPv6 (::/0) przez VPN.

Note: Users of NetworkManager, may need to enable the NetworkManager-wait-online.service and users of systemd-networkd may need to enable the systemd-networkd-wait-online.service to wait until devices are network ready before attempting wireguard connection.

Testowanie tunelu

Po utworzeniu tunelu można użyć netcat do wysyłania przez niego ruchu w celu przetestowania przepustowości, wykorzystania procesora itp. Po jednej stronie tunelu uruchom {ic|nc}} w trybie nasłuchiwania, a po drugiej przesyłaj dane z /dev/zero do nc w trybie wysyłania.

W poniższym przykładzie do ruchu wykorzystywany jest port 2222 (pamiętaj, aby zezwolić na ruch na porcie 2222, jeśli używasz zapory ogniowej).

On one side of the tunnel listen for traffic:

$ nc -vvlnp 2222

Po jednej stronie tunelu nasłuchuj ruchu:

$ dd if=/dev/zero bs=1024K count=1024 | nc -v 10.0.0.203 2222

Status można monitorować za pomocą wg bezpośrednio.

# wg
interface: wg0
  public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
  private key: (hidden)
  listening port: 51820

peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
  preshared key: (hidden)
  endpoint: 192.168.1.216:53207
  allowed ips: 10.0.0.0/0
  latest handshake: 1 minutes, 17 seconds ago
  transfer: 56.43 GiB received, 1.06 TiB sent

Rozwiązywanie problemów

Trasy są okresowo resetowane

Użytkownicy NetworkManager powinni upewnić się, że nie zarządza interfejsami WireGuard. Na przykład utwórz następujący plik konfiguracyjny:

/etc/NetworkManager/conf.d/unmanaged.conf
[keyfile]
unmanaged-devices=interface-name:wg*

Broken DNS resolution

Podczas tunelowania całego ruchu przez interfejs WireGuard połączenie może pozornie zostać utracone po pewnym czasie lub przy nowym połączeniu. Może to być spowodowane zastąpieniem /etc/resolv.conf .przez menedżera sieci lub klienta DHCP.

Domyślnie 'wg-quick używa resolvconf do rejestrowania nowych wpisów DNS (ze słowa kluczowego DNS w pliku konfiguracyjnym). Spowoduje to problemy z menedżerami sieci i klientami DHCP, którzy nie używają resolvconf, ponieważ zastąpią /etc/resolv.conf usuwając w ten sposób serwery DNS dodane przez wg-quick.

Rozwiązaniem jest użycie oprogramowania sieciowego obsługującego resolvconf.

Note: Użytkownicy systemd-resolved powinni upewnić się, że systemd-resolvconf jest zainstalowany.

Użytkownicy NetworkManager powinni wiedzieć, że domyślnie nie używa resolvconf. Zalecane jest użycie systemd-resolved. Jeśli jest to niepożądane, zainstaluj openresolv i skonfiguruj NetworkManager, aby go używał: NetworkManager#Use openresolv.

Low MTU

Z powodu zbyt niskiej MTU (mniejszej niż 1280), wg-quick mogło nie utworzyć interfejsu WireGuard. Można to rozwiązać, ustawiając wartość MTU w konfiguracji WireGuard w sekcji Interfejs na kliencie.

/foo.config
[Interface]
Address = 10.200.200.2/24
MTU = 1500
PrivateKey = PEER_FOO_PRIVATE_KEY
DNS = 10.200.200.1

Porady i wskazówki

Korzystanie z systemd-networkd

systemd-networkd ma natywną obsługę protokołów WireGuard i dlatego nie wymaga pakietu wireguard-tools.

Aby zapobiec wyciekom kluczy prywatnych, zaleca się ustawienie uprawnień do pliku .netdev

# chown root:systemd-network /etc/systemd/network/99-*.netdev
# chmod 0640 /etc/systemd/network/99-*.netdev

Serwer

/etc/systemd/network/99-server.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = WireGuard

[WireGuard]
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

[WireGuardPeer]
PublicKey = PEER_FOO_PUBLIC_KEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.200.2/32

[WireGuardPeer]
PublicKey = PEER_BAR_PUBLIC_KEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.200.3/32
/etc/systemd/network/99-server.network
[Match]
Name = wg0

[Network]
Address = 10.200.200.1/32

[Route]
Gateway = 10.200.200.1
Destination = 10.200.200.0/24

Client foo

/etc/systemd/network/99-client.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = WireGuard

[WireGuard]
PrivateKey = FOO_PRIVATE_KEY

[WireGuardPeer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.0.0/24
Endpoint = my.ddns.example.com:51820
PersistentKeepalive = 25
/etc/systemd/network/99-client.network
[Match]
Name = wg0

[Network]
Address = 10.200.200.2/32

[Route]
Gateway = 10.200.200.1
Destination = 10.200.200.0/24
GatewayOnlink=true

Client bar

/etc/systemd/network/99-client.netdev
[NetDev]
Name = wg0
Kind = wireguard
Description = WireGuard

[WireGuard]
PrivateKey = PEER_BAR_PRIVATE_KEY

[WireGuardPeer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.0.0/24
Endpoint = my.ddns.example.com:51820
PersistentKeepalive = 25
/etc/systemd/network/99-client.network
[Match]
Name = wg0

[Network]
Address = 10.200.200.3/32

[Route]
Gateway = 10.200.200.1
Destination = 10.200.200.0/24
GatewayOnLink=true

Przechowuj klucze prywatne w postaci zaszyfrowanej

It may be desirable to store private keys in encrypted form, such as through use of pass. Just replace the PrivateKey line under [Interface] in the configuration file with:

Może być pożądane przechowywanie kluczy prywatnych w postaci zaszyfrowanej, na przykład poprzez użycie pass. Po prostu zamień wiersz PrivateKey w [Interface] w pliku konfiguracyjnym na:

PostUp = wg set %i private-key <(su user -c "export PASSWORD_STORE_DIR=/path/to/your/store/; pass WireGuard/private-keys/%i")

gdzie użytkownik to nazwa użytkownika systemu Linux będąca przedmiotem zainteresowania. Zobacz stronę podręcznika wg-quick(8), aby uzyskać więcej informacji.

Punkt końcowy ze zmianą adresu IP

Po rozwiązaniu domeny serwera WireGuard nie będzie ponownie sprawdzał zmian w DNS.

Jeśli serwer WireGuard często zmienia swój adres IP z powodu DHCP, Dyndns, IPv6, ..., dowolny klient WireGuard straci połączenie, dopóki jego punkt końcowy nie zostanie zaktualizowany za pomocą czegoś takiego jak wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT".

Należy również pamiętać, że jeśli punkt końcowy kiedykolwiek zmieni swój adres (na przykład podczas przeprowadzki do nowego dostawcy / centrum danych), po prostu aktualizacja DNS nie będzie wystarczająca, więc okresowe uruchamianie polecenia reresolve-dns może mieć sens w dowolnej konfiguracji opartej na DNS .

Na szczęście wireguard-tools udostępnia przykładowy skrypt /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh, który analizuje pliki konfiguracyjne WG i automatycznie resetuje adres punktu końcowego.

Należy okresowo uruchamiać /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh /etc/wireguard/wg.conf aby okresowo odzyskiwać dane z punktu końcowego, który zmienił adres IP.

Jednym ze sposobów jest aktualizacja wszystkich punktów końcowych WireGuard raz na trzydzieści sekund [3] za pomocą systemowego timera:

/etc/systemd/system/wireguard_reresolve-dns.timer
[Unit]
Description=Periodically reresolve DNS of all WireGuard endpoints

[Timer]
OnCalendar=*:*:0/30

[Install]
WantedBy=timers.target
/etc/systemd/system/wireguard_reresolve-dns.service
[Unit]
Description=Reresolve DNS of all WireGuard endpoints
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'for i in /etc/wireguard/*.conf; do /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh "$i"; done'

Następnie włącz i uruchom wireguard_reresolve-dns.timer

Wygeneruj kod QR

Jeśli klient jest urządzeniem mobilnym, takim jak telefon, można użyć kodu qrencode do wygenerowania kodu QR konfiguracji klienta i wyświetlenia go w terminalu:

$ qrencode -t ansiutf8 < client.conf

Włącz dzienniki debugowania

Podczas korzystania z modułu jądra Linux na jądrze obsługującym dynamiczne debugowanie, informacje debugowania można zapisać w buforze pierścieniowym jądra (widocznym za pomocą dmesg i journalctl), uruchamiając:

# modprobe wireguard 
# echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

Zobacz też