到目前为止我有这个,但我错过了一些事情,比如让 cron 作业编写脚本。
这是完成(和更正)您开始的内容的一种方法:
if ! sudo crontab -l | grep certbot; then
echo "15 3 * * * /usr/bin/certbot renew --quiet" | sudo tee -a /var/spool/cron/crontabs/root >/dev/null
fi
这是我更喜欢的另一种方式,因为它不需要知道 crontabs 的路径:
if ! sudo crontab -l | grep certbot; then
sudo crontab -l | { cat; echo "15 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab -
fi
我看到缺少的是证书文件/etc/letsencrypt/live/$domain/fullchain.pem
的创建方式。你是通过其他方式提供的,还是需要这部分的帮助?
不想以 root 身份执行此操作。
大多数步骤都涉及运行apt-get
,为此您已经需要 root。也许您的意思是您不想使用 root 进行续订。一些服务以专用用户而不是 root 身份运行,但查看certbot 的文档我没有看到类似的东西。因此,使用 root 进行更新似乎是一种常见的做法,因此将更新命令添加到 root 的 crontab 对我来说似乎很好。
我会改进脚本中的一些内容以使其更加健壮:
散落在各处的位置参数等容易丢失$1
,$2
从而导致错误。我会给他们正确的名字。
命令行参数验证if [ -z "$3" ]
很弱,我会使其更加严格,因为if [ $# != 3 ]
.
远程脚本生成后,用 调用,有bash -e
利于维护。但是,如果脚本被其他没有 的东西调用-e
,则安全措施将不存在。最好在脚本本身中使用set -e
. 我会走得更远,使用set -euo pipefail
更严格的。我也会把它放在外部脚本中。
远程脚本中的大多数命令都需要sudo
. 一方面写起来很乏味。另一方面,如果一个命令最终花费了很长时间以致sudo
会话过期,您可能不得不再次重新输入 root 密码,这会很烦人,尤其是当您出去喝咖啡时。通过添加对执行用户的 uid 的检查,要求始终以 root 身份运行会更好。
由于您使用bash -x ~/wks ...
而不是仅运行远程脚本~/wks
,因此无需使用 使其可执行chmod
,因此可以删除该步骤。
把上面的东西放在一起(然后是一些),我会这样写:
#!/bin/bash
set -euo pipefail
if [ $# != 3 ]; then
echo "Usage: $0 <server-ssh-address> <ssl-admin-email> <ssl-domain>"
echo "Example: singledomaincertnginx.sh user@mydomain.com admin@mydomain.com some-sub-domain.mydomain.com"
exit 1
fi
remote=$1
email=$2
domain=$3
remote_script_path=./wks
ssh $remote "cat > $remote_script_path" << 'EOF'
#!/bin/bash
set -euo pipefail
if [[ "$(id -u)" != 0 ]]; then
echo "This script must be run as root. (sudo $0)"
exit 1
fi
email=$1
domain=$2
echo email: $email
echo domain: $domain
add-apt-repository -y ppa:certbot/certbot
apt-get update
apt-get upgrade -y
apt-get install -y software-properties-common
apt-get install -y python-certbot-nginx
apt-get install -y nginx
sed -i "s/server_name .*;/server_name $domain;/" /etc/nginx/sites-available/default
systemctl restart nginx.service
#service nginx restart
if [[ -e /etc/letsencrypt/live/$domain/fullchain.pem ]]; then
certbot -n --nginx --agree-tos -m $email -d $domain
fi
if ! crontab -l | grep -q certbot; then
crontab -l | {
cat
echo
echo "15 3 * * * /usr/bin/certbot renew --quiet"
echo
} | crontab -
fi
EOF
ssh -t $remote "sudo bash -x $remote_script_path $email $domain"