Làm chủ Network Visibility: Hướng dẫn thực hành Zeek trên Linux

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Tại sao kiểm tra gói tin (Packet Inspection) thường thất bại

Nhiều năm trước, khi còn là một chuyên viên phân tích bảo mật sơ cấp, tôi đã gặp bế tắc với các công cụ IDS truyền thống như Snort và Suricata. Chúng rất tuyệt vời trong việc khớp chữ ký (signature) với các mối đe dọa đã biết, nhưng thường để tôi rơi vào tình trạng mù mờ trước các cuộc tấn công zero-day hoặc các hoạt động di chuyển ngang (lateral movement). Đó là lúc tôi khám phá ra Zeek (trước đây là Bro).

Một IDS tiêu chuẩn sẽ “la hét” khi nó phát hiện một chuỗi ký tự “xấu”. Zeek thì khác; nó hoạt động như một máy ghi dữ liệu chuyến bay với độ chính xác cao. Nó chuyển đổi các gói tin thô thành các bản ghi log có cấu trúc và có thể tìm kiếm được, cung cấp cho bạn ngữ cảnh để hiểu điều đã xảy ra, thay vì chỉ cảnh báo rằng có điều gì đó không ổn.

Phân tích dựa trên chữ ký vs. Phân tích dựa trên chính sách

Hầu hết các công cụ bảo mật dựa vào phát hiện dựa trên chữ ký (Signature-based detection). Chúng tìm kiếm các mẫu cụ thể—một mã hash file, một IP độc hại hoặc một chuỗi ký tự duy nhất. Nếu kẻ tấn công thay đổi dù chỉ một byte trong mã độc, chữ ký sẽ thất bại. Zeek áp dụng cách tiếp cận dựa trên chính sách (Policy-driven approach). Thay vì tìm kiếm những thứ “xấu”, nó phân tích các giao thức như HTTP, DNS và SSL/TLS để ghi lại siêu dữ liệu (metadata).

Nó không chỉ nhìn thấy lưu lượng TCP trên cổng 80. Nó ghi lại yêu cầu GET cho một URI cụ thể và chính xác User-Agent được sử dụng. Điều này cho phép bạn săn tìm các thay đổi về hành vi. Ví dụ: nếu một người dùng thường duyệt khoảng 10MB dữ liệu mỗi ngày bỗng nhiên tải xuống 5GB từ một máy chủ nội bộ, Zeek sẽ gắn cờ hành vi đó bất kể có chữ ký cho hành động cụ thể đó hay không.

Thực tế khi sử dụng Zeek

  • Ưu điểm:
    • Ghi log chi tiết: Bạn có các bản log riêng biệt cho các truy vấn DNS, bắt tay SSL và thậm chí cả mã hash của các file được trích xuất ngay trên đường truyền.
    • Ngôn ngữ kịch bản Turing-Complete: Bạn có thể tự động hóa các logic phát hiện phức tạp bằng ngôn ngữ riêng của Zeek.
    • Hiệu suất cao: Khả năng mở rộng tốt. Các tổ chức lớn sử dụng các cụm Zeek cluster để giám sát các đường truyền 100Gbps mà không gặp khó khăn gì.
  • Nhược điểm:
    • Độ dốc học tập: Việc làm chủ ngôn ngữ script của Zeek mất vài tuần chứ không phải vài giờ.
    • Yêu cầu lưu trữ: Trên một đường truyền 1Gbps bận rộn, Zeek có thể dễ dàng tạo ra 100GB log chỉ trong một ngày. Bạn cần bộ nhớ dung lượng lớn và tốc độ cao.
    • Chỉ giám sát thụ động: Zeek là một công cụ giám sát. Nó sẽ không chặn gói tin hoặc chặn IP một cách trực tiếp; nó ở đó để cung cấp khả năng hiển thị (visibility).

Yêu cầu phần cứng cho môi trường Production

Đối với môi trường production, tôi khuyên bạn nên sử dụng một máy chủ vật lý riêng biệt hoặc một VM hiệu suất cao với cổng mirrored (SPAN/TAP). Một môi trường văn phòng nhỏ có thể bắt đầu với 4-8 lõi CPU và 16GB RAM.

Bảo mật bắt đầu từ những điều cơ bản. Khi thiết lập tài khoản quản trị cho một node Zeek mới, tôi sử dụng trình tạo tại toolcraft.app/vi/tools/security/password-generator. Tôi ưu tiên công cụ này vì nó chạy hoàn toàn trong trình duyệt của bạn. Điều này đảm bảo các thông tin đăng nhập nhạy cảm không bao giờ đi qua mạng trong quá trình khởi tạo.

Hướng dẫn cài đặt: Zeek trên Ubuntu 22.04/24.04

Đừng tốn công biên dịch từ mã nguồn. Sử dụng các gói đã được build sẵn từ Open Build Service (OBS) là cách nhanh nhất để có một phiên bản ổn định chạy được ngay.

Bước 1: Thiết lập Repository

# Thêm key của repository
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_22.04/Release.key | sudo gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null

# Thêm repository của Zeek
echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' | sudo tee /etc/apt/sources.list.d/security:zeek.list

# Cập nhật và cài đặt
sudo apt update
sudo apt install zeek-6.0

Khi được hỏi về thư mục cài đặt, hãy giữ nguyên mặc định là /opt/zeek. Nó giúp giữ cho các thư mục hệ thống cốt lõi được ngăn nắp và dễ dự đoán.

Bước 2: Môi trường và Đường dẫn

Thêm các file thực thi của Zeek vào PATH của hệ thống để tránh việc phải nhập đầy đủ đường dẫn thư mục mỗi lần sử dụng.

echo "export PATH=$PATH:/opt/zeek/bin" >> ~/.bashrc
source ~/.bashrc

Bước 3: Định nghĩa mạng nội bộ

Zeek cần biết dải IP nào là “nhà”. Sự phân biệt này rất quan trọng để xác định việc trích xuất dữ liệu ra bên ngoài (outbound exfiltration) so với di chuyển ngang trong nội bộ. Chỉnh sửa file networks.cfg:

sudo nano /opt/zeek/etc/networks.cfg

Định nghĩa các mạng con của bạn như sau:

10.0.0.0/8          Không gian mạng nội bộ
192.168.1.0/24      Văn phòng chính
172.16.0.0/12       Phòng Lab phát triển

Bước 4: Chọn Interface

Xác định interface đang nghe (ví dụ: enp0s3) bằng lệnh ip link show. Sau đó, cấu hình node.cfg:

sudo nano /opt/zeek/etc/node.cfg

Cập nhật dòng interface trong phần [zeek]:

[zeek]
type=standalone
host=localhost
interface=enp0s3

Bước 5: Triển khai

Sử dụng zeekctl để khởi tạo và chạy engine. Công cụ này sẽ quản lý các tiến trình chạy ngầm cho bạn.

sudo zeekctl install
sudo zeekctl start
sudo zeekctl status

Khám phá các File Log

Kiểm tra /opt/zeek/logs/current để xem dữ liệu trong thời gian thực. Đây là nơi phép màu xảy ra. Bạn sẽ thấy một số file .log phân loại lưu lượng truy cập của mình:

  • conn.log: Danh sách tổng hợp của mọi kết nối TCP, UDP và ICMP.
  • dns.log: Bản ghi của mọi truy vấn, phản hồi và TTL.
  • http.log: Siêu dữ liệu cho lưu lượng web không mã hóa, bao gồm hostname và referrer.
  • ssl.log: Chi tiết về các phiên mã hóa, hiển thị nhà cấp phát chứng chỉ và phiên bản TLS.
  • files.log: Nhật ký các file được thấy trên đường truyền, thường bao gồm mã hash MD5/SHA1.

Để trích xuất thông tin nhanh chóng, hãy sử dụng zeek-cut. Ví dụ, để tìm 10 tên miền được yêu cầu nhiều nhất trong mạng của bạn, hãy chạy:

cat dns.log | zeek-cut query | sort | uniq -c | sort -rn | head -n 10

Phát hiện đe dọa bằng Script

Sức mạnh thực sự của Zeek là khả năng phản ứng với các sự kiện. Bạn có thể viết một script để gắn cờ các vụ tấn công brute-force SSH tiềm ẩn bằng cách theo dõi các sự kiện xác thực thất bại. Tạo file /opt/zeek/share/zeek/site/detect-brute.zeek:

event ssh_auth_failed(c: connection)
{
    print fmt("Cảnh báo: Lỗi đăng nhập SSH từ %s đến %s", c$id$orig_h, c$id$resp_h);
}

Tải script này bằng cách thêm @load detect-brute.zeek vào file local.zeek của bạn, sau đó chạy sudo zeekctl deploy để áp dụng các thay đổi.

Những bài học xương máu từ thực tế

Đừng bỏ qua log rotation (xoay vòng log). Zeek là một “vòi rồng” dữ liệu. Nếu bạn không cấu hình zeekctl cron, ổ cứng của bạn có thể sẽ đầy 100% trong vòng 48 giờ. Tôi thường thiết lập một cron job chạy mỗi 5 phút để xử lý bảo trì log và kiểm tra sức khỏe hệ thống.

Hãy để mắt đến packet drops (gói tin bị bỏ rơi). Nếu CPU của bạn tăng vọt, Zeek sẽ bắt đầu bỏ lỡ lưu lượng, để lại những lỗ hổng trong lịch sử bảo mật của bạn. Sử dụng zeekctl capstats để giám sát hiệu suất. Nếu bạn thấy tỷ lệ drop vượt quá 5%, đã đến lúc chuyển từ thiết lập “standalone” sang cấu hình “cluster” trong node.cfg để phân phối tải trên nhiều lõi CPU.

Cuối cùng, hãy coi CLI là điểm bắt đầu. Mặc dù zeek-cut rất tuyệt để xử lý sự cố nhanh, nhưng về lâu dài bạn nên đẩy các log này vào ELK stack hoặc Wazuh. Việc có một dashboard trực quan giúp bạn dễ dàng phát hiện các cuộc tấn công “slow and low” (âm thầm và kéo dài) thường ẩn mình trong sự nhiễu loạn của các bản log hàng ngày.

Share: