Ответ 1
У меня есть это до сих пор, но я пропускаю пару вещей, таких как получение сценария 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,
поэтому добавление команды обновления корневому crontab кажется мне прекрасным.
Я бы улучшил пару вещей в script, чтобы сделать его более надежным:
-
Позиционные параметры
$1
,$2
и т.д., рассеянные вокруг, легко потерять, что может привести к ошибкам. Я бы назвал их именами. -
Проверка аргумента командной строки
if [ -z "$3" ]
слаба, я бы сделал более строгим, чемif [ $# != 3 ]
. -
Как только удаленный script сгенерирован, вы вызываете его с помощью
bash -e
, что полезно для защиты. Но если script вызывается чем-то другим без-e
, то защита там не будет. Было бы лучше создать эту гарантию в самой script с помощьюset -e
. Я бы пошел дальше и использовалset -euo pipefail
, который еще более строгий. И я бы добавил это во внешний script. -
Для большинства команд в удаленном script требуется
sudo
. С одной стороны утомительно писать. Для другого, если одна команда закончила длительное время, так что сеансsudo
истечет, вам, возможно, придется повторно ввести пароль root, что будет раздражать, особенно если вы вышли на кофе-брейк. Было бы лучше потребовать, чтобы всегда выполнялся как root, добавив проверку на uid исполняемого пользователя. -
Поскольку вы запускаете удаленный script с
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 [email protected] [email protected] 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"