到目前为止,我已经掌握了这一点,但我错过了一些事情,例如编写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"

最佳答案



这是完成(并纠正)您开始工作的一种方法:

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
您是否通过其他方式提供了该信息,
还是在这方面需要帮助?



大多数步骤涉及运行apt-get
为此,您已经需要root用户。
也许您的意思是您不想使用root进行续订。
某些服务以专用用户(而非root)的身份运行,
但是通过documentation of certbot看,我还没有看到这样的东西。
因此,以root进行续约似乎是一种常见的做法,
因此,将更新命令添加到root的crontab对我来说似乎还不错。

我将在脚本中进行一些改进以使其更强大:
  • 分散的位置参数$1$2等容易丢失,可能导致错误。我会给他们起合适的名字。
  • 命令行参数验证if [ -z "$3" ]很弱,我会像if [ $# != 3 ]一样严格。
  • 一旦生成了远程脚本,就可以使用bash -e对其进行调用,这对于保护脚本很有用。但是,如果脚本被其他没有-e的调用,则保护措施将不存在。最好使用set -e将这种保护措施内置到脚本本身中。我会更进一步,使用更严格的set -euo pipefail。我也将其放在外部脚本中。
  • 远程脚本中的大多数命令都需要sudo。一方面,这很乏味。对于另一个命令,如果一个命令以很长时间结束而使sudo session 终止,则您可能不得不第二次重新输入root密码,这将很烦人,特别是如果您出去喝咖啡休息的时候。最好要求始终以root用户身份运行,方法是在执行用户的uid上添加一个检查。
  • 由于您使用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"
    

    10-08 01:13