为什么现在所有网站都要用HTTPS,HTTP不是挺好用的吗?我当时就笑了,这就像问为什么出门要锁门一样。今天就来聊聊HTTPS这个话题,从原理到实际配置,保证让你看完就能上手。
说起HTTPS,我记得刚开始做运维那会儿,大家对SSL证书还挺陌生的,觉得这玩意儿又贵又麻烦。现在回头看,真是时代变了,不用HTTPS的网站浏览器都会标红警告,用户看到就跑了。
简单说,HTTPS就是HTTP穿了件防弹衣。你知道HTTP吧,就是我们平时访问网站用的协议,但它有个致命问题——裸奔。所有数据都是明文传输,就像在大街上喊话一样,谁都能听到。
我之前遇到过一个案例,某个电商网站用的HTTP,结果用户在咖啡厅连WiFi购物时,密码被人截获了。这事儿闹得挺大,最后老板拍桌子要求全站HTTPS。
HTTPS在HTTP基础上加了SSL/TLS层,这个SSL就像个翻译官,把你要说的话先加密,传到对方那里再解密。即使有人在中间偷听,听到的也是一堆乱码。
具体工作流程是这样的:
服务器客户端(浏览器)服务器客户端(浏览器)3. 验证证书是否可信7. 使用协商的对称密钥进行安全通信1. 发起HTTPS连接请求2. 返回SSL证书(包含公钥)4. 生成随机对称密钥5. 用服务器公钥加密随机密钥并发送6. 用私钥解密获得对称密钥加密数据传输加密数据传输
这个过程叫SSL握手,听起来复杂,其实就几毫秒的事儿。
除了安全性,还有几个现实原因让你不得不用:
搜索引擎偏爱 Google早就明确表示,HTTPS是排名因素之一。百度虽然没明说,但你看看现在排前面的网站,基本都是HTTPS。不用的话,SEO就输在起跑线上了。
浏览器警告 Chrome、Firefox这些主流浏览器,看到HTTP网站就会显示"不安全"标识。用户看到这个,心里就犯嘀咕,还会继续访问吗?
功能限制 很多新的Web API,比如地理位置、摄像头访问等,浏览器强制要求HTTPS环境。不用的话,这些功能就别想了。
我有个朋友做了个在线拍照的网站,结果因为没用HTTPS,摄像头功能在Chrome上根本用不了,用户投诉一大堆。
以前SSL证书动辄几千块,现在免费的一大把,主要有这几个渠道:
Let's Encrypt 这是最知名的免费SSL证书提供商,Mozilla、Google等大厂支持的。证书有效期3个月,但可以自动续期。我现在大部分项目都用这个。
阿里云免费证书 阿里云每年提供20个免费的单域名证书,申请简单,适合小项目。不过现在限制比以前严了。
腾讯云免费证书 和阿里云类似,也有免费额度,界面做得还不错。
Cloudflare 如果你用Cloudflare的CDN服务,SSL证书是免费包含的,而且配置超简单。
我个人推荐Let's Encrypt,虽然配置稍微复杂点,但胜在稳定可靠,而且没有数量限制。
申请Let's Encrypt证书最常用的工具是Certbot,安装很简单:
# CentOS/RHEL
yum install certbot
# Ubuntu/Debian
apt-get install certbot
# 或者用snap安装(推荐)
snap install --classic certbot
申请证书有几种方式,我常用的是webroot模式:
certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com
这个命令会在你的网站根目录下创建验证文件,Let's Encrypt通过访问这个文件来验证域名所有权。
如果你的网站还没上线,可以用standalone模式:
certbot certonly --standalone -d example.com
这种方式会临时启动一个Web服务器来完成验证,但需要先停止现有的Web服务。
申请成功后,证书文件会保存在/etc/letsencrypt/live/example.com/
目录下:
fullchain.pem
- 完整证书链privkey.pem
- 私钥文件拿到证书后就要配置Nginx了,这里有不少坑要注意。
基础配置是这样的:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 其他配置...
}
但这样配置安全性还不够,需要加强一下:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
# SSL会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 其他安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
location / {
root /var/www/html;
index index.html index.htm;
}
}
别忘了还要配置HTTP到HTTPS的重定向:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
配置完记得测试一下语法:
nginx -t
没问题就重载配置:
nginx -s reload
Let's Encrypt证书只有3个月有效期,手动续期太麻烦,必须搞自动化。
Certbot提供了续期命令:
certbot renew --dry-run
--dry-run
参数是测试模式,确认没问题后去掉这个参数。
设置定时任务自动续期:
crontab -e
添加这行:
0 2 * * * /usr/bin/certbot renew --quiet && /usr/sbin/nginx -s reload
这样每天凌晨2点会检查证书是否需要续期,如果需要就自动续期并重载Nginx。
我之前就遇到过证书过期的尴尬,网站突然不能访问了,用户投诉电话打爆了。从那以后我就特别重视自动续期这块。
证书链不完整
有时候会遇到移动端访问正常,但某些老设备或软件报证书错误。这通常是证书链配置问题,确保使用fullchain.pem
而不是cert.pem
。
混合内容警告 HTTPS页面引用HTTP资源会被浏览器阻止。检查页面中的图片、CSS、JS等资源链接,全部改成HTTPS或相对路径。
性能问题 SSL握手确实会增加一些延迟,但可以通过启用HTTP/2、配置SSL会话缓存等方式优化。现在的服务器性能都不错,影响其实很小。
我记得有次客户抱怨网站变慢了,排查半天发现是SSL配置有问题,没启用会话缓存,每次访问都要重新握手。调整后性能立马恢复正常。
生产环境一定要监控证书状态,我一般用这几种方式:
命令行检查
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
在线工具 SSL Labs的SSL Test是个不错的在线检测工具,能给出详细的安全评分和建议。
监控脚本 写个简单脚本定期检查证书有效期,快过期时发邮件提醒:
#!/bin/bash
DOMAIN="example.com"
EXPIRE_DATE=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRE_TIMESTAMP=$(date -d "$EXPIRE_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
DAYS_LEFT=$(( ($EXPIRE_TIMESTAMP - $CURRENT_TIMESTAMP) / 86400 ))
if [ $DAYS_LEFT -lt 30 ]; then
echo "证书将在 $DAYS_LEFT 天后过期!" | mail -s "SSL证书过期提醒" admin@example.com
fi
启用HTTP/2
现在的浏览器基本都支持HTTP/2,能显著提升性能。在Nginx配置中加上http2
就行:
listen 443 ssl http2;
配置OCSP Stapling 这个功能可以减少客户端验证证书的时间:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
使用CDN 如果网站访问量大,建议配合CDN使用。Cloudflare、阿里云CDN等都支持SSL,而且能进一步提升性能。
说到CDN,我之前有个项目,服务器在国外,国内访问很慢。接入CDN后不仅速度快了,SSL配置也简化了不少,一举两得。
HTTPS已经不是可选项,而是必需品了。从安全性、SEO、用户体验各个角度看,都没理由不用。
Let's Encrypt让SSL证书的门槛降到了零,配置也不复杂,就是要注意自动续期和监控。Nginx的SSL配置看起来参数很多,但大部分都是模板化的,复制粘贴改改域名就能用。
最重要的是要养成好习惯:新项目一开始就配置HTTPS,不要等上线后再改;定期检查证书状态;关注安全更新。
我见过太多因为SSL配置问题导致的故障,大部分都是可以避免的。多花点时间在前期配置上,后面能省很多麻烦。
现在各大云厂商的SSL证书服务也越来越完善,如果不想折腾命令行,直接用云服务也是不错的选择。关键是要行动起来,别再让你的网站裸奔了!
如果这篇文章对你有帮助,记得点赞转发哦!有问题欢迎在评论区讨论,我会尽量回复大家。想了解更多运维干货,记得关注@运维躬行录,我们一起在运维的路上越走越远!