8月28日晚实战记录:欧拉服务器 + Apache + frp 内网穿透 + Let’s Encrypt 完整踩坑指南
最近给自己的WordPress站点 blog.xnwxb.cn 配置了HTTPS,从自签名证书到申请公网可信证书,中间踩了不少坑,把完整流程和思考整理成文,方便自己回顾,也给有类似需求的小伙伴一个参考。
特别说明:我的网络环境比较特殊,服务器在本地(欧拉系统),通过 frp 内网穿透对外提供服务。所以配置过程中既涉及本地服务器设置,也涉及 frp 的 HTTPS 转发配置。
Part 1:生成自签名证书(第一步,先让本地跑通 HTTPS)
在正式申请公网证书之前,我先用自签名证书让本地 Apache 先跑通 HTTPS,确保整个链路没问题。
1.1 创建证书存放目录
sudo mkdir -p /etc/ssl/wordpress
1.2 生成自签名证书(有效期10年)
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout /etc/ssl/wordpress/server.key \ -out /etc/ssl/wordpress/server.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=MyBlog/CN=blog.xnwxb.cn"
参数说明
| 参数 | 含义 |
|---|---|
-x509 | 生成自签名证书(而非证书签名请求) |
-nodes | 不加密私钥(免密码输入) |
-days 3650 | 有效期10年 |
-newkey rsa:2048 | 生成2048位RSA密钥 |
CN=blog.xnwxb.cn | 证书绑定的域名(重要! 必须与访问域名一致) |
Part 2:配置 Apache 使用证书
2.1 安装 mod_ssl(如果没有)
欧拉系统(基于 CentOS/RHEL)使用 yum 安装:
sudo yum install mod_ssl -y
2.2 编辑 Apache 配置文件
我选择了直接在 httpd.conf 中添加虚拟主机配置,简单直接:
sudo vi /etc/httpd/conf/httpd.conf
在文件末尾添加以下内容:
<VirtualHost *:443>
DocumentRoot "/var/www/html"
ServerName blog.xnwxb.cn
SSLEngine on
SSLCertificateFile /etc/ssl/wordpress/server.crt
SSLCertificateKeyFile /etc/ssl/wordpress/server.key
</VirtualHost>
配置说明
| 指令 | 含义 |
|---|---|
VirtualHost *:443 | 监听 443 端口(HTTPS 默认端口) |
DocumentRoot | 网站根目录,指向 WordPress 所在位置 |
ServerName | 证书绑定的域名 |
SSLEngine on | 启用 SSL/TLS 加密 |
SSLCertificateFile | 证书文件路径 |
SSLCertificateKeyFile | 私钥文件路径 |
⚠️ 注意:如果系统中有
ssl.conf,也可以编辑该文件。我为了方便统一管理,直接写在httpd.conf末尾。
Part 3:重启 Apache 并验证
# 检查配置语法是否正确 sudo apachectl configtest # 重启 Apache sudo systemctl restart httpd # 检查 443 端口是否在监听 ss -lntp | grep 443
看到类似输出说明 HTTPS 服务已启动:
LISTEN 0 128 *:443 users:(("httpd",...))
Part 4:配置 frp 内网穿透,转发 HTTPS 流量
因为我的服务器在本地,需要通过 frp 将公网请求穿透到内网。
4.1 服务端(frps)开启 HTTPS 端口
在 frps 配置文件中,新增 vhostHTTPSPort:
[server] bindPort = 7000 vhostHTTPPort = 80 vhostHTTPSPort = 443 # 新增 HTTPS 端口
4.2 客户端(frpc)添加 HTTPS 代理
[[proxies]]
name = "web-https"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["blog.xxxx.cn"]
⚠️ 注意:内网服务器必须先有 Web 服务器监听 443 端口(即 Part 2 的配置),否则穿透也没用。
4.3 重启 frpc
sudo systemctl restart frpc
检查 frp 后台日志,确认两个服务(HTTP + HTTPS)都已注册上线。
Part 5:验证自签名证书是否生效
在浏览器中访问:https://blog.xxx.cn
由于是自签名证书,浏览器会提示“您的连接不是私密连接”:
- 点击 “高级”
- 选择 “继续前往 blog.xxx.cn(不安全)”
如果能正常看到 WordPress 页面,说明 HTTPS 穿透成功!✅
Part 6:使用 Really Simple Security 插件完成 WordPress 适配
自签名证书验证通过后,接下来让 WordPress 识别并适配 HTTPS 环境。
- 进入 WordPress 后台 → 插件 → 安装插件
- 搜索 Really Simple Security,安装并启用
- 插件会自动检测到 HTTPS 可用,点击 “启用 SSL”
- 它会帮你自动完成:
- ✅ 强制 HTTP → HTTPS 跳转
- ✅ 修复混合内容问题(混合内容指页面中同时包含 HTTP 和 HTTPS 资源)
- ✅ 更新站点地址为 HTTPS
至此,本地 HTTPS 已完全跑通。但自签名证书在浏览器中会显示“不安全”,所以下一步申请公网可信证书。
Part 7:申请 Let’s Encrypt 免费公网证书
7.1 安装 acme.sh
# 安装 git
sudo dnf install git -y
# 从 Gitee 拉取 acme.sh(国内访问 GitHub 较慢,使用 Gitee 镜像)
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
# 安装
./acme.sh --install -m 123456@qq.com
# 加载环境变量
source ~/.bashrc
7.2 注册账号并申请证书
# 删除旧账号信息(如有) rm -rf /root/.acme.sh/account.conf # 重新注册 acme.sh --register-account -m 449708825@qq.com # 申请证书(使用 Webroot 方式验证域名所有权) acme.sh --issue -d blog.xnwxb.cn -w /var/www/html
📌 说明:这里实际使用的是 ZeroSSL 颁发机构(而非 Let’s Encrypt),ZeroSSL 同样提供免费 90 天证书,浏览器信任级别相同。
看到 Registered 和 ACCOUNT_THUMBPRINT 说明账号注册成功,证书申请成功后会有相关提示。
7.3 安装证书到 Apache
acme.sh --install-cert -d blog.xnwxb.cn \
--key-file /etc/ssl/wordpress/server.key \
--fullchain-file /etc/ssl/wordpress/server.crt \
--reloadcmd "systemctl reload httpd"
7.4 重启 Apache
sudo systemctl restart httpd
Part 8:验证成果
- 浏览器访问
https://blog.xxx.cn - 强制刷新:
Ctrl+F5 - 查看地址栏:应该显示小锁图标 🔒,不再提示“不安全”
🎉 公网可信证书配置成功!
Part 9:自动续期机制
acme.sh 在安装时会自动配置定时任务(Cron Job),每天自动检查证书有效期,无需手动干预。
验证定时任务是否存在
crontab -l
正常输出应类似:
0 0 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh > /dev/null
续期逻辑
- 定时任务每天执行
acme.sh --cron - 如果证书距离过期 超过30天 → 不做任何事
- 如果证书距离过期 不足30天 → 自动续期
- 续期成功后,自动执行
--reloadcmd中的命令(即systemctl reload httpd),无缝切换新证书
手动测试续期流程
acme.sh --renew -d blog.xnwxb.cn --dry-run
看到 The dry run was successful. 说明一切正常。
查看证书信息
acme.sh --list
输出示例:
| 字段 | 值 | 含义 |
|---|---|---|
Main_Domain | blog.xxx.cn | 证书绑定的主域名 |
KeyLength | ec-256 | 使用 ECC 椭圆曲线加密(比 RSA 更快更安全) |
Profile CA | ZeroSSL.com | 证书颁发机构 |
Created | 2026-08-28T16:29:46Z | 证书创建时间(UTC) |
Renew | 2026-09-26T16:29:46Z | 计划续期时间(创建后约30天) |
📌 实际到期时间为 2026年11月27日左右(ZeroSSL 90天有效期)。
今日总结
| 步骤 | 核心操作 | 关键点 |
|---|---|---|
| 1 | 生成自签名证书 | openssl req,CN 必须与域名一致 |
| 2 | 配置 Apache HTTPS | 修改 httpd.conf,添加 VirtualHost *:443 |
| 3 | 验证本地 HTTPS | ss -lntp | grep 443 检查端口监听 |
| 4 | frp 转发 HTTPS | vhostHTTPSPort = 443 + type = https |
| 5 | WordPress 适配 | Really Simple Security 插件一键修复混合内容 |
| 6 | 申请公网证书 | acme.sh + ZeroSSL Webroot 验证 |
| 7 | 自动续期 | cron 每天检查,<30天自动续期 |
写在最后
今天这一课让我深刻体会到:HTTPS 配置不是“装个证书就行”,而是一个完整的链路——从本地 Apache 配置、到 frp 穿透、到 WordPress 适配、再到公网证书申请和自动续期,每一环都要打通。
整条链路跑通之后,最大的感受是:自签名证书用来“验证流程”,公网证书用来“正式上线”,分两步走,心里踏实很多。
证书自动续期也配置好了,后续可以安心写博客,不用再为证书操心。如果后续浏览器提示证书有问题,再回来排查即可。
#服务器运维 #HTTPS #Apache #frp内网穿透 #LetEncrypt #WordPress