Làm thế nào để chạy một máy chủ MongoDB an toàn với OpenVPN và Docker trên Ubuntu 16.04
MongoDB là một cơ sở dữ liệu NoSQL nguồn mở. Một thiết lập MongoDB truyền thống thiếu một số tính năng bảo mật mà bạn muốn nếu bạn lo ngại về bảo mật dữ liệu. Có một vài phương pháp để bảo mật máy chủ chạy cơ sở dữ liệu. Trước tiên, bạn có thể thiết lập VPN và hạn chế quyền truy cập chỉ những ...
MongoDB là một cơ sở dữ liệu NoSQL nguồn mở. Một thiết lập MongoDB truyền thống thiếu một số tính năng bảo mật mà bạn muốn nếu bạn lo ngại về bảo mật dữ liệu.
Có một vài phương pháp để bảo mật máy chủ chạy cơ sở dữ liệu. Trước tiên, bạn có thể thiết lập VPN và hạn chế quyền truy cập chỉ những khách hàng được kết nối với VPN. Sau đó, bạn có thể mã hóa lớp truyền tải giữa máy khách và máy chủ với các chứng chỉ. Bạn sẽ làm cả hai trong hướng dẫn này. Ngoài ra, bạn sẽ sử dụng Docker để chạy cá thể MongoDB của bạn, vì vậy bạn có thể đảm bảo khả năng sử dụng lại cấu hình và chứng chỉ MongoDB của bạn trên nhiều máy chủ.
Điều kiện tiên quyết
Để hoàn thành hướng dẫn này, bạn cần:
- Máy chủ OpenVPN mà bạn có thể thiết lập bằng cách làm theo hướng dẫn Cách thiết lập máy chủ OpenVPN trên Ubuntu 16.04. Đảm bảo bạn kiểm tra Mạng riêng khi tạo máy chủ.
- Một máy tính Ubuntu 16.04 với Docker được cài đặt. Đây là nơi bạn sẽ tạo ra hình ảnh DockoDB Docker của bạn, và nơi bạn sẽ chạy MongoDB trong một thùng chứa. Để tạo, nhấp Tạo các giọt trong bảng điều khiển quản lý DigitalOcean, hãy chọn Ứng dụng một lần nhấpvà sau đó chọn Docker 1.x vào 16.04. Bật mạng riêng trên máy chủ này.
- Một người dùng không phải root với quyền sudo trên cả hai máy chủ. Các Hướng dẫn cài đặt ban đầu cho Ubuntu 16.04 giải thích cách thiết lập.
- MongoDB được cài đặt trên máy cục bộ của bạn. Bạn sẽ sử dụng nó để kiểm tra kết nối đến máy chủ MongoDB của bạn.
Bước 1 - Cấu hình VPN để chuyển tiếp đến địa chỉ IP riêng
Nếu bạn theo dõi bài viết OpenVPN tiền đề, bạn có thể cấu hình máy chủ của bạn để chuyển tiếp các yêu cầu tới giao diện mạng công cộng, nhưng không phải là yêu cầu riêng tư. Trong hướng dẫn này, chúng ta sẽ cấu hình máy chủ MongoDB để nó chỉ có thể được truy cập trên giao diện riêng của nó, mà chúng ta chỉ có thể truy cập thông qua kết nối VPN của chúng ta. Chúng ta cần phải sửa đổi các quy tắc fowarding IP trên máy chủ VPN để lưu lượng từ các máy khách VPN cũng được định tuyến đến mạng riêng.
Kết nối với máy chủ OpenVPN của bạn.
ssh sammy@vpn_server_public_ip
Sau đó đi đến bảng điều khiển DigitalOcean, chọn VPN Droplet của bạn và tìm địa chỉ IP riêng của nó.
Khi bạn có địa chỉ IP riêng, hãy thực hiện lệnh này trên VPN Droplet của bạn để xác định giao diện mạng sử dụng địa chỉ IP đó:
sudo nano /etc/ufw/before.rules ip route | grep vpn_server_private_ip
Bạn sẽ thấy đầu ra tương tự như sau:
Output10.132.0.0/16 dev eth1 proto kernel scope link src vpn_server_private_ip
Lưu ý giao diện mạng trong đầu ra của bạn. Trong ví dụ này, giao diện là eth1nhưng bạn có thể khác.
Khi bạn đã xác định giao diện mạng riêng, hãy chỉnh sửa tệp /etc/ufw/before.rules:
sudo nano /etc/ufw/before.rules
Xác định vị trí phần bạn đã xác định trong hướng dẫn điều kiện tiên quyết, trông giống như sau:
/etc/ufw/before.rules
# START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] # Allow traffic from OpenVPN client to eth0 -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE COMMIT # END OPENVPN RULES
Thêm quy tắc mới cho giao diện mạng riêng:
/etc/ufw/before.rules
# START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] # Allow traffic from OpenVPN client to eth0 -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE -A POSTROUTING -s 10.8.0.0/8 -o eth1 -j MASQUERADE COMMIT # END OPENVPN RULES
Hãy chắc chắn để thay thế eth1 với giao diện cho mạng riêng của bạn. Sau đó lưu tệp và thoát khỏi trình chỉnh sửa.
Tắt và bật lại tường lửa:
sudo ufw disable sudo ufw enable
Sau đó đăng xuất khỏi máy chủ VPN của bạn.
exit
Bây giờ hãy thiết lập kết nối VPN từ máy tính cục bộ của bạn đến máy chủ VPN của bạn. Duy trì kết nối này trong suốt hướng dẫn này.
Bây giờ chúng ta hãy kết nối với máy chủ MongoDB bằng địa chỉ IP riêng của nó và cấu hình tường lửa của nó.
Bước 2 - Thiết lập tường lửa của máy chủ MongoDB
Chúng ta sẽ kết nối với máy chủ MongoDB bằng địa chỉ IP riêng của nó. Nếu bạn không có nó, hãy quay lại bảng điều khiển DigitalOcean và tìm địa chỉ IP riêng cho MongoDB Docker Droplet. Bạn sẽ sử dụng nó ở đây để kết nối với máy chủ, và sau đó bạn sẽ sử dụng nó để kết nối trực tiếp với MongoDB, vì chúng ta sắp giới hạn quyền truy cập vào máy chủ cơ sở dữ liệu cho các máy khách VPN. Bằng cách này, bạn tránh phơi bày cơ sở dữ liệu công khai, đó là một biện pháp bảo mật phải có.
Đảm bảo bạn đã kết nối với VPN của bạn và SSH đến máy chủ MongoDB bằng địa chỉ IP riêng của nó:
ssh sammy@mongodb_server_private_ip
Khi bạn đã đăng nhập, hãy xóa tất cả các quy tắc tường lửa hiện có để ngăn truy cập từ thế giới bên ngoài:
sudo ufw delete limit ssh sudo ufw delete allow 2375/tcp sudo ufw delete allow 2376/tcp
Sau đó, thêm hai quy tắc mới cho phép truy cập SSH và MongoDB chỉ từ các máy tính được kết nối với VPN của bạn. Để thực hiện điều đó, hãy sử dụng địa chỉ IP riêng của máy chủ VPN của bạn cho IP gốc:
sudo ufw allow from vpn_server_private_ip to any port 22 proto tcp sudo ufw allow from vpn_server_private_ip to any port 28018 proto tcp
Đảm bảo đây là hai quy tắc được định cấu hình duy nhất:
sudo ufw status
Bạn sẽ thấy kết quả sau:
OutputTo Action From -- ------ ---- 22/tcp ALLOW vpn_server_private_ip 28018/tcp ALLOW vpn_server_private_ip
Bật tường lửa và đăng xuất khỏi máy chủ:
sudo ufw enable exit
Sau đó đăng nhập lại vào máy chủ MongoDB để đảm bảo bạn vẫn có quyền truy cập vào máy chủ sau khi bật bộ lọc IP.
ssh sammy@mongodb_server_private_ip
Nếu bạn không thể thiết lập kết nối SSH, hãy đảm bảo bạn đã kết nối với VPN và bạn đã thiết lập máy chủ VPN để chuyển tiếp lưu lượng truy cập trên mạng riêng. Nếu điều đó không hiệu quả, hãy đăng nhập bằng cách sử dụng Bảng điều khiển DigitalOcean và kiểm tra các quy tắc tường lửa. Đảm bảo bạn đã chỉ định IP riêng của máy chủ VPN của bạn trong các quy tắc chứ không phải IP riêng của máy chủ MongoDB của bạn.
Để tìm hiểu thêm về UFW, hãy khám phá hướng dẫn UFW DigitalOcean này.
Bây giờ bạn đã cấu hình các biện pháp bảo mật cơ bản, hãy tiến hành cấu hình MongoDB.
Bước 3 - Tạo tệp cấu hình MongoDB
Trong bước này, chúng ta sẽ tạo một cấu hình MongoDB tùy chỉnh để cấu hình MongoDB sử dụng các chứng chỉ SSL.
Hãy tạo một cấu trúc thư mục để giữ cấu hình của chúng ta và các tệp liên quan. Chúng tôi sẽ tạo một thư mục có tên mongoconfvà sau đó tạo config bên trong thư mục đó cho các tệp cấu hình của chúng tôi. Trong config thư mục, chúng tôi sẽ tạo một thư mục có tên ssl , nơi chúng tôi sẽ lưu trữ chứng chỉ.
Tạo cấu trúc bằng lệnh sau:
mkdir -p ~/mongoconf/config/ssl
Sau đó chuyển sang ~/mongoconf/config thư mục:
cd ~/mongoconf/config
Mở một tệp mới có tên mongod.conf với trình soạn thảo văn bản của bạn:
nano mongod.conf
Đầu tiên, thiết lập cơ sở dữ liệu để liên kết với mọi giao diện mạng trên cổng 28018. Liên kết với 0.0.0.0 không phải là vấn đề bảo mật trong trường hợp này vì tường lửa sẽ không cho phép các kết nối từ thế giới bên ngoài. Nhưng chúng ta cần phải cho phép kết nối từ các máy khách bên trong VPN. Thêm phần sau vào tệp:
mongodb.conf
net: bindIp: 0.0.0.0 port: 28018
Cũng trong net , đặt đường dẫn đến chứng chỉ SSL và chỉ định cụm mật khẩu chứng chỉ. Chúng tôi sẽ sớm tạo các tệp chứng thực thực tế và cụm mật khẩu.
mongodb.conf
net: . . . ssl: CAFile: /etc/mongo/ssl/client.pem PEMKeyFile: /etc/mongo/ssl/server.pem PEMKeyPassword: test mode: requireSSL
Cuối cùng, đặt thư mục lưu trữ mặc định và bật nhật ký.
mongodb.conf
. . . storage: dbPath: /mongo/db journal: enabled: true
Để tìm hiểu về tất cả các tùy chọn cấu hình có sẵn, đọc tài liệu MongoDB.
Bây giờ, lưu tệp và thoát khỏi trình chỉnh sửa. Đã đến lúc tạo chứng chỉ SSL mà chúng tôi sẽ sử dụng.
Bước 4 - Tạo chứng chỉ SSL
Để bảo mật việc truyền dữ liệu, bạn cần tạo hai chứng chỉ SSL cho MongoDB - một cho máy chủ và một cho máy khách sẽ truy cập cơ sở dữ liệu.
Chú thích: Chúng tôi tạo chứng chỉ tự ký trong hướng dẫn này. Trong một môi trường sản xuất, bạn sẽ sử dụng một cơ quan cấp chứng chỉ tin cậy để tạo ra chúng.
Để làm điều đó, bạn cần thiết lập trình phân giải DNS riêng tư. Sau đó, sử dụng thử thách Hãy mã hóa DNS để xác thực tên miền mạng nội bộ mới được tạo và cấp chứng chỉ cho chúng.
Đầu tiên, thay đổi thành ~/mongoconf/config/ssl và tạo cặp khóa chứng chỉ máy chủ. Điền vào các lời nhắc với thông tin bạn chọn. Chú ý đến Common Name và PEM Passphrase lĩnh vực.
cd ~/mongoconf/config/ssl openssl req -new -x509 -days 365 -out server.crt -keyout server.key
Bạn sẽ thấy đầu ra sau và sẽ được yêu cầu cung cấp một số chi tiết trong quá trình thực hiện:
Server certificate-key generation. . . Enter PEM pass phrase: test Verifying - Enter PEM pass phrase: test . . . Common Name (e.g. server FQDN or YOUR name) []: mongodb_server_private_ip . . .
Khi bạn được yêu cầu nhập cụm từ PEM, hãy đảm bảo bạn sử dụng cùng một giá trị bạn đã sử dụng trong tệp cấu hình MongoDB của mình trong bước trước.
MongoDB không chấp nhận các tệp chứng chỉ và khóa riêng biệt, vì vậy hãy kết hợp chúng thành một tệp duy nhất .pem tập tin:
cat server.crt server.key >> server.pem
Tiếp theo, tạo cặp khóa chứng chỉ cho máy khách:
openssl req -new -x509 -days 365 -out client.crt -keyout client.key
Bạn sẽ thực hiện theo quy trình tương tự như trước đây, nhưng lần này, sử dụng IP riêng của máy chủ VPN. Cụm từ thông qua PEM có thể là bất cứ điều gì bạn muốn cho bước này.
Client certificate-key generation. . . Enter PEM pass phrase: secret_password Verifying - Enter PEM pass phrase: secret_password . . . Common Name (e.g. server FQDN or YOUR name) []: vpn_server_private_ip . . .
Kết hợp các tệp bạn vừa tạo thành một tệp .pem tập tin:
cat client.crt client.key >> client.pem
Tiếp theo, sao chép cả hai tệp chứng chỉ vào máy cục bộ của bạn để bạn có thể kết nối với máy chủ MongoDB từ xa. Bạn có thể làm điều này với scp lệnh trên máy cục bộ của bạn:
scp sammy@mongodb_server_private_ip:/home/sammy/mongoconf/config/ssl/{client.pem,server.pem} .
Ngoài ra, bạn có thể làm theo hướng dẫn Cách sử dụng SFTP để chuyển tệp an toàn bằng máy chủ từ xa để chuyển client.pem và server.pem tệp cho máy cục bộ của bạn.
Bây giờ chúng ta hãy tạo hình ảnh Docker và chạy công cụ cơ sở dữ liệu trong một thùng chứa để cấu hình này có thể di động hơn.
Bước 5 - Tạo hình ảnh DockoDB Docker và chạy Container
Bạn đã tạo cấu hình MongoDB an toàn và tạo các chứng chỉ. Bây giờ chúng ta hãy làm cho nó di động với Docker. Chúng tôi sẽ tạo một hình ảnh tùy chỉnh cho MongoDB, nhưng chúng tôi sẽ chuyển qua tệp cấu hình và chứng chỉ khi chúng tôi chạy vùng chứa.
Để xây dựng một hình ảnh, bạn cần một Dockerfile.
chú thích: Chạy docker không có sudo, thêm vào sammy đến docker nhóm:
sudo usermod -aG docker sammy
Sau đó đăng xuất khỏi máy chủ và đăng nhập lại để các quyền của nhóm mới có hiệu lực.
Chuyển sang thư mục gốc của dự án và mở một Dockerfile trống trong trình soạn thảo của bạn:
cd ~/mongoconf nano Dockerfile
Thêm phần sau vào tệp mới:
Dockerfile
FROM ubuntu:xenial RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 RUN echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list RUN apt-get update && apt-get install -y mongodb-org RUN mkdir -p /mongo/db /etc/mongo EXPOSE 28018 ENTRYPOINT ["mongod", "--config", "/etc/mongo/mongod.conf"]
Tập tin này cho Docker biết để tạo một hình ảnh dựa trên Ubuntu 16.04 Xenial, tải xuống các tệp nhị phân MongoDB mới nhất và tạo một vài thư mục nơi chúng tôi sẽ lưu trữ các tệp cấu hình và cơ sở dữ liệu. Nó làm cho cổng 28018 của vùng chứa có sẵn cho máy chủ và chạy Mongo mỗi khi người dùng khởi động lại vùng chứa.
Chú thích: Để đơn giản, hình ảnh của chúng tôi dựa trên Ubuntu. Tuy nhiên, các thùng chứa được xây dựng trên các bản phân phối nhẹ như Alpine Linux sử dụng ít không gian đĩa hơn.
Lưu tệp và thoát khỏi trình chỉnh sửa của bạn. Sau đó, xây dựng hình ảnh:
docker build -t mongo .
Khi hình ảnh được tạo, hãy chạy vùng chứa dựa trên hình ảnh. Chúng tôi sẽ gắn kết config thư mục dưới dạng một ổ đĩa bên trong vùng chứa để các cấu hình và khóa tùy chỉnh của chúng ta được hiển thị cho cá thể MongoDB bên trong thùng chứa:
docker run --detach --publish 28018:28018 --volume $PWD/config:/etc/mongo --name mongodb mongo
Bây giờ bạn có một cá thể MongoDB đang chạy, hãy truy cập nó từ máy tính cục bộ của bạn.
Bước 6 - Truy cập MongoDB
Trong một thiết bị đầu cuối mới trên máy cục bộ của bạn, hãy kết nối với cơ sở dữ liệu bằng địa chỉ IP riêng của máy chủ MongoDB. Bạn sẽ cung cấp các tệp client.pem và server.pem mà bạn đã tải xuống máy cục bộ của mình, cũng như cụm mật khẩu bạn đã sử dụng khi tạo chứng chỉ ứng dụng khách. Thực hiện lệnh này:
mongo --ssl --sslCAFile path_to_server_pem --sslPEMKeyFile path_to_client_pem --sslPEMKeyPassword pem_key_passphrase --host mongodb_server_private_ip --port 28018
Nếu mọi thứ đều ổn, bạn sẽ thấy dấu nhắc MongoDB.
Nếu lỗi xuất hiện, hãy kiểm tra kỹ xem bạn đang kết nối với IP riêng của máy chủ MongoDB chứ không phải đến địa chỉ IP của máy chủ VPN. Đồng thời xác minh rằng vị trí chính và cụm mật khẩu là chính xác và kết nối của bạn với VPN vẫn đang chạy.
Phần kết luận
Bây giờ bạn có một MongoDB được cấu hình tùy chỉnh đang chạy trong một thùng chứa Docker. Bảo mật của nó được cấp bởi xác thực máy khách-máy chủ SSL và mã hóa truyền tải. Bạn đã thêm bảo mật bổ sung bằng cách định cấu hình tường lửa để hạn chế các kết nối cơ sở dữ liệu cho các máy khách được kết nối với máy chủ VPN.
Mặc dù thiết lập này là tối ưu để thử nghiệm, hãy nhớ rằng trong môi trường sản xuất, bạn nên sử dụng cơ quan cấp chứng chỉ đáng tin cậy và các chứng chỉ đã ký. Ngoài ra, bạn phải phân tích nhu cầu bảo mật của bạn và hành động phù hợp. Ví dụ, bạn có thể muốn thiết lập người dùng, mật khẩu và vai trò trong cơ sở dữ liệu. Hướng dẫn Làm thế nào để cài đặt và bảo mật MongoDB trên Ubuntu 16.04 có thêm thông tin về việc tạo người dùng và là bước tiếp theo tuyệt vời hướng tới thiết lập sẵn sàng cho sản xuất.