Ubuntu 16.04でOpenVPNとDockerを使用して安全なMongoDBサーバーを実行する方法

http://mongodb.org [MongoDB]は、オープンソースのNoSQLデータベースです。 従来のMongoDBセットアップには、データのセキュリティが心配な場合に必要なセキュリティ機能がいくつか欠けています。

データベースを実行するサーバーを保護するには、いくつかの方法があります。 まず、VPNをセットアップし、VPNに接続されているクライアントのみにアクセスを制限できます。 その後、証明書を使用してクライアントとサーバー間のトランスポート層を暗号化できます。 このチュートリアルでは両方を行います。 さらに、https://www.docker.com/ [Docker]を使用してMongoDBインスタンスを実行します。これにより、複数のサーバーでMongoDB構成と証明書の再利用性を確保できます。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • OpenVPNサーバー。チュートリアルhttps://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04[How Ubuntu 16.04でOpenVPNサーバーをセットアップするには]。 サーバーを作成するときに、[プライベートネットワーキング]ボックスを必ずチェックしてください。

  • DockerがインストールされたUbuntu 16.04マシン。 ここでMongoDB Dockerイメージを作成し、MongoDBをコンテナーで実行します。 作成するには、DigitalOcean管理コンソールで* Create Droplet をクリックし、 One-click apps を選択してから、 Docker 1.x on 16.04 *を選択します。 このサーバーでもプライベートネットワークを有効にします。

  • 両方のサーバーでsudo特権を持つ非rootユーザー。 Ubuntu 16.04の初期セットアップガイドでセットアップ方法を説明しています。

  • https://www.mongodb.com/download-center?jmp=nav#community [ローカルマシンにインストールされたMongoDB]。 これを使用して、MongoDBサーバーへの接続をテストします。

ステップ1-プライベートIPアドレスに転送するためのVPNの構成

前提条件のOpenVPNの記事に従った場合、プライベートネットワークではなくパブリックネットワークインターフェイスにリクエストを転送するようにサーバーを構成した可能性があります。 このチュートリアルでは、VPN接続を介してのみアクセスできるプライベートインターフェイスでのみアクセスできるようにMongoDBサーバーを構成します。 VPNクライアントからのトラフィックがプライベートネットワークにもルーティングされるように、VPNサーバーのIP転送ルールを変更する必要があります。

OpenVPNサーバーに接続します。

ssh @

次に、DigitalOceanダッシュボードに移動して、VPNドロップレットを選択し、プライベートIPアドレスを見つけます。

プライベートIPアドレスを取得したら、VPNドロップレットで次のコマンドを実行して、そのIPアドレスを使用するネットワークインターフェイスを特定します。

sudo nano /etc/ufw/before.rules
ip route | grep

次のような出力が表示されます。

Output10.132.0.0/16 dev   proto kernel  scope link  src

出力のネットワークインターフェイスに注意してください。 この例では、インターフェースは「+ eth1 +」ですが、実際のインターフェースは異なる場合があります。

プライベートネットワークインターフェイスを特定したら、ファイル「+ / etc / ufw / before.rules」を編集します。

sudo nano /etc/ufw/before.rules

前提条件のチュートリアルで定義した次のようなセクションを見つけます。

/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

プライベートネットワークインターフェイスの新しいルールを追加します。

/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

`+ eth1 +`をプライベートネットワークのインターフェースに置き換えてください。 次に、ファイルを保存してエディターを終了します。

ファイアウォールを無効にしてから再度有効にします。

sudo ufw disable
sudo ufw enable

次に、VPNサーバーからログアウトします。

exit

次に、ローカルコンピューターからVPNサーバーへのVPN接続を確立します。 このチュートリアル全体でこの接続を維持します。

次に、プライベートIPアドレスを使用してMongoDBサーバーに接続し、ファイアウォールを構成しましょう。

ステップ2 – MongoDBサーバーのファイアウォールのセットアップ

プライベートIPアドレスを使用してMongoDBサーバーに接続します。 お持ちでない場合は、DigitalOceanダッシュボードに戻り、MongoDB Docker DropletのプライベートIPアドレスを見つけてください。 ここでサーバーに接続するために使用し、その後データベースサーバーへのアクセスをVPNクライアントに制限しようとしているので、後でそれを使用してMongoDBに直接接続します。 これにより、データベースを公開する必要がなくなります。これは、セキュリティ対策が必須です。

VPNに接続していることを確認し、プライベートIPを使用してMongoDBサーバーにSSH接続します。

ssh @

ログインしたら、既存のファイアウォールルールをすべて削除して、外部からのアクセスを防ぎます。

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  to any port 22 proto tcp
sudo ufw allow from  to any port 28018 proto tcp

これらが構成されている唯一の2つのルールであることを確認します。

sudo ufw status

次のような出力が表示されるはずです。

OutputTo                         Action      From
--                         ------      ----
22/tcp                     ALLOW
28018/tcp                  ALLOW

ファイアウォールを有効にして、サーバーからログアウトします。

sudo ufw enable
exit

次に、MongoDBサーバーに再度ログインして、IPフィルターを有効にした後もサーバーにアクセスできることを確認します。

ssh @

SSH接続を確立できない場合は、VPNに接続していることと、プライベートネットワークでトラフィックを転送するようにVPNサーバーを設定していることを確認してください。 それでもうまくいかない場合は、https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-console-to-access-your-droplet [DigitalOcean Console]を使用してログインし、チェックしますファイアウォールルール。 MongoDBサーバーのプライベートIPではなく、ルールでVPNサーバーのプライベートIPを指定したことを確認してください。

UFWの詳細については、https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04 [このDigitalOcean UFWチュートリアル]をご覧ください。 。

基本的なセキュリティ対策を構成したので、MongoDBの構成に進みます。

ステップ3-MongoDB構成ファイルの作成

このステップでは、SSL証明書を使用するようにMongoDBを構成するカスタムMongoDB構成を作成します。

構成と関連ファイルを保持するディレクトリ構造を作成しましょう。 `+ mongoconf `というディレクトリを作成し、その中に設定ファイル用の ` config `ディレクトリを作成します。 ` config `ディレクトリ内に、証明書を保存する ` ssl +`というディレクトリを作成します。

次のコマンドで構造を作成します。

mkdir -p ~/mongoconf/config/ssl

次に、 `+〜/ mongod conf / config`フォルダーに切り替えます。

cd ~/mongoconf/config

テキストエディタで「+ mongod.conf +」という新しいファイルを開きます。

nano mongod.conf

最初に、ポート `+ 28018 `上のすべてのネットワークインターフェースにバインドするようにデータベースを設定します。 この場合、「 0.0.0.0+」へのバインドはセキュリティの問題ではありません。ファイアウォールはいずれにしても外部からの接続を許可しないためです。 ただし、VPN内のクライアントからの接続を許可する必要があります。 ファイルに次を追加します。

mongodb.conf

net:
 bindIp: 0.0.0.0
 port: 28018

また、「+ net +」セクションで、SSL証明書へのパスを設定し、証明書のパスフレーズを指定します。 実際の証明書ファイルとパスフレーズをすぐに作成します。

mongodb.conf

net:
. . .
 ssl:
   CAFile: /etc/mongo/ssl/client.pem
   PEMKeyFile: /etc/mongo/ssl/server.pem
   PEMKeyPassword: test
   mode: requireSSL

最後に、デフォルトのストレージディレクトリを設定し、ジャーナリングを有効にします。

mongodb.conf

. . .
storage:
 dbPath: /mongo/db
 journal:
   enabled: true

利用可能なすべての構成オプションについては、https://docs.mongodb.com/manual/reference/configuration-options/ [MongoDBのドキュメントをご覧ください]をご覧ください。

ここでは、ファイルを保存してエディターを終了します。 使用するSSL証明書を生成します。

ステップ4-SSL証明書の生成

データ転送を保護するには、MongoDB用に2つのSSL証明書を生成する必要があります。1つはサーバー用で、もう1つはデータベースにアクセスするクライアント用です。

最初に、 `〜/ mongoconf / config / ssl +`ディレクトリに移動し、サーバー証明書とキーのペアを生成します。 プロンプトに選択した情報を入力します。 「 Common Name」および「+ PEM Pass Phrase」フィールドに注意してください。

cd ~/mongoconf/config/ssl
openssl req -new -x509 -days 365 -out server.crt -keyout server.key

次の出力が表示され、途中で詳細を入力するよう求められます。

Server certificate-key generation. . .
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
. . .
Common Name (e.g. server FQDN or YOUR name) []:
. . .

PEMパスフレーズの入力を求められたら、前のステップでMongoDB構成ファイルで使用したのと同じ値を使用していることを確認してください。

MongoDBは個別のキーと証明書ファイルを受け入れないため、それらを単一の `+ .pem +`ファイルに結合します。

cat server.crt server.key >>

次に、クライアントの証明書とキーのペアを生成します。

openssl req -new -x509 -days 365 -out client.crt -keyout

以前と同じプロセスに従いますが、今回は、VPNサーバーのプライベートIPを使用します。 PEMのパスフレーズは、このステップでどのようなものでも構いません。

Client certificate-key generation. . .
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
. . .
Common Name (e.g. server FQDN or YOUR name) []:
. . .

生成したファイルを単一の `+ .pem +`ファイルに連結します:

cat client.crt client.key >> client.pem

次に、両方の証明書ファイルをローカルマシンにコピーして、MongoDBサーバーにリモートで接続できるようにします。 ローカルマシンで `+ scp +`コマンドでこれを行うことができます:

scp @:/home//mongoconf/config/ssl/\{client.pem,server.pem\} .

または、チュートリアルhttps://www.digitalocean.com/community/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server[SFTPの使用方法リモートサーバーでファイルを安全に転送する]を選択して、 `+ client.pem `および ` server.pem +`ファイルをローカルマシンに転送します。

次に、Dockerイメージを作成し、コンテナでデータベースエンジンを実行して、この構成の移植性を高めましょう。

ステップ5-MongoDB Dockerイメージの作成とコンテナーの実行

安全なMongoDB構成を作成し、証明書を生成しました。 それでは、Dockerでポータブルにしましょう。 MongoDBのカスタムイメージを作成しますが、コンテナーを実行するときに構成ファイルと証明書を渡します。

イメージを構築するには、Dockerfileが必要です。

プロジェクトのルートディレクトリに切り替えて、エディターで空のDockerfileを開きます。

cd ~/mongoconf
nano Dockerfile

新しいファイルに次を追加します。

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を実行します。

ファイルを保存して、エディターを終了します。 次に、イメージをビルドします。

docker build -t mongo .

イメージが構築されたら、イメージに基づいてコンテナを実行します。 カスタム設定とキーがコンテナ内のMongoDBインスタンスから見えるように、コンテナ内のボリュームとして「+ config +」ディレクトリをマウントします。

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  \
--sslPEMKeyFile  \
--sslPEMKeyPassword  \
--host  \
--port 28018

すべてが正常であれば、MongoDBプロンプトが表示されるはずです。

エラーが表示される場合は、VPNサーバーのIPアドレスではなく、MongoDBサーバーのプライベートIPに接続していることを再確認してください。 また、キーの場所とパスフレーズが正しいこと、およびVPNへの接続がまだ実行されていることを確認します。

結論

これで、Dockerコンテナーで実行されるカスタム構成のMongoDBができました。 そのセキュリティは、SSLクライアントサーバー認証とトランスポート暗号化によって許可されます。 VPNサーバーに接続されたクライアントへのデータベース接続を制限するようにファイアウォールを構成することにより、セキュリティを追加しました。

このセットアップはテストに最適ですが、実稼働環境では、信頼できる認証局と署名付き証明書を使用する必要があることに注意してください。 さらに、セキュリティニーズを分析し、それに応じて行動する必要があります。 たとえば、データベースにユーザー、パスワード、およびロールを設定することができます。 チュートリアルhttps://www.digitalocean.com/community/tutorials/how-to-install-and-secure-mongodb-on-ubuntu-16-04[Ubuntu 16.04にMongoDBをインストールして保護する方法]の詳細についてはユーザーを作成することは、本番環境のセットアップに向けた優れた次のステップです。

Related