Hướng dẫn cài đặt và cấu hình ntopng trên Linux để giám sát và phân tích lưu lượng mạng theo thời gian thực

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

Cơn ác mộng nghẽn băng thông lúc nửa đêm: Chuyện thực tế ở hệ thống thanh toán

Đúng 23h15 một tối thứ Sáu, điện thoại réo liên hồi vì cảnh báo PagerDuty. Cụm API gateway và cổng thanh toán bên mình nhảy vọt độ trễ từ 45ms lên tận 2.8s. Tỷ lệ lỗi 504 Gateway Timeout trên Nginx chạm mốc 18%.

Mở Grafana lên, đồ thị network traffic dốc đứng một màu đỏ rực. Băng thông card mạng trên switch bị vắt kiệt ở ngưỡng 980Mbps (gần kịch trần port 1Gbps). Mình vội SSH vào từng con server, gõ iftop rồi nethogs. Nhưng cách này quá manh mún. Một cụm gần 40 máy ảo microservices thì không thể ngồi soi từng tiến trình thủ công khi sự cố đang diễn ra từng giây.

Hệ thống đang nghẽn nặng. Ai đang gửi dữ liệu đi? Giao thức gì chiếm đường truyền? Đi ra ngoài internet hay dội ngược trong cụm nội bộ? Mọi thứ lúc đó hoàn toàn mù mịt.

Vì sao Prometheus hay Zabbix lại bó tay khi mạng bị nghẽn?

Sau đợt incident đó, team ngồi mổ băng sự cố và nhận ra lỗ hổng lớn nằm ở dữ liệu giám sát:

  • Metrics thông thường (Prometheus node_exporter, Zabbix): Chỉ đo đếm số lượng thô (volume) như tổng bytes gửi/nhận hay số packet/giây. Chúng không hề biết gói tin đó chứa dữ liệu gì ở tầng ứng dụng (Layer 7).
  • Log dịch vụ: Nginx access log hay iptables log chỉ ghi nhận khi một session TCP đã đóng hoặc gói tin bị drop. Chúng hoàn toàn mù tịt trước các luồng kết nối dở dang (in-flight flows) đang ngâm và hút cạn băng thông.
  • Thiếu DPI (Deep Packet Inspection): Một đợt backup dữ liệu qua rsync lạ, database dump đẩy nhầm sang S3, hay tấn công DNS Amplification đều trông giống hệt traffic thông thường nếu không mổ xẻ payload header.

Ba hướng đi khi cần phân tích network flow

Để giải bài toán này, mình đã cân nhắc ba phương án quen thuộc:

  1. Bắt raw packet bằng tcpdump rồi mở Wireshark: Chạy lệnh tcpdump -i eth0 -w dump.pcap. Cách này soi chi tiết tới từng bit. Nhưng file dump phình lên 10GB chỉ sau chưa đầy 3 phút, ăn sạch I/O ổ cứng và không thể phân tích trực tiếp khi tải đang cao.
  2. Đẩy NetFlow / sFlow về cụm ELK: Router đẩy flow sang Logstash rồi lưu vào Elasticsearch. Giải pháp này xịn nhưng ngốn RAM khủng khiếp. Một cụm Elasticsearch phục vụ việc này ngốn tối thiểu 16GB RAM, chưa kể cấu hình pipeline cực kỳ cồng kềnh và dữ liệu hiển thị vẫn có độ trễ 1-2 phút.
  3. Dựng ntopng kết hợp nDPI: ntopng vừa bắt gói tin vừa trực quan hóa dashboard. Nhờ thư viện nDPI tích hợp sẵn, nó bóc tách giao thức Layer 7 ngay tại bộ nhớ, dùng Redis lưu flow tạm thời và hiển thị biểu đồ real-time với mức tiêu thụ tài nguyên rất dễ chịu (chỉ tốn khoảng 500MB đến 1GB RAM).

Cách triển khai ntopng thực chiến trên Ubuntu / Debian

Dưới đây là các bước mình dựng ntopng trực tiếp trên server đóng vai trò network monitor (kết nối qua cổng SPAN/Mirror port của switch hoặc gắn trực tiếp trên gateway Linux).

Bước 1: Cài đặt repository và gói ntopng

Hãy dùng repo chính thức từ ntop thay vì repo mặc định của Ubuntu để có signature nDPI mới nhất:

# 1. Cài các công cụ hỗ trợ
sudo apt update && sudo apt install -y software-properties-common wget lsb-release gnupg

# 2. Tải và thêm repo ntop chính hãng
wget https://packages.ntop.org/apt/$(lsb_release -rs)/all/apt-ntop.deb
sudo dpkg -i apt-ntop.deb
sudo apt update

# 3. Cài ntopng và Redis (dùng làm bộ nhớ đệm cache state)
sudo apt install -y redis-server ntopng

Bước 2: Cấu hình card mạng cần theo dõi

Mở file cấu hình /etc/ntopng/ntopng.conf:

sudo nano /etc/ntopng/ntopng.conf

Xóa nội dung mẫu cũ và điền thông số tối ưu cho môi trường thực tế:

# Port chạy web UI
-w=3000

# Card mạng cần bắt gói tin (kiểm tra lại bằng lệnh 'ip a')
-i=eth0

# Khai báo dải IP nội bộ để ntopng phân định chiều Inbound / Outbound / Local
-m=192.168.1.0/24,10.10.0.0/16

# Nơi lưu trữ RRD metrics và dữ liệu phân tích
-d=/var/lib/ntopng

# Tắt reverse DNS lookup tự động để tránh nghẽn thread khi traffic cao
-n=1

Tùy chọn -n=1 đặc biệt quan trọng. Khi mạng nghẽn với hàng chục nghìn connection mở liên tục, việc ntopng cố phân giải DNS cho từng IP sẽ làm treo cứng tiến trình capture.

Bước 3: Khởi chạy dịch vụ và đăng nhập

Khởi động Redis trước, sau đó kích hoạt ntopng:

sudo systemctl enable redis-server ntopng
sudo systemctl restart redis-server
sudo systemctl restart ntopng

# Kiểm tra dịch vụ có chạy mượt mà không
sudo systemctl status ntopng

Truy cập vào http://<IP-Server>:3000. Tài khoản mặc định là admin / admin. Giao diện sẽ bắt buộc đổi mật khẩu mới ngay lần đầu đăng nhập.

Bước 4: Bài học xử lý “Alert Fatigue” – Tránh bị spam cảnh báo

Tuần đầu tiên chạy ntopng trên production là một thảm họa cảnh báo. Hệ thống bật sẵn toàn bộ rule mặc định: từ packet out-of-order, jitter nhẹ cho tới query DNS lạ. Kết quả là Slack bot nhồi hơn 2.300 thông báo mỗi ngày. Đến ngày thứ ba, cả team quyết định bấm “Mute” kênh thông báo. Hệ thống giám sát bỗng chốc trở thành phế phẩm.

Để trị dứt điểm tình trạng này, mình đã tinh chỉnh lại ba điểm mấu chốt:

  • Phân nhóm Host Pools: Nhóm các cụm máy chủ nội bộ (như Database Replication, Ceph storage) vào một pool riêng. Vào Settings > Alert Entities để tắt các cảnh báo băng thông cao giữa các cụm này, vì việc đồng bộ hàng trăm GB dữ liệu giữa chúng là bình thường.
  • Nâng ngưỡng Flow Flood cho Gateway: Reverse proxy (Nginx/HAProxy) xử lý hàng chục nghìn kết nối đồng thời là hiển nhiên. Hãy vào cấu hình threshold của riêng host đó, tăng ngưỡng Max Number of Flows lên gấp 8 lần mức mặc định để tránh ntopng hiểu nhầm là bị tấn công SYN Flood.
  • Chỉ bắn alert có giá trị hành động: Giữ lại thông báo cho Blacklisted IP Contacts, TCP Connection Refused burst (dấu hiệu port scanning nội bộ), và DNS Tunneling. Nếu một alert không đòi hỏi người trực phải bật máy xử lý ngay, hãy tắt nó đi.

Tổng kết góc nhìn vận hành

Nhờ triển khai ntopng, bài toán nghẽn mạng lúc nửa đêm hôm đó đã được sáng tỏ. Thủ phạm hóa ra là một cronjob sao lưu database tự động viết lỗi: thay vì nén nội bộ rồi đẩy theo luồng phụ, script lại bung toàn bộ uncompressed raw dump 40GB qua cổng public API.

Hiện tại, mỗi khi có cảnh báo băng thông, team chỉ cần mở tab Flows > Top Talkers. Chưa đầy 20 giây là xác định được chính xác IP nào đang xả băng thông, xả qua port nào và thuộc loại ứng dụng gì, chấm dứt hoàn toàn cảnh mò kim đáy bể qua SSH.

Share: