V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
GogoGo666
V2EX  ›  NGINX

想请教大家如何将 http 请求反代到 https 服务

  •  
  •   GogoGo666 · 100 天前 · 2679 次点击
    这是一个创建于 100 天前的主题,其中的信息可能已经有所发展或是发生改变。
    目前有个需求,我们的业务场景是,客户流量->nginx(卸载 ssl ,https 转为 http)->流量处理(类似防火墙,但是有很多处理的过程)->nginx(将处理过的 http 重新加密为 https)->客户服务器,然后要求客户端和服务端都无感知,想请教大家,第二个 nginx(将处理过的 http 重新加密为 https)如何处理?
    31 条回复    2023-01-10 14:15:48 +08:00
    ProProPro
        1
    ProProPro  
       100 天前
    直接 301 跳转?
    Lax
        2
    Lax  
       100 天前
    简单来说可以: “proxy_pass https://backend.example.com;”
    复杂来说的话,有一些关于证书的配置,去文档里看看 proxy_ssl_ 开头的
    zhanlanhuizhang
        3
    zhanlanhuizhang  
       100 天前
    直接加个代理配置就可以了。很简单的配置。
    Lax
        4
    Lax  
       100 天前
    另外建议先看看现有成熟的方案,一般的需求不需要搞两个 nginx 。
    大部分预处理需求都可以在读请求体这个阶段实现。
    zhanlanhuizhang
        5
    zhanlanhuizhang  
       100 天前
    简单来说,就是 nginx 配置 https ,你的服务不配置 https 。然后通过 proxy_pass 设置一下。
    defunct9
        6
    defunct9  
       100 天前   ❤️ 2
    开 ssh ,让我上去试试
    kaedeair
        7
    kaedeair  
       100 天前
    这个应该是要 nginx 管理证书,nginx 我用得比较少
    我用过的 traefik 可以实现,网关后面的服务都是 http ,但是进到网关强制 https
    storyxc
        8
    storyxc  
       100 天前   ❤️ 7
    #6 ssh 哥 虽迟但到
    darkengine
        9
    darkengine  
       100 天前
    nginx 配置文件最后加一个

    server {
    listen 80;
    server_name <your-domain-name>;
    return 307 https://$host$request_uri;
    }
    Xusually
        10
    Xusually  
       100 天前 via iPhone
    就最简单的 proxy_pass 就行了
    sss15
        11
    sss15  
       100 天前
    server {
    listen 443;
    server_name example.com;

    location / {
    proxy_pass http://localhost:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    }
    监听 443 端口,返回出去的也是 443 端口,所有的请求,都会代理到 localhost:8000 端口,且是 http 的,就是这样子简单,无需 2 台 nginx 转来转去,想复杂了
    xwayway
        12
    xwayway  
       100 天前
    看了下,你服务端就是一个流量处理的过程,拓扑图不用这么复杂
    用户请求 --> 贵司 nginx --> 贵司服务 --> 调用三方服务
    至于 nginx 配置可以参考

    server {
    listen 443 ssl;
    server_name abc.com;
    client_max_body_size 10m;

    ssl_certificate conf.d/ssl/abc.com.pem;
    ssl_certificate_key conf.d/ssl/abc.com.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header Via "nginx";
    }
    }
    GogoGo666
        13
    GogoGo666  
    OP
       100 天前
    @darkengine #9 感谢回复,我尝试了你的配置,结果是会重定向,我的目的是使用 nginx 启动 httpserver ,并将 http 数据加密,然后将生成的 https 数据给服务器
    @kaedeair #7 感谢回复,我研究下 traefik
    @zhanlanhuizhang #5 感谢回复,被代理的服务器是 https 服务,我们的业务时先将流量解密,进行安全处理,然后加密回去,再到服务器,我是在不知道怎么办了
    @ProProPro #1 感谢回复,直接 301 不可行,会重定向
    @Lax #4 感谢回复,我尝试了直接使用 proxy_pass 配置,也查看了相关的配置,感觉没有能实现我的目标的配置,我查了相关配置后,感觉 nginx 好像不能对接收到的 http 请求转为 https 请求到服务器,感觉其中难点应该是不使用重定向,直接将 https 的响应解密成 http 在返回给流量处理层。
    500
        14
    500  
       100 天前
    用户-----( https)-----nginx_a
    nginx_a-----( http)-----nginx_b
    nginx_b-----( https)-----服务器

    这样看的话比较清楚:
    1. ( https)-----nginx_a-----( http)
    2. ( http)-----nginx_b-----( https)


    假设:
    用户访问的地址是: https://a.nginx.org
    nginx_b 的地址是: http://b.nginx.org
    服务器的地址是:server.org


    nginx_a 做升级代理,需要证书

    ```
    server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate cert.pem;
    ssl_certificate_key key.pem;
    ssl_client_certificate ca.cer;
    ssl_verify_client optional;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;

    server_name a.nginx.org;

    root /var/www/a.nginx.org;
    index index.html;

    location = / {
    proxy_pass http://b.nginx.org:80;
    proxy_set_header Host $http_host;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    }
    }
    ```

    nginx_b 做降级代理,不需要证书

    ```
    server {
    listen 80;
    listen [::]:80;

    server_name b.nginx.org;

    root /var/www/b.nginx.org;
    index index.html;

    location = / {
    proxy_pass http://server.org:443;
    proxy_set_header Host $http_host;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    }
    }
    ```

    其实这个完全可以一次代理完成,用两次代理是需要劫持流量?
    GogoGo666
        15
    GogoGo666  
    OP
       99 天前
    @500 #14 感谢回复,我马上尝试您的配置,您说的劫持流量,我们的业务应该就是这个意思,我们是与安全厂商合作,中间流量处理会有多个防火墙和 waf ,整体流量调度使用 vswitch 实现的。我是负责做安全厂商 api 对接和镜像制作的工作,所以这个 nginx 镜像的工作交到我这里了,我自己折腾 3 天没搞定。
    crab
        16
    crab  
       99 天前
    o00o
        17
    o00o  
       99 天前
    这是要作恶?
    GogoGo666
        18
    GogoGo666  
    OP
       99 天前
    @o00o #17 感谢回复,不是的,中间的流量处理是安全厂商提供的,最终客户一般是地方 zf 单位
    darkengine
        19
    darkengine  
       99 天前
    我明白你的需求了。根据我当前对后端的理解(本人菜鸡),你还是写个代码吧。例如跑个 go 服务,nginx 的所有 http 请求都到它那里,然后它负责请求目标机( https),将响应作为进来的 http 请求的响应返回去。
    GogoGo666
        20
    GogoGo666  
    OP
       99 天前
    @darkengine #19 感谢,这也是个方法,但是无法保证性能,为了提高性能我们在服务器加了 QAT 卡,用来加速证书加密解密,用 go 不确定性能是否足够,我会想办法试试
    Lax
        21
    Lax  
       99 天前
    @GogoGo666 https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 仔细看看 Syntax proxy_pass 的第一段内容,第二层 nginx 接收 http 协议请求,回源采用 https 协议,有什么问题吗?
    另外,既然要求性能,楼主的这个方案是一定程度上来说是不太靠谱了。如果是串联的方式来做,可以使用 auth_request 或者 nginx-lua-module 。如果是 nginx 流量镜像,是有 ngx_http_mirror_module 可以做到的。
    honhon
        22
    honhon  
       99 天前
    开 ssh ,让我上去试试
    honhon
        23
    honhon  
       99 天前
    流量处理(类似防火墙,但是有很多处理的过程) 这一个阶段也类似反向代理,但是不支持 https ,但是客户服务器只支持 https ,是这个意思么
    EminemW
        24
    EminemW  
       99 天前
    建议直接从交换机镜像流量出来,别搞这种串联的
    yikyo
        25
    yikyo  
       99 天前 via iPhone
    是要对流量进行修改?
    如果仅记录,可以尝试镜像,traefik 也有该功能
    GogoGo666
        26
    GogoGo666  
    OP
       99 天前
    @Lax #21 感谢回复,关于您提到的文档中 proxy_pass 的第一段内容,我是查阅了的,也在本地做了测试,结果依然是重定向实现的。关于方案的问题,其实流量调度是 vswitch 实现的,我只需要在 nginx 配置即可,所以才有了这个方案。我会尝试 nginx-lua-module
    GogoGo666
        27
    GogoGo666  
    OP
       99 天前
    @honhon #23 其实客户服务本身是 https 服务,只是在流量到达客户服务之前,需要过我们业务串联的防火墙,但是 https 需要加密解密,会影响性能,所以才有第一个 nginx 来卸载流量的 ssl ,https 流量卸载 ssl 后变为 http 流量,然后开始由防火墙处理,处理完成后需要重新加密为 https 以请求真实的客户服务,所有才有了第二个 nginx
    @EminemW #24 这种旁路的方式我们也有,只是现在需要实现串联的业务
    @yikyo #25 是的,仅记录的话就简单了
    eryajf
        28
    eryajf  
       99 天前
    @storyxc #8 如果真开了,那就是两个 2 的问题😂
    lazyfighter
        29
    lazyfighter  
       99 天前
    目前能想到的只能是 body_fitler_by_lua, 通过 lua 在将 body 请求转发到 nginx 上面 ,由 nginx 转发到你们的服务器 ,拿到结果 lua 覆盖原始 body , 最终在进行 proxy_pass , 看了一下 nginx 提供的 7 个钩子,基本不可能在 proxy_passs 就是 rewrite 阶段之后在进行 rewrite 。
    lazyfighter
        30
    lazyfighter  
       99 天前
    @lazyfighter 抱歉错了, 应该是在 rewrite 阶段转发到你们的服务上面
    GogoGo666
        31
    GogoGo666  
    OP
       81 天前
    感谢诸位 v 友回复,给了我很大帮助,我不再一一 @回复了,我会把我的配置放到之后的内容
    ————————————————————————————————————————————————————————
    nginx 最终使用了 headers_more 模块,qat_zip 模块,qat 模块
    以下为相关配置

    http {
    ..........................
    map $upstream_http_Location $location {
    ~https://$IP/(?<param>.*) http://$IP/$param;
    default $upstream_http_Location;
    }

    map $sent_http_set_cookie $resp_cookie {
    ~*(?<CK_WITHOUT_SECURE>.+)Secure $CK_WITHOUT_SECURE;
    }

    server {
    listen 80;
    server_name $Name;
    location / {
    proxy_pass https://$IP;
    proxy_ssl_asynch on;
    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 REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
    more_set_headers -s '301 302' 'Location $location';
    more_set_headers 'Set-Cookie: $resp_cookie';
    }
    }
    }
    关于   ·   帮助文档   ·   博客   ·   nftychat   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   2291 人在线   最高记录 5556   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 10:18 · PVG 18:18 · LAX 03:18 · JFK 06:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.