您正在寻找的是如何设置 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 .