This commit is contained in:
Mehdi (OSX) 2023-11-23 09:04:06 +05:00
parent eea54b0cb5
commit 8935adaa90
4 changed files with 96 additions and 43 deletions

View File

@ -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: ## 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 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}`. 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}` 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: ## Notes:
- Set configuration in `generate-certs.sh`
- Set executable permission: `chmod +x generate-certs.sh`
- Run: `generate-certs.sh`
- After the certificates are created: - 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. - 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 - 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. - You can restart nginx in `posthook`, to reload used certificates.
- Example: - Example:
- `nano /etc/cron.d/generate-certs-for-test.com` - `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`

View File

25
config.sh.dummy Normal file
View File

@ -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'"

84
generate-certs.sh Normal file → Executable file
View File

@ -1,34 +1,40 @@
#!/bin/bash #!/bin/bash
#CONFIG: echo ""
#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
#chdir to current dir. #chdir to current dir.
cd "$(dirname "$0")" cd "$(dirname "$0")"
#remove trailing slash from live_certs_dir #Load config
live_certs_dir=${live_certs_dir%/} 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="==========" separator="=========="
@ -39,6 +45,20 @@ chmod 600 ${cloudflare_token_file}
new_ssl_command=${new_ssl_command//#cloudflare_token_file#/$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} 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. #Set dry run flag in command if true.
dry_run_arg="" dry_run_arg=""
if [ "$dry_run" = true ] ; then if [ "$dry_run" = true ] ; then
@ -47,13 +67,11 @@ fi
new_ssl_command=${new_ssl_command//#dry_run_arg#/$dry_run_arg} new_ssl_command=${new_ssl_command//#dry_run_arg#/$dry_run_arg}
renew_command=${renew_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."; 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 #Check if certificate exist
live_cert_file="${live_certs_dir}/cert.pem" live_cert_file="${certs_dir}/live/${domain}/cert.pem"
if [ -d "$live_certs_dir" ] && [ -f "$live_cert_file" ] if [ -f "$live_cert_file" ]
then then
#Renew #Renew
last_modified_time=$(date -r "${live_cert_file}") last_modified_time=$(date -r "${live_cert_file}")
@ -63,9 +81,9 @@ then
echo "TRYING TO RENEW CERTIFICATES..." echo "TRYING TO RENEW CERTIFICATES..."
echo "${separator}" echo "${separator}"
if [ "$dry_run" = true ] ; then 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 else
echo -e "\n${separator}\n[${certbotNotice}]\n${separator}\n" echo -e "${separator}\n[${certbotNotice}]\n${separator}\n"
fi fi
echo -e "Output from renew command:\n" echo -e "Output from renew command:\n"
@ -98,9 +116,9 @@ else
echo "Certificates folder does not exist: ${live_certs_dir}" echo "Certificates folder does not exist: ${live_certs_dir}"
echo "TRYING TO CREATE SSL CERTIFICATES..." echo "TRYING TO CREATE SSL CERTIFICATES..."
if [ "$dry_run" = true ] ; then 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 else
echo -e "\n${separator}\n[${certbotNotice}]\n${separator}\n" echo -e "${separator}\n[${certbotNotice}]\n${separator}\n"
fi fi
echo -e "Output from new ssl command:\n" echo -e "Output from new ssl command:\n"