2020-01-17 2020-05-27
30 MINUTES READ (ABOUT 4442 WORDS)
服务程序集成了OAuth2-Client,以便于用户能够方便集成到支持OAuth2第三方登录的自有业务系统中。开发完成后,本地测试、或者直连服务程序,都没有问题。但凡放到线上环境,经过了nginx 转发后,我们的服务程序OAuth登录永远是以失败告终。
现象如下:
访问需要授权的接口时 https://blog.95id.com:4005/user_attr
,期望是跳转到授权服务器 github.com
进行登录授权,但实际都是跳转到http://blog.95id.com/login`
因为当时直接用服务程序的端口没问题,就将解决思路放在了nginx 转发过程上。
当时线上环境路由规则类似于:
第一层:nginx1 4005 (ssl、负载均配置在这)
第二层:nginx2 4005
第三层:oauth2-client 8082
再看nginx 的配置,第一层nginx 配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 4005;
server_name blog.95id.com;
ssl on;
ssl_certificate xxx.crt
……
location / {
proxy\_set\_header Host $host;
proxy\_set\_header X-Real-IP $remote\_addr;
proxy\_set\_header remote\_addr $remote\_addr;
proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;
proxy\_pass http://xxxserver\_4005;
......
upstream xxxserver_4005 {
server {nginx2-ip}:4005;
}
第二层nginx 的配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 4005;
server_name 0.0.0.0;
port_in_redirect off;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
因为当时nginx配置比较复杂,怎么调oauth的配置都不对,就对问题进行一个个简化拆分,一个问题一个问题的解决
有了nginx ,就会出现异常,那么从最简单的场景开始测试。
程序配置:
1
server.port=8082
nginx 配置:
nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name blog.95id.com;
port_in_redirect off;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
查看请求重定向详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
curl -Lv http://blog.95id.com/user_attr
* 打印信息中有删减,保留跳转的信息
* Connected to blog.95id.com (212.64.15.210) port 80 (#0)
> GET /user_attr HTTP/1.1
> Host: blog.95id.com
< HTTP/1.1 302
< Server: nginx/1.12.2
< Location: http://blog.95id.com/login
< Cache-Control: no-store
> GET /login HTTP/1.1
> Host: blog.95id.com
< HTTP/1.1 302
< Server: nginx/1.12.2
< Date: Tue, 14 Jan 2020 02:18:33 GMT
< Location: https://github.com/login/oauth/authorize?client_id=da2eedb7fbffa926eeab&redirect_uri=http://blog.95id.com/login&response_type=code&state=ApP8wq
> GET /login/oauth/authorize?client_id=da2eedb7fbffa926eeab&redirect_uri=http://blog.95id.com/login&response_type=code&state=ApP8wq HTTP/1.1
> Host: github.com
…….
< HTTP/1.1 302 Found
< Date: Tue, 14 Jan 2020 02:18:34 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Server: GitHub.com
< Status: 302 Found
< Location: https://github.com/login?client_id=da2eedb7fbffa926eeab&return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dda2eedb7fbffa926eeab%26redirect_uri%3Dhttp%253A%252F%252Fblog.95id.com%252Flogin%26response_type%3Dcode%26state%3DApP8wq
跳转一切正常
用 4005 端口 代理 oauth-client的8082
nginx配置
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 4005;
server_name blog.95id.com;
port_in_redirect off;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这时候打印请求详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
curl -Lv http://blog.95id.com:4005/user_attr
# 请求 blog.95id.com:4005/user_attr
* Connected to blog.95id.com (212.64.15.210) port 4005 (#0)
> GET /user_attr HTTP/1.1
> Host: blog.95id.com:4005
# 重定向 blog.95id.com/login
< HTTP/1.1 302
< Server: nginx/1.12.2
< Date: Tue, 14 Jan 2020 02:29:06 GMT
< Location: http://blog.95id.com/login
* Connected to blog.95id.com (212.64.15.210) port 80 (#1)
> GET /login HTTP/1.1
> Host: blog.95id.com
> User-Agent: curl/7.54.0
> Accept: */*
# 无法访问 blog.95id.com/login,缺少port,预期port 为 4005
< HTTP/1.1 502 Bad Gateway
< Server: nginx/1.12.2
如果把 nginx 的port_in_redirect 配置设置为 on,结果也是一样的,这个跳转是oauth-client程序内 spring-security-oauth2 自动做的跳转,也就是spring-security-oauth2 未能正常拿到4005 这个端口
再来看应用程序日志(DEBUG模式下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2020-01-14 10:58:43.388 DEBUG 1918 --- [http-nio-8082-exec-7] o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@5fc01a1e:org.apache.tomcat.util.net.NioChannel@58241aaa:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8082 remote=/127.0.0.1:43746]], Read from buffer: [0]
2020-01-14 10:58:43.388 DEBUG 1918 --- [http-nio-8082-exec-7] o.a.coyote.http11.Http11InputBuffer : Received [GET /user_attr HTTP/1.0
Host: blog.95id.com
X-Real-IP: 208.76.1.123
X-Forwarded-For: 208.76.1.123
Connection: close
User-Agent: curl/7.54.0
Accept: */*
]
…
2020-01-14 10:58:43.391 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
…
org.springframework.security.access.AccessDeniedException: Access is denied
…
2020-01-14 10:58:43.393 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://blog.95id.com/user_attr]
…
2020-01-14 10:58:43.394 DEBUG 1918 --- [http-nio-8082-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@1df284b4
2020-01-14 10:58:43.394 DEBUG 1918 --- [http-nio-8082-exec-7] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://blog.95id.com/login'
从打印的日志看,因为user_attr
需要授权允许,所以跳转到 /login
。但是当时spring-security已经拿不到4005端口了
打印的request信息也证实了,4005丢失不见了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"header": [
"host::blog.95id.com",
"x-real-ip::208.76.1.123",
"x-forwarded-for::208.76.1.123",
….
],
"info": [
"method:GET",
"uri:/print_request",
"url:http://blog.95id.com/print_request",
"context_path:",
"IP:127.0.0.1",
"ServerPort:80",
"LocalPort:8082",
"RemotePort:46856"
]
}
经过查找几次尝试,解决方法是在nginx -server 中加入配置:
1
proxy_set_header Host $host:$server_port;
这时request信息中,ServerPort = 4005
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"header": [
"host::blog.95id.com:4005",
"x-real-ip::208.76.1.123",
"x-forwarded-for::208.76.1.123",
….
],
"info": [
"method:GET",
"uri:/print_request",
"url:http://blog.95id.com:4005/print_request",
"context_path:",
"IP:127.0.0.1",
"ServerPort:4005",
"LocalPort:8082",
"RemotePort:53908"
]
}
该方案解决了端口丢失的问题,接着解决 https 变成 http的问题
443 是 ssl的默认端口,场景二修改监听端口,再加上 ssl的配置,nginx配置如下:
nginx配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 443;
ssl on;
server_name blog.95id.com;
index index.html index.htm index.php;
add_header Timing-Allow-Origin "*";
add_header Access-Control-Allow-Origin "*";
port_in_redirect off;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
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;
}
}
问题现象:
访问:https://blog.95id.com/user_attr
被redirect to :http://blog.95id.com/login
浏览器报 400异常(因为重定向的是http,没配80端口)
1
2
400 Bad Request
The plain HTTP request was sent to HTTPS port
curl 超时(因为重定向的是http,没配80端口)
1
2
3
4
[root@VM_0_17_centos oauth]# curl -Lv https://blog.95id.com/user_attr
* About to connect() to blog.95id.com port 80 (#0)
* Trying 212.64.15.210…
^C
这样配置发现 https 被重定向到 http,并且htts默认的443端口,变成了http的默认端口80
解决方案:
在oauth-client 配置文件中
1
2
3
4
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=X-Forwarded-Proto
#server.tomcat.protocol-header-https-value=https
server.use-forward-headers=true
nginx 配置中加入
1
proxy_set_header X-Forwarded-Proto $scheme;
测试可行
最后nginx配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 443;
ssl on;
server_name blog.95id.com;
index index.html index.htm index.php;
add_header Timing-Allow-Origin "*";
add_header Access-Control-Allow-Origin "*";
port_in_redirect off;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
#proxy_set_header Host $host;
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-Proto $scheme;
}
}
开启ssl,用4005端口代替默认端口443。并且沿用场景二的方案,便于将端口同时带过来,可是还是出问题了
沿用场景三的解决方案,并且带了场景二的方案,发现还是无法重定向到oauth2-server进行登录
访问:https://blog.95id.com:4005/user_attr
最后被重定向到:https://blog.95id.com/login
nginx 配置和场景三类似,只是修改了端口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 4005;
ssl on;
server_name blog.95id.com;
index index.html index.htm index.php;
add_header Timing-Allow-Origin "*";
add_header Access-Control-Allow-Origin "*";
port_in_redirect off;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
#proxy_set_header Host $host;
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-Proto $scheme;
}
}
https 是被带过来了,但是 端口4005丢失了,浏览器报不是私密链接(因为443端口没配ssl),curl 报连接超时 443端口没做转发
在场景二中配置的
1
proxy_set_header Host $host:$server_port;
也在其中,但是还是未生效
在nginx 配置中增加
1
proxy_set_header X-Forwarded-Port $server_port;
在oauth2-client 的配置文件application.properties中添加:
application.properties
1
server.tomcat.port-header=X-Forwarded-Port
改动后的nginx 配置如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
listen 4005;
ssl off;
server_name blog.95id.com;
index index.html index.htm index.php;
add_header Timing-Allow-Origin "*";
add_header Access-Control-Allow-Origin "*";
port_in_redirect off;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
#proxy_set_header Host $host;
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-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}
oauth-client 配置
1
2
3
4
5
6
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=X-Forwarded-Proto
server.use-forward-headers=true
server.tomcat.port-header=X-Forwarded-Port
server.port=8082
测试发现X-Forwarded-Port
这个配置是否能可以解决端口丢失的问题,那么是否能用来解决场景二的问题?回到场景二的配置
1
2
3
4
5
#关闭ssl
ssl off;
# Host 设置为不带port ,而是通过X-Forwarded-Port 传递
proxy_set_header Host $host;
#proxy_set_header Host $host:$server_port;
oauth-client 配置保持和场景三方案一样
测试的nginx 配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
listen 4005;
ssl off;
server_name blog.95id.com;
index index.html index.htm index.php;
add_header Timing-Allow-Origin "*";
add_header Access-Control-Allow-Origin "*";
port_in_redirect off;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header Cache-Control no-store;
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
#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-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}
测试通过,也就是 proxy_set_header Host $host:$server_port;
可以通过X-Forwarded-Port
方案替代
上述场景都是单层的nginx 环境,如果用上述配置放到线上(也就是开篇描述的现象),还是出了问题。
但是单层nginx的解决了,多层的还会远吗?而且经过这么多场景的模拟测试,该问题的本质也逐渐明了,就是nginx 在转发request过程中https和port丢失的问题,多层的情况就是要解决第一层nginx 到最内层的nginx 中一些参数的传递问题
第一层:nginx1 4005 (ssl、负载均配置在这)
第二层:nginx2 4005
第三层:oauth2-client 8082
访问:https://blog.95id.com:4005/user_attr
最后被重定向到:http://blog.95id.com/login
那么经过这么多场景,能够很清晰的定位问题: 协议头和port在nginx 代理过程中丢失,最有可能是第一层nginx 到 第二层nginx 过程中丢失。
另外在最外层nginx 配置了场景4nginx的配置,port不丢失了,但是最终还是重定向到了 http://blog.95id.com:4005/login,https丢了
两种解决方案:
两个方案均需要在外层的nginx 上将https 往下层传,所以都需要:
1
2
3
4
5
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-Port $server_port;
如果是多层,就是要将 schema 和 port 层层往下传
1)方案一:强制使用https
如果nginx服务并没有直接面向最终用户,而是在某些负载均衡/cdn后面,并且ssl证书是在这些负载均衡/cdn上面配置的,那么有可能会导致nginx无法正确获取客户端所使用的协议,从而导致无法将客户端使用的协议传递给最后面的应用程序。在这种情况下,可以修改nginx配置,强制通知服务使用https协议,也就是不使用 $scheme 变量,而是写死 https。
1
2
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto https;
2) 方案二:利用$http_x_forwarded_proto
变量
除了最外层的nginx ,其余层的nginx在的http 内配置:
1
2
3
4
5
6
map $http_x_forwarded_proto $thescheme{
default $http_x_forwarded_proto;
'' $scheme;
}
# $http_x_forwarded_proto 不为空 $thescheme 取 $http_x_forwarded_proto
# $http_x_forwarded_proto 为空 $thescheme 取$scheme
在转发服务的nginx -server 中配置:
1
2
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto $thescheme;
Bingo !尝试大几十遍终于都可以了
上述这些场景导致OAuth2-Client 无法正常使用,本质原因还是因为 request的schema 和port 无法下传到 应用程序导致的。如果java应用程序能正常拿到,就不存在这些问题,所以只需要解决,request从nginx到client,不丢失相关信息即可
通过这些配置,发现后面方案是可以兼容解决前面的场景,所以这里可以给个最终的配置方案
不管是 默认端口代理,还是开启Https ,还是层层代理,这个配置都可以使OAuth2Client 生效
1)在应用程序的主配置文件中加入:
1
2
3
4
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=X-Forwarded-Proto
server.use-forward-headers=true
server.tomcat.port-header=X-Forwarded-Port
2)在nginx 配置中,http模块下,加一个map设置thescheme
参数用来传递scheme,在代理服务的server配置中,加入header
相关配置(proxy_set_header
开头):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
http {
map $http_x_forwarded_proto $thescheme{
default $http_x_forwarded_proto;
'' $scheme;
}
……
server {
listen 4005;
server_name 0.0.0.0;
location / {
proxy\_pass http://127.0.0.1:8082;
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 $thescheme;
proxy\_set\_header X-Forwarded-Port $server\_port;
}
......
}
3)在springboot应用程序中加入如下配置
1
2
3
4
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=X-Forwarded-Proto
server.use-forward-headers=true
server.tomcat.port-header=X-Forwarded-Port
如果是非内嵌的tomcat , 则需要修改tomcat 的配置(无tomcat,未测试)
1
2
3
4
5
测试用的OAuth2-Client源码 和 nginx 最终配置方案可以见 https://github.com/ifengkou/oauth2-client-157
server.tomcat.port-header
设定http header使用的,用来覆盖原来port的value.server.tomcat.protocol-header
设定Header包含的协议,通常是 X-Forwarded-Proto,如果remoteIpHeader有值,则将设置为RemoteIpValve.server.tomcat.protocol-header-https-value
设定使用SSL的header的值,默认https.server.tomcat.remote-ip-header
设定remote IP的header,如果remoteIpHeader有值,则设置为RemoteIpValveserver.use-forward-headers=true
该配置将指示tomcat从HTTP头信息中去获取协议信息(而非从HttpServletRequest中获取),同时,如果你的应用还用到了spring-security则也无需再配置。可以具体见Oauth2-client 项目中 Oauth2Client157Application文件内的 printRequest方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List
//获得所有的头的名称
Enumeration
while(headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
headerInfo.add(headerName+"::"+headerValue);
}
List
urlInfo.add("method:" + request.getMethod());
urlInfo.add("uri:" + request.getRequestURI());
urlInfo.add("url:" + request.getRequestURL());
urlInfo.add("ServerPort:" + request.getServerPort());
urlInfo.add("LocalPort:" + request.getLocalPort());
urlInfo.add("serverName:"+request.getServerName());
urlInfo.add("schema:"+request.getScheme());
访问:https://blog.95id.com:4005/print_request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"header": [
"host::blog.95id.com",
"x-real-ip::213.123.1.2",
"x-forwarded-proto::https",
"x-forwarded-port::4005",
……
],
"info": [
"method:GET",
"uri:/print_request",
"url:https://blog.95id.com:4005/print_request",
"context_path:",
"IP:213.123.1.2",
"ServerPort:4005",
"LocalPort:8082",
"RemotePort:37516",
"serverName:blog.95id.com",
"schema:https"
]
}
nginx ssl 证书配置
1
2
3
4
5
6
7
8
ssl on;
ssl_certificate /data/apps/wwwroot/Nginx/1_blog.95id.com_bundle.crt;
ssl_certificate_key /data/apps/wwwroot/Nginx/2_blog.95id.com.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
配置自动获取协议方式
通过这种方式配置,客户端可以使用http或者https协议,应用服务能够自动获取客户端使用的协议。
配置nginx 反向代理 proxy_set_header 。 在server里面,增加下面的配置:
1
2
3
4
5
6
7
8
9
server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-wiz-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 Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
…
}
如果您的nginx有多层,那么,您可能还需要额外的配置: 在http 模块中加入以下配置:
1
2
3
4
map $http_x_forwarded_proto $thescheme{
default $http_x_forwarded_proto;
'' $scheme;
}
然后在server模块(或者http模块)里面,将前面配置中的proxy_set_header X-Forwarded-Proto $scheme;
,替换为下面的代码:
1
proxy_set_header X-Forwarded-Proto $thescheme;
如果您的nginx服务,并没有直接面向最终用户,而是在某些负载均衡/cdn后面,并且您的ssl证书是在这些负载均衡/cdn上面配置的,那么有可能会导致nginx无法正确获取客户端所使用的协议,这时可以强制https
1
proxy_set_header X-Forwarded-Proto "https";
手机扫一扫
移动阅读更方便
你可能感兴趣的文章