[alibaba/tengine]https协议传输有点问题,谁能帮我看下

2024-05-15 855 views
7

各位好,我发现同样的配置 在 nginx/1.10.2 下 和 在 Tengine/2.2.3 (nginx/1.8.1) 工作有点问题。 具体表现为 post 请求, https 协议访问 后端返回的是 http 协议,java 程序 使用 request.getScheme()获取的协议。

配置如下 `upstream tgauth {
server 172.31.10.43:8003; server 172.31.10.44:8003; }
server { listen 80; server_name ngauth.test.com tgauth.test.com; index index.jsp default.jsp; charset utf-8; access_log /var/log/nginx/access.ngauth.test.com.log main; error_log /var/log/nginx/error.ngauth.test.com.log; location / { proxy_pass http://tgauth; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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; } }

server { listen 443 ssl; server_name ngauth.test.com tgauth.test.com; ssl on; ssl_certificate /etc/nginx/conf.d/test.com.crt; ssl_certificate_key /etc/nginx/conf.d/test.com.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; index index.html index.jsp default.jsp; charset utf-8; access_log /var/log/nginx/access.ngauth.test.com.log main; error_log /var/log/nginx/error.ngauth.test.com.log; location / { proxy_pass http://tgauth; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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; proxy_set_header X-Forwarded-Proto https; proxy_connect_timeout 240; proxy_send_timeout 240; proxy_read_timeout 240; } } ` 请求协助 上述配置 放在 nginx 下正常 ,放在 tengine 下就不正常

回答

6

你做的是ssl卸载,tengine和你java之间传输的当然就是http协议。

你配置里面proxy_set_header X-Forwarded-Proto $scheme,你的java可以尝试获取X-Forwarded-Proto头的值来确定真实的scheme。

1

你做的是ssl卸载,tengine和你java之间传输的当然就是http协议。

你配置里面proxy_set_header X-Forwarded-Proto $scheme,你的java可以尝试获取X-Forwarded-Proto头的值来确定真实的scheme。

您好,我没太懂,请问我该如何修复?

3

“你的java可以通过获取X-Forwarded-Proto头的值来确定真实的scheme”

0

“你的java可以通过获取X-Forwarded-Proto头的值来确定真实的scheme”

我尝试 proxy_set_header X-Forwarded-Proto $scheme; 也不行 proxy_set_header X-Forwarded-Proto https; 也不行 不写这两行 也不行, 还有我好奇一点 同样的配置 在nginx 下是正常的

0

新发现, 当我把upstream 中server 地址写成 localhost 或者 127.0.0.1的时候,是正常的,但是写成 eth0的本地内网地址后,就不正常了。请问这属于bug 吗

3

新发现, 当我把upstream 中server 地址写成 localhost 或者 127.0.0.1的时候,是正常的,但是写成 eth0的本地内网地址后,就不正常了。请问这属于bug 吗

你写eth0时,网络到底有没有通?java有没有收到请求?

9

收到了。确认有日志输出,

5

那你需要确定tengine启动时所使用的是否是你的配置文件。

2

这些都确定的,现在只有tengine 配置中 server localhost:8080; 或者 server 127.0.0.1:8080; 才会正常

7

@Marco1221 你要不把问题重新描述一遍,以及调试结果也描述一遍。怎么突然8080了,你配置文件中写的不是8003吗,你不仅仅改了ip还改了端口?

2

好的 我们正式环境:采用docker ,使用tomcat容器来部署我们的java web。 其中 8003 端口 是docker 8080 ==> 8003 映射给主机的 端口 tengine 配置如下 ` upstream tgauth { server 172.31.10.43:8003; server 172.31.10.44:8003;

} server { listen 80; server_name ngauth.test.com tgauth.test.com; index index.jsp default.jsp; charset utf-8; access_log /var/log/nginx/access.ngauth.test.com.log main; error_log /var/log/nginx/error.ngauth.test.com.log; location / { proxy_pass http://tgauth; proxy_redirect off; proxy_set_header Cookie $http_cookie; 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; } }

server {
    listen      443 ssl;
    server_name  ngauth.test.com tgauth.test.com;
    ssl       on;
    ssl_certificate /etc/nginx/conf.d/test.com.crt;
    ssl_certificate_key /etc/nginx/conf.d/test.com.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    index index.html index.jsp default.jsp;
    charset utf-8;
    access_log /var/log/nginx/access.ngauth.test.com.log main;
    error_log /var/log/nginx/error.ngauth.test.com.log;
    location / {
                    proxy_pass http://tgauth;
                    proxy_redirect off;
                    proxy_set_header Cookie $http_cookie;
                    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;
                    proxy_connect_timeout  240;
                    proxy_send_timeout  240;
                    proxy_read_timeout  240;
            }
    }

` 同时 docker容器tomcat 也修改了server.xml 文件,增加了

Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto"

然后我们在访问https 的时候,后端返回的是http 协议 。 后来我使用线上 tengine 的镜像建立的测试服务器,并且在测试服务器安装了tomcat(非容器)。所以说和线上tengine 的配置环境都是一样的。 然后将我们的应用部署在 tomcat 中。并且同样修改tomcat server.xml 增加Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" 修改如下 (172.31.10.56 为新建测试服务器的内网地址)后测试,还是无法获取https 协议 upstream tgauth { server 172.31.10.56:8080; } 后来修改如下后,使用正常 upstream tgauth { server localhost:8080; }

总结:目前看来就是因为 upstream 中server 地址引起的,只能使用本地回环地址,无法使用 内网的 eth0的地址

8

Tengine不会对localhost或者ip地址有特殊处理,应该是tomcat自身的问题导致。 可以让 java 程序 直接使用 request.getHeader("X-Forwarded-Proto") 获取协议来代替getScheme (),如果这个方法成功,那么说明你需要调试tomcat。

1

好吧 我写了个测试页面,发现 python 项目后端获取到的是 https ,但是 spring 框架的java 项目 确是 http ,我再排查下,有进展我同步到这里

8

已经解决了。是tomcat的问题。源码中存在 协议传输 IP白名单