商用证书 HTTPS 常见部署问题

客户端程序访问 HTTPS 域名时,提示证书不匹配。

原因:客户端不支持 SNI
当域名经过CDN,或者一个IP上有多个不同证书的 HTTPS 网站时,如果客户端程序不支持 SNI,就会提示证书不匹配的现象。

排查步骤:

  1. Windows 用 IE、Firefox、Chrome 等浏览器打开该 https 网站,显示证书正常。
  2. Linux 用 curl -v https://domain.com | head -1 命令,显示证书正常。
    以上任意一个步骤均可以验证服务器证书部署是否有问题。如果服务器证书没有问题,则问题出在客户端不支持 SNI。

解决办法:

  1. 临时不校验证书,等后续客户端的代码升级之后,再进行校验证书。
  2. 升级 http client 客户端的版本库到最新的稳定版本,同时修改相应的配置。
  3. 域名解析不经过CDN,或是该域名在服务器上作为第一个或是唯一的SSL证书部署。[临时回避触发问题的条件,治标不治本]

浏览器访问HTTPS 网站时,静态资源显示有问题, 提示 mix-content

原因:访问流量经过了一个或多个负载均衡,后端代码以为用户访问的还是 HTTP 协议,拼接静态资源的URL仍然以 "http://" 开头。
解决办法: 服务器需要额外配置,某些后端使用旧框架代码需要微调。

nginx 配置

location / {
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_ignore_client_abort on;
  proxy_pass http://upstream_srv;
  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;
}

tomcat 配置

server.xml 文件中, 节点下面 或是  节点下面 增加这一行:


后端代码框架处理:

判断 HTTP 头 X-Forwarded-Proto 为 https 或 HTTPS 头为 on,两种情况存在任意一个,
则认为此服务是 https 协议。

# PHP 代码判断协议 schema
# _SERVER['HTTPS'] == 'on' 或 _SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' 时,为 https 协议
$scheme = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https' : 'http';

前端代码处理

  • 佛系前端1
    前端代码不判断协议类型,绝对路径不写 http://domain.com/j.js , 也不写 https://domain.com/j.js , 直接写成自适应的 //domain.com/j.js , 谷歌,推特都是这样做的。
  • 佛系前端2
    当然 url中不写域名,写成相对路径的 /path/file.js 或是 ../path/file.js 也是没有问题的。

强制 nginx 跳转到 https


set $flag 0;
if ($scheme = "http")  { set $flag "1${flag}"; }
if ($scheme = "https") { set $flag "0${flag}"; }
if ($http_x_forwarded_proto = "https" ) { set $flag "0${flag}"; }
if ($flag ~ "^1") { rewrite ^(.*)$  https://$host/$1 permanent;}

# HSTS
add_header Strict-Transport-Security "max-age=120; preload";

HTTP/2 协议 不支持 WebSocket

截至到目前,2017年11月,HTTP/2 协议 不支持 WebSocket ,如果有业务需要使用WebSocket 协议,记得要关闭 HTTP/2 。
如果有业务依赖https,又需要推送消息,可考虑 SSE(使用 polyfills 解决 IE/EDGE 的支持问题,如 https://github.com/Yaffle/EventSource)

你可能感兴趣的:(商用证书 HTTPS 常见部署问题)