2 giờ sáng. Server VPS vừa reboot xong sau khi cập nhật kernel, và cái mạng không lên. SSH mất. Console access qua VNC provider lag khủng khiếp. NetworkManager báo lỗi device unmanaged. Đúng kiểu lỗi mà bạn không muốn gặp trên production.
Sau lần đó, mình gỡ luôn NetworkManager khỏi tất cả server headless và chuyển sang systemd-networkd. Không cần GUI, không cần daemon phình to, chỉ cần vài file text là xong.
Quick Start — Làm trong 5 phút
Nếu server đang có mạng và bạn muốn chuyển sang systemd-networkd ngay, làm theo đúng thứ tự này. Sai thứ tự là mất SSH như chơi.
Đầu tiên, xác định tên interface đang dùng:
ip link show
# Ví dụ output:
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
# 3: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
Tạo file cấu hình cho interface đó (thay eth0 bằng tên thật của bạn):
sudo nano /etc/systemd/network/20-eth0.network
Cấu hình DHCP (phổ biến nhất với VPS):
[Match]
Name=eth0
[Network]
DHCP=yes
DNS=1.1.1.1
DNS=8.8.8.8
Hoặc cấu hình IP tĩnh:
[Match]
Name=eth0
[Network]
Address=203.0.113.10/24
Gateway=203.0.113.1
DNS=1.1.1.1
DNS=8.8.8.8
Bật systemd-networkd và tắt NetworkManager — đúng thứ tự:
# Bật systemd-networkd trước
sudo systemctl enable --now systemd-networkd
# Bật systemd-resolved (DNS resolver đi kèm)
sudo systemctl enable --now systemd-resolved
# Link resolver config
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# Sau đó mới tắt NetworkManager
sudo systemctl disable --now NetworkManager
Kiểm tra ngay:
networkctl status
ping -c 3 1.1.1.1
ping -c 3 google.com
Cả hai ping thành công — xong. Chưa đầy 5 phút.
Giải thích chi tiết — Hiểu để không sợ
systemd-networkd là gì và tại sao dùng cho server?
systemd-networkd là daemon quản lý mạng tích hợp sẵn trong systemd — thứ mà hầu hết distro Linux hiện đại đều đang chạy. Không cần cài thêm gì cả.
So với NetworkManager, sự khác biệt thực chất là thế này:
- NetworkManager: Thiết kế cho desktop — auto-scan WiFi, VPN qua GUI, mobile hotspot. Tất cả thứ đó bạn không cần trên headless server, nhưng vẫn phải trả overhead cho chúng.
- systemd-networkd: File text + reload là xong. Không có GUI, không có daemon phụ trợ, khởi động nhanh hơn, dễ quản lý bằng Ansible hay script.
Trên server headless không có màn hình, không có WiFi, NetworkManager thuần túy là overhead. Mình đã đo thực tế: boot time giảm 3–4 giây sau khi chuyển sang systemd-networkd trên các VPS Debian/Ubuntu.
Cấu trúc file .network
File cấu hình nằm ở /etc/systemd/network/, đặt tên theo format XX-tên.network — con số phía trước là thứ tự ưu tiên (thấp hơn = ưu tiên hơn).
Một file .network có 3 section chính:
[Match]
# Xác định interface nào áp dụng config này
Name=eth0 # Theo tên interface
# MACAddress=aa:bb:cc:dd:ee:ff # Hoặc theo MAC address
[Network]
# Cấu hình mạng chính
DHCP=yes # Tự động lấy IP từ DHCP
# Address=x.x.x.x/24 # Hoặc IP tĩnh
# Gateway=x.x.x.x
DNS=1.1.1.1
[DHCP]
# Tùy chỉnh DHCP client
RouteMetric=10 # Metric cho route (có nhiều interface)
UseDNS=yes
Section [Match] là quan trọng nhất — nó quyết định file này áp dụng cho interface nào. Không khớp là bị bỏ qua hoàn toàn. Đây là chỗ nhiều người hay nhầm khi đặt tên interface sai.
systemd-resolved — DNS resolver đi kèm
systemd-networkd thường đi chung với systemd-resolved để xử lý DNS. Khi bạn khai báo DNS=1.1.1.1 trong file .network, systemd-resolved nhận và quản lý việc resolve tên miền.
File /etc/resolv.conf cần trỏ về stub resolver của systemd-resolved:
# Kiểm tra resolv.conf hiện tại
cat /etc/resolv.conf
# Nếu chưa link, tạo symlink
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# Xem DNS đang dùng
resolvectl status
Nâng cao — Các trường hợp thực tế
Server có 2 interface (management + data)
Tình huống phổ biến: server có eth0 cho management (SSH) và eth1 cho traffic ứng dụng.
# File cho eth0 — management
# /etc/systemd/network/10-management.network
[Match]
Name=eth0
[Network]
Address=10.0.0.5/24
Gateway=10.0.0.1
DNS=10.0.0.1
[Route]
Gateway=10.0.0.1
Metric=100
# File cho eth1 — data network
# /etc/systemd/network/20-data.network
[Match]
Name=eth1
[Network]
DHCP=yes
[DHCP]
RouteMetric=200
UseRoutes=yes
Metric thấp hơn = route được ưu tiên hơn. eth0 (metric 100) sẽ là interface chính.
Wildcard match — áp dụng cho nhiều interface cùng lúc
[Match]
Name=eth*
[Network]
DHCP=yes
Cái này hữu ích khi bạn có eth0, eth1, eth2 và muốn tất cả đều DHCP. Nhưng dùng cẩn thận — wildcard đôi khi match nhầm interface không mong muốn.
Cấu hình VLAN
# Tạo file netdev cho VLAN interface
# /etc/systemd/network/30-vlan100.netdev
[NetDev]
Name=eth0.100
Kind=vlan
[VLAN]
Id=100
# File network cho VLAN
# /etc/systemd/network/30-vlan100.network
[Match]
Name=eth0.100
[Network]
Address=192.168.100.5/24
systemd-networkd hỗ trợ VLAN, bridge, bond natively — không cần cài thêm package gì.
Tips thực tế — Rút ra từ kinh nghiệm production
Ba năm, hơn 10 VPS, vài lần mất SSH vào đúng lúc nửa đêm — mình đã học những thứ sau theo cách không vui lắm. Cấu hình mạng không được phép sai trên production, nhất là khi provider không có console access như Vultr hay Hetzner.
Tip 1: Luôn test trên server staging trước
Mình có thói quen clone cấu hình lên một VPS test rẻ tiền trước, reboot vài lần để chắc chắn network tự lên lại đúng sau mỗi lần boot.
# Test reload config mà không cần reboot
sudo networkctl reload
# Xem trạng thái từng interface
networkctl list
networkctl status eth0
Tip 2: Debug khi network không lên
# Xem log của networkd
journalctl -u systemd-networkd -n 50
# Xem log theo thời gian thực
journalctl -u systemd-networkd -f
# Kiểm tra file .network có được parse đúng không
networkctl cat eth0
Tip 3: Backup cấu hình NetworkManager trước khi xóa
# Backup cấu hình NetworkManager
sudo cp -r /etc/NetworkManager /etc/NetworkManager.bak
# Xem connection hiện tại đang dùng config gì
nmcli connection show
Tip 4: Naming convention cho file .network
Mình dùng convention: số thấp = ưu tiên cao = interface quan trọng hơn.
10-loopback.network— loopback (nếu cần cấu hình)20-management.network— interface SSH/management30-data.network— interface data90-default.network— wildcard fallback cho interface không có file riêng
Tip 5: Không cần gỡ NetworkManager nếu không chắc
Thực ra bạn chỉ cần disable NetworkManager và enable systemd-networkd là đủ. Gỡ hẳn có thể gây vấn đề nếu package khác depend vào nó. Disable an toàn hơn nhiều:
sudo systemctl disable NetworkManager
sudo systemctl stop NetworkManager
# Không cần apt remove
Tip 6: Khi dùng cloud-init trên VPS
Nhiều VPS dùng cloud-init để cấu hình network lúc khởi tạo. Vấn đề là cloud-init có thể override file .network của bạn sau mỗi lần reboot. Kiểm tra:
cat /etc/cloud/cloud.cfg | grep network
# Nếu muốn disable cloud-init quản lý network
sudo mkdir -p /etc/cloud/cloud.cfg.d/
echo 'network: {config: disabled}' | sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
Mình biết điều này sau khi setup xong, reboot, rồi ngồi debug 30 phút lúc 2 giờ sáng mới phát hiện cloud-init đã ghi đè lại toàn bộ. Khó chịu hơn lỗi ban đầu.
Tất nhiên, systemd-networkd không phải cho tất cả mọi người. Cần WiFi phức tạp? VPN nhiều profile? Desktop? NetworkManager làm tốt hơn. Nhưng server headless chạy 24/7 thì khác — file config tĩnh, ít daemon, ít thứ có thể bung vào đúng lúc bạn không muốn. Cái mình cần lúc 2 giờ sáng không phải là tool thông minh, mà là tool không làm phiền.

