docker - Nginx:根据位置通过HTTPS到不同的目标
问题描述
我是 nginx 反向代理的完全菜鸟,如果这个问题很愚蠢,请原谅我。我的情况是我运行多个自行管理 HTTPS 证书的 docker 容器,我需要反向代理才能从浏览器访问它们。问题是证书需要在这些容器内进行管理,而不是从 nginx 反向代理。
我用谷歌搜索并尝试了很多东西,唯一有效的方法是将流直接传递到容器的本地地址。
events { }
stream {
server {
listen 443;
listen [::]:443;
proxy_pass 10.0.0.1:443;
}
}
当我使用流时(据我所知,这是通过所需的),我不知道如何区分我试图到达的目的地。
我需要使我能够执行以下操作的配置:
https://mail.example.com --> proxy_pass 10.0.0.1
https://mail.example.com --> proxy_pass 10.0.0.1
https://www.example.com --> proxy_pass 10.0.0.2
https://foo.example.com --> proxy_pass 10.0.0.2
有没有办法做到这一点?
解决方案
您正在寻找的是如何设置 SSL 直通代理(TCP 转发)并使用 SNI 信息进行路由。我不确定你是否可以使用 nginx 来做到这一点,因为在 nginx 中没有办法使用 SNI 信息来管道连接(据我所知)。
我尝试为此使用 docker-compose 创建一个 HAproxy 配置,并且它似乎可以按您的意愿工作。我使用 docker-compose 在一个网络中运行所有应用程序,因此您可以根据 docker-compose 中的名称访问其他服务。
./docker-compose.yml
version: '3'
services:
proxy:
image: haproxy:1.9.8
ports:
- "443:443"
volumes:
- "./haproxy:/usr/local/etc/haproxy"
mail:
image: mail # replace it with your app image, it must have port 443 open
ports:
- "445:443" # this port mapping is for debug purposes only, remove it after
foo:
image: foo
ports:
- "446:443"
./haproxy/haproxy.cfg
defaults
maxconn 1000
mode http
log global
option dontlognull # bind *:443 ssl crt .
timeout http-request 5s
timeout connect 5000
timeout client 2000000 # ddos protection
timeout server 2000000 # stick-table type ip size 100k expire 30s store conn_cur
frontend https
bind *:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend foo-servers if { req.ssl_sni -i foo.example.com }
use_backend mail-servers if { req.ssl_sni -i mail.example.com }
backend foo-servers
mode tcp
balance roundrobin
option ssl-hello-chk
server server1 foo:443 # You can use service name from docker-compose here
backend mail-servers
mode tcp
balance roundrobin
option ssl-hello-chk
server server1 mail:443
然后你可以运行它:
$ docker-compose up
然后确保您的应用程序正在运行:
$ curl -k https://localhost:445
mail service
$ curl -k https://localhost:446
foo service
最后我们可以测试我们的代理:
$ curl -k https://mail.example.com
mail service
$ curl -k https://foo.example.com
foo service
注意:为了让它工作,我将 mail.example.com 和 foo.example.com 添加到 /etc/hosts
127.0.0.1 mail.example.com
127.0.0.1 foo.example.com
PS。这是“foo”应用程序的 Dockerfile(相同的配置用于邮件):
./Dockerfile
FROM nginx:latest
COPY ssl.conf /etc/nginx/conf.d/ssl.conf
COPY mail.html /usr/share/nginx/html/index.html
COPY certs/mail.example.com.crt /etc/nginx/certs/
COPY certs/mail.example.com.key /etc/nginx/certs/
COPY certs/dhparam.pem /etc/nginx/certs/
./ssl.conf
server {
listen 443 http2 ssl;
ssl_certificate /etc/nginx/certs/mail.example.com.crt;
ssl_certificate_key /etc/nginx/certs/mail.example.com.key;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
root /usr/share/nginx/html;
location / {
}
}
创建自签名证书:
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout certs/foo.example.com.key -out certs/foo.example.com.crt
$ openssl dhparam -out certs/dhparam.pem 2048
构建图像:
$ docker build -t foo .
推荐阅读
- docker - Kubernetes 安装永远开始
- python - 为 JupyterHub 创建虚拟环境
- javascript - JavaScript 获取匹配前的文本
- c - 我需要用 C 语言为我的学校作业创建一个数字模式程序。模式- 1 141 14941
- tensorflow - 如何在具有使用@tf.keras.utils.register_keras_serializable 注册的自定义函数的 Tensorflow Serving 中提供模型?
- angular - 带有数学公式的羽毛笔编辑器在 Angular 中添加功能
- html - 响应式网页设计 - 浏览器缩放破坏了我的布局
- asp.net - 在主页中动态创建用户控件调用
- python - 如何使用 groupby 仅显示 1 个数字列的平均值
- azure - Azure B2C 会话导致意外流量