Vì sao chọn Docker + wg-easy thay vì SPK kernel module
Lên Google gõ "WireGuard Synology" là ra ngay mấy cái SPK kiểu runfalk/synology-wireguard hay bên blackvoid.club. Nhìn thì ngon, cài xong tưởng xong việc — nhưng thực tế đây là con đường nhiều nước mắt nhất.
Lý do: các package này không được Synology ký. DSM 7.0 trở lên chặn thẳng tay mọi package unsigned chạy quyền root, nên muốn chạy được phải SSH vào gõ lệnh tay để start module mỗi lần. Tệ hơn, module này gắn trực tiếp vào kernel DSM (nền 4.4 cũ kỹ), nên mỗi lần Synology tung update DSM là có khả năng nó gãy. Đã có ghi nhận DSM 7.1 lên 7.2 làm hỏng module, thậm chí có báo cáo NAS bị treo cứng — không phải thứ bạn muốn dính vào một cái máy chạy 24/7 trong nhà.
Còn dùng image wg-easy gốc (ghcr.io/wg-easy/wg-easy) thì đỡ hơn về mặt UI, nhưng nó vẫn cần kernel module WireGuard có sẵn trên host để chạy — mà DSM thì không tích hợp sẵn. Vậy là vòng lại đúng vấn đề trên: vẫn phải cài SPK kernel module trước.
Giải pháp đáng dùng ở đây: fork ghcr.io/redxouls/wg-easy. Fork này dùng wireguard-go — bản WireGuard chạy hoàn toàn ở userspace, không đụng gì đến kernel NAS. Không cần SPK, không cần lo update DSM làm gãy, chạy trong Container thuần túy. Đánh đổi là hiệu năng thấp hơn một chút so với module kernel gốc, nhưng với nhu cầu dùng gia đình — remote vào NAS, xem Plex, backup dữ liệu — chênh lệch đó không đáng để bạn phải tự tay vá kernel mỗi lần Synology phát hành bản vá mới.
Còn native DSM thì Synology chỉ hỗ trợ OpenVPN, L2TP, PPTP, SSTP trong VPN Server/VPN Plus — không có WireGuard, nên phương án này loại ngay từ đầu nếu mục tiêu là WireGuard.
| Cách làm | Ổn định qua update DSM | Độ khó cài | Cần kernel module |
| ------------------------- | ---------------------- | ---------- | ---------------------- |
| SPK kernel module | Kém | Trung bình | Có |
| wg-easy gốc | Kém | Trung bình | Có |
| redxouls/wg-easy (Docker) | Tốt | Dễ | Không |
| VPN Server native | - | - | Không hỗ trợ WireGuard | Đang phân vân giữa WireGuard và Tailscale? WireGuard thuần cho tốc độ cao hơn khi truyền file lớn hoặc stream media, vì không qua server điều phối bên thứ ba — key nằm hoàn toàn trong tay bạn. Đổi lại bạn phải tự lo port forwarding, NAT, DDNS. Tailscale làm sẵn hết nhưng đổi lại bạn phải tin metadata thiết bị đi qua hạ tầng của họ. Bài này tập trung vào WireGuard tự host.
Chuẩn bị trước khi cài
Kiểm tra hai điều bắt buộc trước khi làm gì tiếp:
- NAS phải là dòng x86 (Intel/AMD). Container Manager không chạy trên các dòng ARM như DS223j, DS124, DS223. Vào Control Panel > Info Center xem CPU, hoặc tra model trên trang Synology.
- DSM từ 7.2 trở lên. Container Manager (tên mới của Docker package) yêu cầu bản này.
- RAM khuyến nghị từ 4GB trở lên để Container Manager chạy mượt, nhất là nếu NAS còn chạy song song Plex, Photos hay các package khác.
Nếu NAS bạn thuộc dòng ARM, bài này không áp dụng được — cân nhắc Tailscale hoặc đổi hướng khác.
Vào Package Center, tìm và cài Container Manager.
Bước 1: Bật Synology DDNS
IP public nhà bạn (trừ khi trả tiền IP tĩnh) đổi liên tục theo chu kỳ ISP cấp lại. Hardcode IP vào cấu hình VPN thì y như xây nhà trên cát — một ngày đẹp trời ISP đổi IP là VPN "biến mất" mà bạn chẳng hiểu vì sao.
Vào Control Panel > External Access > DDNS, thêm dịch vụ Synology DDNS, đặt hostname dạng tenban.synology.me. Tiện thể tick luôn phần tạo cert Let's Encrypt cho hostname này — dùng được cho cả các dịch vụ khác chạy trên NAS.
Hostname này sẽ là giá trị bạn điền vào WG_HOST ở bước sau. Không điền IP LAN nội bộ (kiểu 192.168.1.x) vào đây — lỗi này rất phổ biến, cấu hình xong dùng được trong nhà nhưng ra khỏi nhà là VPN không kết nối được gì cả, vì client ở ngoài đơn giản là không biết đường nào tìm 192.168.1.x của bạn.
Bước 2: Kiểm tra NAT — đừng bỏ qua bước này
Trước khi mất công cấu hình, kiểm tra xem mạng nhà bạn có đang dính CGNAT hoặc double NAT không. Cách nhanh nhất: vào trang quản trị router, xem IP WAN hiển thị ở đó, rồi so với IP public mà trang portchecker.co báo về máy bạn.
Nếu hai IP này khác nhau, tức là ISP đang đặt bạn sau một lớp NAT khác (CGNAT) — port forward trên router của bạn lúc này vô nghĩa, vì traffic từ Internet không bao giờ chạm được tới router nhà bạn. Trường hợp này chỉ còn ba đường: gọi ISP xin IP tĩnh/public thật (chuẩn bị tinh thần nghe nhạc chờ tổng đài), dùng VPS relay, hoặc quay sang Tailscale — vốn NAT traversal qua relay của họ nên không cần port forward.
Nếu hai IP trùng khớp, bạn ổn, đi tiếp bước sau.
Bước 3: Tạo Project trong Container Manager
Trước tiên tạo thư mục lưu dữ liệu cấu hình, qua File Station hoặc SSH:
mkdir -p /volume1/docker/wg-easyThư mục này sẽ chứa toàn bộ private key của server và client — nhớ chỗ này, phần bảo mật/backup ở cuối bài sẽ nhắc lại.
Trước khi viết compose, tạo password hash cho Web UI. wg-easy hỗ trợ PASSWORD_HASH dạng bcrypt, an toàn hơn hẳn để plaintext. Chạy lệnh này qua SSH (thay matkhaucuaBan bằng mật khẩu thật):
docker run --rm ghcr.io/redxouls/wg-easy wgpw 'matkhaucuaBan'Lệnh trả về một chuỗi dạng PASSWORD_HASH=$2a$12$.... — copy lại để dùng ở bước sau.
Vào Container Manager > Project > Create, chọn thư mục /volume1/docker/wg-easy, dán compose sau vào ô cấu hình:
services:Chú ý cái dấu
wg-easy:
image: ghcr.io/redxouls/wg-easy
container_name: wg-easy
environment:
- WG_HOST=tenban.synology.me
- PASSWORD_HASH=$$2a$$12$$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- PORT=51821
- WG_PORT=51820
- WG_DEFAULT_ADDRESS=10.8.0.x
- WG_DEFAULT_DNS=1.1.1.1
- LANG=vi
volumes:
- /volume1/docker/wg-easy:/etc/wireguard
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped$$ ở PASSWORD_HASH. Bcrypt hash luôn có ký tự $ ở đầu, mà docker-compose lại coi $ là ký tự đặc biệt để nội suy biến. Không escape thành $$ là container lăn ra lỗi ngay khi start, log báo linh tinh không rõ nguyên nhân. Lỗi vặt nhưng khó chịu bậc nhất trong cả bài — dính một lần là nhớ đời.
Bấm Next > Done để Container Manager pull image và deploy. Xong việc thì vào tab Log của container kiểm tra ngay — hai lỗi hay gặp nhất lúc này là thiếu WG_HOST hoặc thiếu PASSWORD/PASSWORD_HASH, container sẽ báo rõ trong log, không phải đoán mò.
Bước 4: Forward port 51820/UDP trên router
Vào trang quản trị router, tìm mục Port Forwarding, tạo rule chuyển tiếp UDP port 51820 về đúng IP LAN của NAS. WireGuard chỉ chạy trên UDP, không phải TCP, nên đừng forward nhầm loại.
Nếu Synology Firewall trên DSM đang bật (Control Panel > Security > Firewall), nhớ thêm rule cho phép 51820/UDP đi vào. Bước này cực dễ quên — forward xong ở router, đinh ninh là xong, nhưng NAS tự chặn ở tầng firewall của chính nó thì traffic vẫn không lọt vào được container.
Bước 5: Tạo client và kết nối
Mở trình duyệt, truy cập http://ip-nas-cua-ban:51821, đăng nhập bằng mật khẩu vừa tạo hash ở bước 3.
Bấm New Client, đặt tên theo thiết bị (điện thoại, laptop công ty, laptop cá nhân...). Mỗi thiết bị nên có key riêng, đừng dùng chung một file config cho nhiều máy — wg-easy tự sinh key mới cho mỗi client nên việc này gần như không tốn công thêm.
Điểm quan trọng nhất ở bước này: kiểm tra AllowedIPs của client. Mặc định wg-easy thường chỉ định subnet VPN (dạng 10.8.0.0/24). Muốn từ ngoài truy cập luôn các thiết bị khác trong nhà (NAS thứ hai, camera, máy tính khác), phải thêm cả subnet LAN thật của bạn, ví dụ 192.168.1.0/24, vào AllowedIPs. Thiếu bước này là nguyên nhân số một khiến người mới thấy "kết nối VPN được, ping NAS được, nhưng không thấy máy tính khác trong nhà đâu cả".
Cài app client chính thức WireGuard (của WireGuard Development Team) trên App Store/Google Play cho điện thoại. Mở app, chọn thêm tunnel bằng cách quét QR code hiển thị ngay trên Web UI — nhanh, không cần gõ tay.
Với Windows/macOS, tải WireGuard client từ wireguard.com, import trực tiếp file .conf tải về từ Web UI.
Một chi tiết nhỏ nhưng ảnh hưởng lớn tới trải nghiệm trên di động: đảm bảo config có dòng PersistentKeepalive = 25. Thiếu dòng này, tunnel hay tự rớt khi điện thoại chuyển từ WiFi sang 4G hoặc ngược lại, do NAT ở giữa timeout kết nối. wg-easy thường đã set sẵn giá trị này, nhưng nếu tự tay chỉnh file config thì nhớ kiểm tra lại.
Kiểm tra kết nối từ mạng ngoài
Tắt WiFi, chuyển điện thoại sang 4G, bật tunnel WireGuard vừa tạo. Thử ping IP NAS qua địa chỉ VPN, hoặc mở trình duyệt truy cập một thiết bị khác trong LAN nhà để xác nhận route hoạt động đúng.
Muốn chắc chắn hơn, SSH vào NAS và chạy:
sudo wgNhìn dòng latest handshake — có timestamp gần đây nghĩa là kết nối thật sự đang chạy hai chiều. Không có dòng này tức là chưa handshake được, quay lại kiểm tra port forward và firewall.
Lỗi hay gặp và cách xử lý
- Không handshake, "sudo wg" không thấy latest handshake: thường do quên forward UDP 51820 ở router, hoặc ISP đang CGNAT/double NAT — quay lại kiểm tra bước 2.
- VPN chỉ dùng được ở nhà, ra ngoài không kết nối:
WG_HOSTđang trỏ về IP LAN thay vì hostname DDNS/IP public. - Vào được NAS nhưng không thấy thiết bị khác trong nhà: AllowedIPs của client chỉ có subnet VPN, thiếu subnet LAN thật.
- Tunnel tự rớt khi đổi mạng trên điện thoại: thiếu
PersistentKeepalive = 25trong config client. - Container lỗi ngay khi start, log không rõ nghĩa: kiểm tra
PASSWORD_HASHcó escape$thành$$chưa trong file compose. - Traffic bị chặn dù đã forward port ở router: Synology Firewall đang bật mà chưa mở exception cho 51820/UDP.
Bảo mật và bảo trì
Đổi mật khẩu Web UI mặc định ngay sau khi cài, và luôn dùng PASSWORD_HASH bcrypt thay vì để plaintext trong compose file — file compose đôi khi bị vô tình chia sẻ hay commit lên đâu đó, để plaintext là toang.
Đừng lắp thêm SPK kernel module không rõ nguồn hay không được ký chạy root trên DSM nếu không thật sự cần. Cách chạy container userspace như bài này vốn đã giảm hẳn bề mặt tấn công lên kernel NAS, không việc gì phải tự rước thêm rủi ro vào.
AllowedIPs nên giới hạn theo đúng nhu cầu — không nhất thiết để 0.0.0.0/0 nếu bạn không có ý định route toàn bộ traffic internet của thiết bị di động qua NAS nhà mình (kiểu dùng NAS làm proxy khi ra quán cà phê).
Backup thư mục /volume1/docker/wg-easy định kỳ — trong đó chứa toàn bộ private key server lẫn client. Mất thư mục này đồng nghĩa phải tạo lại từ đầu, mọi thiết bị đã kết nối đều phải cấu hình lại. Ổ cứng thì sớm muộn gì cũng hỏng, chuyện chỉ là nó chọn đúng lúc bạn chưa kịp backup hay không thôi.
Thỉnh thoảng mở lại tab Log trong Container Manager liếc qua xem có handshake hay kết nối lạ nào không. VPN mở cửa ra internet, an toàn không phải chuyện cài một lần rồi quên.



No comments yet