Tự dựng máy chủ WireGuard trên VPS Ubuntu, từng bước

Cài WireGuard trên VPS Ubuntu: tạo khoá, wg0.conf, NAT, tường lửa, file cấu hình cho điện thoại và mã QR, rồi nhập vào Tunnel Link của GreenTunnel.

Thuê một VPS rồi tự chạy WireGuard là cách trực tiếp nhất để có một đường hầm do chính bạn kiểm soát. Bạn chọn quốc gia, bạn giữ khoá, và nhật ký chỉ có những gì bạn tự giữ lại. Bài này hướng dẫn dựng gọn gàng trên Ubuntu 22.04 hoặc 24.04, rồi kết nối điện thoại qua Tunnel Link, WireGuard client có sẵn trong GreenTunnel.

Mọi địa chỉ trong bài đều là địa chỉ dùng cho tài liệu. 203.0.113.10 thay cho IP công khai của VPS, còn 10.8.0.0/24 là mạng riêng bên trong tunnel. Hãy thay bằng giá trị của bạn.

Bạn sẽ dựng được gì

Sơ đồ: điện thoại chạy GreenTunnel với Tunnel Link, gửi UDP đã mã hoá tới cổng 51820 của VPS Ubuntu. VPS có wg0 địa chỉ 10.8.0.1, bật chuyển tiếp IP và NAT, tường lửa chỉ mở SSH và UDP 51820. Trang web thấy địa chỉ của VPS.
Một VPS, một cổng UDP, và khoá chỉ nằm trên hai thiết bị của bạn.

Điện thoại nhận địa chỉ trong tunnel là 10.8.0.2. Máy chủ là 10.8.0.1 trên giao diện mạng tên wg0. Lưu lượng mà GreenTunnel đưa vào tunnel sẽ tới máy chủ, rồi máy chủ chuyển tiếp ra Internet bằng địa chỉ công khai của nó. Khi đó trang web thấy 203.0.113.10 thay vì IP nhà mạng của bạn.

Chuẩn bị

  • Một VPS chạy Ubuntu có địa chỉ IPv4 công khai. Gói nhỏ nhất của phần lớn nhà cung cấp là đủ cho một người.
  • Quyền SSH với một tài khoản dùng được sudo.
  • Chọn nhà cung cấp và quốc gia một cách hợp pháp. Đọc điều khoản của nhà cung cấp, và kiểm tra rằng việc chạy VPN cá nhân được phép cả ở nơi đặt máy chủ lẫn nơi bạn sống.

Bước 1: cài WireGuard

WireGuard đã nằm trong nhân Linux từ lâu, nên bạn chỉ cần bộ công cụ dòng lệnh. qrencode dùng để tạo mã QR ở cuối bài.

sudo apt update
sudo apt install wireguard-tools qrencode

Bước 2: tạo khoá

Mỗi thiết bị có một cặp khoá riêng. Tạo một cặp cho máy chủ và một cặp cho điện thoại, thêm một khoá chia sẻ trước (preshared key). Khoá này là tuỳ chọn, nó thêm một lớp mã hoá đối xứng thứ hai cho riêng điện thoại này.

sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee phone.key | wg pubkey > phone.pub
wg genpsk > phone.psk

umask 077 khiến các file mới chỉ root đọc được. Các file .key là khoá riêng. Đừng bao giờ chép chúng tới nơi không cần thiết.

Bước 3: viết wg0.conf

Trước hết, tìm tên giao diện mạng công khai của máy chủ. Thường là eth0 hoặc ens3.

ip route show default
# default via 203.0.113.1 dev eth0 ...

Giờ viết file cấu hình máy chủ. Đoạn heredoc dưới đây tự điền khoá từ các file vừa tạo. Nếu giao diện của bạn không phải eth0, hãy sửa ở cả hai dòng NAT.

cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $(cat server.key)
PostUp = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

[Peer]
# phone
PublicKey = $(cat phone.pub)
PresharedKey = $(cat phone.psk)
AllowedIPs = 10.8.0.2/32
EOF

Dòng AllowedIPs = 10.8.0.2/32 ở phía máy chủ có nghĩa là “peer này chỉ được dùng địa chỉ 10.8.0.2”. Mỗi thiết bị mới nhận địa chỉ tiếp theo, ví dụ 10.8.0.3.

Thích nftables hơn?

Trên Ubuntu hiện nay, lệnh iptables thực chất đã chạy trên nftables. Nếu muốn viết luật nftables gốc, hãy thay hai dòng NAT bằng các dòng sau:

PostUp = nft add table ip wgnat
PostUp = nft 'add chain ip wgnat post { type nat hook postrouting priority srcnat ; }'
PostUp = nft add rule ip wgnat post ip saddr 10.8.0.0/24 oifname "eth0" masquerade
PostDown = nft delete table ip wgnat

Bước 4: chuyển tiếp IP và tường lửa

Mặc định Linux không chuyển gói tin giữa các giao diện mạng. Bật tính năng này vĩnh viễn:

echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-wireguard.conf
sysctl --system

Sau đó chỉ mở những gì cần. Với ufw, hãy cho phép SSH trước để không tự khoá mình bên ngoài, rồi tới cổng WireGuard, rồi cho phép chuyển tiếp từ tunnel ra Internet:

ufw allow OpenSSH
ufw allow 51820/udp
ufw route allow in on wg0 out on eth0
ufw enable

Nhiều nhà cung cấp còn có tường lửa riêng trong trang quản trị, thường gọi là security group. Hãy mở UDP 51820 ở đó nữa, nếu không gói bắt tay sẽ không bao giờ tới được máy chủ.

Bước 5: khởi động máy chủ

systemctl enable --now wg-quick@wg0
wg show

wg show liệt kê giao diện wg0 và điện thoại là một peer. Lúc này chưa có dòng “latest handshake”, vì điện thoại chưa kết nối.

Bước 6: tạo cấu hình cho điện thoại

cat > /etc/wireguard/phone.conf <<EOF
[Interface]
PrivateKey = $(cat phone.key)
Address = 10.8.0.2/32
MTU = 1280

[Peer]
PublicKey = $(cat server.pub)
PresharedKey = $(cat phone.psk)
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF

Điền IP thật hoặc tên miền của VPS vào Endpoint. File hoàn chỉnh trông như sau, với khoá thật ở chỗ chữ in hoa:

[Interface]
PrivateKey = PHONE_PRIVATE_KEY
Address = 10.8.0.2/32
MTU = 1280

[Peer]
PublicKey = SERVER_PUBLIC_KEY
PresharedKey = PHONE_PRESHARED_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Vài lưu ý riêng cho GreenTunnel. MTU = 1280 trùng với mặc định của GreenTunnel và chạy được trên hầu hết các mạng. PersistentKeepalive giúp NAT của mạng di động không cắt tunnel khi đang rảnh. GreenTunnel tự quyết định lưu lượng nào vào tunnel bằng tuyến và quy tắc của nó, nên AllowedIPs và dòng DNS = (nếu có) không được dùng. Bạn vẫn có thể giữ chúng nếu dùng file này cho ứng dụng WireGuard khác.

Bước 7: đưa cấu hình lên điện thoại

Nhanh nhất là in mã QR ngay trong terminal. Phóng to cửa sổ terminal để mã hiện trọn vẹn.

qrencode -t ansiutf8 -r /etc/wireguard/phone.conf

Hoặc lưu thành ảnh PNG, hoặc chép chính file .conf về máy tính qua SSH:

qrencode -o /root/phone.png -r /etc/wireguard/phone.conf
# trên máy tính của bạn:
scp root@203.0.113.10:/etc/wireguard/phone.conf .

Sau đó trong GreenTunnel:

  1. Mở thẻ Nâng cao dưới nút nguồn, chạm Cấu hình.
  2. Ở mục Tunnel Link, chạm Thêm WireGuard.
  3. Chọn Quét mã QR, Chọn file hoặc Dán link hoặc cấu hình.
  4. Xem lại trình chỉnh sửa đã điền sẵn, đặt tên cho profile, ví dụ “VPS của tôi”, rồi lưu.
Bảng Nhập cấu hình với ba lựa chọn: dán link hoặc cấu hình, quét mã QR, chọn file
Quét mã QR trên terminal, hoặc chọn file.
Trình chỉnh sửa WireGuard sau khi nhập, với tên, địa chỉ, endpoint, khoá máy chủ rút gọn, MTU và keepalive. Khoá riêng được ẩn.
Sau khi nhập, khoá riêng không bao giờ hiện lại.

Khi điện thoại đã có cấu hình, hãy xoá các bản sao khoá riêng của điện thoại trên máy chủ. Máy chủ chỉ cần khoá công khai của điện thoại, và khoá đó đã nằm trong wg0.conf.

rm -f /etc/wireguard/phone.key /etc/wireguard/phone.conf /root/phone.png

Các định dạng được hỗ trợ có trong bài nhập profile từ link, mã QR và file.

Bước 8: kiểm tra

  1. Chạm Kiểm tra cạnh profile mới. GreenTunnel thực hiện một lần bắt tay WireGuard và hiện thời gian khứ hồi tính bằng mili giây.
  2. Chọn profile trong thẻ Nâng cao để mọi lưu lượng đi qua nó. Hoặc giữ Đi thẳng và thêm quy tắc cho riêng những trang, những ứng dụng cần dùng.
  3. Trên máy chủ, chạy lại wg show. Bạn sẽ thấy dòng “latest handshake” vừa cập nhật và bộ đếm dữ liệu tăng dần.
  4. Mở một trang kiểu “IP của tôi là gì” trên điện thoại. Trang đó phải hiện địa chỉ VPS của bạn.

Nếu kiểm tra bị quá thời gian

  • Cổng chưa mở: kiểm tra cả ufw status lẫn tường lửa của nhà cung cấp cho UDP 51820.
  • Sai khoá: WireGuard không bao giờ trả lời gói bắt tay dùng sai khoá, nên sai khoá trông y hệt quá thời gian. So khoá PublicKey của máy chủ trong cấu hình điện thoại với file server.pub.
  • Dịch vụ không chạy: systemctl status wg-quick@wg0 sẽ cho biết lý do.
  • Bắt tay được nhưng không vào được web: thường do chuyển tiếp hoặc NAT. Kiểm tra sysctl net.ipv4.ip_forward và tên giao diện trong các dòng NAT.
  • Một số mạng chặn UDP hoặc chặn chính WireGuard. Khi đó, hãy thử dựng thêm máy chủ Shadowsocks trên cùng VPS.

Nếu máy chủ ngừng hoạt động khi đang dùng, các kết nối được định tuyến vào tunnel sẽ thất bại chứ không lọt ra ngoài đi thẳng. Xem bài không rò rỉ khi proxy hoặc tunnel lỗi.

Bài này chỉ dựng IPv4. Các kết nối IPv6 mà GreenTunnel định gửi vào tunnel sẽ bị từ chối, và ứng dụng tự quay về IPv4. Muốn chở cả IPv6, hãy thêm một dải IPv6 riêng vào cả hai dòng Address. Xem thêm bài IPv6 và VPN.

Giữ máy chủ an toàn

  • Tự động cập nhật bảo mật: apt install unattended-upgrades, rồi dpkg-reconfigure -plow unattended-upgrades.
  • SSH chỉ dùng khoá: khi khoá SSH của bạn đã đăng nhập được, đặt PasswordAuthentication no trong cấu hình SSH rồi khởi động lại SSH.
  • Tường lửa tối giản: chỉ mở SSH và UDP 51820. Đừng chạy thêm dịch vụ khác trên cùng máy nếu không thật sự cần.
  • Mỗi thiết bị một cặp khoá: điện thoại, laptop, máy tính bảng đều có khoá và địa chỉ riêng. Khi mất một thiết bị, chỉ cần xoá khối [Peer] của nó và khởi động lại wg-quick@wg0. Các thiết bị khác không bị ảnh hưởng.
  • Thỉnh thoảng thay khoá: tạo cặp khoá mới cho thiết bị, thay khối [Peer] của nó, rồi nhập cấu hình mới. Trong GreenTunnel, nhập cấu hình mới cũng chính là cách đổi khoá.
  • Giữ cấu hình như giữ mật khẩu: một file .conf hay mã QR của nó là chìa khoá đầy đủ vào máy chủ của bạn. Đừng gửi qua ứng dụng chat, và đừng để ảnh chụp mã QR nằm trong thư viện ảnh.

Muốn hiểu cách này khác gì một dịch vụ VPN thương mại? Đọc bài VPN cục bộ và VPN từ xa, hoặc ghé trang chủ.

Câu hỏi thường gặp

Có dùng chung cấu hình này cho laptop được không?

Về kỹ thuật thì được, nhưng đừng làm vậy. Hai thiết bị dùng cùng một khoá sẽ liên tục đẩy nhau ra khỏi máy chủ. Hãy cho mỗi thiết bị một cặp khoá và một địa chỉ riêng. Như vậy bạn còn thu hồi được từng thiết bị mà không đụng tới các thiết bị khác.

GreenTunnel có thấy máy chủ hay khoá của tôi không?

Không. Cấu hình được đọc ngay trên thiết bị, và khoá riêng được cất vào kho bảo mật của hệ điều hành. GreenTunnel không vận hành máy chủ nào và không bao giờ thu thập lưu lượng, tên miền hay nội dung duyệt web của bạn.

Nên dùng cổng nào?

51820 là cổng quen thuộc của WireGuard và dùng tốt. Bạn có thể chọn cổng UDP khác, chỉ cần sửa ở ListenPort, luật tường lửa và Endpoint trong cấu hình điện thoại.

Tunnel có chở được game và cuộc gọi không?

Có. WireGuard hoạt động ở mức gói tin IP, nên cả TCP lẫn UDP đều đi qua, kể cả QUIC. Truy vấn DNS vẫn dùng DNS mã hoá của GreenTunnel.

← Tất cả bài viết