8月份要把服务迁移到青云上,负责搭建 HTTPS 服务的Daniel苦恼两天有余,配置 HTTPS 时一直报告下述问题:
400 Bad Request
The plain HTTP request was sent to HTTPS port
这是什么问题?
这个问题是我们尝试在云服务上搭建 HTTPS 时出现的,要清楚复述这个问题有点复杂,各位直接移步看 stackoverflow 上的 Dealing with nginx 400 “The plain HTTP request was sent to HTTPS port” error 这个例子吧,相信你会有很多收获。
以下这段会帮助你理解其实质:
The error says it all actually. Your configuration tells Nginx to listen on port 80 (HTTP) and use SSL. When you point your browser to http://localhost, it tries to connect via HTTP. Since Nginx expects SSL, it complains with the error.
HTTPS是什么?
HTTPS: HTTP over TLS, HTTP over SSL, and HTTP Secure.
简单地说,HTTPS 就是在一条由 SSL/TLS 加密的连接(connection)上传输HTTP数据,目的是防止HTTP内容被偷听和篡改。
换言之,HTTPS在一个不安全的网络上创建了一个安全通道。
HTTP数据有一个加密和解密的过程。理解了这一点你就理解了在云上配置的两种方案。
我们应用HTTPS做什么?
无他,就是为了防止内容被篡改。
nginx的配置
一定要熟悉nginx的配置,否则,你会到处乱搜解决方法,不是怀疑这儿配错了,就是怀疑那儿配错了。
搭建负载均衡器
有两个方案可以实现HTTPS服务。方案一就是由负载均衡器(LB = Load Balancer)来实现,方案二由后端WebServer来实现。
方案一:LB实现
请按照青云的 搭建 HTTPS 协议的负载均衡器指南 的要求进行 HTTPS 协议搭建。因为我们使用路由器,情况有些许不同,要点:
- LB配置HTTPS
将你的服务器证书的“证书内容” 和 “私钥”配好,监听HTTPS协议,443端口。 - 路由器配置
在路由器上将443映射到后端的80端口(HTTP)。 - 后端nginx配置
这里只需要配置HTTP服务即可,因为解密数据的任务由LB承担了,这里自然不需要配置HTTPS了。
注:Daniel就是折在这里了,他在路由器里将443映射到后端的443 ssl,路由器过来的数据已经解密了,已经是plain HTTP request,还要发送到HTTPS port(443)上,当然就会 complain with the error了。
方案二:后端WebServer实现
- LB配置TCP
监听TCP协议,443端口。 - 路由器配置
在路由器上将443映射到后端的443端口(HTTPS)。 - 后端nginx配置
按照标准的HTTPS服务进行配置。如下:
server {
listen 80;
listen 443 ssl;
server_name c.example.com;
ssl_certificate /usr/local/nginx/conf/app/example/example.crt;
ssl_certificate_key /usr/local/nginx/conf/app/example/example.key;
root /home/app/c.example.com/;
location ~ \.(htm|html)$ {
add_header Cache-Control no-store;
expires -1;
}
location / {
index index.html;
}
access_log /home/logs/c.example.com/access.log access;
error_log /home/logs/c.example.com/error.log info;
}
相对于“原始的nginx配置”的改进:
- 80和443在一个 server 里面即可(保持简单性、一致性)。
- index里的index.php删除,因为网站根本不提供php服务。(不该有的东西一点都不要有,保持简单、简洁)
- 顺序调整(增强可理解性)。
附:原始的nginx配置
建议
- 请记住尽可能使用谷歌搜索服务。
- 优先查阅以下网站:
为何使用https?
我们使用https的初心是防止HTTP内容被篡改,因为做正常CPS业务的导航网站常遇到被流氓推广者强行篡改内容从而劫持流量进行跳转的情况。
跳转地址:http://c.example.com => https://c.example.com。
协议切换
-
zz
js 负责跳转,js 文件中类似语句https://c.example.com/shopid.html?uid=,其中https即指明使用https协议。js文件位于www网站/$version/toolbar/js/toolbar.js。当前3.7和3.9版本在正常维护。
-
sm
由软件提供跳转,需要修改配置文件 unionmap.xml,软件重启后会下载该配置文件的 zip 包(2015-09-07)。该配置文件在 http://click.example.com/admin 后台的商城管理下生成,当下仅点击生成新的商城联盟映射表即可,其他无需操作。
注:由于几经演变,事先需修改 db_cashback 的 t_u_union 表:update t_u_union set un_px_url=replace(un_px_url,'https','http'); 而无需通过后台页面功能修改任何内容。
-
unionmap.xml.sample