Ada*_*ruk 11 ssh bash ssl nginx certbot
到目前为止,我有这个,但我遗漏了一些事情,如编写cron作业脚本.不想以root身份执行此操作.所以我假设可以做更多的事情来同时设置第一个用户.该脚本需要是幂等的(可以反复运行,如果以前使用相同的参数运行,则无需更改任何内容).
singledomaincertnginx.sh:
#!/bin/bash
if [ -z "$3" ]; then
echo use is "singledomaincertnginx.sh <server-ssh-address> <ssl-admin-email> <ssl-domain>"
echo example: "singledomaincertnginx.sh user@mydomain.com admin@mydomain.com some-sub-domain.mydomain.com"
exit
fi
ssh $1 "cat > ~/wks" << 'EOF'
#!/bin/bash
echo email: $1
echo domain: $2
sudo add-apt-repository -y ppa:certbot/certbot
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y software-properties-common
sudo apt-get install -y python-certbot-nginx
sudo apt-get install -y nginx
sudo sed -i "s/server_name .*;/server_name $2;/" /etc/nginx/sites-available/default
sudo systemctl restart nginx.service
if [[ -e /etc/letsencrypt/live/$2/fullchain.pem ]]; then
sudo certbot -n --nginx --agree-tos -m "$1" -d "$2"
fi
if [[ ! sudo crontab -l | grep certbot ]]; then
# todo: add cron job to renew: 15 3 * * * /usr/bin/certbot renew --quiet
EOF
ssh $1 "chmod +x ~/wks"
ssh -t $1 "bash -x -e ~/wks $2 $3"
Run Code Online (Sandbox Code Playgroud)
到目前为止我已经做到了,但我错过了一些事情,比如编写 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
Run Code Online (Sandbox Code Playgroud)
这是我更喜欢的另一种方法,因为它不需要知道 crontab 的路径:
if ! sudo crontab -l | grep certbot; then
sudo crontab -l | { cat; echo "15 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab -
fi
Run Code Online (Sandbox Code Playgroud)
我发现缺少的是证书文件的/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"
Run Code Online (Sandbox Code Playgroud)
有多种方法可以做到这一点,根据具体情况,它们可以被认为是“正确的”。
在启动时执行此操作的一种方法是使用cloud-init,为了在创建实例时使用 AWS 进行测试,您可以添加自定义脚本:
这将允许在启动实例时运行命令,如果您想自动化此过程(类似代码的基础设施),您可以使用例如terraform
如果由于某种原因您已经启动并运行了实例,并且只想按需更新但不使用 ssh,则可以使用saltstack。
从ansible 术语表来看,谈论“幂等性”Ansible 也可能是一个非常好的工具:
如果执行一次操作的结果与重复执行操作而无需任何干预操作的结果完全相同,则该操作是幂等的。
有很多工具可以帮助您实现这一目标,唯一要做的就是找到更适合您的需求/场景的工具。
| 归档时间: |
|
| 查看次数: |
463 次 |
| 最近记录: |