想请教大家如何将 http 请求反代到 https 服务 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GogoGo666
0.71D
V2EX    NGINX

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

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

    server {
    listen 80;
    server_name <your-domain-name>;
    return 307 https://$host$request_uri;
    }
    Xusually
        10
    Xusually  
       2022-12-22 17:10:44 +08:00 via iPhone
    就最简单的 proxy_pass 就行了
    sss15
        11
    sss15  
       2022-12-22 17:13:39 +08:00
    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  
       2022-12-22 17:33:18 +08:00
    看了下,你服务端就是一个流量处理的过程,拓扑图不用这么复杂
    用户请求 --> 贵司 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
       2022-12-22 17:36:04 +08:00
    @darkengine #9 感谢回复,我尝试了你的配置,结果是会重定向,我的目的是使用 nginx 启动 httpserver ,并将 http 数据加密,然后将生成的 https 数据给服务器
    @kaedeair #7 感谢回复,我研究下 traefik
    @zhanlanhuizhang #5 感谢回复,被代理的服务器是 https 服务,我们的业务时先将流量解密,进行安全处理,然后加密回去,再到服务器,我是在不知道怎么办了
    @ProProPro #1 感谢回复,直接 301 不可行,会重定向
    @Lax #4 感谢回复,我尝试了直接使用 proxy_pass 配置,也查看了相关的配置,感觉没有能实现我的目标的配置,我查了相关配置后,感觉 nginx 好像不能对接收到的 http 请求转为 https 请求到服务器,感觉其中难点应该是不使用重定向,直接将 https 的响应解密成 http 在返回给流量处理层。
    y77FXoxF970725SJ
        14
    y77FXoxF970725SJ  
       2022-12-22 17:45:12 +08:00
    用户-----( 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
       2022-12-22 18:20:53 +08:00
    @500 #14 感谢回复,我马上尝试您的配置,您说的劫持流量,我们的业务应该就是这个意思,我们是与安全厂商合作,中间流量处理会有多个防火墙和 waf ,整体流量调度使用 vswitch 实现的。我是负责做安全厂商 api 对接和镜像制作的工作,所以这个 nginx 镜像的工作交到我这里了,我自己折腾 3 天没搞定。
    crab
        16
    crab  
       2022-12-22 18:46:02 +08:00
    o00o
        17
    o00o  
       2022-12-22 18:51:45 +08:00
    这是要作恶?
    GogoGo666
        18
    GogoGo666  
    OP
       2022-12-22 19:14:36 +08:00
    @o00o #17 感谢回复,不是的,中间的流量处理是安全厂商提供的,最终客户一般是地方 zf 单位
    darkengine
        19
    darkengine  
       2022-12-22 19:29:22 +08:00
    我明白你的需求了。根据我当前对后端的理解(本人菜鸡),你还是写个代码吧。例如跑个 go 服务,nginx 的所有 http 请求都到它那里,然后它负责请求目标机( https),将响应作为进来的 http 请求的响应返回去。
    GogoGo666
        20
    GogoGo666  
    OP
       2022-12-22 19:54:58 +08:00
    @darkengine #19 感谢,这也是个方法,但是无法保证性能,为了提高性能我们在服务器加了 QAT 卡,用来加速证书加密解密,用 go 不确定性能是否足够,我会想办法试试
    Lax
        21
    Lax  
       2022-12-22 21:31:02 +08:00
    @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  
       2022-12-22 23:24:25 +08:00
    开 ssh ,让我上去试试
    honhon
        23
    honhon  
       2022-12-22 23:32:30 +08:00
    流量处理(类似防火墙,但是有很多处理的过程) 这一个阶段也类似反向代理,但是不支持 https ,但是客户服务器只支持 https ,是这个意思么
    EminemW
        24
    EminemW  
       2022-12-23 00:09:33 +08:00
    建议直接从交换机镜像流量出来,别搞这种串联的
    yikyo
        25
    yikyo  
       2022-12-23 00:16:01 +08:00 via iPhone
    是要对流量进行修改?
    如果仅记录,可以尝试镜像,traefik 也有该功能
    GogoGo666
        26
    GogoGo666  
    OP
       2022-12-23 09:39:30 +08:00
    @Lax #21 感谢回复,关于您提到的文档中 proxy_pass 的第一段内容,我是查阅了的,也在本地做了测试,结果依然是重定向实现的。关于方案的问题,其实流量调度是 vswitch 实现的,我只需要在 nginx 配置即可,所以才有了这个方案。我会尝试 nginx-lua-module
    GogoGo666
        27
    GogoGo666  
    OP
       2022-12-23 09:45:00 +08:00
    @honhon #23 其实客户服务本身是 https 服务,只是在流量到达客户服务之前,需要过我们业务串联的防火墙,但是 https 需要加密解密,会影响性能,所以才有第一个 nginx 来卸载流量的 ssl ,https 流量卸载 ssl 后变为 http 流量,然后开始由防火墙处理,处理完成后需要重新加密为 https 以请求真实的客户服务,所有才有了第二个 nginx
    @EminemW #24 这种旁路的方式我们也有,只是现在需要实现串联的业务
    @yikyo #25 是的,仅记录的话就简单了
    eryajf
        28
    eryajf  
       2022-12-23 17:50:55 +08:00
    @storyxc #8 如果真开了,那就是两个 2 的问题
    lazyfighter
        29
    lazyfighter  
       2022-12-23 18:09:45 +08:00
    目前能想到的只能是 body_fitler_by_lua, 通过 lua 在将 body 请求转发到 nginx 上面 ,由 nginx 转发到你们的服务器 ,拿到结果 lua 覆盖原始 body , 最终在进行 proxy_pass , 看了一下 nginx 提供的 7 个钩子,基本不可能在 proxy_passs 就是 rewrite 阶段之后在进行 rewrite 。
    lazyfighter
        30
    lazyfighter  
       2022-12-23 18:12:20 +08:00
    @lazyfighter 抱歉错了, 应该是在 rewrite 阶段转发到你们的服务上面
    GogoGo666
        31
    GogoGo666  
    OP
       2023-01-10 14:15:48 +08:00
    感谢诸位 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';
    }
    }
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2796 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:25 PVG 08:25 LAX 17:25 JFK 20:25
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86