Secure Ubuntu bằng WireGuard: Chặn SSH ngoài mạng riêng

15/05/2026 · P T P · Chung

Secure Ubuntu server bằng VPN WireGuard: giới hạn SSH chỉ qua mạng riêng

SSH mở ra Internet → tiện nhưng rủi ro. Bot quét port 22 liên tục, brute-force, dò user, thử key yếu, khai thác CVE mới. Dù bạn dùng key auth, tắt password, đổi port SSH, bật Fail2ban… bề mặt tấn công vẫn còn.

Giải pháp mạnh hơn: không public SSH. Chỉ cho SSH chạy qua mạng riêng WireGuard VPN. Internet không thấy SSH. Muốn quản trị server → phải kết nối VPN trước.

Mô hình:

– Server Ubuntu public IP.
– WireGuard tạo interface riêng: wg0.
– Server VPN IP: 10.8.0.1.
– Laptop/admin VPN IP: 10.8.0.2.
– SSH chỉ listen trên 10.8.0.1 hoặc firewall chỉ cho SSH từ 10.8.0.0/24.
– Port WireGuard UDP 51820 mở ra Internet.
– Port SSH 22 đóng với Internet.

Kết quả: attacker scan public IP → không thấy SSH. Admin có VPN key → vào được.


Vì sao nên đặt SSH sau WireGuard?

Giảm bề mặt tấn công

SSH public → ai cũng thử kết nối được. Dù không login được, daemon vẫn nhận traffic.

SSH qua WireGuard → chỉ peer có private key hợp lệ mới vào mạng VPN. Không có key → packet bị bỏ.

Public SSH → bị quét. SSH private → gần như “biến mất”.

Bảo mật nhiều lớp

Bạn có 2 lớp:

1. WireGuard key để vào mạng riêng.
2. SSH key để đăng nhập server.

Mất 1 key chưa đủ. Attacker cần cả VPN private key + SSH private key + user hợp lệ.

Quản trị sạch hơn

Có nhiều server? Gán mỗi server 1 IP VPN:

10.8.0.1 → bastion/server chính
10.8.0.10 → app server
10.8.0.20 → DB server

Sau đó SSH nội bộ:

ssh [email protected]

Không cần expose SSH từng máy.


Chuẩn bị

Ví dụ dùng Ubuntu 22.04/24.04.

Cần:

– 1 Ubuntu server có public IP.
– Quyền root hoặc user sudo.
– 1 client: laptop Linux/macOS/Windows.
– Đã có SSH hiện tại để cấu hình ban đầu.

Cảnh báo: Đừng khóa SSH public trước khi xác nhận WireGuard hoạt động. Luôn giữ 1 session SSH hiện tại mở trong lúc test.


Cài WireGuard trên Ubuntu server

Cập nhật pkg:

sudo apt update
sudo apt install -y wireguard

Tạo key:

wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key

Xem key:

sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key

Tạo config server:

sudo nano /etc/wireguard/wg0.conf

Nội dung mẫu:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
SaveConfig = false

[Peer] PublicKey = CLIENT_PUBLIC_KEY AllowedIPs = 10.8.0.2/32

Thay:

SERVER_PRIVATE_KEY → nội dung /etc/wireguard/server_private.key
CLIENT_PUBLIC_KEY → tạo ở client, bước sau.


Tạo key client

Trên Linux/macOS client:

wg genkey | tee client_private.key | wg pubkey > client_public.key
cat client_private.key
cat client_public.key

Trên Windows: dùng app WireGuard → Add Tunnel → Empty tunnel → app tự tạo key.

Config client:

[Interface]
Address = 10.8.0.2/32
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1

[Peer] PublicKey = SERVER_PUBLIC_KEY Endpoint = SERVER_PUBLIC_IP:51820 AllowedIPs = 10.8.0.0/24 PersistentKeepalive = 25

Giải thích nhanh:

Address → IP VPN client.
Endpoint → public IP server + port WireGuard.
AllowedIPs = 10.8.0.0/24 → chỉ route mạng VPN qua tunnel, không route toàn bộ Internet.
PersistentKeepalive = 25 → hữu ích nếu client sau NAT.


Bật WireGuard server

Trên server:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo systemctl status wg-quick@wg0

Kiểm tra:

sudo wg
ip addr show wg0

Mở UDP port 51820 trên firewall/cloud firewall.

Nếu dùng UFW:

sudo ufw allow 51820/udp

Nếu cloud provider có security group/firewall riêng, mở thêm UDP 51820.


Test kết nối VPN

Bật tunnel client. Từ client:

ping 10.8.0.1

Nếu ping OK, thử SSH qua VPN:

ssh [email protected]

Nếu login OK → WireGuard + SSH hoạt động.

Nếu không ping được:

– Kiểm tra sudo wg trên server có handshake chưa.
– Kiểm tra public IP/port đúng chưa.
– Kiểm tra UDP 51820 được mở chưa.
– Kiểm tra key peer đúng chưa.
– Kiểm tra AllowedIPs không trùng sai.


Cách 1: Giới hạn SSH bằng firewall UFW

Đây là cách dễ, ít rủi ro. SSH vẫn listen mọi interface, nhưng firewall chỉ cho VPN subnet vào.

Cho phép SSH từ VPN:

sudo ufw allow from 10.8.0.0/24 to any port 22 proto tcp

Từ chối SSH public:

sudo ufw deny 22/tcp

Bảo đảm WireGuard vẫn mở:

sudo ufw allow 51820/udp

Bật UFW nếu chưa bật:

sudo ufw enable
sudo ufw status verbose

Thứ tự rule UFW có thể ảnh hưởng. Kiểm tra:

sudo ufw status numbered

Bạn muốn thấy logic:

– Allow 51820/udp từ anywhere.
– Allow 22/tcp từ 10.8.0.0/24.
– Deny 22/tcp từ anywhere.

Test từ client VPN:

ssh [email protected]

Test từ ngoài VPN:

ssh user@SERVER_PUBLIC_IP

Kỳ vọng: qua VPN OK, public IP bị timeout/refused.


Cách 2: Cho SSH chỉ listen trên IP WireGuard

Cách này gọn hơn: SSH daemon chỉ bind vào 10.8.0.1, không bind public IP.

Mở file:

sudo nano /etc/ssh/sshd_config

Thêm/sửa:

ListenAddress 10.8.0.1

Kiểm tra config:

sudo sshd -t

Restart SSH:

sudo systemctl restart ssh

Kiểm tra socket:

ss -tlnp | grep ssh

Kỳ vọng:

LISTEN 0 128 10.8.0.1:22 ...

Không nên thấy:

0.0.0.0:22

Lưu ý quan trọng: Nếu SSH khởi động trước WireGuard, IP 10.8.0.1 chưa tồn tại → SSH có thể fail bind. Khắc phục bằng systemd dependency hoặc dùng firewall thay vì bind IP. Với hầu hết case, UFW allow/deny đơn giản hơn, an toàn hơn.


Hardening SSH bổ sung

Dù SSH đã nằm sau VPN, vẫn nên harden.

Mở:

sudo nano /etc/ssh/sshd_config

Khuyến nghị:

PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
X11Forwarding no
AllowUsers youruser

Test config:

sudo sshd -t
sudo systemctl reload ssh

Ý nghĩa:

PasswordAuthentication no → chặn brute-force password.
PermitRootLogin no → tránh login root trực tiếp.
AllowUsers → chỉ user cụ thể được SSH.
reload thay vì restart → ít gián đoạn hơn.


Quản lý nhiều admin

Mỗi admin nên có peer riêng. Không dùng chung key.

Ví dụ thêm admin 2:

[Peer]
PublicKey = ADMIN2_PUBLIC_KEY
AllowedIPs = 10.8.0.3/32

Restart:

sudo systemctl restart wg-quick@wg0

Ưu điểm:

– Thu hồi 1 người → xóa peer tương ứng.
– Audit dễ hơn.
– Không phải rotate toàn bộ VPN.

Thu hồi admin:

1. Xóa block [Peer].
2. Restart WireGuard.
3. Xóa SSH public key của admin khỏi ~/.ssh/authorized_keys nếu cần.


Logging và kiểm tra định kỳ

Kiểm tra WireGuard:

sudo wg show

Xem peer, latest handshake, transfer.

Kiểm tra SSH login:

sudo journalctl -u ssh --since "1 day ago"

Kiểm tra auth log:

sudo grep sshd /var/log/auth.log

Kiểm tra port public từ máy ngoài:

nmap -Pn -p 22,51820 SERVER_PUBLIC_IP

Kỳ vọng:

22/tcp → filtered/closed.
51820/udp → open|filtered là bình thường với UDP.


Lỗi thường gặp

Có handshake nhưng không SSH được

Nguyên nhân hay gặp:

– SSH không listen trên 10.8.0.1.
– UFW chặn subnet VPN.
– Client route sai.
– User/key SSH sai.

Debug:

ping 10.8.0.1
nc -vz 10.8.0.1 22
sudo ufw status verbose
ss -tlnp | grep ssh

Không có handshake

Kiểm tra:

Endpoint đúng public IP?
– UDP 51820 mở ở UFW + cloud firewall?
– Server ListenPort đúng?
– Key public/private khớp?
– Client bật tunnel chưa?

Lệnh:

sudo wg
sudo journalctl -u wg-quick@wg0

Tự khóa khỏi server

Nếu lỡ chặn SSH public trước khi VPN hoạt động:

– Dùng cloud console/VNC/serial console.
– Sửa UFW/sshd_config.
– Mở lại SSH tạm:

sudo ufw allow 22/tcp
sudo systemctl restart ssh

Kết luận thực tế

SSH public không còn là mặc định tốt cho server quan trọng. Cấu hình an toàn hơn: WireGuard public, SSH private.

Checklist cuối:

– WireGuard chạy trên wg0.
– Client ping được 10.8.0.1.
– SSH qua 10.8.0.1 OK.
– UFW chỉ allow SSH từ 10.8.0.0/24.
– Public port 22 bị chặn.
– SSH tắt password, tắt root login.
– Mỗi admin có VPN peer riêng.

Mô hình này đơn giản, rẻ, nhanh, hiệu quả. Một port UDP WireGuard thay cho SSH public → bề mặt tấn công giảm mạnh. Với vài dòng config, Ubuntu server kín hơn rất nhiều nhưng vẫn dễ quản trị hằng ngày.

#bang #chan #secure #ubuntu #wireguard
Chia sẻ:
← Trước
Tạo User Sudo An Toàn Và Mật Khẩu Mạnh Trên Ubuntu Server

Bài viết tương tự

Bình luận

Chưa có bình luận. Hãy là người đầu tiên!