Bối cảnh & Lý do
Vào lúc 2:15 sáng thứ Ba, máy chủ syslog của tôi bất ngờ ghi nhận hơn 14.000 cảnh báo chỉ trong chưa đầy hai phút. Một chiếc Android TV Box trôi nổi không rõ thương hiệu đã bị nhiễm một biến thể của Mirai. Ngay lập tức, nó làm tràn ngập dải mạng phẳng 192.168.1.0/24 bằng hàng loạt SYN scan, đồng thời dồn dập tấn công giao diện web Proxmox tại 192.168.1.2:8006 với tần suất 450 lần xác thực mỗi giây. Việc một thiết bị phát media giá 30 USD không đáng tin cậy ngang nhiên dò quét mặt phẳng điều khiển (control plane) của hypervisor quả thực là một hồi chuông cảnh tỉnh tức thì.
Mạng phẳng (flat subnet) tiềm ẩn rủi ro rất lớn. Khi hệ thống lưu trữ, máy trạm làm việc và các ổ cắm thông minh dùng chung một broadcast domain Layer 2, chỉ cần một thiết bị bị xâm nhập là toàn bộ hệ thống của bạn sẽ gặp nguy hiểm. Đưa OPNsense vào vận hành bên trong Proxmox VE giúp cô lập các phân vùng mạng này mà không cần sắm thêm 5 thiết bị phần cứng chuyên dụng. Bạn còn có thể tận dụng khả năng snapshot và rollback tức thì của ZFS trước khi nâng cấp kernel, tối ưu hóa điện năng tiêu thụ, cũng như linh hoạt chuyển mạch phần mềm giữa các cổng ảo và cổng vật lý.
Passthrough trực tiếp card mạng PCIe vào máy ảo (VM) sẽ làm mất đi tính linh hoạt vốn có ở tầng hypervisor. Thay vào đó, chúng ta sẽ sử dụng Linux bridge hỗ trợ nhận biết VLAN (VLAN-aware) trên Proxmox. Chỉ với một card mạng 2 cổng 2.5GbE hoặc 10GbE duy nhất, bạn đã có thể truyền tải toàn bộ lưu lượng được gắn tag cho WAN, quản trị hypervisor, các thiết bị tin cậy và khu vực cách ly (quarantine). OPNsense sẽ đảm nhận vai trò định tuyến inter-VLAN, còn Zenarmor sẽ kiểm tra payload của gói tin ở Layer 7 theo thời gian thực.
Cài đặt
Trước tiên, hãy cấu hình tầng mạng của Proxmox để chuyển tiếp trực tiếp các khung dữ liệu gắn tag 802.1Q vào card mạng ảo (virtual NIC) của máy khách. Kết nối SSH vào node Proxmox và kiểm tra file /etc/network/interfaces.
1. Chuẩn bị VLAN-Aware Bridge trên Proxmox
Định nghĩa hai bridge logic: một bridge riêng biệt dành cho việc kết nối với gateway của ISP, và một trunk bridge xử lý toàn bộ lưu lượng nội bộ:
# Đoạn cấu hình mẫu /etc/network/interfaces
auto lo
iface lo inet loopback
iface eno1 inet manual
# NIC vật lý chuyên dụng để kết nối với modem WAN của ISP
iface eno2 inet manual
# Đường trunk vật lý nối tới switch L2+ được quản lý (ví dụ: UniFi Pro, TP-Link Omada)
auto vmbr0
iface vmbr0 inet manual
bridge-ports eno1
bridge-stp off
bridge-fd 0
# WAN Bridge (Bridge Layer 2 trực tiếp tới modem)
auto vmbr1
iface vmbr1 inet manual
bridge-ports eno2
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
# Trunk Bridge nội bộ
auto vmbr1.10
iface vmbr1.10 inet static
address 192.168.10.2/24
gateway 192.168.10.1
# Giao diện quản trị Proxmox được cô lập trên VLAN 10
Áp dụng ngay cấu hình interface mới bằng ifupdown2 mà không cần khởi động lại máy chủ host:
ifreload -a
2. Khởi tạo VM OPNsense qua Proxmox CLI
Tải file ISO DVD chính thức của OPNsense vào thư mục chứa ISO cục bộ. Sau đó khởi tạo máy ảo với các tham số tối ưu cho hypervisor:
qm create 100 --name "OPNsense-Core" \
--memory 8192 --cores 4 --cpu host \
--net0 virtio,bridge=vmbr0,firewall=0 \
--net1 virtio,bridge=vmbr1,firewall=0 \
--scsihw virtio-scsi-pci \
--scsi0 local-lvm:32,discard=on,ssd=1 \
--boot order=scsi0;ide2 \
--ide2 local:iso/OPNsense-dvd.iso,media=cdrom \
--ostype other --onboot 1 --startup order=1
Có hai tham số mang lại sự khác biệt rõ rệt về hiệu năng:
- Model CPU được đặt thành
host: Truyền thẳng các tập lệnh mở rộng như AES-NI và SHA tới FreeBSD. Điều này giúp WireGuard đạt băng thông mã hóa tối đa tương đương tốc độ đường truyền (line-rate) với mức tải CPU tối thiểu. - Card mạng VirtIO được cấu hình với
firewall=0: Bỏ qua các bộ lọc ebtables và iptables của Linux trên bridge. Thiết lập này ngăn chặn việc theo dõi gói tin hai lần và tránh tình trạng rớt gói không mong muốn trước khi lưu lượng đến được firewall engine.
3. Cài đặt cơ bản và tắt các tính năng Hardware Offload
Bật nguồn VM 100 và mở console noVNC. Đăng nhập với tài khoản installer và mật khẩu opnsense. Chọn ZFS làm filesystem gốc, định dạng này xử lý tốt hơn nhiều so với UFS tiêu chuẩn khi máy chủ gặp sự cố khởi động lại đột ngột. Sau khi hoàn tất cài đặt, hãy tháo file ISO cài đặt và khởi động lại máy ảo.
Trong trình hướng dẫn cấu hình ban đầu trên console, hãy gán các card mạng chính:
- Giao diện WAN:
vtnet0(liên kết với WAN bridgevmbr0) - Giao diện trunk LAN:
vtnet1(liên kết với trunk bridgevmbr1)
Truy cập vào giao diện web OPNsense tại https://192.168.1.1. Truy cập ngay vào mục Interfaces > Settings và bật (chọn vô hiệu hóa) ba tùy chọn sau:
- Disable Hardware Checksum Offload
- Disable Hardware TCP Segmentation Offload
- Disable Hardware Large Receive Offload
Driver VirtIO của FreeBSD (vtnet) rất thường làm rớt các frame được bridge nếu các tính năng hardware offload vẫn bật trong máy ảo KVM. Hãy lưu thay đổi, nhấp Apply và khởi động lại VM từ console web.
Cấu hình
1. Thiết lập Multi-VLAN
Để phân chia các subnet, hãy mở Interfaces > Other Types > VLAN. Thêm các sub-interface ảo dựa trên trunk cha vtnet1:
- VLAN 10 (MGMT): Tag
10, Interface chavtnet1— Hypervisor, IPMI, Switch quản lý (192.168.10.1/24) - VLAN 20 (TRUSTED): Tag
20, Interface chavtnet1— Máy tính để bàn, laptop làm việc, điện thoại admin (192.168.20.1/24) - VLAN 30 (SERVERS): Tag
30, Interface chavtnet1— TrueNAS, Docker, Jellyfin (192.168.30.1/24) - VLAN 40 (IOT): Tag
40, Interface chavtnet1— Camera IP, Smart TV, cảm biến ESP32 (192.168.40.1/24)
Đi tới Interfaces > Assignments, gán từng thẻ VLAN và kích hoạt các interface. Gán địa chỉ IPv4 tĩnh cho các gateway. Tiếp theo, mở Services > ISC DHCPv4 (hoặc Kea) và định nghĩa dải cấp phát địa chỉ (address pool) cho từng subnet, đồng thời cấu hình cấp IP tĩnh (static lease) cho các hypervisor và switch quản lý.
2. Quy tắc tường lửa nghiêm ngặt và cô lập Subnet
Theo mặc định, OPNsense sẽ chặn toàn bộ lưu lượng qua lại giữa các interface sau khi interface được gán. Để cô lập các mạng không tin cậy một cách triệt để nhưng vẫn đảm bảo quyền truy cập quản trị, hãy tạo các quy tắc thông qua alias cụ thể.
Chuyển đến Firewall > Aliases và tạo một alias tổng hợp các dải mạng:
- Name:
RFC1918_Networks - Type: Network(s)
- Content:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Mở Firewall > Rules > IOT. Tạo các quy tắc theo đúng thứ tự sau:
- Cho phép DNS: Pass | IPv4 UDP | Source:
IOT net| Destination:This Firewall| Port:53 - Cho phép NTP: Pass | IPv4 UDP | Source:
IOT net| Destination:This Firewall| Port:123 - Chặn RFC1918: Block | IPv4 * | Source:
IOT net| Destination:RFC1918_Networks(Chặn hoàn toàn thiết bị IoT truy cập vào tất cả các subnet nội bộ) - Cho phép truy cập Internet: Pass | IPv4 * | Source:
IOT net| Destination:*(Cho phép các kết nối outbound ra các địa chỉ IP public bên ngoài)
3. Lọc mối đe dọa Layer 7 với Zenarmor
Các quy tắc Layer 4 tiêu chuẩn chỉ kiểm tra địa chỉ IP và số hiệu cổng. Chúng không thể ngăn chặn các tín hiệu beacon HTTPS bất thường gửi ra ngoài qua cổng 443. Zenarmor giải quyết triệt để vấn đề này nhờ công nghệ kiểm tra gói tin sâu (Deep Packet Inspection – DPI), nhận dạng TLS SNI và cập nhật nguồn cấp dữ liệu tình báo mối đe dọa (threat intelligence) theo thời gian thực.
Truy cập vào System > Firmware > Plugins. Cài đặt plugin os-sunnyvalley, nhấp vào Check for updates, sau đó cài tiếp os-sensei cùng os-sensei-updater.
Chọn mục menu Zenarmor để bắt đầu trình hướng dẫn cấu hình ban đầu:
- Database Engine: Chọn SQLite đối với các mô hình homelab có dưới 50 thiết bị đầu cuối. Hãy chọn máy chủ Elasticsearch hoặc MongoDB bên ngoài nếu bạn cần lưu trữ và phân tích sự kiện dài hạn.
- Deployment Mode: Chọn Routed Mode (L3).
- Protected Interfaces: Chọn các VLAN nội bộ (
vlan0.20,vlan0.30,vlan0.40). Không chọn interface WAN. Việc kiểm tra lưu lượng trước khi qua NAT (pre-NAT) sẽ giúp giữ nguyên địa chỉ IP gốc của client nội bộ trong file log. - Hardware Engine: Netmap (VirtIO Emulated Netmap driver).
Mở Zenarmor > Policies > Default > Security. Bật các mục chặn bảo vệ theo thời gian thực: Malicious Software (Phần mềm độc hại), Phishing (Lừa đảo), Botnets và Aggressive Trackers (Trình theo dõi xâm hại).
Kiểm tra & Giám sát
Đừng chỉ tin vào các dấu tích trên giao diện GUI. Hãy luôn xác thực ranh giới bảo mật bằng cách chủ động gửi các gói tin thử nghiệm từ bên trong các subnet bị cô lập.
1. Xác thực cô lập Subnet qua CLI
Khởi tạo một container Alpine Linux được gán thẻ VLAN 40 (IoT) với địa chỉ IP 192.168.40.50. Thực thi các lệnh chẩn đoán sau để kiểm tra giới hạn ranh giới mạng:
# Thử nghiệm 1: Xác minh phân giải DNS của gateway nội bộ hoạt động bình thường
dig @192.168.40.1 api.weather.com +short
# Thử nghiệm 2: Ping tới máy chủ Proxmox trên VLAN 10 (Kết quả phải mất gói 100%)
ping -c 3 -W 1 192.168.10.2
# Thử nghiệm 3: Quét cổng dịch vụ SSH và web trên Gateway quản trị (Phải trả về timeout / closed)
nc -zvw3 192.168.10.1 22 80 443
Nếu các gói ping bị rớt hoàn toàn và netcat dừng lại cho đến khi hết thời gian chờ (timeout), quy tắc chặn RFC1918 đang thực thi phân tách ranh giới mạng một cách chính xác.
2. Kiểm tra khả năng lọc Layer 7 của Zenarmor
Đăng nhập vào một máy thuộc VLAN 20 (Trusted) và gửi một yêu cầu curl tới endpoint kiểm tra an toàn theo chuẩn tiêu chuẩn ngành:
curl -I http://malware.wicar.org/data/eicar.com
Zenarmor sẽ lập tức ngắt kết nối TCP hoặc trả về trang mã lỗi HTTP 403 Forbidden. Hãy chuyển tới Zenarmor > Live Sessions trên OPNsense để kiểm tra giao dịch đã bị đánh dấu cảnh báo, địa chỉ IP nguồn của client và mức độ nghiêm trọng của mối đe dọa.
3. Đo điểm chuẩn hiệu năng và độ ổn định
Kết quả thử nghiệm với iperf3 trên dàn máy thử nghiệm Intel Core i5-12400 cấp phát 4 vCPU cho thấy thông lượng duy trì ổn định đạt 2,38 Gbps giữa VLAN 20 và VLAN 30. Mức sử dụng CPU của host hypervisor duy trì dưới 6% trong các đợt truyền dữ liệu tải cao đột biến, và mức RAM sử dụng ở trạng thái nghỉ dao động quanh mức 2,4 GB.
Để bảo vệ cấu hình định tuyến của bạn, hãy lên lịch tự động snapshot ZFS hàng ngày trên Proxmox tại mục VM > Backup. Nếu quá trình nâng cấp kernel của OPNsense gặp sự cố, bạn có thể khôi phục lại toàn bộ cấu hình tường lửa chỉ trong chưa đầy 20 giây trực tiếp từ giao diện GUI của Proxmox.

