Hướng dẫn bảo mật MongoDB Server trên Linux: Cấu hình RBAC, TLS và Encryption at Rest

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

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.conf chỉ 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:mongodb và 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.
Share: