在新的Ubuntu 16.04服务器上使用SSL编写新的nginx实例的正确方法是什么?

问题描述 投票:11回答:5

到目前为止,我有这个,但我遗漏了一些事情,如编写cron作业脚本。不想以root身份执行此操作。所以我假设可以做更多的事情来同时设置第一个用户。该脚本需要是幂等的(可以反复运行,如果之前使用相同的参数运行,则无需更改任何内容)。

single domain cert Nginx.是:

#!/bin/bash
if [ -z "$3" ]; then
        echo use is "singledomaincertnginx.sh <server-ssh-address> <ssl-admin-email> <ssl-domain>"
        echo example: "singledomaincertnginx.sh [email protected] [email protected] 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"
bash ssl nginx ssh certbot
5个回答
3
投票

到目前为止,我有这个,但我遗漏了一些事情,如编写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用户运行,但通过documentation of 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 [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"

1
投票

有多种方法可以做到这一点,根据场景,它们可以被认为是“合适的”。

在启动时执行此操作的一种方法可能是使用cloud-init,要在创建实例时使用AWS进行测试,您可以添加自定义脚本:

enter image description here

这将允许running commands on launch of your instance,如果你想自动化这个过程(像代码的基础设施),你可以使用例如terraform

如果由于某种原因你已经启动并运行实例并且只想按需更新但不使用ssh,则可以使用saltstack

谈论“Idempotency”Ansible可能也是一个非常好的工具,从ansible glossary

如果执行一次的结果与在没有任何干预动作的情况下重复执行它的结果完全相同,则操作是幂等的。

有许多工具可以帮助您实现这一目标,唯一的办法就是找到能够更好地适应您的需求/场景的工具。


1
投票

你在寻找这样的东西:

if [[ "$(grep '/usr/bin/certbot' /var/spool/cron/crontabs/$(whoami))" = "" ]]
then
    echo "15 3 * * * /usr/bin/certbot renew --quiet" >> /var/spool/cron/crontabs/$(whoami)
fi

和最后的fi

你也可以通过连接它们来避免做那么多的sudo:

sudo bash -c 'add-apt-repository -y ppa:certbot/certbot;apt-get update;apt-get upgrade -y;apt-get install -y software-properties-common python-certbot-nginx nginx;sed -i "s/server_name .*;/server_name $2;/" /etc/nginx/sites-available/default;systemctl restart nginx.service'

1
投票

如果您使用sudo执行此操作,则以root身份执行此操作

在ansible中这是一个简单的事情,最好在那里做

做cron工作做到这一点:

CRON_FILE = “的/ etc / cron.d / certbot”

如果[! -f $ CRON_FILE];然后

echo '15 3 * * * / usr / bin / certbot renew --quiet'> $ CRON_FILE


0
投票

nginx + Ubuntu的复制粘贴解决方案

Install dependencies

sudo apt-get install nginx -y
sudo apt-get install software-properties-common -y
sudo add-apt-repository universe -y
sudo add-apt-repository ppa:certbot/certbot -y
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx -y

Get SSL certificate and redirect all traffic from http to https

certbot --nginx --agree-tos --redirect --noninteractive \
        --email [email protected] \
        --domain YOUR.DOMAIN.COM

Test renewal

certbot renew --dry-run

Docs

https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx

© www.soinside.com 2019 - 2024. All rights reserved.