apisix/ssl_manager/README.md

350 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# APISIX SSL 证书自动管理
基于 Certbot + APISIX Admin API 的 SSL 证书自动申请和续期方案。
## 功能特性
- ✅ 自动申请 Let's Encrypt 免费 SSL 证书
- ✅ 自动将证书同步到 APISIX
- ✅ 自动续期证书90 天有效期)
- ✅ 监听路由创建,自动为新域名申请证书
- ✅ 支持多域名证书
- ✅ 支持测试环境staging
## 目录结构
```
ssl_manager/
├── ssl_manager.py # SSL 证书管理主脚本
├── route_watcher.py # 路由监听服务
├── certbot_deploy_hook.sh # Certbot 部署钩子
├── config.json # 配置文件
├── requirements.txt # Python 依赖
└── README.md # 说明文档
```
## 安装步骤
### 1. 安装 Certbot
```bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install certbot
# CentOS/RHEL
sudo yum install certbot
```
### 2. 安装 Python 依赖
```bash
cd /home/jingrow/apisix/ssl_manager
# 方法一:使用 uv推荐更快
uv pip install --system -r requirements.txt
# 方法二:使用 pip3
pip3 install -r requirements.txt
```
### 3. 配置
配置已直接定义在 Python 文件中,**不需要** `config.json`
**方式一:直接修改 Python 文件(推荐)**
编辑 `ssl_manager.py` 中的 `DEFAULT_CONFIG`
```python
DEFAULT_CONFIG = {
'apisix_admin_url': 'http://localhost:9180',
'apisix_admin_key': '你的APISIX管理密钥', # 修改这里
'letsencrypt_email': 'your-email@example.com', # 修改这里
'letsencrypt_staging': False, # 生产环境改为 False
# ... 其他配置 ...
}
```
**方式二:使用环境变量**
```bash
export APISIX_ADMIN_KEY="your-admin-key"
export LETSENCRYPT_EMAIL="your-email@example.com"
export LETSENCRYPT_STAGING="false"
```
详细配置说明请查看 `CONFIG.md`
### 4. 创建 Webroot 目录
Certbot 需要 webroot 目录用于验证:
```bash
sudo mkdir -p /var/www/certbot
sudo chown -R www-data:www-data /var/www/certbot
```
### 5. 配置 APISIX 支持 Webroot 验证
需要在 APISIX 中配置一个路由,将 `/.well-known/acme-challenge/` 请求转发到 webroot 目录。
## 使用方法
### 手动申请证书
```bash
# 申请单个域名证书
python3 ssl_manager.py request --domain example.com
# 申请多域名证书
python3 ssl_manager.py request --domain example.com --additional-domains www.example.com api.example.com
```
### 手动续期证书
```bash
# 续期单个域名
python3 ssl_manager.py renew --domain example.com
# 续期所有证书
python3 ssl_manager.py renew-all
```
### 同步现有证书到 APISIX
```bash
python3 ssl_manager.py sync --domain example.com
```
### 检查证书过期时间
```bash
python3 ssl_manager.py check --domain example.com
```
### 启动路由监听服务
```bash
# 持续监听(每 60 秒检查一次)
python3 route_watcher.py
# 只执行一次
python3 route_watcher.py --once
# 自定义检查间隔
python3 route_watcher.py --interval 30
```
## 自动续期配置
### 方法一:使用 Certbot 自动续期 + 部署钩子
1. 配置 Certbot 自动续期:
```bash
# 编辑 Certbot 续期配置
sudo nano /etc/letsencrypt/renewal/example.com.conf
```
在配置文件中添加部署钩子:
```ini
[renewalparams]
deploy_hook = /home/jingrow/apisix/ssl_manager/certbot_deploy_hook.sh
```
2. 测试续期:
```bash
sudo certbot renew --dry-run
```
3. 设置 systemd timer推荐
创建 `/etc/systemd/system/certbot-renew.timer`
```ini
[Unit]
Description=Certbot Renewal Timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target
```
创建 `/etc/systemd/system/certbot-renew.service`
```ini
[Unit]
Description=Certbot Renewal Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook /home/jingrow/apisix/ssl_manager/certbot_deploy_hook.sh
```
启用定时器:
```bash
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer
```
### 方法二:使用自定义脚本 + systemd timer
创建 `/etc/systemd/system/apisix-ssl-renew.service`
```ini
[Unit]
Description=APISIX SSL Certificate Renewal
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /home/jingrow/apisix/ssl_manager/ssl_manager.py renew-all
User=root
```
创建 `/etc/systemd/system/apisix-ssl-renew.timer`
```ini
[Unit]
Description=APISIX SSL Certificate Renewal Timer
[Timer]
OnCalendar=weekly
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target
```
启用:
```bash
sudo systemctl enable apisix-ssl-renew.timer
sudo systemctl start apisix-ssl-renew.timer
```
## 路由监听服务
路由监听服务会自动检测新创建的路由,并为其中的域名申请证书。
### 启动服务
```bash
# 使用 systemd推荐
sudo systemctl start apisix-route-watcher.service
# 或使用 screen/tmux
screen -S route-watcher
python3 route_watcher.py
```
### 创建 systemd 服务
创建 `/etc/systemd/system/apisix-route-watcher.service`
```ini
[Unit]
Description=APISIX Route Watcher Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/jingrow/apisix/ssl_manager/route_watcher.py
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
```
启用服务:
```bash
sudo systemctl enable apisix-route-watcher.service
sudo systemctl start apisix-route-watcher.service
```
## 环境变量配置
也可以通过环境变量配置:
```bash
export APISIX_ADMIN_URL="http://localhost:9180"
export APISIX_ADMIN_KEY="your-admin-key"
export LETSENCRYPT_EMAIL="your-email@example.com"
export LETSENCRYPT_STAGING="false"
export WEBROOT_PATH="/var/www/certbot"
```
## 注意事项
1. **首次使用建议使用 staging 模式测试**
```json
"letsencrypt_staging": true
```
2. **确保 80 端口可访问**Let's Encrypt 需要验证域名所有权,通常使用 HTTP-01 验证方式。
3. **DNS 验证**:如果无法使用 HTTP-01 验证,可以配置 DNS-01 验证(需要修改脚本)。
4. **证书存储**:证书存储在 `/etc/letsencrypt/live/` 目录,请确保有备份。
5. **日志位置**
- SSL 管理器日志:`/var/log/apisix-ssl-manager.log`
- 路由监听日志:`/var/log/apisix-route-watcher.log`
- Certbot 部署钩子日志:`/var/log/apisix-certbot-deploy.log`
## 故障排查
### 证书申请失败
1. 检查域名 DNS 解析是否正确
2. 检查 80 端口是否可访问
3. 检查 webroot 目录权限
4. 查看 Certbot 日志:`/var/log/letsencrypt/letsencrypt.log`
### 证书无法同步到 APISIX
1. 检查 APISIX Admin API 是否可访问
2. 检查 Admin Key 是否正确
3. 查看 SSL 管理器日志
### 自动续期不工作
1. 检查 systemd timer 状态:`systemctl status certbot-renew.timer`
2. 手动测试续期:`certbot renew --dry-run`
3. 检查部署钩子脚本权限:`chmod +x certbot_deploy_hook.sh`
## 测试
### 测试环境staging
```json
"letsencrypt_staging": true
```
Staging 环境有更高的申请频率限制,适合测试。
### 生产环境
测试通过后,设置:
```json
"letsencrypt_staging": false
```
## 许可证
Apache License 2.0