Thiết lập bảo mật máy chủ MongoDB

 

Giới thiệu

MongoDB là một cơ sở dữ liệu được sử dụng trong nhiều ứng dụng, web,... Nó là cơ sở dữ liệu NoSQL vì không dựa trên cấu trúc cơ sở dữ liệu quan hệ dựa trên bảng truyền thống. Thay vào đó, nó sử dụng các tài liệu giống JSON với các lược đồ động.

Theo mặc định MongoDB không bật xác thực theo mặc định, có nghĩa là bất kỳ người dùng nào có quyền truy cập vào máy chủ cơ sở dữ liệu được cài đặt đều có thể thêm và xóa dữ liệu mà không bị hạn chế. Để bảo mật lỗ hổng này, hướng dẫn này sẽ hướng dẫn bạn cách tạo người dùng quản trị và kích hoạt xác thực.



Điều kiện tiên quyết

Máy chủ chạy Ubuntu 22.04. MongoDB được cài đặt trên máy chủ của chúng ta. Nếu máy chủ chúng ta chưa cài đặt Mongo thì có thể tham khảo hướng dẫn sau : Hướng dẫn cài đặt MongoDB trên Ubuntu 22.04 LTS .

Tạo user quản trị

Để tạo user quản trị, đăng nhập vào MongoDB shell, hãy chạy lệnh sau bên dưới.

bash (root)
mongo

MongoDB shell sẽ được thực thi.

Kết quả
MongoDB shell version v5.0.9
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("6fbbef38-57b2-47c0-a1d0-a253ef7a5842") }
MongoDB server version: 5.0.9
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
    https://community.mongodb.com
---
The server generated these startup warnings when booting:
        2022-07-12T10:12:03.522+07:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
        2022-07-12T10:12:04.401+07:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>

Thực hiện 1 câu truy vấn dữ liệu như sau:

bash (root)
show dbs

Kết quả trả về toàn bộ database có trên máy chủ của chúng ta:

Kết quả
admin   0.000GB
config  0.000GB
local   0.000GB

Trong kết quả trên thì chỉ các cơ sở dữ liệu mặc định mới xuất hiện. Tuy nhiên, nếu chúng ta có bất kỳ cơ sở dữ liệu nào chứa dữ liệu nhạy cảm trên hệ thống, thì bất kỳ người dùng nào cũng có thể tìm thấy chúng bằng lệnh này.

Và MongoDB Shell sẽ cảnh báo chúng ta "The server generated these startup warnings when booting: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted" như vậy bất kỳ hành động nào liên quan đến đọc, ghi dữ liệu hoặc config sẽ đều không bị cấm.

Như vậy để giảm thiểu lỗ hổng này cần tiến hành tạo user quản trị, trước tiên ta cần kết nối đến Mongo shell:

bash (root)
mongo

Sau khi đã truy cập MongoDB Shell thực thi lệnh sau để quyền hạn của user được gán thông qua role userAdminAnyDatabase. DB admin được chỉ định là nơi sẽ lưu trữ thông tin xác thực:

bash (root)
use admin
db.createUser(
    {
        user: "123host",
        pwd: "123hostpassword",
        roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
    }
)

Kết quả trả về:

Kết quả
Successfully added user: {
    "user" : "123host",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

Đến đây chúng ta đã kết thúc quá trình tạo tài khoản quản trị cho Mongodb, chúng ta có thể thoát khỏi Mongodb shell bằng cách dùng lệnh exit hoặc CTRL+C

Tại thời điểm này, user 123host của chúng ta đã được phép sử dụng thông tin xác thực.

Bật Authentication

Để có thể bật Authentication chúng ta cần sửa file mongod.conf

bash (root)
vi /etc/mongod.conf

Chuyển đến dòng #security, bỏ comment # và thêm authorization: "enabled"

/etc/mongod.conf
security:
  authorization: "enabled"

Khởi động lại mongod

bash (root)
systemctl restart mongod

Kiểm tra xem authentication đã hoạt động chưa

Tiến hành truy cập lại mongoDB shell để kiểm tra xem authentication đã hoạt động chưa:

bash (root)
mongo

Kết quả trả về như sau không còn cảnh báo như trước nữa:

Kết quả
MongoDB shell version v5.0.9
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("cbc36865-5378-42cf-9ee0-1d8499dd96fc") }
MongoDB server version: 5.0.9
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
>

Sau khi đã tiến hành cấu hình bảo mật cho mongoDB tiến hành thực hiện 1 câu truy vấn dữ liệu như sau:

bash (root)
show dbs

Kết quả trả về như sau:

Kết quả
MongoServerError: command listDatabases requires authentication

Như vậy authentication của chúng ta đã được bật thành công cho mongdb.

Kiểm tra với tài khoản quản trị đã tạo trước đó

Thực thi lệnh sau:

bash (root)
mongo -u 123host -p --authenticationDatabase admin

Lưu ý: Thay 123host sang tài khoản quản trị mà bạn đã tạo trước đó.

Chúng ta sẽ được yêu cầu nhập vào password:

Kết quả
MongoDB shell version v5.0.9
Enter password:

Sau khi nhập đúng password sẽ có output như sau:

Kết quả
connecting to: mongodb://127.0.0.1:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("f55db66f-711b-4ae8-a0e6-9279ed0e34a3") }
MongoDB server version: 5.0.9
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
>

Từ đây chúng ta có thể thoải mái thực thi các câu lệnh truy vấn dữ liệu mà không lo gì về xác thực nữa.

bash (root)
show dbs

Kết quả trả về như sau:

Kết quả
admin   0.000GB
config  0.000GB
local   0.000GB

Thay đổi port mặc định mongoDB

Cũng giống như bất kỳ cơ sở dữ liệu khác, theo mặc định, MongoDB sẽ lắng nghe các kết nối trên một cổng đó là 27017. Chúng ta có thể sử dụng lệnh netstat để kiểm tra cỗng mà MongoDB đang lắng nghe.

bash (root)
netstat -lptn

Chúng ta có thể thấy mongoDB đã listen port 27017:

Kết quả
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 10.123.11.36:27017      0.0.0.0:*               LISTEN      7716/mongod
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      7716/mongod

Chúng ta có thể thay đổi cổng mặc định của mongoDB bằng cách tuỳ chỉnh phần net trong file /etc/mongod.conf:

/etc/mongod.conf
# network interfaces
net:
  port: 21233

Chúng ta có thể thay đổi sang port khác phù hợp theo nhu cầu của cá nhân.

Sau khi chúng ta đã thay đổi port mặc định của mongoDB thì chúng ta tiến hành khởi động lại dịch vụ mongoDB:

bash (root)
systemctl restart mongod

Tiến hành sử dụng lệnh netstat để kiểm tra lại port mà chúng ta đã tiến hành thay đổi cho dịch vụ mongoDB:

bash (root)
netstat -lptn

Chúng ta có thể thấy mongoDB đã listen port 21233:

Kết quả
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:21233         0.0.0.0:*               LISTEN      8593/mongod
tcp        0      0 10.123.11.36:21233      0.0.0.0:*               LISTEN      8593/mongod

Giới hạn IP lắng nghe

MongoDB liên kết với localhost theo mặc định. Đó là một mặc định tốt mà chúng ta có thể sẽ cần phải thay đổi trừ khi tất cả các máy client của chúng ta kết nối từ cùng một node.

Sử dụng tuỳ chọn net cấu hình để chỉ định địa chỉ IP mà máy client của chúng ta sẽ sử dụng để kết nối với máy chủ hoặc DNS bằng cách tiến hành tuỳ chỉnh trong file /etc/mongod.conf:

/etc/mongod.conf
# network interfaces
net:
  bindIp: localhost,10.123.11.36,mongodb0.replset.member

Lưu ý: Tránh sử dụng 0.0.0.0 làm IP và tuỳ chọn net.bindIpAll điều này sẽ khiến máy chủ lắng nghe trên tất cả các IP kết nối.

Sử dụng Unix domain sockets

Nếu kết nối từ cùng một node, chúng ta có thể xem xét việc tắt hoàn toàn tính năng lắng nghe cổng TCP và kết nối qua Unix domain sockets, trên các hệ thống dựa trên Unix.

Chúng ta có thể đặt đường dẫn socket làm IP và điều chỉnh quyền đối với file socket để cho phép kết nối bằng cách tuỳ chỉnh file /etc/mongod.conf:

/etc/mongod.conf
# network interfaces
net:
  bindIp: /tmp/mongodb-27017.sock
  unixDomainSocket:
    filePermissions: 0660

Chúng ta có thể sử dụng lệnh netstat để đảm bảo rằng máy chủ MongoDB không lắng nghe bất kỳ port nào:

bash (root)
netstat -lpten | grep mongo

Thiết lập Remote Access cho Mongodb

Nếu chúng ta cài đặt Mongodb trên một instance riêng biệt, hoặc vì một yêu cầu thiết lập kết nối đến Mongodb từ môi trường bên ngoài, chúng ta buộc phải thiết lập Remote Access cho Mongodb

Thiết lập UFW

Trước tiên chúng ta ta cần bật UFW và cài đặt để cho phép một IP cụ thể nào đó được kết nối đến instance chứa Mongodb thông qua cổng 27017

Kiếm tra trạng thái UFW

bash (root)
ufw status

Kết quả như sau:

Kết quả
Status: inactive

Nếu kết quả trả về là inactive, chúng ta cần phải kích hoạt lại:

bash (root)
ufw enable

Kết quả như sau:

Kết quả
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Cấu hình lại Public bindIp

Cho phép 1 IP cụ thể kết nối đến Mongodb

bash (root)
ufw allow from client_ip to any port 21233

Bởi vì client của chúng ta cần phải kết nối đến Mongodb thông qua public IP, do đó ngoài việc ràng buộc Mongodb listen tại 127.0.0.1, ta cần thông báo cho Mongodb để lắng nghe thêm tại public ip bằng cách thêm IP public của chúng ta vào file: /etc/mongod.conf

bash (root)
vi /etc/mongod.conf

Tìm đến đoạn bindIp: 127.0.0.1 và thêm địa chỉ IP public của chúng ta:

/etc/mongod.conf
# network interfaces
net:
  port: 21233
  bindIp: 127.0.0.1,mongodb0.replset.member,171.250.158.21

Khởi động lại Mongodb:

bash (root)
systemctl restart mongod

Kiểm tra Remote Access

Chúng ta có thể dùng lệnh sau để kiểm tra kết nối đến Mongodb instance

bash (root)
mongo -u myusername -p --authenticationDatabase admin --host mongo_instance_ip

Sau khi nhập mật khẩu chúng ta sẽ nhận được thông tin giống như khi mở Mongo shell tại local

Kết quả
MongoDB shell version v5.0.9
Enter password:
connecting to: mongodb://171.250.158.21:27017/
MongoDB server version: 5.0.9

Sử dụng xác thực X.509

Sử dụng xác thực server X.509

Cấu hình xác thực TLS của máy chủ cho phép kết nối của client để xác minh danh tính của máy chủ. Trước tiên, chúng ta cần lấy chứng chỉ TLS mà máy chủ của chúng ta sẽ hiển thị cho client và chứng chỉ CA mà client sẽ sử dụng để xác minh rằng chứng chỉ đã xuất trình được ký bởi một cơ quan đáng tin cậy.

Chúng ta có thể sử dụng certbot để nhận chứng chỉ TLS miễn phí từ Let's Encrypt hoặc chỉ cần tạo CA và ký chứng chỉ cục bộ bằng lệnh openssl.

Tiến hành tạo CA tự ký bằng cách thực hiện lệnh sau:

bash (root)
openssl req -sha256 -new -x509 -days 365 -nodes \
    -out server-ca.crt \
    -keyout server-ca.key

Tiếp theo tạo CSR của máy chủ bằng cách thực thi lệnh bên dưới:

bash (root)
openssl req -sha256 -new -nodes \
    -subj "/CN=mongo-123host.internal/O=ACME" \
    -out mongo-123host.csr \
    -keyout mongo-123host.key

Ký chứng chỉ máy chủ:

bash (root)
openssl x509 -req -sha256 -days 365 \
    -in mongo-123host.csr \
    -CA server-ca.crt \
    -CAkey server-ca.key \
    -CAcreateserial \
    -out mongo-123host.crt

Đối với các cụm nhiều node, hãy ký một chứng chỉ cho mỗi node. MongoDB yêu cầu chứng chỉ và khóa phải nằm trong cùng một file, vì vậy hãy đặt chúng lại với nhau trong một file PEM:

bash (root)
cat mongo-123host.crt mongo-123host.key > mongo-123host.pem

Bây giờ chúng ta có thể cập nhật cấu hình máy chủ để bật TLS. Chúng ta cũng nên tắt các phiên bản TLS cũ và buộc client sử dụng TLS 1.3, bằng cách cấu hình file /etc/mongod.conf tại phần net:

/etc/mongod.conf
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /root/mongo-123host.pem
    disabledProtocols: TLS1_0,TLS1_1,TLS1_2

Cho phép truy cập và ghi log

Để kiểm tra chi tiết là một phần không thể thiếu trong quá trình tăng cường bảo mật của bất kỳ hệ thống. MongoDB không cung cấp khả năng ghi nhật ký kiểm tra tích hợp trong phiên bản mã nguồn mở của nó. Chúng ta có thể bật tính năng ghi log.

Hệ thống ghi log của MongoDB dựa trên thành phần:

  • network: để bắt các kết nối
  • accessControl: để bắt thông tin xác thực
  • command và query: để nắm bắt hoạt động của mongoDB

Tiến hành bật trong cấu hình của mongoDB tại /etc/mongod.conf tại phần systemLog:

/etc/mongod.conf
systemLog:
  component:
    accessControl:
      verbosity: 1
    network:
      verbosity: 1
    command:
      verbosity: 1
    query:
      verbosity: 1
    write:
      verbosity: 1

Đăng nhận xét

0 Nhận xét

Liên hệ