目录
- 写在前面
- 使用https的步骤
- 单纯使用https
- 负载均衡和web均用https
- [负载均衡https,web用http(外网访问https,内网互访http)](#负载均衡https,web用http(外网访问https,内网互访http))
- 优化
- 监控
写在前面
这是Nginx的第七篇,内容是Nginx中如何使用https,以及https的优化和监控
使用https的步骤
- 申请https证书 (ca证书)
- 可以用
公有云
(aws、华为云等)申请https证书,个人用户一年有20个免费证书权限。(前提:必须有已经备案通过的域名 && 使用和申请证书的域名必须相同
) - 通过
openssl手动创建证书
,不过该证书不被认可
,会在使用时提示不安全(可以忽略或在浏览器中信任签发证书的主机) #创建私钥openssl genrsa -idea -out server.key 2048
#根据私钥创建 证书
openssl req -days 36500 -x509 -sha256 -nodes -newkey
rsa:2048 -keyout server.key -out server.crt
- 可以用
- nginx server模块中调用证书 listen 443 ssl;
ssl_certificate /etc/nginx/ssl_keys/server.pem;
ssl_certificate_key /etc/nginx/ssl_keys/server.key;
- 若有跳转或负载均衡,根据需求修改
单纯使用https
shell
# 将http请求重定向到https,$request_uri即携带uri
server {
listen 80;
server_name ssl.test.cn;
return 301 https://ssl.test.cn$request_uri;
# 另一种写法
# rewrite ^(.*)$ https://ssl.test.cn$1 permanent
}
server {
listen 443 ssl; #指定443承载于ssl之上
#ssl on ; nginx1.15.0之前需要启用,后续不用
server_name ssl.test.cn;
root /app/code/ssl;
#ssl key 调用
ssl_certificate /etc/nginx/ssl_keys/ssl.test.cn.pem;
ssl_certificate_key /etc/nginx/ssl_keys/ssl.test.cn.key;
location / {
index index.html;
}
}
负载均衡和web均用https
- 整个过程中,lb需要转换http请求重定向为https
- web仅需处理https请求
shell
# web
[root@web01 ~]# cat /etc/nginx/conf.d/ssl.test.cn.conf
server {
listen 443 ssl;
server_name ssl.test.cn;
root /app/code/ssl;
ssl_certificate /etc/nginx/ssl_keys/ssl.test.cn.pem;
ssl_certificate_key /etc/nginx/ssl_keys/ssl.test.cn.key;
location / {
index index.html;
}
}
# lb
[root@lb01 ~]# cat /etc/nginx/conf.d/ssl.test.cn.conf
upstream ssl_pools {
server 192.168.100.148:443 ; # 使用https访问,所以指定端口为443
}
server {
listen 80;
server_name ssl.test.cn;
return 301 https://ssl.test.cn$request_uri;
}
server {
listen 443 ssl;
server_name ssl.test.cn;
ssl_certificate /etc/nginx/ssl_keys/ssl.test.cn.pem;
ssl_certificate_key /etc/nginx/ssl_keys/ssl.test.cn.key;
location / {
proxy_pass https://ssl_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Ip $remote_addr;
}
}
负载均衡https,web用http(外网访问https,内网互访http)
shell
# web
[root@web01 ~]# cat /etc/nginx/conf.d/ssl.test.cn.conf
server {
listen 80;
server_name ssl.test.cn;
root /app/code/ssl;
location / {
index index.html;
}
}
# lb
[root@lb01 ~]# cat /etc/nginx/conf.d/ssl.test.cn.conf
upstream ssl_pools {
server 192.168.100.148:80; # 因为内网使用http互访,所以upstream也只用指定端口80
}
server {
listen 80;
server_name ssl.test.cn;
return 301 https://ssl.test.cn$request_uri;
}
server {
listen 443 ssl http2; # 若指定使用http2只需添加该参数
server_name ssl.test.cn;
ssl_certificate /etc/nginx/ssl_keys/ssl.test.cn.pem;
ssl_certificate_key /etc/nginx/ssl_keys/ssl.test.cn.key;
location / {
proxy_pass https://ssl_pools;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Ip $remote_addr;
}
}
部分加密时,访问动态资源会出现问题
对php动态资源的模块添加fastcgi_param HTTPS on;
,表明前面部分的请求是https
shell
server {
listen 80;
server_name blog.test.cn;
root /app/code/blog;
error_log /var/log/nginx/blog-error.log notice;
access_log /var/log/nginx/blog-access.log main;
location / {
index index.php;
}
location ~* \.(html|js|css|jpg|png|jpeg)$ {
expires max;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param HTTPS on; # 添加该条
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
优化
shell
server {
listen 443 ssl;
# 会话保持时间
keepalive_timeout 70;
#指定ssl加密协议的版本
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#加密算法. 需要排除算法前用!
#排除null空算法, md5算法
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;
#设置https 会话缓存 10MB大小的缓存空间
ssl_session_cache shared:SSL:10m;
#超时时间 10分钟
ssl_session_timeout 10m;
...
}
监控
监控https证书是否过期
本地证书过期时间
shell
openssl x509 -in 证书文件路径 -nnout -dates
任意url的证书
如何获得过期时间
shell
# | 默认标准输出,即输出正确内容;curl的过程信息不被认为为正确内容
# |& 错误输出,正确错误内容均输出,可以查看到curl的过程信息
curl -vL https://www.baidu.com |& grep 'expire date'
* expire date: Aug 6 01:51:05 2024 GMT
# 只要日期信息
[root@e ~]# curl -vL https://www.baidu.com |& grep 'expire date' | awk -F': ' '{print $2}'
Aug 6 01:51:05 2024 GMT
编写脚本,获取过期时间
shell
# 编写脚本
[root@ecm-98ce ~]# vim /server/scripts/check_ssl.sh
#!/bin/bash
url=https://www.baidu.com
expire_date_ori=`curl -vL https://www.baidu.com |& grep 'expire date' | awk -F'date:|GMT' '{print $2}'`
expire_date_opt=`date -d "$expire_date_ori" +%F`
echo 原始格式的过期时间 $expire_date_ori
echo 处理后的过期时间 $expire_date_opt
# 测试
[root@ecm-98ce ~]# sh /server/scripts/check_ssl.sh
原始格式的过期时间 Aug 6 01:51:05 2024
处理后的过期时间 2024-08-06
最终脚本,计算过期时间
shell
# 编写脚本
[root@ecm-98ce ~]# cat /server/scripts/check_ssl.sh
#!/bin/bash
# author: tassel
# desc: 检查指定url,https证书过期时间
url=https://www.baidu.com
expire_date_ori=`curl -vL https://www.baidu.com |& grep 'expire date' | awk -F'date:|GMT' '{print $2}'`
expire_date_opt=`date -d "$expire_date_ori" +%F`
echo 原始格式的过期时间 $expire_date_ori
echo 处理后的过期时间 $expire_date_opt
# 过期时间-当前时间 秒数
expire_date_opt=`date -d "$expire_date_ori" +%s`
date_now_second=`date +%s`
expire_days=`echo "($expire_date_opt - $date_now_second )/(60*60*24)"|bc`
echo "--------------------"
echo "网站$url证书过期倒计时:还有 $expire_days 天"
echo "网站过期日期是:`date -d "$expire_date_ori" +%F`"
# 测试
[root@ecm-98ce ~]# sh /server/scripts/check_ssl.sh
原始格式的过期时间 Aug 6 01:51:05 2024
处理后的过期时间 2024-08-06
--------------------
网站https://www.baidu.com证书过期倒计时:还有 43 天
网站过期日期是:2024-08-06