05/03/2012 09:17 | Thông tin công nghệ
- Trong bài viết sau, chúng tôi sẽ tiếp tục giới thiệu với các bạn về tính năng Security và Authentication trong loạt bài viết về hệ quản trị cơ sở dữ liệu MongoDB. Thực chất, tính năng xác nhận tài khoản ở mức cơ bản đã có sẵn trong MongoDB, nhưng đã bị tắt bỏ ở chế độ mặc định, và ở chế độ này thì hệ thống yêu cầu ít nhất 1 database hoạt động trong môi trường đảm bảo (hạn chế kết nối mạng).
Đây là tùy chọn mặc định và được khuyến cáo sử dụng, tỏ ra khá hữu ích khi chạy cơ sở dữ liệu trong Trusted Environment mà không có chức năng bảo mật từ bên trong database cũng như xác nhận tài khoản (hay còn gọi là memcached). Tất nhiên, trong quá trình cấu hình thì 1 yêu cầu tối thiểu cần đảm bảo là chỉ những máy nhất định nào đó mới được phép truy cập tới cơ sở dữ liệu qua cổng TCP.
Phiên bản hiện tại của Mongo chỉ hỗ trợ cơ chế bảo mật ở mức cơ bản. Người sử dụng xác nhận thông tinUsername và Password trong 1 database nhất định nào đó. Khi quá trình này hoàn tất thì 1 tài khoản người dùng thông thường sẽ có đầy đủ quyền truy cập đọc và ghi dữ liệu tới cơ sở dữ liệu, bên cạnh đó thì chúng ta còn có thể tạo được các tài khoản chỉ có quyền đọc (read only) tùy theo yêu cầu.
Tuy nhiên, cơ sở dữ liệu admin là 1 trường hợp đặc biệt, một vài câu lệnh quản trị chỉ có thể hoạt động trên database admin này (và cũng chỉ được thực thi dưới tài khoản có quyền quản trị). Và mặt khác, quá trình xác nhận trên admin cũng cho phép người dùng đọc và ghi tới tất cả cơ sở dữ liệu trên server.
Mặc dù, các tài khoản quản trị có thể truy cập tới tất cả database thì chúng ta phải đăng nhập vào cơ sở dữ liệu admin. Ví dụ, nếu tài khoản someAdminUser có quyền admin thì lệnh đăng nhập dưới đây sẽ thất bại:
> use test
> db.auth("someAdminUser", password)
Còn lệnh sau sẽ thành công:
> use admin
> db.auth("someAdminUser", password)
Để kích hoạt tính năng bảo mật, hãy chạy cơ sở dữ liệu (quá trình mongod) với lựa chọn --auth (hoặc --keyFile để sharding và tạo bản sao). Người dùng bắt buộc phải gán tài khoản tới database admin trước khi khởi động server với quá trình xác nhận, hoặc gán tài khoản người dùng đầu tiên từ localhost (không thể gán người dùng đầu tiên từ kết nối không liên quan tới database của mongo).
Các bạn có thể tham khảo thêm về các khái niệm tương ứng của Python, Ruby, Java và PHP.
Việc trước tiên cần làm ở đây là tạo tài khoản administrator để sử dụng cho toàn bộ server. Và tài khoản này được lưu trữ trong 1 cơ sở dữ liệu admin đặc biệt. Còn nếu không có tài khoản admin thì có thể truy cập tới database từ giao diện localhost mà không cần phải xác nhận. Do vậy, từ server đang chạy cơ sở dữ liệu (hoặc localhost) hãy chạy shell và cấu hình tài khoản quản trị như sau:
$ ./mongo
> use admin
> db.addUser("theadmin", "anadminpassword")
Và chúng ta đã có tài khoản người dùng được tạo trong cơ sở dữ liệu admin. Lưu ý rằng nếu chưa tiến hành xác nhận tài khoản thì phải thực hiện ngay nếu muốn thực hiện thêm nhiều thao tác khác.
> db.auth("theadmin", "anadminpassword")
Tiếp theo, khởi tạo 1 tài khoản người dùng bình thường đối với cơ sở dữ liệu khác.
> use projectx
> db.addUser("joe", "passwordForJoe")
Và cuối cùng, gán tài khoản người dùng readonly (chỉ hỗ trợ từ phiên bản 1.3.2 trở lên):
> use projectx
> db.addUser("guest", "passwordForGuest", true)
Về cơ bản, toàn bộ thông tin của người dùng được lưu trữ trong từng collection system.users của database. Ví dụ, trên cơ sở dữ liệu projectx thì projectx.system.users chính là thành phần lưu trữ thông tin cần tìm. Chúng ta có thể xem các tài khoản có sẵn trong database hiện tại với câu lệnh query:
> db.system.users.find()
Lệnh shell addUser bên cạnh chức năng cơ bản còn được dùng để thay đổi mật khẩu trong trường hợp nếu tài khoản người dùng đã có sẵn, thì mật khẩu chỉ cần cập nhật. Một số driver Mongo còn cung cấp chức năng tương đương trong cú pháp addUser của database shell.
Để thực hiện việc này, các bạn hãy áp dụng lệnh:
db.removeUser( username )
hoặc:
db.system.users.remove( { user: username } )
Replica set và sharding có thể sử dụng cơ chế xác nhận tài khoản trong phiên bản v1.9.1 hoặc mới hơn (còn trong phiên bản v1.8 thì chỉ có replica set và không có sharding). Từ phía client, quá trình này tương đối đồng nhất để sử dụng cơ chế xác nhận trên server single: thực hiện kết nối tới hệ thống mongos, tạo tài khoản người dùng, và kiểm tra, giám sát người dùng đó khi tạo kết nối.
Điểm khác biệt duy nhất ở đây là server sẽ sử dụng key file để xác nhận các thông tin liên lạc bên trong. Về cơ bản thì key file chỉ là 1 file text đơn thuần đã được mã hóa bằng thuật toán hash và được dùng như mật khẩu bên trong.
Để thiết lập replica set hoặc sharding với cơ chế xác nhận, các bạn cần thực hiện theo quy trình sau:
Khi người dùng kích hoạt cơ chế xác nhận trên các cluster sharded thì toàn bộ kết nối bên trong sẽ được bảo mật thông qua toàn bộ mongos chứ không phải một nguồn dữ liệu riêng lẻ nào, giống như server single hoặcreplica set. Đây cũng là 1 phần không thể thiếu trong hệ thống bởi vì thông tin, dữ liệu bảo mật được lưu trữ trong cơ sở dữ liệu cấu hình sharding chứ không phải trực tiếp trên shard. Một điều quan trọng nữa là nhữngcluster shard phải luôn luôn có máy client kết nối qua mongos chứ không phải trực tiếp tới bất kỳ nguồn dữ liệu nào như server shard hoặc server cấu hình.
Nếu các bạn không gán từng tài khoản người dùng trên nguồn shard cũng như từng thành viên shard riêng rẽ thì những tài khoản đó sẽ hoàn toàn riêng biệt khỏi người dùng sharding. 2 nguồn tài khoản này khác vớicluster sharded và shard, người sử dụng nên tuyệt đối cẩn thận khi phân việt và áp dụng vào thực tế.
Để kích hoạt cơ chế này trên cluster đã có sẵn, các bạn hãy tắt hoạt động của toàn bộ thành viên người dùng trong hệ thống, sau đó khởi động lại với tùy chọn --keyFile. Và hãy ghi nhớ rằng phải gán tài khoản người dùng trước khi truy cập đến lượng dữ liệu từ xa. Ngược lại, nếu muốn tắt bỏ cơ chế nhận dạng thì chỉ cần khởi động lại toàn bộ hệ thống người dùng mà không có thông số --keyFile.
1 key file điển hình phải có chứa ít nhất 6 ký tự Base64, dung lượng không quá 1KB (tính cả khoảng trắng). Những ký tự khoảng trắng này khá đơn giản (chủ yếu là dễ tương thích với nhiều nền tảng khác nhau) cho nên một số key đặc biệt dưới đây được quy chuẩn và áp dụng trên nhiều hệ thống database:
$ echo -e "my secret key" > key1
$ echo -e "my secret key\n" > key2
$ echo -e "my secret key" > key3
$ echo -e "my\r\nsecret\r\nkey\r\n" > key4
Nếu bạn chạy lệnh mongod với tham số -v thì các key sẽ được lưu vào file log.
Trên *NIX, các nhóm và tài khoản người dùng cá nhân phải có permission 0 (tối đa là 700), nếu mức permission này không được kiểm soát đầy đủ thì MongoDB sẽ kết thúc đi kèm với lỗi hiển thị. Và tại thời điểm này, permission không được kiểm tra bởi mongod trên Windows.
Giá trị cổng TCP mặc định dành cho MongoDB như sau:
Bên cạnh đó, các bạn có thể thay đổi cổng bằng giá trị port ngay khi khởi động mongod. Lưu ý rằng chúng ta không nên dựa vào những cổng non standard như 1 phương pháp bảo mật server Mongo. Những công cụ chuyên rà soát lỗ hổng sẽ lợi dụng điều này để tìm kiếm điểm yếu trên hệ thống của người dùng.
Ở chế độ mặc định, server mongod sẽ “lắng nghe” tất cả các địa chỉ IP trên toàn bộ hệ thống máy tính. Tuy nhiên, người dùng có thể hạn chế hoặc cấm 1 địa chỉ IP nào đó qua tùy chọn thiết lập bind_ip dành chomongod. Thông thường, những giá trị này sẽ được chuyển thành 127.0.0.1, qua giao diện loopback để yêu cầu mongod chỉ được “chấp nhận” các tín hiệu từ những máy giống nhau (tương tự như localhost). Để thay đổi lại, chúng ta chỉ cần loại bỏ tùy chọn bind_ip từ file cấu hình trên server.