杨斌
发布于 2025-09-03 / 1 阅读
0
0

如何解决多个系统共用一个公网IP的80/443端口

这是一个非常经典且常见的网络架构问题。标准且完美的解决方案是:使用反向代理服务器

这个方案可以完美地满足所有需求:单一公网IP多个域名共用80/443端口全HTTPS加密

核心解决方案:反向代理 (Reverse Proxy)

1. 工作原理

反向代理服务器(如 Nginx, Apache Traffic Server, HAProxy)位于公网入口,监听80和443端口。它根据客户端请求中的 SNI (Server Name Indication) 字段(即访问的域名)来决定将请求转发到后端的哪个内部系统。

工作流程:

  1. 用户访问 https://app1.yourdomain.com,DNS 将该域名解析到您的公网IP。

  2. 请求到达反向代理服务器的443端口。

  3. 反向代理读取 TLS 握手阶段的 SNI 信息,得知用户要访问的域名是 app1.yourdomain.com

  4. 根据预先配置好的规则,反向代理将此请求转发至内网中对应的服务器(例如 192.168.1.10:3000)。

  5. 内部服务器处理请求并将响应返回给反向代理。

  6. 反向代理最终将响应返回给用户。

  7. 对于 app2.yourdomain.com 的请求,过程同上,但会被转发到另一个内部服务器(例如 192.168.1.20:4000)。

2. 优势

  • 一个IP,多个服务:完美解决端口冲突问题。

  • 集中化管理SSL证书:所有域的SSL证书都可以在反向代理上统一申请、安装和更新,无需在每个内部系统上单独配置,管理非常方便。

  • 增强安全性:隐藏了内部服务器的真实IP和端口,对外只暴露反向代理,增强了后端服务的安全性。

  • 附加功能:可以轻松实现负载均衡、缓存、压缩、访问控制、日志记录等功能。


具体实施步骤(以最常用的 Nginx 为例)

第1步:部署反向代理服务器

  • 准备一台服务器(可以是物理机、虚拟机或云实例),安装 Linux 系统(如 Ubuntu, CentOS)。

  • 在这台服务器上安装 Nginx(通常包管理器直接安装即可,如 apt install nginxyum install nginx)。

  • 确保此服务器拥有您唯一的公网IP,并且防火墙开放80和443端口。

第2步:配置域名解析

  • 将您所有的域名(如 app1.com, app2.org, service.net)的DNS A 记录都指向这个唯一的公网IP。

第3步:申请和安装SSL证书

  • 推荐使用 Certbot 和 Let‘s Encrypt 来自动化免费证书的申请和续签。

  • 在反向代理服务器上安装 Certbot 及其 Nginx 插件(如 apt install certbot python3-certbot-nginx)。

  • 执行命令为所有域名申请证书(Nginx插件会自动修改配置):

    bash

    sudo certbot --nginx -d app1.yourdomain.com -d app2.yourdomain.com -d service.yourdomain.com
  • Certbot 会自动完成证书申请并修改 Nginx 配置以启用HTTPS。它还会设置自动续期任务,您无需担心证书过期。

第4步:配置 Nginx 作为反向代理

  • 这是最关键的一步。您需要为每个域名(或每个服务)创建一个独立的 server block 配置文件(通常在 /etc/nginx/conf.d//etc/nginx/sites-available/ 目录下)。

  • 示例配置文件:/etc/nginx/conf.d/app1.conf

    nginx

    # 处理 app1.yourdomain.com 的请求
    server {
        # 监听443端口,并启用SSL,http2是可选的性能优化选项
        listen 443 ssl http2;
        server_name app1.yourdomain.com;
    
        # SSL证书和密钥路径(通常Certbot已自动配置好)
        ssl_certificate /etc/letsencrypt/live/app1.yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/app1.yourdomain.com/privkey.pem;
    
        # 其他SSL优化配置可以放在这里或一个单独的公共文件中
    
        location / {
            # 核心反向代理配置:将请求转发到内网的应用服务器
            proxy_pass http://192.168.1.10:3000; # 这里填写app1服务器的内网IP和端口
    
            # 以下是一些重要的反向代理头设置,用于向后端传递真实客户信息
            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;
        }
    }
    
    # 强制将HTTP访问重定向到HTTPS
    server {
        listen 80;
        server_name app1.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }
  • 为第二个服务创建配置文件:/etc/nginx/conf.d/app2.conf

    nginx

    server {
        listen 443 ssl http2;
        server_name app2.yourdomain.com;
    
        ssl_certificate /etc/letsencrypt/live/app2.yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/app2.yourdomain.com/privkey.pem;
    
        location / {
            proxy_pass http://192.168.1.20:4000; # 指向第二个内部系统
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            ... # 其他头设置同上
        }
    }
    
    server {
        listen 80;
        server_name app2.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }

第5步:测试并重载配置

  1. 检查 Nginx 配置语法是否正确:

    bash

    sudo nginx -t
  2. 如果显示 syntax is oktest is successful,则重新加载 Nginx 使配置生效:

    bash

    sudo systemctl reload nginx

第6步:配置后端系统

  • 确保您的各个内部系统(192.168.1.10, 192.168.1.20)正在运行并监听正确的端口(3000, 4000)。

  • 这些后端系统可以不再需要配置SSL证书,因为与反向代理之间的通信可以在内网中通过HTTP进行(前提是内网是可信的)。如果安全性要求极高,也可以在内部通信中使用HTTPS。

  • 这些后端系统的防火墙不需要对外开放80/443端口,只需允许反向代理服务器的IP访问其服务端口即可。


备选方案

如果由于某些原因不能使用反向代理,可以考虑以下方案,但它们都有明显缺陷:

  1. 端口映射 (Port Forwarding)

    • 方法:在出口路由器上,将不同的公网端口映射到不同内网系统的443端口。例如:

      • 公网IP:8443 -> 内网系统1:443

      • 公网IP:9443 -> 内网系统2:443

    • 缺点

      • URL中必须带端口:用户访问时需要用 https://app1.com:8443,非常不专业且用户体验极差。

      • 证书问题:如果证书校验域名,可能会因为端口不匹配而报错。非常不推荐。

  2. TCP层代理 (4层负载均衡)

    • 方法:使用 HAProxy 或 Nginx 的 stream 模块在TCP层进行代理。它同样依赖SNI,但不会解析HTTP协议。

    • 适用场景:适用于非HTTP协议(如数据库、邮件协议)或需要完全透传TCP数据的场景。对于您的HTTPS Web服务,应用层(7层)的反向代理是更优选择,因为它功能更强大。

总结

方案

优点

缺点

推荐度

反向代理 (Nginx等)

一个IP/端口,无端口号,集中管理证书,安全,功能强大

需要额外一台服务器作为代理

⭐⭐⭐⭐⭐ 强烈推荐

端口映射

配置简单

URL带端口,不美观,证书可能出错,体验差

⭐ 不推荐用于Web服务

TCP层代理

可代理任何TCP协议,性能稍高

无法做HTTP层的高级处理(如根据URL路径路由)

⭐⭐ 适用于特殊场景


评论