Tóm tắt: Mỗi máy sinh một cặp key (wg genkey | wg pubkey), chỉ trao đổi public key. Viết /etc/wireguard/wg0.conf gồm [Interface] (private key, địa chỉ tunnel, port) và một [Peer] cho mỗi bên kia (public key, AllowedIPs, Endpoint). Bật bằng wg-quick up wg0 hoặc systemctl enable --now wg-quick@wg0, kiểm tra bằng wg show. Mở UDP port trên firewall (nftables).
Luồng hoạt động
flowchart LR A["Laptop (peer)"] -->|"UDP 51820, mã hoá"| B["Server wg0 203.0.113.10"] B -->|"AllowedIPs khớp src?"| C{"Nhận gói"} C -->|có| D["Chuyển vào LAN 192.0.2.0/24"] C -->|không| E[Drop] D -->|"Trả lời: dst khớp AllowedIPs của peer nào"| B
AllowedIPs có hai vai trò cùng lúc:
| Chiều | Ý nghĩa |
|---|---|
| Gửi đi | Bảng định tuyến nội bộ của wg: gói có dst thuộc AllowedIPs của peer nào thì gửi cho peer đó (cryptokey routing) |
| Nhận về | Gói giải mã từ peer chỉ được nhận nếu src thuộc AllowedIPs của chính peer đó |
wg-quick còn tự thêm route hệ thống cho mọi AllowedIPs (trừ khi đặt Table = off).
Cấu hình
Ví dụ: server có IP public 203.0.113.10, tunnel dùng 198.51.100.0/24, LAN sau server là 192.0.2.0/24.
Sinh key
sudo apt install wireguard # gói wireguard-tools có wg và wg-quick
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genpsk > peer1.psk # tuỳ chọn: pre-shared key cho từng cặp peerPrivate key chỉ nằm trên máy sở hữu nó, quyền 0600. Không dán vào ticket/chat/Git. File cấu hình chứa private key nên cũng phải chmod 600.
Server
[Interface]
Address = 198.51.100.1/24
ListenPort = 51820
PrivateKey = <private-key-của-server>
# Cho peer đi vào LAN: bật forward + NAT (bỏ nếu LAN có route ngược về 198.51.100.0/24)
PostUp = sysctl -q -w net.ipv4.ip_forward=1
PostUp = nft add table ip wgnat; nft add chain ip wgnat post '{ type nat hook postrouting priority 100; }'; nft add rule ip wgnat post ip saddr 198.51.100.0/24 oifname "eth0" masquerade
PostDown = nft delete table ip wgnat
[Peer]
# laptop-alice
PublicKey = <public-key-của-laptop>
PresharedKey = <psk-của-cặp-này>
AllowedIPs = 198.51.100.2/32Trên server, AllowedIPs của peer client thường là /32 địa chỉ tunnel của client (thêm subnet phía sau nếu là site-to-site).
Client
[Interface]
Address = 198.51.100.2/32
PrivateKey = <private-key-của-laptop>
# DNS = 192.0.2.53 # wg-quick đặt DNS qua resolvconf, cần gói resolvconf/systemd-resolved
[Peer]
PublicKey = <public-key-của-server>
PresharedKey = <psk-của-cặp-này>
Endpoint = 203.0.113.10:51820
AllowedIPs = 198.51.100.0/24, 192.0.2.0/24 # split tunnel: chỉ mạng lab đi qua VPN
PersistentKeepalive = 25 # giữ mapping NAT khi client sau NATAllowedIPs = 0.0.0.0/0, ::/0 = full tunnel (mọi traffic đi qua VPN); wg-quick tự xử lý policy routing để không mất route tới chính Endpoint.
Bật và kiểm tra
sudo chmod 600 /etc/wireguard/wg0.conf
sudo wg-quick up wg0 # tắt: wg-quick down wg0
sudo systemctl enable --now wg-quick@wg0 # chạy khi boot
sudo wg show # peer, endpoint, latest handshake, transfer
sudo wg show wg0 latest-handshakes
ping -c3 198.51.100.1
ip route get 192.0.2.20 # phải đi dev wg0Thêm/sửa peer không cắt tunnel đang chạy
# Sửa wg0.conf rồi áp phần cấu hình wg (không đụng Address/route):
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'
# Hoặc thêm nóng một peer (nhớ ghi lại vào wg0.conf):
sudo wg set wg0 peer <public-key-của-peer-mới> allowed-ips 198.51.100.3/32wg syncconf không thêm route mới cho AllowedIPs mới; với subnet mới phía sau peer, thêm route thủ công (ip route add ... dev wg0) hoặc systemctl restart wg-quick@wg0.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
wg show không có latest handshake |
UDP 51820 bị chặn, sai Endpoint, sai public key | Mở port trên firewall/security group; so public key hai bên; tcpdump -ni eth0 udp port 51820 |
| Có handshake nhưng ping không qua | AllowedIPs thiếu src/dst; gói bị drop ở chiều nhận |
Kiểm tra cả hai đầu: src của gói phải nằm trong AllowedIPs của peer gửi |
| Vào được server nhưng không vào được LAN | Chưa bật ip_forward hoặc thiếu NAT/route ngược |
sysctl net.ipv4.ip_forward; thêm masquerade hoặc route 198.51.100.0/24 về server |
Hai peer có AllowedIPs trùng nhau |
Prefix chỉ thuộc một peer, peer thêm sau "lấy mất" | Mỗi prefix chỉ khai báo cho đúng một peer |
| Kết nối chết sau vài phút không dùng | NAT timeout, client sau NAT | PersistentKeepalive = 25 phía client |
| Web chậm/treo, ping nhỏ thì được | MTU (mặc định wg-quick tính từ route, thường 1420) | Đặt MTU = 1380 trong [Interface], kiểm tra bằng ping -M do -s 1352 |
resolvconf: command not found khi up |
Có dòng DNS = nhưng thiếu resolvconf |
Cài resolvconf (hoặc dùng resolvectl), hoặc bỏ dòng DNS |
Tham khảo
- WireGuard quickstart
man wg,man wg-quick- Cryptokey routing