Mục lục
Hạn chế của iptables thuần túy (Cơ chế O(N))
Iptables từ lâu đã là hệ thống Firewall cốt lõi trên các hệ điều hành Linux. Nó rất mạnh mẽ trong việc kiểm soát luồng dữ liệu (traffic) vào và ra khỏi máy chủ. Tuy nhiên, nó có một điểm yếu chí mạng khi phải xử lý số lượng quy tắc (rules) quá lớn.
Theo nguyên lý thiết kế, iptables hoạt động dựa trên việc quét các rule một cách tuần tự (Sequential Matching) từ trên xuống dưới. Điều này có nghĩa là mỗi khi có một gói tin (packet) đi vào server, Kernel sẽ mang gói tin đó đi "hỏi" từng rule một:
iptables -A INPUT -s 1.1.1.1 -j DROP
iptables -A INPUT -s 2.2.2.2 -j DROP
iptables -A INPUT -s 3.3.3.3 -j DROP
# ... 10.000 rules tương tự
Nếu bạn có một danh sách chặn (blacklist) gồm 10.000 IP, một gói tin bình thường (không bị chặn) khi đi vào sẽ phải chạy qua kiểm tra đủ 10.000 rule này trước khi được chấp nhận. Độ phức tạp thời gian lúc này là O(N).
IPset là gì và tại sao nó lại nhanh?
IPset là một extension mở rộng (framework) đi kèm với iptables. Thay vì bắt iptables lưu trữ từng IP dưới dạng từng rule rời rạc, IPset cung cấp một vùng chứa (container) đặc biệt để gom nhóm hàng ngàn, thậm chí hàng triệu địa chỉ IP, MAC, hoặc Port vào cùng một "tập hợp" (set).
Điểm làm nên sự thần kỳ của IPset chính là cách nó lưu trữ dữ liệu trong Linux Kernel bằng các cấu trúc dữ liệu tối ưu cao như Bảng băm (Hash Map) hoặc Bitmap.
- Hash Map: Giúp tìm kiếm một phần tử với thời gian gần như ngay lập tức.
- Độ phức tạp O(1): Bất kể tập hợp IPset của bạn chứa 10 IP hay 1.000.000 IP, thời gian để hệ thống kiểm tra xem một IP mới đi vào có nằm trong danh sách hay không là bằng nhau và cực kỳ nhanh.
Lúc này, thay vì tạo 10.000 rule iptables, bạn chỉ cần tạo đúng 1 rule duy nhất trỏ vào IPset:
# Chỉ 1 rule iptables thay cho hàng vạn rule
iptables -A INPUT -m set --match-set my_blacklist src -j DROP
So sánh hiệu năng thực tế
Để thấy rõ sự khác biệt, dưới đây là kết quả Benchmark hiệu năng thực tế khi xử lý các gói tin TCP với 10.000 IP bị chặn trên cùng một server:
| Tiêu chí | Iptables thuần túy | Iptables + IPset |
|---|---|---|
| Cấu trúc dữ liệu | Linked List (Danh sách liên kết) | Hash Map / Bitmap |
| Độ phức tạp tra cứu | O(N) - Quét tuần tự | O(1) - Tra cứu tức thì |
| CPU Load (khi bị scan) | Tăng vọt lên 90% - 100% | Rất thấp (Gần như không đổi) |
| Khả năng quản lý | Khó quản lý, lệnh dài dòng | Gọn gàng, dễ cập nhật realtime |
Hướng dẫn cài đặt và sử dụng cơ bản
Cài đặt IPset
Hầu hết các bản phân phối Linux đều hỗ trợ sẵn iptables và ipset trong Kernel. Tuy nhiên, để sử dụng các tập lệnh quản lý, bạn cần cài đặt gói công cụ người dùng (userspace tools):
# Đối với Ubuntu / Debian
sudo apt update
sudo apt install ipset
# Đối với CentOS / RHEL / AlmaLinux
sudo yum install ipset
Tạo một Set mới
Chúng ta sẽ tạo một danh sách băm (hash) chứa các địa chỉ IP với tên gọi blacklist và giới hạn tối đa 1 triệu IP:
sudo ipset create blacklist hash:ip maxelem 1000000
Để xem danh sách các set đang có, bạn có thể chạy lệnh:
sudo ipset list
Thêm và Xóa IP khỏi Set
Việc thao tác dữ liệu rất đơn giản và diễn ra ngay lập tức:
# Thêm 1 IP độc hại
sudo ipset add blacklist 192.168.1.100
# Xóa 1 IP khỏi danh sách (nếu lỡ block nhầm)
sudo ipset del blacklist 192.168.1.100
# Xóa trắng toàn bộ IP trong danh sách
sudo ipset flush blacklist
Tích hợp Set vào Iptables
Đây là bước quan trọng nhất. Chúng ta cần nói cho iptables biết hãy kiểm tra các gói tin đến (INPUT) xem nguồn (src) của nó có nằm trong blacklist hay không, nếu có thì DROP nó.
sudo iptables -I INPUT -m set --match-set blacklist src -j DROP
-I INPUT: Chèn rule lên đầu chuỗi INPUT (ưu tiên cao nhất).-m set: Gọi module set của iptables.--match-set blacklist src: Đối chiếu (match) với tập hợp có tên "blacklist", áp dụng lên địa chỉ Nguồn (Source - src).-j DROP: Vứt bỏ gói tin.
Các tính năng nâng cao
Tự động gỡ IP sau khoảng thời gian (Timeout)
Rất hữu ích để phối hợp với Fail2Ban hoặc các script chống DDoS tự động. Bạn có thể chặn một IP trong thời gian nhất định (ví dụ 1 ngày), sau đó Kernel sẽ tự động gỡ IP đó đi mà không cần bạn phải cấu hình cronjob rườm rà.
# Tạo set có hỗ trợ thuộc tính timeout
sudo ipset create temp_blocks hash:ip timeout 3600
# Thêm IP vào danh sách, mặc định sẽ tự gỡ sau 3600 giây (1 tiếng)
sudo ipset add temp_blocks 10.0.0.5
# Bạn cũng có thể ghi đè thời gian timeout cho một IP cụ thể
sudo ipset add temp_blocks 10.0.0.9 timeout 86400 # Xóa sau 1 ngày
Lưu và Phục hồi cấu hình (Save & Restore)
Danh sách IPset nằm trong RAM (Kernel Memory). Do đó, nếu bạn khởi động lại máy chủ (Reboot), toàn bộ danh sách sẽ bị mất trắng. Bạn cần lưu nó ra một file văn bản trước khi tắt máy:
# Lưu toàn bộ cấu hình ra file
sudo ipset save > /etc/ipset.conf
Sau khi máy chủ khởi động lên, hãy khôi phục (restore) danh sách bằng lệnh:
# Đọc và nạp lại cấu hình từ file
sudo ipset restore < /etc/ipset.conf
Trên môi trường production thực tế, chúng ta thường dùng systemd hoặc tích hợp với cấu hình lưu trữ dài hạn của hệ thống mạng (ví dụ iptables-persistent kết hợp netfilter-persistent) để tự động hóa hoàn toàn quy trình này.