Bookmark

Dựng WireGuard server trên OpenWrt bằng UCI và kiểm tra tunnel

WireGuard server trên OpenWrt có ba ranh giới tôi phải giữ rõ: key của server/client, firewall cho UDP listen port và interface VPN nằm trong zone nào. Bài dưới dùng chính tên/địa chỉ của mẫu nguồn; private key, PSK và password chỉ được sinh trên máy thật, không ghi vào Markdown.1

Mục tiêu và giả định

Nguồn hướng tới VPN mã hóa, truy cập LAN từ xa, split/full tunnel và tránh leak ở client. Tôi giả định router đã có WAN hoạt động, client có thể tạo key, và đã chuẩn bị đường port-forward UDP từ Internet vào VPN_PORT nếu router nằm sau modem. Bài này không thay thế phần cấu hình client; sau khi server xong, đối chiếu thêm tài liệu WireGuard client/extras.

1. Preparation

Cài package và đặt tham số. VPN_IF, VPN_PORT, IPv4 /24 và ULA IPv6 /64 là đúng chuỗi của nguồn; nếu đổi thì đổi nhất quán ở firewall, network và client:1

1
2
3
4
5
6
7
8
9
# Install packages
opkg update
opkg install wireguard-tools

# Configuration parameters
VPN_IF="vpn"
VPN_PORT="51820"
VPN_ADDR="192.168.9.1/24"
VPN_ADDR6="fd00:9::1/64"

2. Key management

Tạo private/public key của server và client cùng PSK. Các file wgserver.key, wgserver.pub, wgclient.key, wgclient.pub, wgclient.psk phải được lưu ngoài repo với permission chặt; chỉ public key mới được đưa sang peer kia.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Generate keys
umask go=
wg genkey | tee wgserver.key | wg pubkey > wgserver.pub
wg genkey | tee wgclient.key | wg pubkey > wgclient.pub
wg genpsk > wgclient.psk

# Server private key
VPN_KEY="$(cat wgserver.key)"

# Pre-shared key
VPN_PSK="$(cat wgclient.psk)"

# Client public key
VPN_PUB="$(cat wgclient.pub)"

umask go= là chuỗi lệnh được giữ nguyên từ nguồn; tôi kiểm tra shell/release thực tế trước khi chạy. Không dán giá trị private key hoặc PSK vào log, chat hay Git.

3. Firewall

Nguồn đưa interface VPN vào LAN zone để giảm số rule nội bộ, rồi mở UDP VPN_PORT từ WAN:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Configure firewall
uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.lan.network="${VPN_IF}"
uci add_list firewall.lan.network="${VPN_IF}"
uci -q delete firewall.wg
uci set firewall.wg="rule"
uci set firewall.wg.name="Allow-WireGuard"
uci set firewall.wg.src="wan"
uci set firewall.wg.dest_port="${VPN_PORT}"
uci set firewall.wg.proto="udp"
uci set firewall.wg.target="ACCEPT"
uci commit firewall
service firewall restart

Đây là lựa chọn policy, không phải mặc định an toàn cho mọi LAN. Nếu VPN client chỉ cần một VLAN/service, tôi tạo zone riêng và forward tối thiểu thay vì cho toàn bộ VPN vào LAN.

4. Network và peer

Tạo interface WireGuard với private key/listen port/addresses, sau đó thêm client peer với public key, PSK và allowed IP /32 + /128 của client:1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Configure network
uci -q delete network.${VPN_IF}
uci set network.${VPN_IF}="interface"
uci set network.${VPN_IF}.proto="wireguard"
uci set network.${VPN_IF}.private_key="${VPN_KEY}"
uci set network.${VPN_IF}.listen_port="${VPN_PORT}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR6}"

# Add VPN peers
uci -q delete network.wgclient
uci set network.wgclient="wireguard_${VPN_IF}"
uci set network.wgclient.public_key="${VPN_PUB}"
uci set network.wgclient.preshared_key="${VPN_PSK}"
uci add_list network.wgclient.allowed_ips="${VPN_ADDR%.*}.2/32"
uci add_list network.wgclient.allowed_ips="${VPN_ADDR6%:*}:2/128"
uci commit network
service network restart

Ở code trên, ${VPN_ADDR%.*}.2/32${VPN_ADDR6%:*}:2/128 là phép suy ra địa chỉ client từ biến server. Tôi xác nhận kết quả thực tế bằng uci show network trước khi restart.

Testing

Kiểm tra cả IPv4 và IPv6 bằng traceroute:

1
2
traceroute openwrt.org
traceroute6 openwrt.org

Sau khi client handshake, kiểm tra log, cổng UDP, runtime WireGuard, bảng route/rule, nftables và cấu hình lưu trong UCI:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Restart services
service log restart; service network restart; sleep 10

# Log and status
logread -e vpn; netstat -l -n -p | grep -e "^udp\s.*\s-$"

# Runtime configuration
pgrep -f -a wg; wg show; wg showconf vpn
ip address show; ip route show table all
ip rule show; ip -6 rule show; nft list ruleset

# Persistent configuration
uci show network; uci show firewall; crontab -l

Troubleshooting

Nếu không handshake, kiểm tra lần lượt public key của peer, PSK, endpoint/port-forward UDP, listen port, clock, allowed_ips và firewall. Nếu handshake có nhưng không đi LAN, kiểm tra zone/forwarding, địa chỉ 192.168.9.0/24, route IPv6 và nft list ruleset. Nếu full tunnel làm mất truy cập endpoint, phải có route ngoại lệ tới endpoint trước khi ép default route.

Kiểm tra an toàn và rollback

Chụp uci show networkuci show firewall trước thay đổi. Khi rollback, xóa đúng network.vpn, network.wgclient và rule firewall do bài tạo, commit rồi restart; không xóa nhầm zone đang phục vụ WAN/LAN. Private key bị lộ phải tạo key mới và cập nhật toàn bộ peer.

Nguồn


  1. https://openwrt.org/docs/guide-user/services/vpn/wireguard/server — OpenWrt Wiki – WireGuard server. Nội dung được biên tập độc lập từ snapshot ngày 2023-11-05; key/PSK trong bài chỉ được sinh cục bộ khi triển khai. ↩︎ ↩︎ ↩︎


0 Bình luận

Góp Ý / Bình Luận / Đánh giá