Docker内nginx使用301强制http跳转https,解决请求http无数据返回问题

那年仲夏 提交于 2019-11-27 10:27:56

Docker内nginx使用301强制http跳转https,解决请求http无数据返回问题

1、情景说明:

公司这几天进行数据安全升级,大数据自然首当其冲了,基础环境nginx,supervisor等都是安装在docker内,第一次发文,不对的地方请多度指教。

2、 nginx下default.conf配置

配置问下供两个server,先说下第一个server
1、docker容器启动时,需对外映射443 和80端口,其中443端口供https使用,这里使用301进行重定向跳转到443端口

server {
listen 80;
server_name xxx;
index index.html index.php ;
access_log  /var/log/nginx/80-access.log;
error_log  /var/log/nginx/80-error.log;
return      301 https://$server_name$request_uri;
location ~ / {
root /code/public;
index index.html index.php;
}

}
2、第二个server为配置https ssl
需要注意的是, ssl on必须要开启,ssl证书这里就不过多描述,可申请免费ssl,也可通过openssl自己颁发一个

server {
listen       443 ;
## listen for ipv6
listen   [::]:443 default ipv6only=on;
server_name  _;

ssl on;
ssl_certificate /code/public/conf.d/.crt;
ssl_certificate_key /code/public/conf.d/xxx.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;                                            
ssl_prefer_server_ciphers on;
root /code/public;

}

3、ok,配置完conf文件,docker中重启下nginx,或者重启docker都可以,这时通过curl请求一下http域名
curl -I http://xxx:80

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Tue, 12 Mar 2019 02:54:30 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://xxx:443

此时发现已经成功跳转到https,由于我们的nginx服务是用来提供接口,为了不影响服务端,所以才强制http跳转到https,本着不影响服务为原则,于是我就测试一下通过http调接口,看看是否有数据返回,命令如下

curl -L -XPOST http://xxx:9100/city/bi.php -d 'mod=/CityBrain_Warning_today_type_count' -k -v

-k :跳过ssl证书验证,-v:debug,-L:重定向

请求信息如下

* About to connect() to xxx port 9100 (#0)
*   Trying 10.0.0.27...
* Connected to xxx (10.0.0.27) port 9100 (#0)
> POST /city/bi.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: xxx:9100
> Accept: */*
> Content-Length: 39
> Content-Type: application/x-www-form-urlencoded
> 
* upload completely sent off: 39 out of 39 bytes
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Tue, 12 Mar 2019 03:00:28 GMT
< Content-Type: text/html
< Content-Length: 178
< Connection: keep-alive
< Location: https://xxx:443/xxx
< 
* Ignoring the response-body
* Connection #0 to host xxx left intact
* Issue another request to this URL: 'https://xxx:443/xxx'
* Violate RFC 2616/10.3.2 and switch from POST to GET
* Found bundle for host xxx: 0x1c09e60
* About to connect() to xxx port 443 (#1)
*   Trying 10.0.0.27...
* Connected to xxx (10.0.0.27) port 443 (#1)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
* Server certificate:
*       subject: E=xxx@163.com,CN=xxx,OU=it,O=tsl,L=beijing,ST=beijing,C=cn
*       start date: Mar 11 03:04:16 2019 GMT
*       expire date: Mar 10 03:04:16 2020 GMT
*       common name: xxx
*       issuer: E=xxx@163.com,CN=xxx,OU=it,O=tsl,L=beijing,ST=beijing,C=cn
> GET /city/bi.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: xxx
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 12 Mar 2019 03:00:28 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Vary: Accept-Encoding
< 
* Connection #1 to host xxx left intact

从信息中可以看到,已经成功跳转到https,但是跳转到https后,post请求的参数为何不见了呢,其中upload completely sent off: 39 out of 39 bytes 是在请求http接口的信息,但是跳转后https后却没有了这条信息

而后便查了下301、3xx等的含义:

  1. 对于301、302的location中包含的重定向url,如果请求method不是GET或者HEAD,那么浏览器是禁止自动重定向的,除非得到用户的确认,因为POST、PUT等请求是非冥等的(也就是再次请求时服务器的资源可能已经发生了变化)。
  2. 虽然rfc明确了上述的规定,但是很多的浏览器不遵守这条规定,无论原来的请求方法是什么都会自动用GET方法重定向到location指定的url。就是说现存的很多浏览器在遇到POST请求返回301、302状态码的时候自动用GET请求location中的url,无需用户确认。
  3. HTTP 1.1中新增了303、307状态码,用来明确服务器期待客户端进行何种反应。
  4. 303状态码其实就是上面301、302状态码的”不合法”动作,指示客户端可以自动用GET方法重定向请求location中的url,无需用户确认。也就是把前面301、302状态码的处理动作”合法化”了。
  5. 307状态码就是301、302原本需要遵守的规定,除GET、HEAD方法外,其他的请求方法必须等客户确认才能跳转。
  6. 303、307其实就是把原来301、302不”合法”的处理动作给”合法化”,因为发现大家都不太遵守,所以干脆就增加一条规定。

原来301请求的数据会丢失,而307则不会,于是果断将301改为307,重启nginx

再次请求接口
发现已经有数据返回

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!