Nginx 配置HTTPS证书
Nginx 配置HTTPS证书
现在网站都要HTTPS,配置证书是必备技能。
1. 为什么要HTTPS
- 加密传输,防窃听
- 浏览器安全标识
- SEO 排名加分
- 现在主流浏览器都要求HTTPS
2. 证书文件
一般有两个文件:
.crt:证书文件.key:私钥文件
# 证书文件放在这里
/etc/nginx/ssl/
├── example.com.crt
└── example.com.key
3. 基本HTTPS配置
server {
listen 443 ssl;
server_name example.com;
# 证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 其他配置
location / {
root /var/www/html;
index index.html;
}
}
4. HTTP 跳转 HTTPS
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
5. 优化配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 优化SSL配置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# 加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}
6. 检查配置
# 检查配置语法
nginx -t
# 重载配置
nginx -s reload
7. 证书申请
免费证书:
- Let's Encrypt(用 certbot 申请)
- 阿里云免费证书
- 腾讯云免费证书
certbot 申请:
# 安装 certbot
yum install certbot python3-certbot-nginx
# 自动申请并配置
certbot --nginx -d example.com
自动续期:
# 测试续期
certbot renew --dry-run
# 加入定时任务
0 3 * * * certbot renew --quiet
8. 常见问题
1)证书不生效
- 检查证书路径对不对
- 检查文件权限
- 重载 Nginx
2)浏览器提示不安全
- 证书过期了
- 域名不匹配
- 中间证书没装全
3)HTTPS 访问慢
- 开启 HTTP/2
- 优化 SSL 会话缓存
4)证书续期失败
- 检查域名解析
- 检查80端口是否通
- 手动运行 certbot 看报错
9. 证书有效期
- 免费证书一般 3 个月
- 要设置自动续期
- 不然到期网站就挂了
10. 生产建议
1)强制 HTTPS
- HTTP 全部 301 跳转
- 开启 HSTS
2)开启 HTTP/2
- listen 443 ssl http2
- 提升访问速度
3)定期检查证书
- 监控证书到期时间
- 提前续期
4)中间证书
- 有些证书要把中间证书合并
- 不然浏览器不信任
总结
Nginx 配置HTTPS要点:
- 配置证书和私钥路径
- HTTP 跳转 HTTPS
- 开启 HTTP/2
- 优化 SSL 会话缓存
- 用 certbot 免费申请
- 设置自动续期
- 定期检查证书有效期
- 开启 HSTS
- 注意中间证书问题
HTTPS 是网站标配,一定要配置好。
PHP file_get_contents获取https内容失败
前言
PHP用file_get_contents获取http内容没问题,换成https就报错了?这是最常见的问题,一般就是openssl扩展没开,或者SSL证书验证没过。本文讲怎么解决。
一、问题现象
<?php
$url = 'https://api.example.com/data';
$result = file_get_contents($url);
echo $result;
结果报错:
Warning: file_get_contents(): failed to open stream: Unable to find the wrapper "https"
或者:
Warning: file_get_contents(): SSL operation failed with code 1
二、常见原因
原因1:openssl扩展没装
PHP默认不开openssl扩展,file_get_contents不支持https。
原因2:allow_url_open没开
php.ini里禁了远程打开。
原因3:SSL证书验证失败
对方网站证书有问题,PHP验证不通过。
原因4:网络问题
服务器出不去,或者DNS解析不了。
三、排查步骤
第一步:看openssl扩展装了没
php -m | grep openssl
有输出就是装了,没输出就是没装。
或者写个phpinfo:
<?php
phpinfo();
搜"openssl",看有没有。
第二步:看allow_url_open开了没
<?php
echo ini_get('allow_url_fopen');
输出1就是开了,空就是没开。
第三步:用curl测试
curl https://api.example.com/data
curl能通就是PHP的问题,curl也不通就是网络问题。
四、解决方法
方法1:装openssl扩展(推荐)
CentOS
yum install php-openssl
或者:
yum install php7x-openssl
(x是你的PHP版本)
Ubuntu
apt install php-openssl
装完重启
systemctl restart php-fpm
方法2:改php.ini配置
打开php.ini,找到:
;extension=openssl
去掉前面的分号:
extension=openssl
然后重启php-fpm。
方法3:关掉SSL验证(临时)
不想改配置,可以在代码里关验证:
<?php
$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
]);
$result = file_get_contents('https://api.example.com/data', false, $context);
echo $result;
注意: 这是临时方案,生产环境建议把证书配好。
方法4:改用curl(推荐)
file_get_contents不好用,直接用curl:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo '错误: ' . curl_error($ch);
}
curl_close($ch);
echo $result;
curl比file_get_contents好用多了,推荐用curl。
五、常见坑
坑1:CLI和FPM配置不一样
命令行里openssl装了,网页上还是不行。
原因: CLI和FPM用不同的php.ini。
解决: 看phpinfo里的配置路径,改对应的那个。
坑2:装了扩展没重启
装完忘了重启php-fpm。
解决:
systemctl restart php-fpm
坑3:对方网站证书过期
对方网站SSL证书过期了,PHP验证不通过。
解决: 关验证,或者让对方更新证书。
坑4:allow_url_fopen没开
php.ini里禁了远程打开。
解决:
allow_url_fopen = On
坑5:防火墙挡了出站
服务器防火墙挡了443端口出站。
解决:
# 看能不能出去
curl -I https://www.baidu.com
# 不行的话开防火墙
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload
六、POST请求示例
file_get_contents发POST:
<?php
$url = 'https://api.example.com/submit';
$data = http_build_query([
'name' => '张三',
'age' => 20
]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $data,
'timeout' => 30
],
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
]);
$result = file_get_contents($url, false, $context);
echo $result;
还是建议用curl,更灵活。
七、封装函数
function http_get($url, $timeout = 30)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
$result = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
return ['code' => -1, 'msg' => $error];
}
curl_close($ch);
return ['code' => 0, 'data' => $result];
}
// 使用
$res = http_get('https://api.example.com/data');
if ($res['code'] == 0) {
echo $res['data'];
} else {
echo '请求失败: ' . $res['msg'];
}
总结
记住:
- file_get_contents不支持https,是openssl扩展没装
- 装openssl扩展,重启php-fpm
- 或者关SSL验证临时解决
- 最推荐:改用curl,比file_get_contents好用多了
推荐方案:
直接用curl,别用file_get_contents搞https。
遇到问题加QQ23979811 协助处理
Nginx HTTPS 配置详解
Nginx HTTPS 配置详解
现在网站都要上 HTTPS,Nginx 配置 SSL 很简单。
1. 准备证书
免费证书可以用:
- Let's Encrypt
- 阿里云免费证书
- 腾讯云免费证书
下载后有两个文件:
- 证书文件:xxx.pem
- 私钥文件:xxx.key
2. 基础配置
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/xxx.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.key;
location / {
root /www/wwwroot/html;
index index.html;
}
}
3. HTTP 跳转 HTTPS
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
4. 优化配置
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/xxx.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.key;
# SSL 优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
root /www/wwwroot/html;
index index.html;
}
}
5. 验证配置
# 检查配置是否正确
nginx -t
# 重载配置
nginx -s reload
6. 常见问题
1)证书不生效:
- 检查证书路径对不对
- 检查证书文件名
- 重载 Nginx
2)浏览器提示不安全:
- 证书域名不对
- 证书过期了
- 缺少中间证书
3)HTTP 打不开:
- 检查 80 端口是否放行
- 检查防火墙
7. Let's Encrypt 免费证书
用 certbot 自动申请:
# 安装
yum install certbot python3-certbot-nginx
# 自动申请并配置
certbot --nginx -d www.example.com
# 自动续期
certbot renew
总结
Nginx HTTPS 配置要点:
- 443 端口监听 SSL
- 配置证书和私钥路径
- HTTP 跳转 HTTPS
- 开启 http2 提升性能
- 定期续期证书
现在做网站,HTTPS 是标配。
Nginx 配置 HTTPS 详解
Nginx 配置 HTTPS 详解
现在网站都要求上 HTTPS,Nginx 配置 HTTPS 是运维必备技能。
1. 申请 SSL 证书
免费证书推荐:
- Let's Encrypt(免费 90 天)
- 阿里云/腾讯云免费 DV 证书
用 acme.sh 申请 Let's Encrypt:
# 安装 acme.sh
curl https://get.acme.sh | sh
# 申请证书
~/.acme.sh/acme.sh --issue -d www.example.com --webroot /www/wwwroot/example.com/
# 安装证书
~/.acme.sh/acme.sh --install-cert -d www.example.com \
--key-file /www/server/ssl/private.key \
--fullchain-file /www/server/ssl/cert.crt
2. Nginx 基础 HTTPS 配置
server {
listen 443 ssl;
server_name www.example.com;
# 证书文件
ssl_certificate /www/server/ssl/cert.crt;
ssl_certificate_key /www/server/ssl/private.key;
# SSL 优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
root /www/wwwroot/example.com;
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
3. HTTP 自动跳转 HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
4. 优化 HTTPS 性能
开启 HTTP/2:
listen 443 ssl http2;
HSTS 强制 HTTPS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
开启 OCSP Stapling:
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 114.114.114.114 valid=300s;
5. 常见问题
1)证书不生效:
- 检查证书路径对不对
- 证书文件格式是否正确
- Nginx 配置重载了吗
2)混合内容问题:
- 页面里有 http:// 的资源,浏览器会拦截
- 全部改成 https:// 或 // 协议相对路径
3)证书过期:
- 免费证书 90 天过期
- 用 acme.sh 自动续期
# acme.sh 自动安装了定时任务
crontab -l | grep acme
6. 检查配置
# 检查 Nginx 配置
nginx -t
# 重载配置
nginx -s reload
# 测试证书
curl -I https://www.example.com
总结
Nginx 配置 HTTPS 要点:
- 申请 SSL 证书
- 配置 443 端口和证书路径
- HTTP 跳转 HTTPS
- 开启 HTTP/2 和 SSL 优化
- 设置自动续期
现在没有 HTTPS 的网站浏览器都标"不安全",赶紧给网站配上。
HTTPS 原理详解:从证书到握手的完整流程
前言
HTTPS 现在已经是网站标配了,但很多人只知道"HTTPS 更安全",却不知道它到底是怎么安全的。本文用最通俗的方式,带你完整理解 HTTPS 的工作原理。
一、HTTP 为什么不安全
HTTP 是明文传输的,就像你在明信片上写信,邮局的每个人都能看到内容。
具体来说,HTTP 有三个问题:
- 窃听风险:中间人可以看到你传输的所有内容
- 篡改风险:中间人可以修改你传输的内容
- 冒充风险:中间人可以冒充服务器欺骗你
HTTPS 就是为了解决这三个问题而生的。
二、HTTPS = HTTP + SSL/TLS
HTTPS 本质上就是在 HTTP 和 TCP 之间加了一层 SSL/TLS 协议。
TLS 做了三件事:
- 加密:数据加密传输,中间人看不到内容
- 完整性校验:数据被篡改了能发现
- 身份认证:确认你连接的是真的服务器
三、数字证书
HTTPS 信任的基础是数字证书。
你可以把数字证书理解成身份证:
- 谁发的:CA 机构(证书颁发机构)
- 证明什么:这个域名属于谁
- 有效期:身份证有有效期,证书也有
- 怎么验证:CA 用私钥签名,浏览器用公钥验证
常见的免费证书:Let's Encrypt
四、TLS 握手流程
TLS 握手是 HTTPS 最核心的部分,用大白话讲一遍:
第一步:Client Hello
客户端说:"你好,我支持这些加密算法,这是我的随机数 A。"
Client → Server:
- TLS 版本
- 支持的加密算法列表
- 随机数 A
第二步:Server Hello
服务器说:"好的,我们用这个加密算法,这是我的随机数 B,这是我的证书。"
Server → Client:
- 选择的加密算法
- 随机数 B
- 数字证书(包含服务器公钥)
第三步:客户端验证证书
客户端做几件事:
- 证书是不是可信 CA 签的?
- 证书过期了没?
- 证书上的域名和当前访问的域名一致吗?
验证通过,才继续。
第四步:生成会话密钥
客户端用服务器公钥加密一个"预主密钥"发给服务器。
Client → Server:
- 预主密钥(用服务器公钥加密)
服务器用自己的私钥解密,拿到预主密钥。
然后客户端和服务器都用:
- 随机数 A
- 随机数 B
- 预主密钥
这三个东西,计算出会话密钥(Session Key)。
第五步:开始加密通信
双方都有了会话密钥,之后的所有通信都用这个密钥加密。
Client ↔ Server:
- 用会话密钥加密的数据
五、为什么用非对称加密交换密钥,对称加密传数据
这是很多人困惑的点:
- 非对称加密(公钥私钥):安全但慢
- 对称加密(同一个密钥):快但不安全
HTTPS 的设计很巧妙:
- 先用非对称加密安全地交换会话密钥(只交换一次)
- 然后用对称加密快速传输数据(所有通信都用这个密钥)
既保证了安全,又保证了性能。
六、证书链
一张证书不是孤立的,它背后有一条证书链:
根证书(Root CA)
└─ 中间证书(Intermediate CA)
└─ 服务器证书(你的网站)
浏览器信任根证书,根证书签中间证书,中间证书签你的服务器证书。这样一层层验证下来,就信任了你的服务器证书。
七、常见问题
1. 为什么有的网站 HTTPS 显示"不安全"
通常是因为:
- 证书过期了
- 证书域名不匹配
- 证书是自签名的,不是可信 CA 签发的
- 页面里混了 HTTP 的资源
2. HTTPS 一定安全吗?
不一定。如果:
- 你电脑上的根证书被篡改了
- CA 机构被攻破了
- 你主动信任了恶意证书
那 HTTPS 也会不安全。
3. HTTPS 会影响性能吗?
会有一点影响,主要在握手阶段。但现在 TLS 1.3 已经把握手优化到 1-RTT,加上会话复用,性能影响很小了。
总结
HTTPS 的核心思路:
- 用非对称加密安全交换会话密钥
- 用对称加密快速传输数据
- 用数字证书验证服务器身份
- 用 MAC 校验数据完整性
搞懂这四点,HTTPS 的原理你就掌握了一大半。