From 8935adaa9012f3194adf4a285f7328aa4ae431f2 Mon Sep 17 00:00:00 2001 From: "Mehdi (OSX)" Date: Thu, 23 Nov 2023 09:04:06 +0500 Subject: [PATCH] changes --- README.md | 30 +++++++++++------ certs/.gitkeep | 0 config.sh.dummy | 25 ++++++++++++++ generate-certs.sh | 84 ++++++++++++++++++++++++++++------------------- 4 files changed, 96 insertions(+), 43 deletions(-) delete mode 100644 certs/.gitkeep create mode 100644 config.sh.dummy mode change 100644 => 100755 generate-certs.sh diff --git a/README.md b/README.md index b15ae32..ce27398 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,24 @@ -**Check config options in** `generate-certs.sh`. - ---- +## Usage: +1. Create ssl folder to store certificates and this repository. +2. Clone this repository or use as submodule: + - `git submodule add ssh://git@git.w3goodies.com:17001/mehdi-mac/certbot-docker-script.git` +3. Creat certs folder inside ssl folder. +4. Put config.sh inside ssl folder. Copy contents from certbot-docker-script/config.sh.dummy +5. The folder structure would be: +``` +/your-project/ssl/ +├── certs (Your certificates will be stored here) +├── config.sh (Your config file) +├── certbot-docker-script (this repository) +``` +6. Run: +```shell +your-project/ssl/certbot-docker-script/generate-certs.sh ../config.sh +``` ## Info: - It uses certbot's docker to generate LetsEncrypt SSL certificates, and it comes with simple script to generate and renew certificate for **single domain.** -- It **does not support multiple domains**. But you can create certificate for test.com, abc.test.com, *.test.com (wildcard). +- It **does not support multiple domains**. But it will automatically generate a single certificate for test.com and *.test.com (wildcard). 1. This script will **create** SSL certificates based on `${new_ssl_command}`. 2. If the `${live_certs_dir}` and `${live_certs_dir}/cert.pem` exist then certificate is **renewed** based on `${renew_command}` @@ -14,11 +28,7 @@ ## Info: --- -## Usage: - -- Set configuration in `generate-certs.sh` -- Set executable permission: `chmod +x generate-certs.sh` -- Run: `generate-certs.sh` +## Notes: - After the certificates are created: - Make sure to mount both `certs/live/test.com` and `certs/archive/test.com` directory, and use `live/test.com/*.pem` certificates in your nginx config. - Because archive directory has actual files, but live directory has symlink to archive. In archive, certs are stored like this fullchain1.pem, cert1.pem and number is increased based on renewals. But live folder has direct certificates without number like cert.pem, fullchain.pem @@ -52,4 +62,4 @@ ## Cron: - You can restart nginx in `posthook`, to reload used certificates. - Example: - `nano /etc/cron.d/generate-certs-for-test.com` - - `0 1 * * * root /script-location/generate-certs.sh > /script-location/generate-certs.log` + - `0 1 * * * root /your-project/ssl/certbot-docker-script/generate-certs.sh ../config.sh > /your-project/ssl/generate-certs.log` diff --git a/certs/.gitkeep b/certs/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/config.sh.dummy b/config.sh.dummy new file mode 100644 index 0000000..0b84dd6 --- /dev/null +++ b/config.sh.dummy @@ -0,0 +1,25 @@ +#using dry_run, certificates are not actually generated, instead it will only do test run. +#Remember that if you build certificates (dry_run=false) then DON'T keep on doing it in short interval (more than 5in a day), as otherwise certbot might apply rate limits on further usages. +dry_run=true + +#Create token from Cloudflare API tokens page, and limit it the DNZ zone of your domain. +cloudflare_token='s3R-_EDhlG6-O-iBUQ2TJD9IadwYD7vqX98s3tjh' + +#Set location for certificates to store in. +certs_dir="../certs/" + +#Script will create certificate for domain.com and as well as *.domain.com (wildcard) +domain="test.com" + +#Email to receive expiration notices or other mails from certbot +email="w3goodies.com@gmail.com" + +#Generate certificates using this command. +#Script will generate certificate for domain.com and as well as *.domain.com (wildcard) +new_ssl_command="docker run --rm -v #certs_dir#:/etc/letsencrypt -v #cloudflare_token_file#:/certbot-cloudflare certbot/dns-cloudflare certonly #dry_run_arg# #domain_arg# --dns-cloudflare --dns-cloudflare-credentials /certbot-cloudflare --preferred-challenges dns-01 --preferred-chain 'ISRG Root X1' --non-interactive --dns-cloudflare-propagation-seconds 20 --agree-tos #email_arg#"; + +#domains cant be changed in renewal. If you want to change, then clear certs/* folder and regenerate certificates. +renew_command="docker run --rm -v #certs_dir#:/etc/letsencrypt -v #cloudflare_token_file#:/certbot-cloudflare certbot/dns-cloudflare renew #dry_run_arg# --non-interactive --agree-tos --email w3goodies.com@gmail.com --no-random-sleep-on-renew" + +#posthook is executed if certificate is created for first time, or if "${live_certs_dir}/cert.pem" file is modified (based on checking last modified time). +post_hook="echo 'dummy post hook result'" \ No newline at end of file diff --git a/generate-certs.sh b/generate-certs.sh old mode 100644 new mode 100755 index 2bb6d1d..9773efa --- a/generate-certs.sh +++ b/generate-certs.sh @@ -1,34 +1,40 @@ #!/bin/bash -#CONFIG: - -#using dry_run, certificates are not actually generated, instead it will only do test run. -#Remember that if you build certificates (dry_run=false) then don't keep on doing it in short interval (more than 5in a day), as otherwise certbot might apply rate limits on further usages. -dry_run=true - -#Create it from Cloudflare, and limit it the DNZ zone of your domain. -cloudflare_token='' - -#Script will check this directory for empty, to determine to create or renew ssl certificates. -live_certs_dir="certs/live/test.com"; - -#-d test.com, -d *.test.com means certificate for: test.com and it's wildcard subdomains. -#Only 1 certificate will be generated, regardless of number of subdomains provided here. -new_ssl_command="docker run --rm -v ./certs:/etc/letsencrypt -v #cloudflare_token_file#:/certbot-cloudflare certbot/dns-cloudflare certonly #dry_run_arg# --dns-cloudflare --dns-cloudflare-credentials /certbot-cloudflare -d test.com -d \*.test.com --preferred-challenges dns-01 --preferred-chain 'ISRG Root X1' --non-interactive --dns-cloudflare-propagation-seconds 20 --agree-tos --email w3goodies.com@gmail.com"; - -#domains cant be changed in renewal. If you want to change, then clear certs/* folder and regenerate certificates. -renew_command="docker run --rm -v ./certs:/etc/letsencrypt -v #cloudflare_token_file#:/certbot-cloudflare certbot/dns-cloudflare renew #dry_run_arg# --non-interactive --agree-tos --email w3goodies.com@gmail.com --no-random-sleep-on-renew" - -#posthook is executed if certificate is created for first time, or if "${live_certs_dir}/cert.pem" file is modified (based on checking last modified time). -post_hook="docker-compose restart nginx" - -#END CONFIG +echo "" #chdir to current dir. cd "$(dirname "$0")" -#remove trailing slash from live_certs_dir -live_certs_dir=${live_certs_dir%/} +#Load config +config_file=$1 +if [ ! -f "$config_file" ]; then + echo -e "Error: You must provide config file to load as argument or config file does not exist: ${config_file}\n" + exit 1 +fi + +source $config_file + +#Check certs dir exist +certs_dir="${certs_dir%/}" #Remove trailing slash +if [ ! -d "$certs_dir" ]; then + echo -e "Error: Certs dir does not exist: ${certs_dir}\n" + exit 1 +fi +certs_dir=$(readlink -f $certs_dir) #absolute path from relative + +#Check cloudflare token set +if [ -z "${cloudflare_token}" ]; then + echo -e "Error: You must provide cloudflare_token.\n" + exit 1 +fi + +#Check cloudflare token set +if [ -z "${domain}" ]; then + echo -e "Error: You must provide domain.\n" + exit 1 +fi + +#End load config separator="==========" @@ -39,6 +45,20 @@ chmod 600 ${cloudflare_token_file} new_ssl_command=${new_ssl_command//#cloudflare_token_file#/$cloudflare_token_file} renew_command=${renew_command//#cloudflare_token_file#/$cloudflare_token_file} +#Set certs folder +new_ssl_command=${new_ssl_command//#certs_dir#/$certs_dir} +renew_command=${renew_command//#certs_dir#/$certs_dir} + +#Set domain arg +domain_arg=" -d ${domain} -d \*.${domain} " +new_ssl_command=${new_ssl_command//#domain_arg#/$domain_arg} +renew_command=${renew_command//#domain_arg#/$domain_arg} + +#Set email arg +email_arg=" --email ${email} " +new_ssl_command=${new_ssl_command//#email_arg#/$email_arg} +renew_command=${renew_command//#email_arg#/$email_arg} + #Set dry run flag in command if true. dry_run_arg="" if [ "$dry_run" = true ] ; then @@ -47,13 +67,11 @@ fi new_ssl_command=${new_ssl_command//#dry_run_arg#/$dry_run_arg} renew_command=${renew_command//#dry_run_arg#/$dry_run_arg} -echo "" - certbotNotice="It's not a dry-run, therefore don't keep generating/renewing certificates (more than 5 in a day), as certbot has rate limitations."; #Check if certificate exist -live_cert_file="${live_certs_dir}/cert.pem" -if [ -d "$live_certs_dir" ] && [ -f "$live_cert_file" ] +live_cert_file="${certs_dir}/live/${domain}/cert.pem" +if [ -f "$live_cert_file" ] then #Renew last_modified_time=$(date -r "${live_cert_file}") @@ -63,9 +81,9 @@ then echo "TRYING TO RENEW CERTIFICATES..." echo "${separator}" if [ "$dry_run" = true ] ; then - echo -e "\n${separator}\n[DRY-RUN ENABLED]\n${separator}\n" + echo -e "${separator}\n[DRY-RUN ENABLED]\n${separator}\n" else - echo -e "\n${separator}\n[${certbotNotice}]\n${separator}\n" + echo -e "${separator}\n[${certbotNotice}]\n${separator}\n" fi echo -e "Output from renew command:\n" @@ -98,9 +116,9 @@ else echo "Certificates folder does not exist: ${live_certs_dir}" echo "TRYING TO CREATE SSL CERTIFICATES..." if [ "$dry_run" = true ] ; then - echo -e "\n${separator}\n[DRY-RUN ENABLED]\n${separator}\n" + echo -e "${separator}\n[DRY-RUN ENABLED]\n${separator}\n" else - echo -e "\n${separator}\n[${certbotNotice}]\n${separator}\n" + echo -e "${separator}\n[${certbotNotice}]\n${separator}\n" fi echo -e "Output from new ssl command:\n"