https证书部署
7052 字
35 分钟
https证书部署
.CzXBPj40_Z1BUyDf.webp)
https证书部署
[TOC]
HTTPS证书
HTTPS = HTTP + SSL/TLS# 安全通信协议'了解ssl协议,我们现在使用的更多的是TLS加密协议'=========================================为什么需要 HTTPS?HTTP是明文传输,不安全HTTPS 解决了这些问题: 1.加密传输 2.防止内容被篡改 3.通过数字证书确认网站真实性,防止钓鱼.png)
在OSI七层模型中 应用层是http协议 表示层是TLS协议-->发挥作用'TLS加密工作在哪一层?-->表示层'=========================================1.HTTPS 通过 TLS 协议在 HTTP 下方建立一个加密通道2.在用户无感知的情况下,TLS 利用非对称加密交换密钥、对称加密传输数据、数字证书验证身份,从而全面保障网络通信的安全性工作流程

第一步:申请证书 —— “我要办个身份证”1.你是一个网站运营者👉需要申请一个“数字身份证”(也就是 SSL/TLS 证书)2.先去登记机构报备👉核实你的身份3.生成 CSR(证书签名请求)👉就是你“申请证书”的申请表4.登记机构转交给 CA👉确认你没问题后,就把你的CSR发给CA# CA:证书颁发机构5.CA颁发证书👉里面包含 ①CA的签名(证明这是真的) ②你的域名 ③你的公钥 ④证书有效期 # 不是域名的6.你拿到证书,部署到服务器👉现在你的网站就“有身份证”了========================================='CA 的签名 ≠ CA 的私钥'✅签名 = CA私钥( hash(证书内容) )浏览器怎么验证???浏览器收到证书后:1.从浏览器内置的可信 CA 列表中找到对应 CA 的公钥2.用这个 CA 公钥去“解密”证书中的签名 → 得到一个哈希值 H13.同时,浏览器自己对证书内容(域名、公钥等)重新计算一次哈希 → 得到 H24.比较 H1 和 H2: 如果一样 → 说明证书没被篡改,且确实是该 CA 签发的 ✅ 如果不一样 → 证书被伪造或损坏 ❌🔍 注意:这里“解密签名”只是为了还原出原始哈希值,不是为了获取私钥!# 私钥从未出现在网络上传输,也不可能被解出来💡私钥用来“签”,公钥用来“验”;签名可验证,私钥永不露=========================================第二步:用户访问网站 —— “我怎么知道你是真的?”1.浏览器请求证书2.服务器发送证书3.浏览器验证证书 ①是不是由它信任的 CA 签发的 ②再看证书有没有过期 ③最重要的是:这个证书有没有被吊销?=========================================第三步:如何判断证书有没有被吊销?—— CRL vs OCSP❌ 方法一:CRL(证书吊销列表)(黑名单)👉 问题来了:名单太长了!又慢又耗流量✅ 方法二:OCSP(在线证书状态协议)👉 更快更省流量!但每次都要联网问一次,对 OCSP 服务器压力很大=========================================第四步:Nginx 的“聪明做法”—— OCSP Stapling(OCSP 缓存)'既然 OCSP 查询这么频繁,能不能让服务器帮我们提前问好?'⭐你可以在 Nginx 里开启一个开关:OCSP Stapling⭐启动后,Nginx 会每隔一段时间主动去 OCSP 服务器问一次:“我的证书还有效吗?”⭐OCSP 服务器回复:“有效,我给你一个临时凭证(OCSP Response)”⭐Nginx 把这个“临时凭证”缓存起来=========================================当浏览器来访问时:1.浏览器说:“请出示身份证!”2.Nginx 不仅发证书,还附带一个 OCSP 响应: “你看,我已经问过了,我这个证书是有效的!”3.浏览器一看: “哦,你已经帮我查好了,不用我再跑一趟 OCSP 服务器了”Note
🧠 ==一句话总结:==
你申请证书 → CA 给你发“身份证” → 用户访问时,浏览器验证身份证真假 → 为了确认没被吊销,要么查“黑名单”(CRL,慢),要么问“实时状态”(OCSP,快但压力大)→ 所以 Nginx 可以提前帮你问好,直接告诉浏览器“我没错”,这就是 OCSP Stapling!
加密流程

'流程(面试题)'✅ 第一步:握手认证(证书验证)1、浏览器发起往服务器的443端口发起请求👉请求携带了浏览器支持的加密算法和哈希算法2、服务器收到请求👉选择浏览器支持的加密算法和哈希算法3、服务器将数字证书返回给浏览器👉证书里有CA的签名、服务器网址、证书有效期、服务器公钥...4、浏览器进入数字证书认证环节# 这一部分是浏览器内置的TLS完成的 ①查看它是不是由可信机构签发的 ②检查网址、证书有没有过期和被吊销? ❌️弹出“警告:这个网站不安全!” ✅️说明这个网站是可信的# 通过认证时,浏览器就可以安全使用证书中的网站公钥了=========================================🔐 第二步:建立加密通道(数据传输)1.浏览器生成一个“秘密密码”(随机数 R)→ 这个密码只有你和服务器知道2.用服务器的公钥把 R 加密后发过去→ 只有服务器能用自己的私钥解开这个密码3.服务器收到后,用私钥解密,得到 R→ 现在双方都有了同一个“秘密密码”4.之后所有通信都用这个 R 做对称加密→ 对称加密又快又安全,比非对称加密高效得多=========================================✅ 总结一句话:先验证对方身份(证书),再商量一个只有你们知道的秘密密码(R),然后用这个密码加密传输所有数据,确保安全!模拟网站篡改
# 配置WEB01正常访问的网站[root@web01 conf.d]# vim 1.test.confserver { listen 80; server_name test.kpyun.com; root /code/test; location / { index index.html; }}[root@web01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web01 conf.d]# systemctl restart nginx[root@web01 conf.d]# vim /code/test/index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>我是title</title></head><body><article> <header> <h1>我是哥哥</h1> <b>学习新思想,争做新青年;欢迎来到...</b> </p> <footer> <p><small>版权所有!</small></p> </footer></article></body></html>
windows的hosts解析10.0.0.7 test.kpyun.com
# WEB02配置为劫持的服务器'反向代理!'[root@web02 conf.d]# cat jc.confupstream jc { server 172.16.1.7:80;}server { server_name jc.com; root /code/test;
location / { index index.html; proxy_pass http://jc; sub_filter '<h1>我是哥哥' '<h1>我是妹妹'; sub_filter '<small>版权所有' ' <small>开源'; # 明文字符串替换,默认只替换一次! proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; }}[root@web02 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web02 conf.d]# systemctl restart nginx
windows的hosts劫持10.0.0.8 jc.com
'也可以配置链接地址'[root@web02 conf.d]# cat jc.conflocation / { sub_filter '<h1>我是哥哥' '<img src=“https://pic.rmb.bdstatic.com/bjh/bc1192d8897b/250522/aca2164d2d66e293dd0e230e497ff895.jpeg”>'; # '<img 空格 src="">'...}
证书类型介绍
| 对比 | 域名型 DV | 企业型 OV | 增强型 EV |
|---|---|---|---|
| 绿色地址栏 | 小锁标记+https | 小锁标记+https | 小锁标记+企业名称+https |
| 一般用途 | 个人站点和应用; 简单的https加密需求 | 中小企业或电商网站 | 银行、大型企业或政府网站 |
| 审核内容 | 只需证明域名所有权 | 除验证域名外,还需审核企业真实身份;证书详情中包含企业信息 | 审核最严格,包括全面的企业资质核查 |
| 颁发时长 | 几分钟 | 3-5个工作日 | 5-7个工作日 |
| 单次申请年限 | 3个月 | 1-2年(1年一换) | 1-2年 |
| 赔付保障金 | —— | 125-175万美金 | 150-175万美金 |
证书对域名的保护
1.单域名证书 特点:一个证书仅保护一个完整域名✅ www.oldboy.com2.多域名证书 特点:一个证书可保护多个完全不同的域名或子域名✅ www.test.com✅ www.oldboy.com✅ news.oldboy.com3.通配符证书 特点:使用 * 通配符,保护同一级所有子域名证书为 *.oldboy.com,可保护:✅ www.oldboy.com✅ test.oldboy.com✅ mail.oldboy.com
生成假证流程
[root@web01 ~]# openssl genrsa -aes256 -passout pass:5218 -out server.key 2048'免交互式输入密码!'openssl genrsa # 生成 RSA 私钥-aes256 # AES-256加密算法-passout pass:5218 # 表示密码就是5218-out server.key # 指定输出的私钥文件名[root@web01 ~]# lltotal 4-rw------- 1 root root 1766 Mar 21 14:54 server.key# 刚生成的带密码的私钥=================[root@web01 ~]# openssl req -x509 \ -key server.key \ -passin pass:5218 \ -out server.crt \ -days 36500 \ -subj "/C=CN/ST=Guangdong/L=Shenzhen/O=kpyun/OU=kpyun/CN=jiuzhao/emailAddress=123@qq.com"# 直接用现成的私钥,而不是再生成了keyout# 输入私钥的密码[root@web01 ~]# lsserver.crt server.keyNote
- 👆带密码的私钥⚠️
- 1️⃣生成带密码的私钥⚠️
- 因为私钥带密码,每次重启🔄服务都需要输入密码,比较麻烦
- 2️⃣用这个私钥生成证书
- 1️⃣生成带密码的私钥⚠️
- 下面👇才是不带密码的私钥✅️
- 一步即可! 推荐下面这种
单节点
'充当CA机构给自己颁发假证'
(1)创建存放证书的路径&生成自签证书&内容自定义填写[root@web01 conf.d]# mkdir /etc/nginx/ssl_key[root@web01 conf.d]# cd /etc/nginx/ssl_key[root@web01 ssl_key]# openssl req -x509 \ -newkey rsa:2048 \ -nodes \ -keyout server.key \ -out server.crt \ -days 36500 \ -subj "/C=CN/ST=Guangdong/L=Shenzhen/O=kpyun/OU=kpyun/CN=jiuzhao/emailAddress=123@qq.com"===========================================-x509 # 生成自签名证书(而非 CSR)-newkey rsa:2048 # 生成一个新的 2048 位 RSA 私钥-nodes # 私钥不加密(无密码)-keyout server.key # 私钥输出文件-out server.crt # 证书输出文件-days 36500 # 有效期 36500 天-subj "..." # 指定证书主体信息[root@web01 ssl_key]# lltotal 8-rw-r--r-- 1 root root 1415 Mar 21 15:25 server.crt-rw------- 1 root root 1700 Mar 21 15:25 server.key
(3)配置证书[root@web01 ssl_key]# cd ../conf.d/[root@web01 conf.d]# vim wp.confserver { listen 443 ssl; # 443 ssl server_name wp.kpyun.com; root /code/wordpress; ssl_certificate ./ssl_key/server.crt; ssl_certificate_key ./ssl_key/server.key; # 指定证书和私钥的位置:/etc/nginx/ssl_key
location / { index index.php index.html; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}[root@web01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web01 conf.d]# systemctl restart nginx[root@web01 conf.d]# ss -lntup | grep nginxtcp LISTEN 0 128 0.0.0.0:80tcp LISTEN 0 128 0.0.0.0:443# 80 & 443 监听两个端口!
浏览器访问:https://wp.kpyun.com/'不能直接访问wp.kpyun.com👉这个监听的端口是80'


❌️问题来了!'每次都要输入https://...好麻烦!'
# 配置80跳转443[root@web01 conf.d]# cat wp.confserver { listen 80; server_name wp.kpyun.com; # rewrite ^(.*)$ https://$server_name$request_uri redirect; # 临时跳转,每次请求都要先请求源站 # 配置将用户访问http请求临时跳转https return 302 https://$server_name$request_uri; # 尽量用return,直接返回,快一点! # 上面的更多的用做资源的跳转!
}server { listen 443 ssl; server_name wp.kpyun.com; root /code/wordpress; ssl_certificate ./ssl_key/server.crt; ssl_certificate_key ./ssl_key/server.key;
location / { index index.php index.html; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}[root@web01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web01 conf.d]# systemctl restart nginx
浏览器访问:wp.kpyun.com'直接跳转过去!'集群
lb01、web01、web02三台都要配置https嘛???'只需要lb01配置即可!'# 后台的web服务器,和我们负载处于同一内网# 负载与后台web使用http即可!
(1)将证书部署到负载均衡[root@lb01 ~]# mkdir -p /etc/nginx/ssl_key[root@lb01 ~]# cd /etc/nginx/ssl_key/[root@lb01 ssl_key]# scp 10.0.0.7:/etc/nginx/ssl_key/* .# 拷贝到当前目录Authorized users only. All activities may be monitored and reported.root@10.0.0.7's password: 'server.crt 100% 1415 1.6MB/s 00:00server.key 100% 1700 1.4MB/s 00:00[root@lb01 ssl_key]# lltotal 8-rw-r--r-- 1 root root 1415 Mar 21 16:17 server.crt-rw------- 1 root root 1700 Mar 21 16:17 server.key
(2)配置负载均衡[root@lb01 ssl_key]# cd ../conf.d/[root@lb01 conf.d]# vim wp.conf[root@lb01 conf.d]# cat wp.confserver { listen 80; server_name wp.kpyun.com; return 302 https://$server_name$request_uri; # 临时跳转,每次请求都要先请求源站}upstream web { server 172.16.1.7:80; server 172.16.1.8:80;}server { listen 443 ssl; server_name wp.kpyun.com; ssl_certificate ./ssl_key/server.crt; ssl_certificate_key ./ssl_key/server.key; include lb_env; # 负载的其他配置!
location / { proxy_pass http://web; }}[root@lb01 conf.d]# vim ../lb_env# 头部信息,来源IP... proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1;
proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60;
proxy_buffering on; proxy_buffer_size 32k; proxy_buffers 4 128k;[root@lb01 conf.d]# ll ../lb_env-rw-r--r-- 1 root root 267 Mar 21 16:31 ../lb_env[root@lb01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@lb01 conf.d]# systemctl restart nginx
(3)配置fstcgi支持https的请求'web01'[root@web01 conf.d]# vim wp.confserver { listen 80; server_name wp.kpyun.com; root /code/wordpress;
location / { index index.php index.html; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_param HTTPS on; # 添加此参数 }}[root@web01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web01 conf.d]# systemctl restart nginx
'web02'[root@web02 conf.d]# vim wp.conf# 同上nginx -tsystemctl restart nginx
windows的hsots解析10.0.0.5 wp.kpyun.com
# 测试验证负载!'刷新页面!'[root@web01 conf.d]# tail -f /var/log/nginx/access.log172.16.1.5 - - [21/Mar/2026:16:44:33 +0800] "GET / HTTP/1.1" 200 62406 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" "10.0.0.1"....[root@web02 conf.d]# tail -f /var/log/nginx/access.log172.16.1.5 - - [21/Mar/2026:16:44:33 +0800] "GET / HTTP/1.1" 200 62398 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" "10.0.0.1"...根CA -> 中间人 -> 服务器
-
前面简单粗暴, 直接生成假证
- 浏览器访问,会提示不安全(因为是自己发的证)
- 点“高级/继续”就能用
-
下面==详细==演示证书信任链的原理
让浏览器不报错的核心秘密在于:你需要把你的“根证书”(Root CA)安装到操作系统的“受信任的根证书颁发机构”里
生成证书
我们要造三个东西:
- 根证书 (Root CA):最高权力机关
- 中间证书 (Intermediate):办事大厅
- 服务器证书 (Server Cert):给 Nginx 用的,证明网站身份
🛠️ 准备工作:建立工作区[root@Server ~]# pwd/root[root@Server ~]# mkdir -p /root/myca[root@Server ~]# cd /root/myca[root@Server myca]# mkdir private certs# 创建专门的目录 ✅️private: # 存放私钥 ✅️certs: # 来存放各种证书[root@Server myca]# chmod 700 private# 更改私钥目录权限
1)生成“根证书” (Root CA)[root@Server myca]# openssl genrsa -out private/rootCA.key 2048# 生成根私钥[root@Server myca]# openssl req -x509 -new -nodes -key private/rootCA.key -sha256 -days 3650 \ -out certs/rootCA.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyRootCA/CN=MyRootCA"[root@Server myca]# tree ././├── certs│ └── rootCA.crt└── private └── rootCA.key✅️ 现在是一个CA的证书,一个CA的私钥📌 生成的 certs/rootCA.crt 就是我们以后要导入浏览器/系统的文件# 导入它,浏览器就信任你了
2)生成“中间证书”"这是那个“中间人”,用来给服务器证书签字的"[root@Server myca]# openssl genrsa -out private/intermediate.key 2048# 生成中间人的私钥[root@Server myca]# openssl req -new -key private/intermediate.key -out intermediate.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyIntermediate/CN=MyIntermediate"# 生成中间人的申请文件 (CSR)[root@Server myca]# openssl x509 -req -in intermediate.csr -CA certs/rootCA.crt -CAkey private/rootCA.key -CAcreateserial \ -out certs/intermediate.crt -days 1825 -sha256 \ -extfile <(echo -e "basicConstraints=CA:TRUE\nkeyUsage=critical,keyCertSign,cRLSign")# 用“根证书”给“中间人”盖章Certificate request self-signature oksubject=C=CN, ST=Beijing, L=Beijing, O=MyIntermediate, CN=MyIntermediate[root@Server myca]# tree ././├── certs│ ├── intermediate.crt│ ├── rootCA.crt│ └── rootCA.srl├── intermediate.csr└── private ├── intermediate.key └── rootCA.key
3)生成“服务器证书”# 创建扩展配置文件# 为了支持域名,必须用配置文件,不能直接写在命令里[root@Server myca]# cat > server.ext <<EOFauthorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentextendedKeyUsage = serverAuthsubjectAltName = @alt_names
[alt_names]DNS.1 = php.shihao.labIP.1 = 10.0.0.101IP.2 = 127.0.0.1EOF[root@Server myca]# openssl genrsa -out private/server.key 2048# 生成服务器私钥[root@Server myca]# openssl req -new -key private/server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyServer/CN=php.shihao.lab"# 生成请求文件[root@Server myca]# openssl x509 -req -in server.csr -CA certs/intermediate.crt -CAkey private/intermediate.key -CAcreateserial \ -out certs/server.crt -days 365 -sha256 -extfile server.ext# 用“中间人”签发服务器证书Certificate request self-signature oksubject=C=CN, ST=Beijing, L=Beijing, O=MyServer, CN=php.shihao.lab
4)合并证书链# Nginx 需要看到完整的链条(服务器证书 + 中间证书)# 否则浏览器不知道中间人是谁[root@Server myca]# cat certs/server.crt certs/intermediate.crt > certs/fullchain.crt# 合并成一个 fullchain.crt[root@Server myca]# tree $(pwd)/root/myca├── certs│ ├── fullchain.crt│ ├── intermediate.crt│ ├── intermediate.srl│ ├── rootCA.crt│ ├── rootCA.srl│ └── server.crt├── intermediate.csr├── private│ ├── intermediate.key│ ├── rootCA.key│ └── server.key├── server.csr└── server.extphp配置
[root@Server cert-authority]# cd -/root
1)安装服务和插件[root@Server ~]# yum -y install php php-bcmath php-cli php-common php-devel php-embedded php-fpm php-gd php-intl php-mbstring php-mysqlnd php-opcache php-pdo php-process php-xml php-json# 里面有一些插件
2)配置PHP服务&修改默认启动用户[root@Server ~]# ll /etc/php.ini /etc/php-fpm.d/www.conf-rw-r--r-- 1 root root 19491 Jan 8 08:00 /etc/php-fpm.d/www.conf-rw-r--r-- 1 root root 62851 Jan 8 08:00 /etc/php.ini'两个重要的配置文件'[root@Server ~]# grep apache /etc/php-fpm.d/www.confuser = apachegroup = apache# 我们统一用户为www[root@Server ~]# groupadd -g666 www[root@Server ~]# useradd -u666 -g666 -M -s /sbin/nologin www[root@Server ~]# vim /etc/php-fpm.d/www.confuser = wwwgroup = wwwlisten = 127.0.0.1:9000
3)检测与启动[root@Server ~]# php-fpm -t[25-Apr-2026 15:53:04] NOTICE: configuration file /etc/php-fpm.conf test is successful[root@Server ~]# systemctl enable --now php-fpmCreated symlink '/etc/systemd/system/multi-user.target.wants/php-fpm.service' → '/usr/lib/systemd/system/php-fpm.service'.[root@Server ~]# netstat -lntup | grep phptcp 0 0 127.0.0.1:9000 0.0.0.0:* 2455/php-fpm: mastenginx测试连接
1)安装nginx[root@Server ~]# vim /etc/yum.repos.d/nginx.repo[nginx-stable]name=nginx stable repobaseurl=https://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=0enabled=1[root@Server ~]# yum -y install nginxnginx stable repo 9.9 kB/s | 15 kB
2)修改主配置文件[root@Server ~]# cd /etc/nginx/[root@Server nginx]# lltotal 24drwxr-xr-x 2 root root 46 Apr 25 16:03 conf.ddrwxr-xr-x 2 root root 22 Apr 25 15:42 default.d-rw-r--r-- 1 root root 1007 Apr 14 08:00 fastcgi_params.................-rw-r--r-- 1 root root 644 Apr 14 08:00 nginx.conf[root@Server nginx]# head -2 nginx.confuser nginx;# 修改启动用户为www[root@Server nginx]# vim nginx.confuser www;
3)创建子配置文件'测试php联通性'[root@Server nginx]# cd conf.d/[root@Server conf.d]# rm -rf default.conf[root@Server conf.d]# vim shihao.confserver { listen 80; server_name php.shihao.lab; root /code;
location / { index index.php index.html; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}
4)创建必要信息&&重启服务器[root@Server conf.d]# mkdir /code[root@Server conf.d]# vim /code/info.php<?php phpinfo();?>[root@Server conf.d]# chown -R www:www /code/[root@Server conf.d]# systemctl restart nginx[root@Server conf.d]# ss -lntup | grep 80tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=2898,fd=6),("nginx",pid=2897,fd=6))
5)Windows主机映射10.0.0.101 php.shihao.lab
HTTPS证书导入与优化
1)证书准备[root@Server conf.d]# mkdir -p /etc/nginx/ssl_key# 创建 Nginx 证书目录[root@Server conf.d]# cd /root/myca/[root@Server myca]# cp certs/fullchain.crt /etc/nginx/ssl_key/fullchain.crt[root@Server myca]# cp private/server.key /etc/nginx/ssl_key/server.key# 复制联合证书 && 服务器私钥
2)编辑Nginx子配置文件[root@Server myca]# cd /etc/nginx/conf.d/[root@Server conf.d]# vim shihao.confserver { listen 80; server_name php.shihao.lab; return 302 https://$server_name$request_uri;}server { listen 443 ssl; server_name php.shihao.lab; root /code; ssl_certificate /etc/nginx/ssl_key/fullchain.crt; ssl_certificate_key /etc/nginx/ssl_key/server.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on;
location / { index index.php index.html; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}[root@Server conf.d]# mv /code/info.php /code/index.php'改为index.php'[root@Server conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@Server conf.d]# systemctl restart nginx
3)再次访问浏览器http://php.shihao.lab'自动跳转'
[root@Server conf.d]# sz /root/myca/certs/rootCA.crt
- 根证书导出
- 导入浏览器中
- 导入之前, 把缓存清理一下




MySQL数据库

[root@Server ~]# cd /server/tmp/[root@Server tmp]# rz[root@Server tmp]# ls mysql-8.0.36-1.el9.x86_64.rpm-bundle.tarmysql-8.0.36-1.el9.x86_64.rpm-bundle.tar[root@Server tmp]# tar -xf mysql-8.0.36-1.el9.x86_64.rpm-bundle.tar[root@Server tmp]# dnf install -y \> mysql-community-common-8.0.36-1.el9.x86_64.rpm \> mysql-community-icu-data-files-8.0.36-1.el9.x86_64.rpm \> mysql-community-libs-8.0.36-1.el9.x86_64.rpm \> mysql-community-client-plugins-8.0.36-1.el9.x86_64.rpm \> mysql-community-client-8.0.36-1.el9.x86_64.rpm \> mysql-community-server-8.0.36-1.el9.x86_64.rpm \> mysql-community-devel-8.0.36-1.el9.x86_64.rpm[root@Server tmp]# rm -rf ./*# 删除软件包
1)启动[root@Server tmp]# cd[root@Server ~]# systemctl enable --now mysqld[root@Server ~]# cat /var/log/mysqld.log | grep root@local2026-04-25T13:16:32.041957Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: k+eRPaf>88h&[root@Server ~]# mysql -uroot -p'k+eRPaf>88h&'"Welcome to the MySQL monitor."Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
2)root用户基础配置mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Oldboy123.com';mysql> SET GLOBAL validate_password.length = 6;mysql> SET GLOBAL validate_password.policy = 0;mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'passwd';
3)创建数据库和表mysql> CREATE DATABASE php CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;mysql> SHOW DATABASES;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || php || sys |+--------------------+mysql> CREATE TABLE my_table ( -> id INT(2) NOT NULL AUTO_INCREMENT PRIMARY KEY, -> name CHAR(25) NOT NULL, -> age INT(3) NOT NULL -> );mysql> SHOW TABLES;+---------------+| Tables_in_php |+---------------+| my_table |+---------------+mysql> INSERT INTO my_table (name, age) VALUES ('zed', 52);mysql> INSERT INTO my_table (name, age) VALUES ('yevont', 48);mysql> SELECT * FROM my_table;+----+--------+-----+| id | name | age |+----+--------+-----+| 1 | zed | 52 || 2 | yevont | 48 |+----+--------+-----+
4)专库专管mysql> CREATE USER 'jiu'@'%' IDENTIFIED BY 'passwd';mysql> SELECT user,host FROM mysql.user WHERE user='jiu';+------+------+| user | host |+------+------+| jiu | % |+------+------+mysql> GRANT ALL PRIVILEGES ON php.* TO 'jiu'@'%';mysql> FLUSH PRIVILEGES;mysql> exitBye[root@Server ~]# vim /code/table_data.php<?php// 设置响应头为 JSON 格式,方便客户端读取header('Content-Type: application/json; charset=utf-8');
// 数据库配置信息$host = '127.0.0.1'; // 数据库地址$db = 'php'; // 数据库名$user = 'jiu'; // 用户名$pass = 'passwd'; // 密码$charset = 'utf8mb4';
// DSN (数据源名称)$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
// 连接选项$options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 开启异常模式 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认获取关联数组 PDO::ATTR_EMULATE_PREPARES => false, // 关闭模拟预处理];
try { // 尝试连接数据库 $pdo = new PDO($dsn, $user, $pass, $options);
// 执行查询 $sql = "SELECT id, name, age FROM `my_table`"; // 注意:table 是关键字,最好加反引号 $stmt = $pdo->query($sql);
// 获取所有数据 $data = $stmt->fetchAll();
// 输出 JSON 数据给客户端 echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
} catch (\PDOException $e) { // 如果出错,输出错误信息 http_response_code(500); echo json_encode(['error' => '数据库连接失败: ' . $e->getMessage()]);}?>5)配置与优化[root@Server ~]# chown -R www:www /code[root@Server ~]# nginx -tnginx: the configuration xxx is oknginx: configuration xxx is successful[root@Server ~]# systemctl reload nginx
6)浏览器访问http://php.shihao.lab/table_data.php
Flask应用
1)数据库准备[root@Server ~]# mysql -uroot -ppasswdType 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE IF NOT EXISTS `quote` DEFAULT CHARACTER SET utf8mb4;mysql> USE quote;mysql> CREATE TABLE `quota` ( -> `ID` INT AUTO_INCREMENT PRIMARY KEY, -> `QUOTE` TEXT NOT NULL, -> `author` VARCHAR(100) NOT NULL -> ) ENGINE=InnoDB;mysql> INSERT INTO `quota` (`QUOTE`, `author`) VALUES -> ('The only way to do great work is to love what you do.', 'Steve Jobs'), -> ('生活不止眼前的苟且,还有诗和远方。', '高晓松'), -> ('人生如逆旅,我亦是行人。', '苏轼'), -> ('In the middle of difficulty lies opportunity.','Albert Einstein'), -> ('天行健,君子以自强不息。', '《周易》'), -> ('Stay hungry, stay foolish.', 'Steve Jobs'), -> ('博观而约取,厚积而薄发。', '苏轼'), -> ('路漫漫其修远兮,吾将上下而求索。', '屈原'), -> ('海内存知己,天涯若比邻。', '王勃'), -> ('Do or do not. There is no try.', 'Yoda'), -> ('人固有一死,或重于泰山,或轻于鸿毛。', '司马迁'), -> ('不积跬步,无以至千里。', '荀子'), -> ('To be or not to be, that is the question.', 'William Shakespeare'), -> ('山重水复疑无路,柳暗花明又一村。', '陆游'), -> ('业精于勤,荒于嬉。', '韩愈'), -> ('Knowledge is power.', 'Francis Bacon'), -> ('长风破浪会有时,直挂云帆济沧海。', '李白'), -> ('学而不思则罔,思而不学则殆。', '孔子'), -> ('All that we see or seem is but a dream within a dream.', 'Edgar Allan Poe'), -> ('非淡泊无以明志,非宁静无以致远。', '诸葛亮');mysql> GRANT ALL ON quote.* TO "jiu"@"%";mysql> FLUSH PRIVILEGES;mysql> exitBye
2)客户端准备应用[root@Client ~]# mkdir -p /var/app/quote/templates# 创建应用目录"创建应用文件"[root@Client ~]# vim /var/app/quote/app.pyfrom flask import Flask, render_templateimport mysql.connectorfrom dotenv import load_dotenvimport os
# 加载环境变量load_dotenv()
app = Flask(__name__)
def get_db_connection(): """获取数据库连接""" connection = mysql.connector.connect( host=os.getenv('DB_HOST'), port=int(os.getenv('DB_PORT')), user=os.getenv('DB_USER'), password=os.getenv('DB_PASSWORD'), database='quote' ) return connection
@app.route('/')def index(): """主页 - 随机显示一条名言""" try: conn = get_db_connection() cursor = conn.cursor(dictionary=True)
# 随机获取一条名言 cursor.execute("""" SELECT QUOTE, author FROM quota ORDER BY RAND() LIMIT 1 """)" quote = cursor.fetchone()
cursor.close() conn.close()
if quote: return render_template('index.html', quote=quote['QUOTE'], author=quote['author']) else: return render_template('index.html', quote="暂无名言数据", author="系统")
except Exception as e: print(f"数据库错误: {e}") return render_template('index.html', quote="数据库连接失败", author="系统")
@app.route('/all')def all_quotes(): """显示所有名言""" try: conn = get_db_connection() cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT QUOTE, author FROM quota ORDER BY ID") quotes = cursor.fetchall()
cursor.close() conn.close()
return render_template('index.html', quotes=quotes)
except Exception as e: print(f"数据库错误: {e}") return render_template('index.html', quotes=[], error="无法获取名言数据")
if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False)- vim /var/app/quote/.env
DB_HOST=10.0.0.101 # 数据库IPDB_PORT=3306 # 数据库端口DB_USER=jiu # 数据库授权用户DB_PASSWORD=passwd # 用户密码- vim /var/app/quote/templates/index.html
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>每日名言</title> <style> body { font-family: 'Microsoft YaHei', Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); margin: 0; padding: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; } .container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); max-width: 600px; width: 90%; text-align: center; } .quote { font-size: 1.2rem; line-height: 1.6; color: #333; margin-bottom: 1rem; font-style: italic; } .author { font-size: 1rem; color: #666; margin-top: 1rem; } .all-link { margin-top: 1rem; } .all-link a { color: #667eea; text-decoration: none; } .error { color: red; } </style></head><body> <div class="container"> <h1>每日名言</h1>
{% if quote and not quotes %} <!-- 显示单条随机名言 --> <div class="quote">"{{ quote }}"</div> <div class="author">— {{ author }}</div> {% elif quotes %} <!-- 显示所有名言 --> <h2>所有名言</h2> {% for item in quotes %} <div class="quote">"{{ item.QUOTE }}"</div> <div class="author">— {{ item.author }}</div> <hr> {% endfor %} {% else %} <div class="error">{{ error or "暂无名言数据" }}</div> {% endif %}
<div class="all-link"> <a href="/">随机名言</a> | <a href="/all">查看全部</a> </div> </div></body></html>- vim /var/app/requirements.txt
Flask==2.3.3mysql-connector-python==8.1.0python-dotenv==1.0.0gunicorn==21.2.03)安装python环境与依赖[root@Client ~]# dnf -y install python3-pip[root@Client ~]# pip3 install -r /var/app/requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple# 安装应用依赖[root@Client ~]# pip3 install gunicorn -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple# 安装Gunicorn
4)创建用户和systemd文件[root@Client ~]# groupadd -g666 www[root@Client ~]# useradd -u666 -g666 -M -s /sbin/nologin www[root@Client ~]# vim /etc/systemd/system/quote-app.service[Unit]Description=Flask quote appAfter=network.target
[Service]User=wwwGroup=wwwWorkingDirectory=/var/app/quoteExecStart=/usr/local/bin/gunicorn -w 4 -b 0.0.0.0:5000 app:appRestart=always
[Install]WantedBy=multi-user.target
[root@Client ~]# systemctl daemon-reload[root@Client ~]# systemctl enable --now quote-appCreated symlink '/etc/systemd/system/multi-user.target.wants/quote-app.service' → '/etc/systemd/system/quote-app.service'.[root@Client ~]# systemctl status quote-app● quote-app.service - Flask quote app Loaded: loaded (/etc/systemd/system/quote-app.service; enabled; preset: disabled) Active: active (running)[root@Client ~]# ss -anput | grep 5000tcp LISTEN 0 2048 0.0.0.0:5000 0.0.0.0:* users:(("gunicorn",pid=1871,fd=5),("gunicorn",pid=1870,fd=5),("gunicorn",pid=1869,fd=5),("gunicorn",pid=1868,fd=5),("gunicorn",pid=1867,fd=5))
5)浏览器测试访问http://10.0.0.102:5000/
服务端代理
1)https证书配置[root@Server ~]# cd /root/myca[root@Server myca]# cat > server.ext <<EOFauthorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentextendedKeyUsage = serverAuthsubjectAltName = @alt_names
[alt_names]DNS.1 = quote.shihao.labIP.1 = 10.0.0.101IP.2 = 127.0.0.1EOF[root@Server myca]# openssl genrsa -out private/server.key 2048# 生成服务器私钥[root@Server myca]# openssl req -new -key private/server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyServer/CN=quote.shihao.lab"# 生成请求文件[root@Server myca]# openssl x509 -req -in server.csr -CA certs/intermediate.crt -CAkey private/intermediate.key -CAcreateserial \ -out certs/server.crt -days 365 -sha256 -extfile server.ext# 用“中间人”签发服务器证书Certificate request self-signature oksubject=C=CN, ST=Beijing, L=Beijing, O=MyServer, CN=quote.shihao.lab[root@Server myca]# cat certs/server.crt certs/intermediate.crt > certs/fullchain.crt
2)nginx配置文件[root@Server myca]# cp certs/fullchain.crt /etc/nginx/ssl_key/fullchain.crtcp: overwrite '/etc/nginx/ssl_key/fullchain.crt'? y[root@Server myca]# cp private/server.key /etc/nginx/ssl_key/server.keycp: overwrite '/etc/nginx/ssl_key/server.key'? y[root@Server myca]# cd /etc/nginx/conf.d/[root@Server conf.d]# vim shihao.confserver { listen 80; server_name quote.shihao.lab; return 302 https://$server_name$request_uri; }server { listen 443 ssl; server_name quote.shihao.lab; ssl_certificate /etc/nginx/ssl_key/fullchain.crt; ssl_certificate_key /etc/nginx/ssl_key/server.key;
location / { index index.html; proxy_pass http://10.0.0.102:5000; # 代理访问
# 传递客户端真实IP 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_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; }}[root@Server conf.d]# nginx -tnginx: the configuration xxx is oknginx: configuration xxx is successful[root@Server conf.d]# systemctl reload nginx
3)Windows解析10.0.0.101 quote.shihao.lab'这里解析的是⚠️101⚠️'
配置真实证书流程

申请和下载真实证书
前提必须有一个 ==备案好的域名==


我们提前搭建好的wordpress中的域名已经写入数据库中了!❌️所以没有办法直接替换,否则会报错的✅️只能恢复快照重新部署才行============================================(1)上传并解压[root@web01 ~]# cd /etc/nginx/ssl_key/[root@web01 ssl_key]# rm -rf server.*[root@web01 ssl_key]# rz# 把证书上传进来![root@web01 ssl_key]# lltotal 16-rw-r--r-- 1 root root 4142 Mar 21 17:04 22680182_www.kpyun.fun_nginx.zip☝[root@web01 ssl_key]# unzip 22680182_www.kpyun.fun_nginx.zip -d .# 解压到当前目录中Archive: 22680182_www.kpyun.fun_nginx.zipAliyun Certificate Download inflating: ./www.kpyun.fun.pem inflating: ./www.kpyun.fun.key[root@web01 ssl_key]# rm -rf 22680182_www.kpyun.fun_nginx.zip[root@web01 ssl_key]# lltotal 8-rw-r--r-- 1 root root 1675 Mar 21 17:04 www.kpyun.fun.key-rw-r--r-- 1 root root 3813 Mar 21 17:04 www.kpyun.fun.pem
(2)配置证书[root@web01 ssl_key]# cd ../conf.d/[root@web01 conf.d]# vim 1.test.confserver { listen 80; server_name www.kpyun.fun; return 302 https://$server_name$request_uri;}server { listen 443 ssl; server_name www.kpyun.fun; root /code/test/; ssl_certificate ./ssl_key/www.kpyun.fun.pem; ssl_certificate_key ./ssl_key/www.kpyun.fun.key;
location / { index index.html; }}[root@web01 conf.d]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful[root@web01 conf.d]# systemctl restart nginx
Windows的hosts文件修改!10.0.0.7 www.kpyun.fun
证书过期时间
'面试题'# 命令查看证书的过期时间openssl x509 -in /path/to/your/certificate.crt -noout -dates-in your_cert.crt:指定你的证书文件路径(.crt、.pem 等格式都可以)-noout:不输出证书的完整内容(避免刷屏)-dates:只显示证书的有效期,包括 开始时间(notBefore) 和 过期时间(notAfter)=======================================[root@web01 ~]# openssl x509 -in /etc/nginx/ssl_key/www.kpyun.fun.pem -noout -datesnotBefore=Jan 11 00:00:00 2026 GMTnotAfter=Apr 10 23:59:59 2026 GMTHTTPS优化参数
'Nginx SSL 配置'1. ssl_session_cache shared:SSL:1m;👉作用:开启 SSL 会话缓存,提升 HTTPS 性能🐴这里的1m表示 1MB 的共享内存空间,用来存储 SSL 会话信息# 在建立完ssl握手后(比较耗时),如果断开连接,只要在session_timeout时间内再次连接,就可以“复用”之前的会话,跳过部分握手步骤,从而加快了加载速度、减少服务器压力2. ssl_session_timeout 5m;👉作用:设置 SSL 连接断开后的超时时间3. ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;👉作用:指定允许使用的加密算法,同时禁用不安全的老算法4. ssl_protocols TLSv1.2 TLSv1.3;👉作用:只允许使用较新的 TLS 协议版本# TLSv1.2 和 TLSv1.3 是目前最安全、最主流的 HTTPS 协议版本# 主动禁用老版本,因为它们存在已知漏洞⚠️注意:极老的浏览器(如 IE 10 以下)可能无法访问,但如今绝大多数设备都支持 TLS 1.2+,所以强烈建议只开这两个版本5. ssl_prefer_server_ciphers on;👉作用:让服务器决定用哪种加密套件,而不是听浏览器的# 默认情况下,浏览器会告诉服务器“我喜欢用哪些加密方式”,然后服务器从中选一个# 好处:防止浏览器“偷懒”选了个不安全的旧算法,更安全可控 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on;文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
Tomcat动静分离
Web服务Tomcat动静分离与多端适配实战,通过Redis共享Session、Nginx正则分发及User-Agent路由
2
搭建企业内部yum仓库
Web服务企业内网YUM私有仓库搭建,使用createrepo+Nginx实现RPM包统一管理与离线快速分发
3
Keepalived 高可用
Web服务Keepalived高可用集群实战,讲解VRRP原理、主备部署、脑裂处理及Nginx健康检查自动切换
4
Nginx性能优化
Web服务Nginx性能优化全面指南,涵盖压力测试、内核调优、缓存压缩、防盗链与CPU亲和绑定
5
rewrite跳转
Web服务Nginx rewrite重写与重定向实战,涵盖四类flag标记、301/302跳转、正则改写与维护页跳转
随机文章随机推荐



