私の問題を投稿する前に、私が望むことを達成することさえ可能かどうかを知りたいです。
たとえば、myserver.comでnginxとletsencryptを使用してDockerコンテナーを実行しています。同じサーバー上に、Webサイトを実行しているさらに2つのDockerコンテナーがあります。
現時点ではすべてが正常にリダイレクトされるため、www.myserver.comはdocker 1に移動し、site2.myserver.comはdocker 2に移動します。
すべての通信をHTTPSで実行したいのですが、ここで問題が発生します。したがって、私の質問は、nginxとletsencryptを使用するdockerが、letsencryptからの証明書を使用して別のdockerに接続することは可能ですか?私にとって、それはある種の中間者「攻撃」のようです。もう少し回路図:
Http:// site2.myserver.com-> nginxにアクセスしてhttps:// site2.myserver.comにリダイレクトします->ポート80でコンテナ2(192.168.0.10)に接続します。または、別のオプション:http://にアクセスしますsite2.myserver.com-> nginxはhttps:// site2.myserver.comにリダイレクトします-> site2.myserver.com証明書を持つポート443のコンテナー2(192.168.0.10)に接続します。
それができない場合、解決策は何ですか?証明書をDockerコンテナーにコピーしてhttpsを実行させると、httpリクエストがそのコンテナーのhttpsポートにリダイレクトされますか?
Http:// site2.myserver.comにアクセスします-> nginxがリクエストを転送します-> site2.myserver.com証明書を持つポート443でコンテナ2(192.168.0.10)に接続します。
ありがとう、グレギー
私が理解しているように、あなたのnginxリバースプロキシはコンテナと同じネットワーク上にあるので、TLSでそれらの間の接続を保護する必要はあまりありません(これはプライベートネットワークであり、攻撃者がそのネットワークにアクセスできる場合、彼はサーバーへのアクセス、およびすべての暗号化されていないデータ)。
ローカルネットワーク上の接続を保護するために有効な証明書が絶対に必要な場合は、ローカルIPに解決する追加のサブドメインを作成できます。次に、手動DNSオプションを使用して証明書を取得する必要があります(これは、ドメインのTXTエントリとしてキーを手動で入力する必要があるcertbotオプションです)。
server {
listen 80;
server_name example.com;
return 301 https://example.com/;
}
server{
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
location / {
proxy_pass http://container:8080/;
proxy_set_header Host $Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
include tls.conf;
}
これが私のやり方です:
https://github.com/KyleAMathews/docker-nginx のDockerイメージを使用して、次のようにカスタムのデフォルトファイルを作成しました。
server {
root /var/www;
index index.html index.htm;
server_name localhost MYHOST.COM;
# Add 1 week expires header for static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1w;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
try_files $uri $uri/ @root;
return 301 https://$Host$request_uri;
}
# If nginx can't find a file, fallback to the homepage.
location @root {
rewrite .* / redirect;
}
include /etc/nginx/basic.conf;
}
これが私のDockerfileです。静的コンテンツがhtml /ディレクトリの下にあることを考慮しています。
COPY conf/default.conf /etc/nginx/sites-enabled/default
ADD certs/myhost.com.crt /etc/nginx/ssl/server.crt
ADD certs/myhost.com.key /etc/nginx/ssl/server.key
RUN ln -s /etc/nginx/sites-available/default-ssl /etc/nginx/sites-enabled/default-ssl
COPY html/ /var/www
CMD 'nginx'
ローカルテストの場合は、myhost.comを127.0.0.1に追加してファイル/ etc/hostsを変更し、次のコマンドを実行します。
curl -I http://www.myhost.com/
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 04 Mar 2018 04:32:04 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://www.myhost.com/
X-UA-Compatible: IE=Edge
私はすぐに使えるソリューションで行きます:
JWilder Nginx +暗号化しましょう。
まず、NGINX Containerをリバースプロキシとして起動します。
docker run -d -p 80:80 -p 443:443 \
--name nginx-proxy \
-v /path/to/certs:/etc/nginx/certs:ro \
-v /etc/nginx/vhost.d \
-v /usr/share/nginx/html \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
jwilder/nginx-proxy
次に、Lets Encryptコンテナを開始します。
docker run -d \
-v /path/to/certs:/etc/nginx/certs:rw \
--volumes-from nginx-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
jrcs/letsencrypt-nginx-proxy-companion
あなたのウェブサイトでは、いくつかの環境変数を設定する必要があります:
docker run -d \
--name website1 \
-e "VIRTUAL_Host=website1.com" \
-e "LETSENCRYPT_Host=website1.com" \
-e "LETSENCRYPT_EMAIL=webmaster@website1" \
tutum/Apache-php
Nginxコンテナは彼の設定に新しいエントリを作成し、レット暗号化コンテナは証明書を要求します(そして更新を行います)。
もっと: Nginx + LetsEncrypt
いいですね、opHASnoNAMEとPaul Trehiouの答えをマージすることで、最終的に私が望んでいたものを得ることができました。 opHASnoNAMEの答えの追加として私がしたことは、nginxとletsencrypt Dockerの間にファイルシステムをマウントすることです。 nginxの設定ファイルを適切な証明書にリンクすることができます(後述)。
これは私がやったことです:
docker run --name nginx-prod --restart always -d -p 80:80 -p 443:443 -v /choose/your/dir/letsencrypt:/etc/nginx/certs:ro -v /etc/nginx/vhost.d -v /usr/share/nginx/html -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_Host=myserver.com jwilder/nginx-proxy
docker run --name letsencrypt --restart always -d -v /choose/your/dir/letsencrypt:/etc/nginx/certs:rw --volumes-from nginx-prod -v /var/run/docker.sock:/var/run/docker.sock:ro jrcs/letsencrypt-nginx-proxy-companion
次に、Webサーバーで任意のコンテナーを実行します。 LETSENCRYPT変数を設定する必要はありません。現在のコンテナは設定しなくてもアクセスできます。
Jwilder/nginx-proxyは、/ etc/nginx/conf.d/default.confで実行中のすべてのコンテナをリストします。次の再起動時に上書きされるため、このファイルには何も追加しないでください。 Webサーバーごとに、同じディレクトリに新しい.confファイルを作成します。このファイルには、Paul Trehiouによって提案されたhttps情報が含まれます。私は例site2.confを作成しました:
server{
listen 443 ssl http2;
server_name site2.myserver.com;
ssl_certificate /etc/nginx/certs/live/myserver.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/myserver.com/privkey.pem;
ssl_trusted_certificate /etc/nginx/certs/live/myserver.com/fullchain.pem;
location / {
proxy_pass http://192.168.0.10/;
proxy_set_header Host $Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Proxy_passアドレスは、default.confファイルから取得できるものであり、IPアドレスは各コンテナーにそこにリストされます。これらの.confファイルをバックアップできるように、nginxコンテナーを再作成して、ローカルファイルシステムを/etc/nginx/conf.dにマウントします。 .confファイルのエラーが原因でコンテナが起動しない場合にも、これは容易になります。
あなたのご意見をありがとうございました。パズルが完成しました;-)