Hướng dẫn dùng nmap quét mạng và kiểm tra bảo mật Linux server

Network tutorial - IT technology blog
Network tutorial - IT technology blog

Tại sao mình bắt đầu dùng nmap thường xuyên hơn

Hồi mới nhận quản lý hệ thống mạng cho văn phòng 50 người và một datacenter nhỏ, mình hay bị bất ngờ bởi những port “lạ” bỗng dưng xuất hiện trên server. Một lần, team dev deploy thử nghiệm một service nội bộ và quên tắt — service đó bind ra 0.0.0.0, tức là lộ ra internet. May mà mình phát hiện sớm trước khi có vấn đề.

Từ đó nmap trở thành một phần cố định trong checklist hàng tuần. Không phải để hack — mà để biết chính xác server của mình đang mở cái gì ra ngoài. Thay vì kiểm tra từng service thủ công, một lệnh nmap quét xong cả subnet trong vài phút.

Cài đặt nmap trên Linux

Trên hầu hết distro phổ biến, nmap có sẵn trong repo chính thức:

# Ubuntu / Debian
sudo apt update && sudo apt install nmap -y

# CentOS / RHEL / Rocky Linux
sudo dnf install nmap -y

# Arch Linux
sudo pacman -S nmap

Kiểm tra version sau khi cài:

nmap --version
# Nmap version 7.94 ( https://nmap.org )

Một lưu ý quan trọng: chạy nmap trên hệ thống của chính mình là hoàn toàn hợp lệ. Còn quét IP của người khác mà không có phép là vi phạm pháp luật — ở Mỹ có thể bị truy tố theo Computer Fraud and Abuse Act, Việt Nam cũng có quy định tương tự trong Luật An ninh mạng. Mình chỉ dùng nmap để audit hạ tầng mà mình có quyền quản lý.

Cấu hình và kỹ thuật quét chi tiết

1. Quét port cơ bản — biết ngay server đang mở gì

Bắt đầu đơn giản — xem server đang lắng nghe port nào:

# Quét 1000 port phổ biến nhất (mặc định)
nmap 192.168.1.100

# Quét toàn bộ 65535 port — chậm hơn nhưng đầy đủ hơn
nmap -p- 192.168.1.100

# Quét range port cụ thể
nmap -p 22,80,443,3306,6379 192.168.1.100

Output mẫu:

PORT     STATE  SERVICE
22/tcp   open   ssh
80/tcp   open   http
443/tcp  open   https
3306/tcp open   mysql

Thấy MySQL (3306) đang open? Nếu server này public thì đó là vấn đề nghiêm trọng. Trường hợp này mình từng gặp thật — dev để mặc định bind 0.0.0.0 khi test, sau đó quên không đổi lại.

2. Phát hiện phiên bản dịch vụ — quan trọng cho vulnerability assessment

Port mở mới chỉ là phần nổi. Quan trọng hơn là version — để đối chiếu với CVE database:

# -sV: detect service version
nmap -sV 192.168.1.100

# Kết hợp với -sC (default scripts) để lấy thêm thông tin
nmap -sV -sC 192.168.1.100

Kết quả cụ thể hơn nhiều:

PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp  open  http    nginx 1.24.0 (Ubuntu)
443/tcp open  ssl/http nginx 1.24.0

OpenSSH 8.9, nginx 1.24 — vào NVD (nvd.nist.gov) tra ngay xem có CVE nào đang active không. Bước này tốn 2 phút nhưng hay phát hiện lỗ hổng nghiêm trọng trước khi ai đó khai thác.

3. Quét toàn bộ subnet — audit mạng nội bộ

Lệnh này mình chạy mỗi thứ Hai sáng để kiểm tra mạng có gì thay đổi không:

# Ping scan — liệt kê host đang online trong subnet
nmap -sn 192.168.1.0/24

# Kết hợp với quét port nhanh
nmap -sn -oG - 192.168.1.0/24 | grep 'Status: Up' | awk '{print $2}' > live_hosts.txt
nmap -iL live_hosts.txt -p 22,80,443,3306,5432,6379,27017 -oN scan_result.txt

Kết quả lưu vào file, rồi diff với kết quả tuần trước. Thấy IP mới hoặc port lạ xuất hiện đột ngột — thường là service ai đó deploy mà chưa báo.

4. Phát hiện OS và fingerprinting

# -O: OS detection (cần root)
sudo nmap -O 192.168.1.100

# Aggressive scan — tổng hợp nhiều kỹ thuật
sudo nmap -A 192.168.1.100

Option -A gộp 4 thứ vào một lần chạy: OS detection, version detection, script scanning và traceroute. Dùng khi cần audit kỹ một host cụ thể. Nhưng tránh chạy thường xuyên trên production — nó tạo khá nhiều traffic và để lại dấu vết rõ ràng trong log.

5. Stealth scan — quét ít gây noise hơn

# SYN scan (half-open) — nhanh, ít log trên target
sudo nmap -sS 192.168.1.100

# UDP scan — nhiều service quan trọng dùng UDP (DNS, SNMP, NTP)
sudo nmap -sU -p 53,123,161 192.168.1.100

UDP scan hay bị bỏ qua vì chậm hơn TCP. Đừng bỏ qua nó. Mình từng phát hiện SNMP (port 161 UDP) đang bật với community string mặc định “public” trên một thiết bị mạng — qua đó ai cũng có thể đọc toàn bộ cấu hình switch, router trong mạng nội bộ mà không cần authentication gì cả.

6. Sử dụng NSE scripts — kiểm tra bảo mật chuyên sâu

NSE (Nmap Scripting Engine) đi kèm hơn 600 script — từ kiểm tra lỗ hổng đến enum thông tin chi tiết:

# Kiểm tra các lỗ hổng phổ biến
nmap --script vuln 192.168.1.100

# Kiểm tra SSH: brute force protection, thuật toán mã hóa
nmap --script ssh-auth-methods,ssh2-enum-algos -p 22 192.168.1.100

# Kiểm tra HTTP headers bảo mật
nmap --script http-security-headers -p 80,443 192.168.1.100

# Kiểm tra SSL/TLS config
nmap --script ssl-enum-ciphers -p 443 192.168.1.100

Script ssl-enum-ciphers đặc biệt hữu ích — nó liệt kê cipher suite nào đang được hỗ trợ và đánh giá từng cipher (A/B/C/F). Mình dùng cái này để verify sau mỗi lần update TLS config trên nginx.

Kiểm tra kết quả và thiết lập monitoring thường xuyên

Lưu kết quả quét để so sánh theo thời gian

Nmap hỗ trợ nhiều format output. XML để parse bằng script, plaintext để đọc trực tiếp:

# Output XML — dùng để parse hoặc import vào tool khác
nmap -sV -oX scan_$(date +%Y%m%d).xml 192.168.1.0/24

# Output tất cả format cùng lúc
nmap -sV -oA scan_$(date +%Y%m%d) 192.168.1.0/24
# Tạo ra: scan_YYYYMMDD.nmap, scan_YYYYMMDD.xml, scan_YYYYMMDD.gnmap

# So sánh 2 lần quét để phát hiện thay đổi
diff scan_20240101.nmap scan_20240108.nmap

Script automation đơn giản cho weekly audit

#!/bin/bash
# /opt/scripts/weekly_nmap_audit.sh

SUBNET="192.168.1.0/24"
OUTDIR="/var/log/nmap-audit"
DATE=$(date +%Y%m%d_%H%M)

mkdir -p $OUTDIR

# Quét port quan trọng trên toàn subnet
nmap -sV -p 22,23,80,443,3306,5432,6379,27017,11211,9200 \
  --open -oN "$OUTDIR/scan_$DATE.txt" $SUBNET

# Gửi cảnh báo nếu thấy port nguy hiểm (23=telnet, 11211=memcached)
if grep -E '^[0-9]+.*23/tcp|11211/tcp' "$OUTDIR/scan_$DATE.txt"; then
  echo "CẢNH BÁO: Phát hiện port nguy hiểm!" | mail -s "[ALERT] nmap audit" [email protected]
fi

Thêm vào crontab để chạy tự động:

crontab -e
# Chạy mỗi thứ Hai lúc 7 giờ sáng
0 7 * * 1 /opt/scripts/weekly_nmap_audit.sh

Những gì cần chú ý trong kết quả quét

  • Port 23 (Telnet) — thấy cái này thì tắt ngay, Telnet truyền mọi thứ không mã hóa kể cả password
  • Port 3306/5432 (MySQL/PostgreSQL) mở ra internet — database không bao giờ nên public trực tiếp
  • Port 6379 (Redis) không có authentication — mình từng xử lý case Redis bị cài cryptominer, CPU server chạy 100% suốt một tuần trước khi phát hiện ra nguyên nhân
  • Port 9200 (Elasticsearch) mở không có auth — hàng nghìn vụ data leak đã xảy ra vì lý do này, nhiều vụ lộ thông tin khách hàng quy mô lớn
  • Port 11211 (Memcached) — hay bị dùng để khuếch đại DDoS, amplification factor có thể lên tới 51.000x

Gần 3 năm dùng nmap để audit hệ thống, mình nhận ra giá trị thật sự không nằm ở lần quét đầu tiên. Nằm ở việc chạy định kỳ và so sánh kết quả. Hạ tầng thay đổi liên tục — deploy service mới, update bật thêm port, firewall rule bị reset sau reboot. Quét định kỳ giúp phát hiện sớm, trước khi người khác phát hiện thay mình.

Share: