2017-10-18 42 views
11

Tôi có điều này cho đến nay nhưng tôi thiếu một vài điều như nhận được công việc cron kịch bản. Không muốn làm điều này như là người chủ. Vì vậy, tôi giả định một số chi tiết có thể được thực hiện để thiết lập người dùng đầu tiên cùng một lúc. Kịch bản sẽ cần phải là idempotent (có thể được chạy hơn và hơn nữa mà không có rủi ro thay đổi bất cứ điều gì nếu nó đã được chạy với các đối số tương tự trước).Cách thích hợp để viết một phiên bản nginx mới với SSL trên một máy chủ Ubuntu 16.04 mới là gì?

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 [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" 
+3

Tại sao không sử dụng Ansible? –

+1

Có vẻ ổn, vấn đề ở đâu? – aggsol

+0

ngoại trừ thiếu 'fi' bên trong tài liệu ở đây, có vẻ tốt. Có thể phù hợp với dbl-quoting của bạn của '" $ 1 "'? Để được thực sự chống đạn, có thể thêm một số kiểm tra dbl rằng mỗi bước được làm việc. Bạn có thể chuỗi tất cả các 'apt-get' cùng với '&&' s (thực sự tất cả các bước) (có, điên) và/hoặc kiểm tra các tệp nhật ký mà công cụ đã thực sự xảy ra hoặc chụp Std-err và đảm bảo nó là trống rỗng, vv HOẶC bạn có thể nhìn vào nó từ "kết thúc hoàn thành" của sự vật và thêm một thử nghiệm chứng minh "nginx dụ với SSL" của bạn đang làm việc theo yêu cầu. (Tất cả các câu hỏi hợp lệ ở trên). Chúc may mắn! – shellter

Trả lời

1

Có nhiều cách để làm điều này và họ có thể được coi là "đúng đắn" tùy thuộc vào kịch bản.

Một cách để làm điều đó vào thời gian khởi động có thể được sử dụng cloud-init, Để kiểm tra trong trường hợp sử dụng AWS khi tạo Ví dụ bạn có thể thêm kịch bản tùy chỉnh của bạn:

enter image description here

này sẽ cho phép running commands on launch of your instance, Trong trường hợp bạn muốn tự động hóa quá trình này (cơ sở hạ tầng như mã), bạn có thể sử dụng ví dụ terraform

Nếu vì lý do nào đó bạn đã cài đặt và chạy và chỉ muốn cập nhật theo yêu cầu nhưng không sử dụng ssh, bạn cou ld sử dụng saltstack.

Nói về "idempotency" Ansible có thể cũng là một công cụ rất tốt để làm điều này, từ ansible glossary:

Một hoạt động là idempotent nếu kết quả thực hiện nó một lần là chính xác giống như kết quả của thực hiện nó liên tục mà không có bất kỳ hành động can thiệp nào.

Có nhiều công cụ có thể giúp bạn đạt được điều này, điều duy nhất là tìm công cụ phù hợp hơn với nhu cầu/kịch bản của bạn.

1

Bạn đang tìm kiếm một cái gì đó như thế này:

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 

và fi ở cuối

bạn cũng có thể tránh làm điều đó nhiều sudo bằng cách kết hợp chúng như trong:

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

Nếu bạn đang làm điều này với sudo bạn đang làm điều này như là root

điều này là như điều imple để làm trong ansible, cố gắng hết sức nó ở đó

để làm công việc cron làm điều này:

CRON_FILE = "/ etc/cron.d/certbot"

nếu [! -f $ CRON_FILE]; sau đó

vang '15 3 * * */usr/bin/certbot mới --quiet'> $ CRON_FILE

fi

2

Tôi có điều này cho đến nay nhưng tôi thiếu một vài những thứ như nhận được cron job scripted.

Dưới đây là một cách để hoàn thành (và đúng) những gì bạn bắt đầu:

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 

Dưới đây là một cách khác tôi thích bởi vì nó không cần phải biết đường dẫn của crontabs:

if ! sudo crontab -l | grep certbot; then 
    sudo crontab -l | { cat; echo "15 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab - 
fi 

Điều tôi thấy thiếu là cách tệp giấy chứng nhận /etc/letsencrypt/live/$domain/fullchain.pem được tạo. Bạn có cung cấp điều đó bằng các cách khác, hoặc bạn có cần trợ giúp với phần đó không?

Không muốn làm điều này dưới dạng gốc.

Hầu hết các bước liên quan đến việc chạy apt-get, và cho rằng bạn đã yêu cầu root. Có lẽ bạn có nghĩa là bạn không muốn làm gia hạn bằng cách sử dụng gốc. Một số dịch vụ hoạt động như một người dùng chuyên dụng thay vì root, nhưng nhìn qua documentation of certbot Tôi chưa thấy bất cứ điều gì như thế. Vì vậy, có vẻ như một thực tế phổ biến để làm gia hạn với gốc, để thêm lệnh gia hạn vào crontab của root có vẻ tốt với tôi.

tôi sẽ cải thiện một vài điều trong kịch bản để làm cho nó mạnh mẽ hơn:

  • Các tham số vị trí $1, $2 và vân vân nằm rải rác xung quanh rất dễ bị mất theo dõi, điều này có thể dẫn đến sai sót . Tôi sẽ cho họ tên riêng.

  • Xác thực đối số dòng lệnh if [ -z "$3" ] yếu, tôi sẽ thực hiện điều đó nghiêm ngặt hơn như if [ $# != 3 ].

  • Khi tập lệnh từ xa được tạo, bạn hãy gọi nó bằng bash -e, cách tốt để bảo vệ. Nhưng nếu kịch bản được gọi bởi một cái gì đó khác mà không có -e, các biện pháp bảo vệ sẽ không có ở đó. Nó sẽ là tốt hơn để xây dựng mà tự vệ vào kịch bản chính nó với set -e. Tôi sẽ đi xa hơn và sử dụng set -euo pipefail thậm chí còn nghiêm ngặt hơn. Và tôi cũng sẽ đặt nó trong kịch bản bên ngoài.

  • Hầu hết các lệnh trong tập lệnh từ xa yêu cầu sudo. Đối với một điều đó là tẻ nhạt để viết. Đối với một lệnh khác, nếu một lệnh kết thúc mất một thời gian dài sao cho phiên sudo hết hạn, bạn có thể phải nhập lại mật khẩu gốc lần thứ hai, điều này sẽ gây phiền toái, đặc biệt là nếu bạn bước ra để ngắt cà phê. Nó sẽ là tốt hơn để yêu cầu phải luôn luôn chạy như là người chủ, bằng cách thêm một kiểm tra trên uid của người dùng thực hiện.

  • Vì bạn chạy tập lệnh từ xa với bash -x ~/wks ... thay vì chỉ ~/wks, bạn không cần phải thực thi nó với chmod, do đó, bước đó có thể bị xóa.

Đưa trên cùng (và sau đó một số), tôi sẽ viết như thế này:

#!/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" 
Các vấn đề liên quan