给 IP 地址申请 TLS 证书
Certbot 现在支持直接为 IP 地址申请证书,流程和域名证书类似,使用 HTTP-01 Webroot 验证。
环境:
- Red hat
- Nginx
- Certbot
Python 版本
Certbot 5 不再支持 Python 3.9。部分 Red Hat 系发行版的默认 Python3 仍然是 3.9,需要安装使用 Python 3.11。
dnf install -y epel-release
dnf install -y python3.11 python3.11-pip pipx cronie
安装命令也需要替换成 python3.11:
pipx install \
--python /usr/bin/python3.11 \
"certbot>=5.4"
准备 Nginx
创建 ACME 验证目录:
sudo mkdir -p /var/www/acme/.well-known/acme-challenge
Nginx 配置:
sudo vim /etc/nginx/conf.d/acme.conf
填入下列配置,并修改为真实 IP 地址:
server {
listen 80;
listen [::]:80;
server_name <替换为IP地址>;
location ^~ /.well-known/acme-challenge/ {
root /var/www/acme;
try_files $uri =404;
}
location / {
return 404;
}
}
然后重新加载配置:
sudo nginx -t
sudo systemctl reload nginx
SELinux
如果系统开启了 SELinux,需要给 ACME 目录设置正确上下文。
sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_content_t '/var/www/acme(/.*)?'
sudo restorecon -Rv /var/www/acme
ls -Zd /var/www/acme
应包含:
httpd_sys_content_t
防火墙
如果系统使用 firewalld,需要开放 HTTP 和 HTTPS:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
自动申请和续期脚本
保存为:
vim letsencrypt.sh
#!/usr/bin/env bash
set -Eeuo pipefail
IP="${1:-}"
EMAIL="${2:-}"
export PIPX_HOME=/opt/pipx
export PIPX_BIN_DIR=/usr/local/bin
if [[ $EUID -ne 0 || -z "$IP" || -z "$EMAIL" ]]; then
echo "Usage: sudo $0 PUBLIC_IP EMAIL" >&2
exit 1
fi
dnf install -y epel-release
dnf install -y python3 pipx cronie
mkdir -p /var/www/acme/.well-known/acme-challenge
if [[ ! -x /usr/local/bin/certbot ]]; then
pipx install \
--python /usr/bin/python3 \
"certbot>=5.4"
fi
/usr/local/bin/certbot certonly \
--non-interactive \
--agree-tos \
--email "$EMAIL" \
--preferred-profile shortlived \
--webroot \
--webroot-path /var/www/acme \
--ip-address "$IP"
cat >/etc/cron.d/certbot-ip <<'EOF'
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
17 */6 * * * root /usr/local/bin/certbot renew -q --deploy-hook "/usr/sbin/nginx -t && /usr/bin/systemctl reload nginx"
EOF
chmod 644 /etc/cron.d/certbot-ip
systemctl enable --now crond
然后执行:
chmod +x letsencrypt.sh
sudo ./letsencrypt.sh <IP地址> admin@example.com
证书位置:
/etc/letsencrypt/live/<IP地址>/
如存在同名记录时,Certbot 可能添加数字后缀。也可以使用命令查看路径:
sudo /usr/local/bin/certbot certificates
HTTPS 配置参考
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name <IP地址>;
ssl_certificate /etc/letsencrypt/live/<IP地址>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<IP地址>/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
}
}