资讯动态

Docker化多服务共存:Nginx 443 SNI 实现多 HTTPS 站点与加密通信无缝部署

发布时间:2026/9/10 1:53:28 来源:尧图企业网站定制
Docker化多服务共存Nginx 443 SNI 实现多 HTTPS 站点与加密通信无缝部署Docker 化多服务共存实战Nginx 443 端口 SNI 分流实现多 HTTPS 站点与加密通信服务无缝部署郑重声明本文所有内容仅用于技术学习与合法合规的企业远程办公、跨地域内网加密访问、安全数据传输场景请严格遵守《中华人民共和国网络安全法》等相关法律法规严禁用于任何违法违规行为。前言在单台 Linux 服务器的日常运维中我们常常会遇到一个核心的技术痛点一台服务器需要同时部署多个带独立 SSL 证书的 HTTPS Web 站点同时还要运行一套稳定的 TLS 加密通信服务而 HTTPS 协议默认使用的 443 端口在同一台服务器上只能被一个进程独占监听极易出现端口冲突导致多个服务无法同时正常运行。传统的部署方案要么只能让服务共用端口、强耦合绑定要么需要牺牲 HTTPS 标准端口、改用非默认端口访问不仅运维复杂度高还会影响服务的兼容性与稳定性。本文将分享一套生产环境可用、全 Docker 化部署的Nginx 4 层 SNI 流量分流架构彻底解决 443 端口复用难题实现多 HTTPS 站点与加密通信服务的完全解耦、稳定共存全程配置简洁、扩展性强新手也能快速落地。一、核心架构与技术原理解析本方案采用「Nginx 4 层 TCP 流量预读 SNI 域名精准分流」为核心架构全程不破坏 TLS 加密流量的完整性完美解决端口冲突与服务解耦的核心需求核心逻辑如下1. 核心痛点解决思路我们需要同时运行两类基于 TLS 加密的服务对外提供访问的 HTTPS Web 站点需要通过 443 端口对外提供服务Trojan-Go 加密通信服务同样需要基于标准 TLS 协议、通过 443 端口完成加密通信握手如果直接让两个服务同时监听服务器的 443 端口必然会出现端口占用冲突。因此我们采用Nginx 前置统一监听的方案让 Nginx 成为唯一监听公网 443 端口的进程再通过流量特征精准分发到对应的后端服务。2. 关键技术SNI 域名预读分流SNIServer Name Indication是 TLS 协议的扩展字段客户端在发起 TLS 握手时会携带当前要访问的目标域名信息。本方案利用 Nginx 的stream模块与ssl\_preread特性实现无解密流量分流Nginx 在接收到 443 端口的 TLS 流量时不会终止 TLS 握手也不会对流量进行解密仅通过ssl\_preread预读取 TLS 握手包中的 SNI 域名信息识别客户端的访问目标根据预设的分流规则将原始 TLS 流量原封不动地转发到对应的后端服务后端服务Web 站点 / 加密通信服务自行完成 TLS 握手与业务处理互不干扰3. 为什么不能用 Nginx 的 http 模块做转发这里是整个方案的核心技术要点Nginx 的http模块是 7 层应用层的代理模块当接收到 HTTPS 流量时会自动终止 TLS 握手、解密流量后再进行转发。而 Trojan-Go 加密通信服务的核心校验逻辑依赖客户端发送的完整、未经修改的原始 TLS 加密流量如果经过 http 模块解密后再转发Trojan-Go 服务无法完成正常的加密通信校验会直接导致服务异常。而 Nginx 的stream模块是 4 层传输层的代理模块仅做 TCP 流量的转发不会触碰 TLS 加密内容完美满足原始流量透传的需求。4. 最终流量流转架构客户端公网请求 → 服务器443端口 → Nginx stream模块监听 ↓ SNI域名预读识别 ↙️ ↘️ 访问Web站点域名流量 访问加密通信服务域名流量 ↓ ↓ 转发至Web服务后端 转发至Trojan-Go服务后端 Nginx http模块4443端口 Docker容器映射1443端口 ↓ ↓ 完成TLS握手返回Web内容 完成加密通信校验与业务处理5. 方案核心优势✅ 彻底解决 443 端口冲突所有服务均可基于标准 HTTPS 端口对外提供服务✅ 全 Docker 化部署服务之间完全解耦重启 / 升级 / 扩容互不影响✅ 多域名独立证书支持Web 站点与加密通信服务可使用完全隔离的 SSL 证书✅ 原始流量无损透传不破坏 TLS 加密完整性无额外的性能损耗✅ 配置简洁易扩展新增 Web 站点仅需修改分流规则与站点配置无需重构架构二、前置准备工作一台 Linux 服务器推荐 Debian 11/Ubuntu 20.04/CentOS 7兼容主流 Linux 发行版至少 2 个已完成合规备案国内服务器需完成 ICP 备案的域名示例如下Web 站点域名site1\.yourdomain\.com可扩展多个站点域名加密通信服务域名tls\-service\.yourdomain\.com所有域名已正确解析到服务器的公网 IP 地址服务器防火墙 / 安全组已放行80、443 端口TCP 协议已获取服务器 root 或 sudo 管理员权限完成基础系统环境初始化已为各域名申请好对应的 SSL 证书可使用 Let#39;s Encrypt 免费证书或商用 SSL 证书三、基础环境部署本方案所有服务均采用 Docker 容器化部署无需在宿主机安装额外的服务依赖环境干净统一迁移与运维成本极低。3.1 安装 Docker 与 Docker Compose执行以下官方脚本一键安装 Docker 最新稳定版# 一键安装Docker官方稳定版curl-fsSLhttps://get.docker.com|sudobash# 启动Docker服务并设置开机自启sudosystemctlenabledocker--now# 验证Docker安装是否成功输出版本号即为正常sudodocker--version# 安装Docker Compose插件# Debian/Ubuntu系统执行sudoaptinstall-ydocker-compose-plugin# CentOS/RHEL系统执行# sudo yum install -y docker-compose-plugin# 验证Docker Compose安装是否成功sudodockercompose version3.2 创建 Docker 自定义网桥网络为了让 Nginx 与 Trojan-Go 服务容器之间可以稳定、安全地内网通信我们创建专属的自定义 Docker 网络# 创建自定义网桥网络trojan-netsudodockernetwork create trojan-net# 验证网络创建成功sudodockernetworkls|greptrojan-net四、Docker 部署 Trojan-Go 加密通信服务Trojan-Go 是一款开源轻量级的 TLS 加密通信工具基于标准 TLS 协议实现加密数据传输兼容性强、安全性高非常适合用于企业级远程加密通信场景。4.1 创建配置与证书目录首先在宿主机创建 Trojan-Go 服务的配置文件目录、证书挂载目录用于容器数据持久化# 创建配置文件目录sudomkdir-p/etc/trojan# 创建证书挂载目录可根据自己的证书存放路径调整sudomkdir-p/www/my_certs/tls-service4.2 编写 Trojan-Go 服务配置文件创建 Trojan-Go 的核心配置文件config\.json配置加密通信的核心参数sudonano/etc/trojan/config.json粘贴以下完整配置内容仅需修改密码、域名、证书路径为自己的实际信息即可{run_type:server,local_addr:0.0.0.0,local_port:443,remote_addr:127.0.0.1,remote_port:80,password:[请设置你的强密码建议使用大小写字母数字特殊符号的组合],ssl:{cert:/config/certs/fullchain.pem,key:/config/certs/privkey.pem,sni:tls-service.yourdomain.com,min_version:tls1.2,prefer_server_cipher:true},log_level:info}配置说明local\_port: 443容器内 Trojan-Go 服务监听 443 端口无需修改password加密通信的校验密码客户端需与服务端保持一致ssl\.cert/ssl\.key容器内的证书路径与后续的容器挂载路径对应ssl\.sni加密通信服务的域名需与解析的域名保持一致4.3 证书文件准备将你的加密通信服务域名对应的 SSL 证书文件上传到宿主机的/www/my\_certs/tls\-service目录下确保目录内包含证书公钥文件fullchain\.pem与私钥文件privkey\.pem。4.4 启动 Trojan-Go 服务容器执行以下 docker run 命令启动 Trojan-Go 服务容器完成端口映射、目录挂载与网络配置sudodockerrun-d\--nametrojan\--restartalways\-p127.0.0.1:1443:443\-v/etc/trojan/config.json:/config/config.json\-v/www/my_certs/tls-service:/config/certs\--networktrojan-net\-eTZAsia/Shanghai\trojangfw/trojan命令参数说明\-\-name trojan设置容器名称为 trojan便于运维管理\-\-restart always设置容器开机自启异常退出时自动重启\-p 127\.0\.0\.1:1443:443将容器内的 443 端口映射到宿主机本地回环地址的 1443 端口公网无法直接访问安全性更高\-v挂载宿主机的配置文件与证书目录到容器内实现配置持久化\-\-network trojan\-net将容器加入我们创建的专属自定义网络与 Nginx 容器实现内网通信4.5 验证服务启动状态执行以下命令验证 Trojan-Go 服务是否正常启动# 查看容器运行状态STATUS为Up即为正常运行sudodockerps|greptrojan# 查看服务运行日志无报错信息即为配置正常sudodockerlogs trojan五、Docker 部署 Nginx 反向代理服务Nginx 作为整个架构的核心流量入口负责统一监听 443 端口完成 SNI 域名识别与流量分流同时承载 Web 站点的 HTTPS 服务。5.1 创建宿主机挂载目录创建 Nginx 服务的配置目录、站点目录、证书目录、日志目录用于容器数据持久化# Nginx核心配置目录sudomkdir-p/www/nginx# 站点配置目录sudomkdir-p/www/nginx/conf.d# 站点文件根目录sudomkdir-p/www/nginx/html# 证书挂载目录sudomkdir-p/www/my_certs# 日志存放目录sudomkdir-p/var/log/nginx5.2 编写 Nginx 核心配置文件Nginx 的核心配置分为两部分stream块4 层流量分流与http块7 层 Web 站点服务我们先编写核心的nginx\.conf主配置文件sudonano/www/nginx/nginx.conf粘贴以下完整配置内容核心的分流规则已配置完成http 块保留标准默认配置即可# 运行用户与进程配置 user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; # 4层TCP流量处理核心块SNI分流配置 stream { # 基于SNI域名映射后端服务地址 map $ssl_preread_server_name $backend_address { # Web站点域名统一转发到Nginx本地Web服务端口4443 site1.yourdomain.com 127.0.0.1:4443; # 新增Web站点仅需在此处添加域名与映射地址即可 site2.yourdomain.com 127.0.0.1:4443; # 加密通信服务域名转发到Trojan-Go服务映射的宿主机端口1443 tls-service.yourdomain.com 127.0.0.1:1443; # 域名不匹配的默认规则drop为丢弃流量也可配置为默认Web站点地址 default drop; } # 核心监听公网443端口实现流量统一接入与分流 server { listen 443 reuseport; listen [::]:443 reuseport; proxy_pass $backend_address; ssl_preread on; # 关键配置开启TLS SNI预读取不解密流量 tcp_nodelay on; timeout_client 300s; timeout_connect 5s; timeout_server 300s; } } # 7层HTTP/HTTPS Web服务处理块 http { include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式配置 log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for; access_log /var/log/nginx/access.log main; # 基础性能配置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # Gzip压缩配置 gzip on; gzip_vary on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript; # 包含站点配置目录 include /etc/nginx/conf.d/*.conf; }核心配置说明stream块必须放在http块的外面这是 Nginx 的配置规范ssl\_preread on开启 SNI 预读功能是整个分流方案的核心map块中的域名映射规则可根据自己的实际域名无限扩展reuseport开启端口复用提升高并发场景下的性能与稳定性5.3 启动 Nginx 服务容器执行以下 docker run 命令启动 Nginx 服务容器完成端口映射、目录挂载与网络配置sudodockerrun-d\--namenginx\--restartalways\-p80:80\-p443:443\-v/www/nginx/nginx.conf:/etc/nginx/nginx.conf\-v/www/nginx/conf.d:/etc/nginx/conf.d\-v/www/nginx/html:/usr/share/nginx/html\-v/www/my_certs:/etc/nginx/cert\-v/var/log/nginx:/var/log/nginx\--networktrojan-net\-eTZAsia/Shanghai\nginx命令参数说明\-p 80:80/\-p 443:443映射公网 80/443 端口作为 Web 服务与流量分流的统一入口\-v挂载宿主机的配置、站点文件、证书、日志目录到容器内实现配置持久化与日志本地化存储\-\-network trojan\-net将容器加入专属自定义网络与 Trojan-Go 服务实现内网互通5.4 验证 Nginx 配置与服务状态# 进入Nginx容器校验配置文件语法输出test is successful即为配置正常sudodockerexec-itnginx nginx-t# 若配置无报错重载Nginx配置使分流规则生效sudodockerexec-itnginx nginx-sreload# 查看容器运行状态STATUS为Up即为正常运行sudodockerps|grepnginx六、多 HTTPS 站点配置与扩展完成核心分流架构部署后我们只需要在 Nginx 中添加 Web 站点配置即可实现多 HTTPS 站点的稳定运行。原有 HTTPS 站点配置仅需修改监听端口即可无缝适配本方案无需大幅改动。6.1 编写 Web 站点配置文件以site1\.yourdomain\.com为例创建站点配置文件仅需将原有 HTTPS 配置中的listen 443修改为listen 4443即可sudonano/www/nginx/conf.d/site1.yourdomain.com.conf粘贴以下完整配置内容仅需修改域名、证书路径、网站根目录为自己的实际信息即可server { listen 4443 ssl http2; server_name site1.yourdomain.com; # 网站根目录可根据自己的实际需求修改 root /usr/share/nginx/html/site1; index index.html index.htm; # 该站点独立的SSL证书与加密通信服务证书完全隔离 ssl_certificate /etc/nginx/cert/site1/fullchain.pem; ssl_certificate_key /etc/nginx/cert/site1/privkey.pem; # 标准SSL安全配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age31536000; includeSubDomains always; # 网站常规配置可根据自己的程序需求修改 location / { try_files $uri $uri/ 404; } }6.2 站点内容准备与配置生效# 创建站点根目录sudomkdir-p/www/nginx/html/site1# 写入测试页面验证站点是否正常运行echoh1Hello! site1.yourdomain.com/h1|sudotee/www/nginx/html/site1/index.html# 将站点域名对应的SSL证书上传到宿主机的/www/my_certs/site1目录下# 校验Nginx配置并重载生效sudodockerexec-itnginx nginx-tsudodockerexec-itnginx nginx-sreload6.3 多站点扩展方法如需新增更多 HTTPS 站点仅需 3 步即可完成为新域名申请独立的 SSL 证书上传到宿主机证书目录在nginx\.conf的stream块map规则中添加新域名与127\.0\.0\.1:4443的映射关系在/www/nginx/conf\.d目录下新增对应的站点配置文件将监听端口改为 4443重载 Nginx 配置即可生效七、服务验证与效果确认7.1 Web 站点服务验证在浏览器中访问你的 Web 站点域名https://site1\.yourdomain\.com若满足以下条件说明配置完全正常可以正常打开网站页面无访问异常浏览器地址栏显示安全锁标识无 SSL 证书告警查看证书信息显示为该站点对应的独立 SSL 证书7.2 加密通信服务验证使用支持 Trojan-Go 协议的远程访问客户端配置以下核心参数即可正常连接使用加密通信服务配置项参数值通信协议Trojan服务地址你的加密通信服务域名tls-service.yourdomain.com服务端口443校验密码你在 Trojan-Go 配置文件中设置的强密码TLS 版本TLS 1.2/1.3SNI 域名你的加密通信服务域名tls-service.yourdomain.com证书校验开启八、运维优化与安全加固8.1 证书自动续期若使用 Let#39;s Encrypt 免费证书可通过 Certbot 配置自动续期避免证书过期导致服务异常续期完成后可通过钩子脚本自动重载 Nginx 与 Trojan-Go 服务。8.2 日志管理Nginx 的访问日志与错误日志存放在宿主机的/var/log/nginx目录下可通过日志分析工具监控访问情况Trojan-Go 服务的运行日志可通过sudo docker logs trojan命令查看便于排查连接异常问题8.3 安全加固定期更新 Docker 镜像与服务版本修复安全漏洞Trojan-Go 服务的校验密码建议使用高强度密码定期更换避免泄露可在 Nginx 中配置 IP 黑白名单、访问速率限制、WAF 防护规则提升服务器整体安全性所有服务仅开放必要的公网端口非必要端口不对外暴露写在最后这套全 Docker 化的 Nginx SNI 分流架构彻底解决了单台服务器 443 端口复用的核心痛点实现了多 HTTPS 站点与加密通信服务的完全解耦、稳定共存配置简洁、扩展性强无论是个人站点运维还是企业级服务部署都能稳定落地。再次郑重提醒所有技术操作请严格遵守《中华人民共和国网络安全法》等相关法律法规仅用于合法合规的场景共同维护健康的网络环境。注文档部分内容可能由 AI 生成

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价