前言
在自建网络穿透体系中,FRP(Fast Reverse Proxy) 是一款非常高效、稳定的工具。
搭建了一个小型但完整的结构:
- 多台 VPS 运行 FRPS(服务端);
- 一台局域网主机运行 FRPC(客户端);
- 通过 systemd 实现多实例独立管理与定期自动维护。
由于使用 Certbot 为 FRPS 生成 HTTPS / TLS 证书,这些证书会在 90 天内自动续期。
为了让 FRPS 与 FRPC 在证书替换后自动加载新证书、避免手动重启,设计了一个每两个月执行一次的自动重启计划。
这既保证证书长期有效,也保持隧道连接的稳定性。
一、架构概览
| 角色 | 实例 | 主机类型 | 功能说明 |
|---|---|---|---|
| FRPC | frpc1、frpc2、(frpc3 预留) | 局域网穿透节点 | 为内网设备提供公网访问 |
| FRPS | frps-main、frps-backup | 公网 VPS | 接收客户端连接,终止 TLS |
二、服务文件结构
FRPC(客户端)
/etc/systemd/system/frpc1.service:
[Unit]
Description=frp client instance 1
[Service]
User=root
WorkingDirectory=/opt/frp
ExecStart=/opt/frp/frpc -c /opt/frp/frpc1.toml
Restart=unless-stopped
[Install]
WantedBy=multi-user.target
第二个实例仅需复制并修改文件名与配置路径:
cp frpc1.service frpc2.service
FRPS(服务端)
/etc/systemd/system/frps.service:
[Unit]
Description=frp server
[Service]
User=root
WorkingDirectory=/opt/frp
ExecStart=/opt/frp/frps -c /opt/frp/frps.toml
Restart=always
[Install]
WantedBy=multi-user.target
说明:
Restart=always保证服务端在意外退出后立即重启;- 证书文件路径通常由
frps.toml中的tls_cert_file/tls_key_file指定。
三、自动重启机制的设计思路
Certbot 证书默认有效期 90 天,但 FRPS / FRPC 启动时才会加载新证书。
因此需要一个机制,确保在证书更新后自动重启进程以生效。
选择 每两个月(偶数月)1 日 00:00:00 自动重启,足以覆盖证书更新周期,同时避免频繁中断。
该机制通过 systemd timer 实现,无需 crontab,具备更高可靠性与可观察性。
四、systemd 定时器实现
以下以 frpc1 为例,服务端与其他实例只需改名。
/etc/systemd/system/frpc1-restart.service
[Unit]
Description=Restart frpc1 service
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart frpc1.service
/etc/systemd/system/frpc1-restart.timer
[Unit]
Description=Restart frpc1 every even month on the 1st at 00:00
[Timer]
# 偶数月:2/4/6/8/10/12 月的 1 日 00:00 执行
OnCalendar=*-02-01 00:00:00
OnCalendar=*-04-01 00:00:00
OnCalendar=*-06-01 00:00:00
OnCalendar=*-08-01 00:00:00
OnCalendar=*-10-01 00:00:00
OnCalendar=*-12-01 00:00:00
AccuracySec=1s
RandomizedDelaySec=0
Persistent=true
Unit=frpc1-restart.service
[Install]
WantedBy=timers.target
Persistent=true可确保若主机在触发时关机,开机后会立即补执行一次。
五、启用与验证
sudo systemctl daemon-reload
sudo systemctl enable --now frpc1-restart.timer
验证是否加载成功:
systemctl list-timers 'frpc*.timer'
输出示例:
NEXT LEFT UNIT ACTIVATES
Mon 2025-12-01 00:00:00 JST 1 month 18 days left frpc1-restart.timer frpc1-restart.service
六、适配 Certbot 自动更新流程
Certbot 每次成功更新证书时,会触发 /etc/letsencrypt/renewal-hooks/deploy/ 下的脚本。
也可以在其中直接写入:
#!/bin/bash
systemctl restart frps.service
但如果有多个节点,或希望统一在夜间重启,则保持本文的 systemd 定期方案 更安全且易控。
它不会依赖具体证书更新时间,而是周期性地确保服务加载最新证书。
七、可选改进与实践建议
- 记录日志
在 restart service 中加入:ExecStart=/bin/bash -c 'echo "$(date "+%%F %%T") restarting frpc1..." >> /var/log/frpc1-restart.log && systemctl restart frpc1.service' - 错开多个实例的重启时间
防止瞬时中断:RandomizedDelaySec=300 - 统一管理脚本
可写一个/usr/local/bin/restart-frp-all.sh,批量重启所有实例,再由一个 timer 触发。 - 远程管理
若服务端与客户端分布多台 VPS,可用 SSH + systemd-analyze calendar 定期检查下次触发时间。
八、常用命令速查
| 操作 | 命令 |
|---|---|
| 手动重启服务 | systemctl restart frps |
| 手动触发定时器 | systemctl start frpc1-restart.service |
| 查看所有定时器 | systemctl list-timers |
| 检查服务状态 | systemctl status frps |
| 查看最近日志 | journalctl -u frps --since -10m |
结语
通过 systemd 的 timer 与 service 机制,我们可以实现:
- FRP 多实例的独立部署;
- Certbot 证书更新后的自动生效;
- 稳定、周期性的运行维护;
这一套机制几乎无需人工干预,即可让 FRP 系统长期运行、自动更新、持续可靠。
对于有公网节点与内网穿透需求的用户来说,这是一种兼顾自动化与安全性的理想方案。