Wireguard筆記(一) 節點安裝配置和參數說明


目錄

Wireguard筆記(一) 節點安裝配置和參數說明
Wireguard筆記(二) 命令行操作
Wireguard筆記(三) lan-to-lan子網穿透和多網段並存

簡介

虛擬子網軟件,類似於OpenWPN,使用虛擬網卡,但是只支持UDP協議連接,配置簡單。在Kernel 5.6之后已經內置。

中繼服務器

作為中繼服務器(Bounce Server),和普通的對等節點一樣,它能夠在 NAT 后面的客戶端之間充當中繼服務器,可以將收到的任何子網流量轉發到正確的對等節點,這個過程並非由WireGuard處理,而是由系統內核和iptables處理的。公網可達的子網不需要中繼服務器,只有當有節點位於 NAT 后面時才需要。

在WireGuard里客戶端和服務端的功能是平等的,差別只是誰主動連接誰而已。如果雙方都在監聽端口,誰主動連接,誰就是客戶端。主動連接的一方需要預知對方的公網地址和端口(Endpoint),被動連接的一方則不需要。如果雙方都位於NAT后面,則需要加一個中繼節點,雙方都以中繼服務器作為對等節點,它們的通信流量會先進入中繼服務器,然后再轉發給對方。

如果某一端同時連接了多個對端,當它想訪問某個IP時,如果有具體的路由可用,則優先使用具體的路由,否則就會將流量轉發到中繼服務器,中繼服務器再根據系統路由表進行轉發。可以通過檢查wg show wg0route找到WireGuard對一個給定地址的路由方式。

安裝

服務器

參考
https://www.iplayio.cn/post/70750984
https://www.cnblogs.com/a5idc/p/13895146.html
https://yooooex.com/2019/05/23/wireguard-deploy/

ubuntu安裝

sudo apt install wireguard

centos7安裝

先升級Kernel到ml, 現在是5.11.x, 看看是否有wg模塊

lsmod|grep wireguard
# 沒有就modprobe一下再試試
modprobe wireguard

安裝wg工具

yum install epel-release
yum provides wg-quick
yum install wireguard-tools

打開轉發

sudo vi /etc/sysctl.conf
# 取消這行的注釋
net.ipv4.ip_forward=1
# 保存文件並應用更改
sudo sysctl -p
# 輸出:net.ipv4.ip_forward = 1

配置防火牆
Ubuntu: 如果啟用了UFW,需要添加規則,本例使用的端口是50004

# 添加端口
sudo ufw allow 50004/udp
# 查看
sudo ufw status verbose

Centos7

firewall-cmd --zone=public --add-port=50004/udp --permanent
firewall-cmd --reload

配置

# 生成公私鑰, 如果是對本機進行初始化, 先cd到/etc/wireguard目錄下
umask 077
wg genkey | tee private.key | wg pubkey > public.key

# 創建新文件wg0.conf, 這個是服務wg-quick@wg0默認使用的配置文件. 添加以下內容:
sudo vi /etc/wireguard/wg0.conf
# ==================== begin ===================
[Interface]
PrivateKey = [填入服務端私鑰]
Address = 10.253.0.1/24
ListenPort = 50004
# 規則說明:接受來源為%i的轉發;接受出口為%i的轉發;增加對出口為本機網卡的NAT映射
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens160 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens160 -j MASQUERADE

[Peer]
PublicKey = [填入客戶端公鑰]
# 允許客戶端使用的IP段,對於peer的隧道IP, 建議使用/32的固定IP, 以避免和其他peer重復導致無法連接
AllowedIPs = 10.253.0.2/32
# ===================== end ====================

# 啟動wg0
sudo wg-quick down wg0
# 停止wg0
sudo wg-quick up wg0
# 查看
sudo wg
# 查看單個
sudo wg show wg0

如果需要支持IPv6

# 啟動動作, 要把 ens160 替換成自己的網口名稱
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens160 -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens160 -j MASQUERADE
# 關閉動作
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens160 -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens160 -j MASQUERADE

設置為自啟動

systemctl enable wg-quick@wg0

多個wireguard服務並存

可以在/etc/wireguard/下創建多個配置文件, 例如wg0.conf, wg1.conf配置多個服務

  • 使用systemctl enable/start wg-quick@wg0, systemctl enable/start wg-quick@wg1 啟動
  • 使用wg show能同時看到這些wiguard服務的連接情況
  • 各配置使用不同的隧道網段, 會體現到route上
  • 各配置當中, peer中的allowedIP會影響route規則, 如果相同會產生沖突

對於非服務端, 配置文件的例子為

[root@vm_ci01 ~]# more /etc/wireguard/wg0.conf 
[Interface]
PrivateKey = [填入私鑰]
Address = 10.253.0.3/32
ListenPort = 50004
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; ip6tables -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; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = [填入服務端的公鑰]
AllowedIPs = 10.253.0.0/24,192.168.116.0/24
Endpoint = 1.123.45.67:50004(服務端的IP端口)
PersistentKeepalive = 25

客戶端(命令行)

先生成公私鑰,然后使用配置文件

[Interface]
PrivateKey = [客戶端私鑰]
Address = 10.253.0.2/24
DNS = 114.114.114.114

[Peer]
PublicKey = [服務端公鑰]
# 允許通過的IP段,如果設為0.0.0.0/0則攔截本機所有流量
AllowedIPs = 192.168.116.0/24,10.253.0.0/24
Endpoint = [服務器的IP]:50004
PersistentKeepalive = 25

注意

  • 如果這個客戶端是作為逆向穿透的節點
    • [Interface]中增加PostUp, PostDown, 但是不需要DNS;
    • [Interface]中Address掩碼可以使用/24也可以使用/32
    • [Peer]中增加PersistentKeepalive
  • 如果這是Windows Wireguard客戶端
    • [Interface]中不需要PostUp, PostDown, 可以不需要DNS;
    • [Interface]中Address掩碼使用/24, 否則會出現連接不上服務端的情況(本地顯示已連接, 但是服務端看不到, 並且接收字節為0)
    • [Peer]中只需要PublicKey, AllowedIPs, Endpoint

Ubuntu20.04客戶端(通過NetworkManager)

NetworkManager界面對Wireguard的支持, 要到版本1.26之后, 如果是Ubuntu20.04, 需要自己編譯.

sudo apt install wireguard git dh-autoreconf libglib2.0-dev intltool build-essential libgtk-3-dev libnma-dev libsecret-1-dev network-manager-dev resolvconf

從Github clone對應的項目

git clone https://github.com/max-moser/network-manager-wireguard
cd network-manager-wireguard
./autogen.sh --without-libnm-glib

./configure --without-libnm-glib --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib/x86_64-linux-gnu --libexecdir=/usr/lib/NetworkManager --localstatedir=/var

make   
sudo make install

然后在網絡配置界面的WPN中點擊+號, 就能看到Wireguard的選項了. 配置說明

  • Identity
    • Name: 可以使用wg0之類的名稱, 這個會被用於網口名稱, 所以不要太長太復雜
    • Interface:
      • Address(IPv4): 10.253.0.4/32 這個是開啟wg之后本機的隧道IP
      • Address(IPv6): 可以留空
      • Listen Port: 可以留空, 也可以指定為50004
      • Private Key: 本機的私鑰
      • 其他都可以留空
    • Peer
      • Public Key: 服務端的公鑰
      • Allow IPs: 需要走隧道的IP段, 一般包含隧道自身IP段, 以及要借道隧道的IP段, 但是這里設置並不會產生對應的route
      • Endpoint: 服務端的IP和端口
      • Persis.Keepalive: 25 保持活動的時間間隔
      • 其他都可以留空
  • IPv4
    • IPv4 method: Automatic (DHCP) 實際產生的IP還是之前在Identity->Interface中配置的IP地址
    • DNS: Automatic
    • Routes: 取消Automatic, 添加
      • 10.253.0.0, 255.255.255.0, 10.253.0.102, 5 將10.253.0.0/24這個段的路由, 設置到10.253.0.102(即本機的隧道網口)上
      • 192.168.13.0, 255.255.255.0, 10.253.0.102, 5 將192.168.13.0/24這個段的路由也設置到本機隧道網口上
      • 如果還有其他需要走隧道的IP段, 則繼續添加.
    • 不勾選Use this connection only for resources on its network

注意: 如果不手動添加路由, 在啟動此wg網口后, 本機路由沒有變化, 訪問不生效, 但是通過ping 10.253.0.1 -I wg0可以ping通服務端隧道IP, 說明僅是路由的問題.

配置說明

關於AllowedIPs

Wireguard的AllowedIPs因為涉及服務端和客戶端的允許IP范圍,需要理清一下這個設置的含義

  • 首先,AllowedIPs會影響當前機器的路由設置,在AllowedIPs配置的每一段IP,都會在路由表里指向這個wireguard網卡
    那么在A節點,如果你要訪問B節點后面的網絡,你就要把B節點后面網絡的IP段,配到Peer.B下面去
  • 其次,提供轉發的節點,不需要關心從各個節點到來的流量要訪問何處,不需要為自身轉發的目標網段配置AllowedIPs
    比如A節點處於5.5.5.0/24網段,A已經提供了轉發,那么A不需要在自己節點下面的Peer的AllowedIPs中配置5.5.5.0/24

服務端和客戶端的[Peer]中配置的AllowedIPs

  • 無論哪一端,AllowedIPs的IP段都會加入路由表
  • AllowedIPs需要包含對方節點的隧道IP
  • AllowedIPs需要包含對方節點提供轉發的IP網段,這將通過增加路由規則攔截本機對這些IP范圍的訪問流量
  • 當配置的AllowedIPs為0.0.0.0/0時,會將虛擬網卡的Default Gateway設為0.0.0.0,而不是通過路由表

公網中繼的AllowedIPs配置問題

使用公網中繼節點進行穿透時(例如R為公網中繼, A為工作區內網節點, B為個人接入),
如果AllowedIPs配置不正確, 會導致B->R, R->A都能訪問, 但是B->A就無法訪問的問題. 需要檢查A節點的配置, 檢查其中R這個節點的[Peer]配置中AllowedIPs是否未包含B節點的隧道IP.
舉例:
R節點 有公網IP, 提供前往192.168.116.x和192.168.117.x的中轉

[Interface]
Address = 10.253.0.1/32
...
[Peer]
AllowedIPs = 10.253.0.3/32,192.168.117.0/24

A節點 處於192.168.117.0/24的內網

[Interface]
Address = 10.253.0.3/32
[Peer]
AllowedIPs = 10.253.0.1/32,192.168.116.0/24
Endpoint = xx.xx.xx.xx:10004

B節點 個人外網接入, 需要訪問192.168.117.0/24網段

[Interface]
Address = 10.253.0.101/24
[Peer]
AllowedIPs = 192.168.116.0/24, 10.253.0.0/24, 192.168.117.0/24
Endpoint = xx.xx.xx.xx:10004

這時候就會出現前面提到的情況, B->RR->A訪問都通但是B->A訪問不通, 需要將A配置中R的AllowedIPs改為10.253.0.1/24才行, 如下所示.

[Interface]
Address = 10.253.0.3/32
[Peer]
AllowedIPs = 10.253.0.1/24,192.168.116.0/24
Endpoint = xx.xx.xx.xx:10004

或者更進一步, 僅僅將B節點和R節點的IP放入, 如下所示, 這樣就只允許B->R->A, 其他節點連接到R之后, 無法訪問A

[Interface]
Address = 10.253.0.3/32
[Peer]
AllowedIPs = 10.253.0.1/32,10.253.0.101/32,192.168.116.0/24
Endpoint = xx.xx.xx.xx:10004

關於PresharedKey

即PSK 預共享密鑰,節點可以給連接自己的每一個peer都分配一個PSK,這個PSK會設置在每對節點的[Peer]中,連接時檢查是否一致

# 生成(每個peer一個)
wg genpsk > presharedkey
# 配置格式
[Peer]
PublicKey    = P556VVMhhBb+kc2Gm7JV46jh1oRv75YscK8q131iSnM=
PresharedKey = oZ33KPYBwo7aFyxewm5Eutlelztz9lXQ2Z8tyouc7TM=
AllowedIPs   = 10.253.0.0/24
Endpoint     = 123.123.123.123:31231
...

關於PersistentKeepAlive

這個參數用於內網節點定期發送報文以保持連接。默認情況下WG盡量保持沉默以避免發送太多數據,但是如果連接中一些節點處於內網或防火牆后,在長時間無數據后連接可能被防火牆關閉,此時如果外網節點需要發送數據,會發現連接不可用。這種情況下就需要內網節點定期主動發送數據以保持連接。
注意:這個參數與最后握手時間是不一樣的。一次握手會建立一個約三分鍾長度的會話時間,在這個會話時間內,發送keep-alive報文不需要再次建立會話。在實際使用中,如果發送報文時會話時間已經剩余不到1分鍾,會在此會話到期前就創建一個新的會話。正常情況下,如果PersistentKeepAlive設為了25,握手時間基本上不會超過3分鍾,除非處於移動設備上,因為設備節電等原因導致發送時間滯后等情況。

關於DNS

客戶端如果配置為全流量攔截(0.0.0.0/0),則必須設置DNS項,如果不配置DNS,在連接后會不能正確解析域名

關於子網間穿透

Wireguard可以配置通過一個公共服務器同時連接多個子網。這時候需要在服務器和每個子網節點上,都配置同一個網段的隧道IP和相應的路由,可以參考
https://anyisalin.github.io/2018/11/21/fast-flexible-nat-to-nat-vpn-wireguard/ 主要的設置有三處:

  1. 服務器和子網節點: 在sysctl中開啟ip forward
  2. 服務器和子網節點: 在[Interface]中增加PostUp和PostDown的路由設置
  3. 服務器: 需要設置一下端口號,並在防火牆中打開此端口
  4. 服務器和子網節點如果安裝了firewalld, 還需要在firewalld中開啟masquerade
firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --reload

Windows節點
windows做這個穿透會比較復雜,因為windows不像linux那樣有iptables可以配置,需要設置的可以參考這篇 https://www.henrychang.ca/how-to-setup-wireguard-vpn-server-on-windows/

使用TCP來避免防火牆的UDP規則影響

可以使用udptunnel
https://gist.github.com/insdavm/90cbeffe76ba4a51251d83af604adf94
或者udp2raw-tunnel
https://github.com/wangyu-/udp2raw-tunnel
以及TunSafe
https://github.com/TunSafe/TunSafe

后兩者有支持windows和android的客戶端
實現思路是在服務端運行一個TCP隧道, 代理wg的端口, 在客戶端運行TCP隧道的客戶端, 連接到服務端的TCP隧道, 客戶端的wg連接本地端口

iptables規則

單包驗證SPA規則

# 清空iptables
iptables -F
# 已經建立的tcp連接允許通過 -m state --state ESTABLISHED 只針對tcp
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
# 允許訪問udp 62201端口 
iptables -A INPUT -p udp --dport 62201  -j ACCEPT
# 允許22端口通過
iptables -A INPUT -p tcp --dport 22  -j ACCEPT
# 允許入包回環
iptables -A INPUT -i lo -j ACCEPT
# 出包的tcp
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
# 出包的udp
iptables -A OUTPUT -p udp -j ACCEPT
# 允許出包回環
iptables -A OUTPUT -o lo -j ACCEPT
# 允許建立的FORWARD通過
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
# 最后一步 關閉IMPUT,OUTPUT,FORWARD
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

其他

提供內核支持的發行版

在Ubuntu20.04最近的更新中, Kernel已經升級到5.8.0, 自帶了wireguard

~$ uname -a
Linux milton-t550 5.8.0-43-generic #49~20.04.1-Ubuntu SMP Fri Feb 5 09:57:56 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
~$ sudo modprobe wireguard
[sudo] password for milton: 
~$ lsmod
Module                  Size  Used by
wireguard              86016  0
curve25519_x86_64      49152  1 wireguard
libchacha20poly1305    16384  1 wireguard
chacha_x86_64          28672  1 libchacha20poly1305
poly1305_x86_64        28672  1 libchacha20poly1305
libblake2s             16384  1 wireguard
blake2s_x86_64         20480  1 libblake2s
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             16384  1 wireguard

對於Centos7, 可以升級內核至5.11.x: Centos7 和 Centos8 升級內核

Debug日志

啟用WireGuard debug

echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control

Disable WireGuard debug

echo 'module wireguard -p' | sudo tee /sys/kernel/debug/dynamic_debug/control

查看輸出

dmesg
# or
journalctl -f

性能測試

https://www.reddit.com/r/linux/comments/9bnowo/wireguard_benchmark_between_two_servers_with_10/
對Wireguard性能的測試, 比較的對象是直接傳輸和OpenVPN. 用netperf在MTU8500~9000的情況下, 三者的速度對比是44:23:1

netperf -t TCP_STREAM -l 600 -H 10.0.9.11


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM