Cú lừa Firewall: Khi Docker âm thầm “đi cửa sau”
Bạn vừa thuê một con VPS, hăm hở cài UFW và gõ lệnh ufw deny 8080 để “đóng cửa” server. Nhưng ngay khi bạn chạy Docker với tham số -p 8080:80, cái port tưởng chừng đã khóa lại mở toang cho cả thế giới. Tin mình đi, đây là “vố đau” mà rất nhiều anh em SysAdmin từng nếm trải khi mới vào nghề.
Thực tế, đây không phải lỗi phần mềm. Đó là hệ quả từ cách Docker “nói chuyện” trực tiếp với nhân Linux. Nếu chủ quan, những container nhạy cảm như Redis hay MongoDB sẽ biến thành “mồi ngon” cho hacker, ngay cả khi bạn đinh ninh firewall đang hoạt động cực kỳ nghiêm ngặt.
Bản chất cuộc chiến: Docker vs iptables
Hãy tưởng tượng UFW chỉ là một lớp vỏ trang trí (frontend) giúp ta gõ lệnh iptables dễ thở hơn. Trong khi đó, Docker lại là một “tay chơi” quyền lực, cũng dùng iptables để điều phối dòng dữ liệu ra vào container.
Vừa khởi động, Docker sẽ “chen hàng” và chèn các quy tắc của mình vào vị trí ưu tiên số 1 trong iptables. Khi một gói tin (packet) gửi tới VPS, nó sẽ va phải luật của Docker trước khi kịp chạm đến lớp bảo vệ của UFW. Thế là Docker “mở cửa” mời khách vào nhà, bỏ mặc UFW đứng ngoài la hét vô vọng.
Kinh nghiệm thực chiến cho thấy đây là lỗ hổng chết người. Mình từng chứng kiến một server Redis của khách hàng bị “vét sạch” data và dính ransomware chỉ sau 2 tiếng lộ port 6379, dù UFW vẫn đang báo status: active.
Giải pháp 1: Trói port vào Localhost (Mì ăn liền nhưng hiệu quả)
Nếu bạn chỉ cần container phục vụ cho một ứng dụng khác trên cùng server (như Nginx làm Reverse Proxy), đừng bao giờ dùng cách public port thông thường.
Thay vì chạy lệnh này:
docker run -d -p 8080:80 nginx
Hãy sửa lại thành:
docker run -d -p 127.0.0.1:8080:80 nginx
Thủ thuật này buộc Docker chỉ “lắng nghe” yêu cầu từ chính nội bộ server. Ngay cả khi Docker lách qua UFW, kẻ xấu từ internet cũng không thể mò tới port 8080 vì nó không tồn tại trên địa chỉ IP công cộng (Public IP). Cách này mình đã áp dụng cho toàn bộ stack microservices của công ty, cực kỳ an tâm và dễ quản lý.
Giải pháp 2: Dùng ufw-docker (Chuyên nghiệp và bài bản)
Nếu bạn muốn quản lý Docker bằng đúng phong cách “ngon-bổ-rẻ” của UFW, ufw-docker chính là chân ái. Đây là script giúp đồng bộ hóa luật lệ giữa Docker và firewall một cách hoàn hảo.
Đầu tiên, tải script về máy:
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
Sau đó, chạy lệnh khởi tạo để script tự động cấu hình lại các chain trong iptables:
ufw-docker install
Bây giờ, thay vì dùng ufw allow, bạn hãy dùng ufw-docker allow. Ví dụ, để mở port 80 cho container tên là web-app:
ufw-docker allow web-app 80/tcp
Mọi thứ sẽ hoạt động đúng như kỳ vọng: UFW nắm quyền sinh sát, không còn chuyện Docker tự ý “mở cửa” nữa.
Giải pháp 3: Can thiệp thủ công vào DOCKER-USER
Dành cho anh em thích “vọc” sâu, Docker để dành riêng một khu vực gọi là DOCKER-USER để chúng ta chèn các quy tắc tùy chỉnh. Các luật ở đây luôn được ưu tiên chạy trước khi Docker xử lý gói tin.
Bạn mở file cấu hình của UFW:
sudo nano /etc/ufw/after.rules
Và thêm đoạn code này vào cuối file:
# Chặn tất cả truy cập từ bên ngoài vào Docker mặc định
*filter
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
# Chỉ cho phép IP văn phòng (ví dụ 1.2.3.4) truy cập port 8080
-A DOCKER-USER -p tcp -m tcp --dport 8080 -s 1.2.3.4 -j RETURN
# Chặn tất cả những người lạ còn lại
-A DOCKER-USER -p tcp -m tcp --dport 8080 -j DROP
COMMIT
Cảnh báo nhẹ: Bạn cần hiểu rõ dải IP nội bộ (ví dụ: 172.17.0.0/16) để tránh cấu hình nhầm. Một sai sót nhỏ ở đây có thể khiến container bị “cô lập” hoàn toàn khỏi internet.
Tổng kết và lời khuyên
Docker tự ý mở port là một tính năng giúp app chạy ngay lập tức, nhưng trên môi trường Production, nó là rủi ro. Đừng để đến khi mất dữ liệu mới cuống cuồng đi tìm cách chặn port.
Tóm lại, anh em nên nhớ 3 nguyên tắc vàng:
- Service nội bộ: Luôn bind port vào
127.0.0.1. - Quản lý tập trung: Dùng
ufw-dockercho chuyên nghiệp. - Cảnh giác cao độ: Tuyệt đối không tắt
iptables: falsetrong filedaemon.jsonnếu không muốn hệ thống mạng của Docker bị vỡ vụn.
Bảo mật server là một hành trình dài. Hãy bắt đầu từ việc kiểm soát chặt chẽ từng cái port mà bạn mở ra hôm nay.

