自建Nginx反向代理实现HTTPS转发和解析端口隐藏

通过在云服务器ECS上部署Nginx反向代理,可自行控制请求转发规则以支持HTTPS协议的URL转发、端口代理等,弥补云解析DNSURL转发协议支持缺失、无法配置解析到指定端口的不足。常规解析场景可通过添加解析记录实现。

业务场景说明

云解析DNS提供的解析配置功能在特定场景下存在局限性:

  • 协议限制:由于证书管理机制,无法支持从HTTPSHTTPS的请求转发,导致客户端访问失败。

  • 端口限制:DNS标准协议规定只能将域名解析至IP地址,无法指定端口。若后端应用使用非标准端口(如3000),用户访问时必须在URL中手动加入端口号(如http://www.example.com:3000)。

方案架构

image
  • 原始链路:客户通过域名发起访问请求。经由Local DNS递归查询,获取后端服务IP地址后,直接访问IP对应的后端服务。

  • 新链路:自建Nginx反向代理后,Nginx作为流量入口和分发中枢,转发请求,整体访问链路如下:

    1. 客户端通过域名发起访问请求。经由Local DNS递归查询,最终从权威DNS服务器获取指向Nginx服务器的公网IP地址。

    2. 客户端向该公网IP地址发送HTTP/HTTPS请求。

    3. Nginx服务器接收到请求后,根据其配置文件中基于Host请求头(即访问的域名)的转发规则,将请求代理转发至对应的后端应用。

    4. 后端应用处理请求后将响应返回给Nginx,再由Nginx最终传递给客户端。

实施步骤

Alibaba Cloud Linux 3操作系统的云服务器ECS为例,介绍部署和配置流程。若已经在系统上部署了Nginx服务,可直接跳转到步骤三:配置Nginx实现不同场景

步骤一:准备云服务器环境

  1. 参考控制台自定义购买并使用ECS实例,创建一台ECS实例。

    • 操作系统:选择 Alinux 3。

    • 网络:确保已分配公网IP地址。

  2. 在实例的安全组配置中,添加入方向规则,放行TCP协议的2280443端口,用于SSH远程连接和Web服务。

步骤二:安装并启动Nginx

  1. 使用SSH客户端登录到ECS实例。

  2. 执行以下命令安装Nginx。

    sudo yum install -y nginx
  3. 启动Nginx服务并设置为开机自启动。

    sudo systemctl start nginx
    sudo systemctl enable nginx
  4. 检查Nginx服务状态,确认其已成功运行。

    sudo systemctl status nginx

    若状态显示为 active (running),则表示服务启动正常。

  5. 修改Nginx配置后,执行以下命令使配置生效。该命令会平滑重载配置,不中断现有连接。

    sudo systemctl reload nginx

步骤三:配置Nginx实现不同场景

Nginx的核心配置位于/etc/nginx/nginx.conf,但最佳实践是将每个站点的独立配置创建为.conf文件并存放在/etc/nginx/conf.d/目录下。以下为不同业务场景的配置示例。

场景一:HTTPS协议的URL转发

DNS无法支持HTTPS协议到HTTPS协议的URL转发的根本原因:云解析DNS无法自定义上传用户HTTPS证书导致。通过自建Nginx,用户可自行为原域名配置有效的SSL证书,并配置URL转发规则。

  • URL重定向(显性转发)

    https://example.com的访问永久重定向到https://aliyun.com,浏览器地址栏变成重定向之后的地址。请在/etc/nginx/conf.d/redirect.conf文件中添加以下内容:

    server {
        listen 443 ssl http2;
        server_name example.com;
    
        # 配置源域名的SSL证书和私钥
        ssl_certificate /etc/nginx/certs/example.com.fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/example.com.key;
    
        location / {
            return 301 https://aliyun.com$request_uri;
        }
    }
  • 反向代理(隐性转发)

    https://example.com网站的请求交由https://aliyun.com域名处理,地址栏保持不变,但内容实际由其他后端服务提供。请在/etc/nginx/conf.d/proxy.conf文件中添加以下内容:

    # 将对 example.com 的访问代理到 aliyun.com
    server {
        listen 443 ssl http2;
        server_name example.com;
    
        # 配置源域名的SSL证书和私钥
        ssl_certificate /etc/nginx/certs/example.com.fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/example.com.key;
    
        location / {
            # 将请求转发至目标服务器
            proxy_pass http://aliyun.com;
    
            # 关键配置:将Host请求头设置为目标服务的域名,确保后端能正确处理请求
            proxy_set_header Host "aliyun.com";
            
            # 传递客户端真实IP地址,便于后端服务记录和分析
            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;
        }
    }
    

场景二:域名解析到指定端口

此配置使得运行在非标准端口(如3000)的应用能通过标准80端口访问,解决了DNSA记录无法指定端口的问题。在/etc/nginx/conf.d/port_mapping.conf文件中添加以下内容:

# 通过 example.com 访问本地3000端口的服务
server {
    listen 80;
    server_name example.com;

    location / {
        # 将请求转发到本地(localhost)的3000端口
        proxy_pass http://127.0.0.1:3000;

        # 传递原始的Host请求头,以便后端应用能识别访问的域名
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

步骤四:配置DNS解析

完成了自建Nginx反向代理服务的搭建和配置后,需要根据代理的服务和关联的域名,配置DNS解析。

  1. 准备好域名,如还没有购买域名,请前往 阿里云域名注册购买。若域名关联的网站需要部署在中国内地,请提前完成ICP备案

  2. 获取部署Nginx反向代理所在服务器的公网IP地址,本案例中直接获取ECS实例的公网IP地址。

    image

  3. 访问云解析DNS-公网权威解析,找到目标域名。

  4. 添加/修改解析记录。

    1. 若之前未设置过解析记录,则添加解析记录,为每个在Nginx中配置的域名(如example.com)创建一条A记录,将其指向ECS实例的公网IP地址。

    2. 若已经存在解析记录,则将原来的记录值换成Nginx服务的公网IP地址即可,注意:修改解析记录后,需要等待5-10分钟,解析记录才会陆续生效。

      image

成本与风险

  • 成本构成:主要成本来自运行Nginx所需的云服务器ECS实例,具体费用取决于所选实例的规格、地域和计费方式。Nginx为开源软件。

  • 风险与维护:自建反向代理服务需要自行承担运维责任,包括定期更新操作系统和Nginx的安全补丁、监控服务健康状态、备份配置文件等。配置不当或缺乏维护可能导致服务中断或引入安全漏洞。

  • 生产环境建议:对于生产环境,建议进一步强化Nginx的安全配置,并建立监控和日志分析体系。

常见问题

云解析DNS是否支持端口解析?

如何将域名指向另外一个站点?