1. Quick start (Khóa cổng ngay trong 5 phút)
Mặc định sau khi cài trên Ubuntu hay CentOS, MongoDB mở toang cửa mà không yêu cầu mật khẩu. Chỉ cần sơ ý mở port 27017 ra internet, các công cụ quét tự động như Shodan chỉ mất vài phút để dò ra database của bạn. Sau đây là các bước nhanh nhất để chặn đứng rủi ro này.
Bước 1: Tạo tài khoản root admin
Mở terminal trên server và truy cập vào shell MongoDB:
mongosh
Chuyển sang database admin và khởi tạo tài khoản quản trị tối cao:
use admin
db.createUser({
user: "siteRootAdmin",
pwd: "MatKhauCucKyPhucTap123!@#",
roles: [ { role: "root", db: "admin" } ]
})
exit
Bước 2: Bật xác thực trong file cấu hình
Mở file /etc/mongod.conf bằng quyền root:
sudo nano /etc/mongod.conf
Tìm đến mục security và bật tính năng authorization:
security:
authorization: enabled
Kiểm tra thêm mục net để đảm bảo MongoDB không bind bừa bãi ra ngoài:
net:
port: 27017
bindIp: 127.0.0.1
Bước 3: Khởi động lại dịch vụ và kiểm tra
sudo systemctl restart mongod
# Đăng nhập thử với user vừa tạo
mongosh -u siteRootAdmin -p --authenticationDatabase admin
Lúc này, mọi kết nối không kèm user/pass hợp lệ sẽ bị từ chối ngay lập tức.
2. Đi sâu vào 3 lớp phòng thủ cho Production
Đi dọn dẹp hạ tầng cho nhiều team, mình gặp kịch bản này hoài: dev tiện tay ném luôn user root vào file .env của 4-5 microservices. Khi một service dính lỗ hổng, hacker chiếm trọn cả cụm database. Muốn yên tâm ngủ ngon, bạn phải dựng đủ 3 lớp rào chắn: RBAC, TLS và Encryption at Rest.
Lớp 1: Phân quyền theo vai trò (RBAC)
Nguyên tắc sống còn: Cấp quyền vừa đủ. Backend service cần làm gì thì chỉ cho phép đúng quyền đó trên database chỉ định.
Ví dụ tạo tài khoản cho API backend với quyền readWrite riêng trên ecommerce_db:
use ecommerce_db
db.createUser({
user: "app_backend",
pwd: "AppSecurePassword_2026_!$",
roles: [
{ role: "readWrite", db: "ecommerce_db" }
]
})
Với mật khẩu database và các kết nối nội bộ, hãy tạo chuỗi ngẫu nhiên dài tối thiểu 24-32 ký tự. Bạn có thể dùng nhanh công cụ Password Generator của ToolCraft. Tiện ích này xử lý 100% tại trình duyệt (client-side), không đẩy dữ liệu về server nên tuyệt đối an toàn khi tạo secret key.
Lớp 2: Mã hóa đường truyền với TLS/SSL
Nếu server MongoDB và app backend nằm ở 2 VPS riêng biệt, dữ liệu chạy qua mạng có thể bị sniff nếu không bật TLS. Hãy gom cert và private key vào một file PEM duy nhất (ví dụ /etc/ssl/mongodb.pem).
Cấu hình TLS trong file /etc/mongod.conf:
net:
port: 27017
bindIp: 127.0.0.1,10.0.1.15
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.crt
Khởi động lại mongod và test kết nối kèm chứng chỉ CA:
mongosh --tls --tlsCAFile /etc/ssl/ca.crt -u app_backend -p --authenticationDatabase ecommerce_db
3. Nâng cao: Mã hóa dữ liệu lưu trữ (Encryption at Rest)
Mã hóa dữ liệu tại chỗ giúp bảo vệ dữ liệu khi ai đó vô tình làm rò rỉ snapshot ổ đĩa hoặc lấy cắp ổ cứng vật lý.
Phương án 1: Native WiredTiger Encryption (MongoDB Enterprise)
Bản Enterprise hỗ trợ mã hóa trực tiếp engine lưu trữ WiredTiger thông qua keyfile:
# Tạo keyfile 32 bytes ngẫu nhiên và phân quyền nghiêm ngặt
openssl rand -base64 32 | sudo tee /etc/mongodb-keyfile
sudo chown mongodb:mongodb /etc/mongodb-keyfile
sudo chmod 400 /etc/mongodb-keyfile
Khai báo đường dẫn keyfile trong /etc/mongod.conf:
security:
authorization: enabled
enableEncryption: true
encryptionKeyFile: /etc/mongodb-keyfile
Phương án 2: Mã hóa tầng Block Device (MongoDB Community)
Bản Community không có sẵn cờ enableEncryption. Cách tối ưu nhất là đặt thư mục dữ liệu /var/lib/mongodb lên phân vùng mã hóa cấp kernel (LUKS) hoặc dùng fscrypt. Dữ liệu, chỉ mục (index) và nhật ký ghi (journal) đều được mã hóa trong suốt. Mức độ suy giảm hiệu năng I/O thường chỉ rơi vào khoảng 2-4%, hoàn toàn chấp nhận được trên production.
4. Kinh nghiệm thực chiến khi vận hành
- Kiểm tra cú pháp YAML trước khi restart: File
mongod.confchỉ cần thụt sai một dấu space hoặc nhầm tab là service lập tức fail khi restart. Bạn có thể kiểm tra cấu trúc file bằng công cụ YAML ↔ JSON Converter để phát hiện sớm lỗi định dạng. - Chặn cổng bằng UFW Firewall: Chỉ cho phép đúng IP nội bộ của backend gọi vào port 27017:
sudo ufw default deny incoming sudo ufw allow from 10.0.1.20 to any port 27017 proto tcp sudo ufw reload - Cảnh giác với database profiler: Đừng bật
profile: 2(ghi lại toàn bộ truy vấn) trên production. Khi có lỗi đăng nhập hay update thông tin nhạy cảm, MongoDB có thể ghi trần trụi cả mật khẩu người dùng vào file/var/log/mongodb/mongod.log. - Luôn siết quyền file key ở mức 400: Mọi file chứng chỉ TLS và encryption keyfile phải thuộc sở hữu của user
mongodb:mongodbvà chỉ cho phép đọc (chmod 400). MongoDB sẽ tự động dừng khởi động nếu phát hiện quyền của file key quá lỏng lẻo.
