Ubuntu16.04でOpenVPNとDockerを使用して安全なMongoDBサーバーを実行する方法
MongoDB は、オープンソースのNoSQLデータベースです。 従来のMongoDBセットアップには、データセキュリティが心配な場合に必要なセキュリティ機能がいくつかありません。
データベースを実行するサーバーを保護するには、いくつかの方法があります。 まず、VPNを設定し、VPNに接続されているクライアントのみにアクセスを制限できます。 次に、クライアントとサーバー間のトランスポート層を証明書で暗号化できます。 このチュートリアルでは両方を行います。 さらに、 Docker を使用してMongoDBインスタンスを実行するため、複数のサーバー間でMongoDB構成と証明書の再利用性を確保できます。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- チュートリアルUbuntu16.04でOpenVPNサーバーをセットアップする方法に従ってセットアップできるOpenVPNサーバー。 サーバーを作成するときは、必ずプライベートネットワークボックスをオンにしてください。
- DockerがインストールされたUbuntu16.04マシン。 ここで、MongoDB Dockerイメージを作成し、コンテナーでMongoDBを実行します。 作成するには、DigitalOcean管理コンソールでドロップレットの作成をクリックし、ワンクリックアプリを選択してから、16.04でDocker1.xを選択します。 このサーバーでもプライベートネットワークを有効にします。
- 両方のサーバーでsudo権限を持つroot以外のユーザー。 Ubuntu 16.04の初期セットアップガイドでは、セットアップ方法について説明しています。
- ローカルマシンにインストールされたMongoDB。 これを使用して、MongoDBサーバーへの接続をテストします。
ステップ1—プライベートIPアドレスに転送するようにVPNを構成する
前提条件のOpenVPNの記事に従っている場合は、リクエストをパブリックネットワークインターフェイスに転送するようにサーバーを構成している可能性がありますが、プライベートネットワークインターフェイスには転送していません。 このチュートリアルでは、MongoDBサーバーを構成して、VPN接続を介してのみアクセスできるプライベートインターフェイスでのみアクセスできるようにします。 VPNクライアントからのトラフィックもプライベートネットワークにルーティングされるように、VPNサーバーのIP転送ルールを変更する必要があります。
OpenVPNサーバーに接続します。
ssh sammy@vpn_server_public_ip
次に、DigitalOceanダッシュボードに移動し、VPNドロップレットを選択して、そのプライベートIPアドレスを見つけます。
プライベートIPアドレスを取得したら、VPNドロップレットで次のコマンドを実行して、そのIPアドレスを使用するネットワークインターフェイスを特定します。
- sudo nano /etc/ufw/before.rules
- ip route | grep vpn_server_private_ip
次のような出力が表示されます。
Output10.132.0.0/16 dev eth1 proto kernel scope link src vpn_server_private_ip
出力のネットワークインターフェイスに注意してください。 この例では、インターフェースは eth1
、しかしあなたのものは異なるかもしれません。
プライベートネットワークインターフェイスを特定したら、ファイルを編集します /etc/ufw/before.rules
:
- sudo nano /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
プライベートネットワークインターフェイスの新しいルールを追加します。
# 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
必ず代用してください eth1
プライベートネットワークのインターフェイスを使用します。 次に、ファイルを保存してエディターを終了します。
ファイアウォールを無効にしてから再度有効にします。
- sudo ufw disable
- sudo ufw enable
次に、VPNサーバーからログアウトします。
- exit
次に、ローカルコンピューターからVPNサーバーへのVPN接続を確立します。 このチュートリアル全体を通して、この接続を維持してください。
次に、プライベートIPアドレスを使用してMongoDBサーバーに接続し、ファイアウォールを構成しましょう。
ステップ2–MongoDBサーバーのファイアウォールを設定する
プライベートIPアドレスを使用してMongoDBサーバーに接続します。 お持ちでない場合は、DigitalOceanダッシュボードに戻り、MongoDBDockerDropletのプライベートIPアドレスを見つけてください。 ここではこれを使用してサーバーに接続し、その後、データベースサーバーへのアクセスをVPNクライアントに制限しようとしているため、これを使用してMongoDBに直接接続します。 このようにして、データベースを公開することを回避できます。これは、必須のセキュリティ対策です。
VPNに接続していることを確認し、プライベートIPを使用してMongoDBサーバーにSSHで接続します。
ssh sammy@mongodb_server_private_ip
ログインしたら、既存のファイアウォールルールをすべて削除して、外部からのアクセスを防止します。
- sudo ufw delete limit ssh
- sudo ufw delete allow 2375/tcp
- sudo ufw delete allow 2376/tcp
次に、VPNに接続されているコンピューターからのみSSHとMongoDBへのアクセスを許可する2つの新しいルールを追加します。 これを行うには、オリジンIPにVPNサーバーのプライベートIPアドレスを使用します。
- 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
構成されているルールが2つだけであることを確認してください。
- sudo ufw status
次の出力が表示されます。
OutputTo Action From
-- ------ ----
22/tcp ALLOW vpn_server_private_ip
28018/tcp ALLOW vpn_server_private_ip
ファイアウォールを有効にして、サーバーからログアウトします。
- sudo ufw enable
- exit
次に、MongoDBサーバーに再度ログインして、IPフィルターを有効にした後もサーバーにアクセスできることを確認します。
ssh sammy@mongodb_server_private_ip
SSH接続を確立できない場合は、VPNに接続していることと、プライベートネットワークでトラフィックを転送するようにVPNサーバーを設定していることを確認してください。 それでも問題が解決しない場合は、 DigitalOcean Console を使用してログインし、ファイアウォールルールを確認してください。 MongoDBサーバーのプライベートIPではなく、VPNサーバーのプライベートIPをルールで指定していることを確認してください。
UFWの詳細については、このDigitalOceanUFWチュートリアルをご覧ください。
基本的なセキュリティ対策を構成したので、MongoDBの構成に進みます。
ステップ3—MongoDB構成ファイルを作成する
このステップでは、SSL証明書を使用するようにMongoDBを構成するカスタムMongoDB構成を作成します。
構成ファイルと関連ファイルを保持するディレクトリ構造を作成しましょう。 というディレクトリを作成します mongoconf
、次に作成します config
その中の構成ファイル用のディレクトリ。 以内 config
ディレクトリ、というディレクトリを作成します ssl
、証明書を保存します。
次のコマンドを使用して構造を作成します。
- mkdir -p ~/mongoconf/config/ssl
次に、に切り替えます ~/mongoconf/config
フォルダ:
- cd ~/mongoconf/config
と呼ばれる新しいファイルを開きます mongod.conf
テキストエディタで:
- nano mongod.conf
まず、ポート上のすべてのネットワークインターフェイスにバインドするようにデータベースを設定します 28018
. にバインドする 0.0.0.0
ファイアウォールはとにかく外界からの接続を許可しないため、この場合はセキュリティの問題ではありません。 ただし、VPN内のクライアントからの接続を許可する必要があります。 ファイルに以下を追加します。
net:
bindIp: 0.0.0.0
port: 28018
また、 net
セクションで、SSL証明書へのパスを設定し、証明書のパスフレーズを指定します。 実際の証明書ファイルとパスフレーズをまもなく作成します。
net:
. . .
ssl:
CAFile: /etc/mongo/ssl/client.pem
PEMKeyFile: /etc/mongo/ssl/server.pem
PEMKeyPassword: test
mode: requireSSL
最後に、デフォルトのストレージディレクトリを設定し、ジャーナリングを有効にします。
. . .
storage:
dbPath: /mongo/db
journal:
enabled: true
利用可能なすべての構成オプションについては、MongoDBのドキュメントをお読みください。
今のところ、ファイルを保存してエディターを終了します。 使用するSSL証明書を生成するときが来ました。
ステップ4—SSL証明書の生成
データ転送を保護するには、MongoDB用に2つのSSL証明書を生成する必要があります。1つはサーバー用で、もう1つはデータベースにアクセスするクライアント用です。
注:このチュートリアルでは、自己署名証明書を作成します。 実稼働環境では、信頼できる認証局を使用してそれらを生成します。
これを行うには、プライベートDNSリゾルバーを設定する必要があります。 次に、 Let’s Encrypt DNSチャレンジを使用して、新しく作成されたイントラネットドメインを検証し、それらの証明書を発行します。
まず、に変更します ~/mongoconf/config/ssl
ディレクトリを作成し、サーバーの証明書とキーのペアを生成します。 プロンプトに選択した情報を入力します。 に注意してください Common Name
と PEM Passphrase
田畑。
- cd ~/mongoconf/config/ssl
- openssl req -new -x509 -days 365 -out server.crt -keyout server.key
次の出力が表示され、途中で詳細を入力するように求められます。
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
. . .
PEMパスフレーズの入力を求められたら、前の手順でMongoDB構成ファイルで使用したのと同じ値を使用していることを確認してください。
MongoDBは個別のキーファイルと証明書ファイルを受け入れないため、それらを1つに結合します .pem
ファイル:
- cat server.crt server.key >> server.pem
次に、クライアントの証明書とキーのペアを生成します。
- openssl req -new -x509 -days 365 -out client.crt -keyout client.key
以前と同じプロセスに従いますが、今回はVPNサーバーのプライベートIPを使用します。 PEMパスフレーズは、このステップで好きなものにすることができます。
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
. . .
生成したファイルを1つに連結します .pem
ファイル:
- cat client.crt client.key >> client.pem
次に、両方の証明書ファイルをローカルマシンにコピーして、MongoDBサーバーにリモートで接続できるようにします。 あなたはこれを行うことができます scp
ローカルマシンでのコマンド:
- scp sammy@mongodb_server_private_ip:/home/sammy/mongoconf/config/ssl/\{client.pem,server.pem\} .
または、チュートリアルSFTPを使用してリモートサーバーでファイルを安全に転送する方法に従って転送することもできます。 client.pem
と server.pem
ローカルマシンへのファイル。
次に、Dockerイメージを作成し、コンテナーでデータベースエンジンを実行して、この構成の移植性を高めましょう。
ステップ5—MongoDBDockerイメージの作成とコンテナーの実行
安全なMongoDB構成を作成し、証明書を生成しました。 それでは、Dockerで移植できるようにしましょう。 MongoDBのカスタムイメージを作成しますが、コンテナーを実行するときに構成ファイルと証明書を渡します。
イメージを構築するには、Dockerfileが必要です。
注:実行するには docker
それなし sudo
、sammyをdockerグループに追加します。
- sudo usermod -aG docker sammy
次に、サーバーからログアウトして再度ログインし、新しいグループのアクセス許可を有効にします。
プロジェクトのルートディレクトリに切り替えて、エディタで空のDockerfileを開きます。
- cd ~/mongoconf
- nano 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"]
このファイルは、Ubuntu 16.04 Xenialに基づくイメージを作成し、最新のMongoDBバイナリをダウンロードし、構成ファイルとデータベースを保存するいくつかのディレクトリを作成するようにDockerに指示します。 ポートになります 28018
ホストが利用できるコンテナの数であり、ユーザーがコンテナを再起動するたびにMongoを実行します。
注:わかりやすくするために、イメージはUbuntuに基づいています。 ただし、Alpine Linuxのような軽量ディストリビューションで構築されたコンテナは、使用するディスク容量が少なくなります。
ファイルを保存して、エディターを終了します。 次に、イメージを作成します。
- docker build -t mongo .
イメージがビルドされたら、イメージに基づいてコンテナーを実行します。 マウントします config
コンテナ内のボリュームとしてディレクトリを作成し、カスタム構成とキーがコンテナ内のMongoDBインスタンスに表示されるようにします。
- docker run \
- --detach \
- --publish 28018:28018 \
- --volume $PWD/config:/etc/mongo \
- --name mongodb \
- mongo
これで、実行中のMongoDBインスタンスができたので、ローカルコンピューターからアクセスします。
ステップ6—MongoDBへのアクセス
ローカルマシンの新しい端末で、MongoDBサーバーのプライベートIPアドレスを使用してデータベースに接続します。 ローカルマシンにダウンロードしたclient.pemファイルとserver.pemファイル、およびクライアント証明書の作成時に使用したパスフレーズを提供します。 次のコマンドを実行します。
- mongo \
- --ssl \
- --sslCAFile path_to_server_pem \
- --sslPEMKeyFile path_to_client_pem \
- --sslPEMKeyPassword pem_key_passphrase \
- --host mongodb_server_private_ip \
- --port 28018
すべてが正常であれば、MongoDBプロンプトが表示されます。
-
エラーが表示された場合は、VPNサーバーのIPアドレスではなく、MongoDBサーバーのプライベートIPに接続していることを再確認してください。 また、キーの場所とパスフレーズが正しいこと、およびVPNへの接続がまだ実行されていることを確認してください。
結論
これで、Dockerコンテナーで実行されているカスタム構成のMongoDBができました。 そのセキュリティは、SSLクライアントサーバー認証とトランスポート暗号化によって付与されます。 VPNサーバーに接続されているクライアントへのデータベース接続を制限するようにファイアウォールを構成することにより、セキュリティを強化しました。
この設定はテストに最適ですが、実稼働環境では、信頼できる認証局と署名付き証明書を使用する必要があることに注意してください。 さらに、セキュリティのニーズを分析し、それに応じて行動する必要があります。 たとえば、データベースにユーザー、パスワード、および役割を設定したい場合があります。 チュートリアルUbuntu16.04にMongoDBをインストールして保護する方法には、ユーザーの作成に関する詳細情報があり、本番環境に対応したセットアップに向けた優れた次のステップです。