前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx以HTTP协议反向代理HTTPS服务

Nginx以HTTP协议反向代理HTTPS服务

作者头像
dhyuan
发布2022-05-30 14:24:00
12.6K0
发布2022-05-30 14:24:00
举报
文章被收录于专栏:响应式编程

简单记录一下 Nginx 作为反向代理,以 HTTP 协议向下游客户端代理基于Spring Security 实现的HTTPS 服务时遇到的问题及解决办法。

背景

有个基于 Spring Security、Spring MVC 实现的 HTTPS Web 应用,需要通过 Nginx 作为反向代理向外提供服务。 Nginx 和 Web 应用部署在同一台机器,IP 为 10.115.6.165。Web 应用以 HTTPS 协议监听在端口 19026。

关于Nginx,因为我们会需要 headers more 模块中的 more_set_headers 指令。所以,如果是 Windows 环境,推荐在 http://nginx-win.ecsds.eu/ 下载,因为它的nginx编译进了更多模块。如果是 Linux 环境,也请确认 headers more 模块的 more_set_headers 指令可用。

Nginx 以 HTTP 的方式反向代理。

用以下配置运行 Ngnix, 使Nginx用 HTTP 协议在 9080 端口反向代理 19026 上的 HTTPS 服务。

代码语言:javascript
复制
server {
    listen       9080;
    server_name  10.115.6.165;

    location /databoard/ {
        proxy_pass  https://10.115.6.165:19026/databoard/;
        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;
    }
}

但是如果我们用浏览器访问http://10.115.6.165:9080/databoard/login,就会发现如下图所示的两个问题:

1)后端服务使用 redirect 重定向导致的问题

浏览器地址栏上显示被重定向到了https://10.115.6.165/databoard/dataCmder。这是因为后端Web应用执行了redirect重定向语句,而重定向的协议、地址是基于web应用上下文的,而nginx并没有做特别的处理就转发给了浏览器,浏览器自然不能访问到这个地址。解决办法如下:

代码语言:javascript
复制
map $upstream_http_Location $location {
  ~https://10.115.6.165/(?<param>.*) http://10.115.6.165:9080/$param;
  default $upstream_http_Location;
}

server {
    ... ...
    location /databoard/ {
        ... ...
        more_set_headers -s '301 302' 'Location $location';
2)Cookie 携带 Secure 属性导致浏览器不能在请求中携带 SessionID 的问题。

有 Secure 属性的 Cookie 意味着如果浏览器不是使用 HTTPS 与服务建立链接,那么这个 cookie 里的值不会随请求一起向服务器发送。要解决这个问题就需要在 Nginx 中把 cookie 中的 Secure 属性去掉再传给浏览器。解决办法如下:

代码语言:javascript
复制
map $sent_http_set_cookie $resp_cookie {
    ~*(?<CK_WITHOUT_SECURE>.+)Secure $CK_WITHOUT_SECURE;
}

server {
    ... ...
    location /databoard/ {
        ... ...
        more_set_headers 'Set-Cookie: $resp_cookie';
完整的相关配置
代码语言:javascript
复制
map $upstream_http_Location $location {
  ~https://10.115.6.165/(?<param>.*) http://10.115.6.165:9080/$param;
  default $upstream_http_Location;
}

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

server {
    listen       9080;
    server_name  10.115.6.165;

    location /databoard/ {
        proxy_pass  https://10.115.6.165:19026/databoard/;

        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';
    }
}

Nginx 以 HTTPS 的方式反向代理。

如果 nginx 是以 HTTPS 协议向外提供反向代理,那么无论使用七层代理还是四层代理配置起来都很简单,如下:

3)四层反向代理。
代码语言:javascript
复制
stream {
    upstream databoardServer {
        hash $remote_addr consistent;
        server 10.115.6.165:19026 weight=5;
    }

    server {
        listen 9082;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass databoardServer;
    }
}
4)七层反向代理。
代码语言:javascript
复制
server {
    listen       443 ssl;
    server_name  10.115.6.165;
    ssl_certificate D:\\tmp\\opensslCrt\\demoAppChain.crt;
    ssl_certificate_key D:\\tmp\\opensslCrt\\demoApp.key;

    location / {
        proxy_pass https://10.115.6.165:19026;
        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 Referer https://10.115.6.165;
    }
}

关于 Spring Session Cookie Secure 配置

当时为了不用在 Nginx 上处理 Cookie ,想通过直接配置 Spring Web 应用不让 Cookie 带上 Secure 属性。于是直接修改配置 application.properties 如下,但是返回给 nginx 的 Cookie 还是带 Secure 属性。(类似的还有cookie的HttpOnly也不仅仅是一个配置能决定的)

代码语言:javascript
复制
server.session.cookie.secure=false

通过跟踪 Spring 源码发现,只要应用是运行在 HTTPS 协议下的,那么就会让生成的 Cookie 是 Secure 的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 响应式编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • Nginx 以 HTTP 的方式反向代理。
    • 1)后端服务使用 redirect 重定向导致的问题
      • 2)Cookie 携带 Secure 属性导致浏览器不能在请求中携带 SessionID 的问题。
        • 完整的相关配置
        • Nginx 以 HTTPS 的方式反向代理。
          • 3)四层反向代理。
            • 4)七层反向代理。
            • 关于 Spring Session Cookie Secure 配置
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档