first commit
This commit is contained in:
commit
270ae0245f
14 changed files with 491 additions and 0 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!scripts/
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
dev/
|
19
Dockerfile
Normal file
19
Dockerfile
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Base image
|
||||
FROM ubuntu:latest
|
||||
|
||||
# Maintainer information
|
||||
LABEL maintainer="Maksim Stojkovic <https://github.com/maksimstojkovic>" \
|
||||
org.label-schema.vcs-url="https://github.com/maksimstojkovic/docker-letsencrypt"
|
||||
|
||||
# Install tools required
|
||||
RUN apt update
|
||||
RUN apt upgrade -y
|
||||
RUN apt install bash certbot curl python3-certbot-nginx -y jq
|
||||
|
||||
# Copy scripts
|
||||
WORKDIR /scripts
|
||||
COPY ./scripts /scripts
|
||||
RUN chmod -R +x /scripts
|
||||
|
||||
# Image starting command
|
||||
CMD ["/bin/bash", "/scripts/start.sh"]
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Maksim Stojkovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
39
README.md
Normal file
39
README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Let's Encrypt for Duck DNS
|
||||
|
||||
[](https://github.com/maksimstojkovic/docker-letsencrypt)
|
||||
[](https://hub.docker.com/r/maksimstojkovic/letsencrypt)
|
||||
[](https://hub.docker.com/r/maksimstojkovic/letsencrypt)
|
||||
[](https://hub.docker.com/r/maksimstojkovic/letsencrypt)
|
||||
[](https://hub.docker.com/r/maksimstojkovic/letsencrypt)
|
||||
|
||||
Automatically generates Let's Encrypt certificates using a lightweight Docker container without requiring any ports to be exposed for DNS challenges.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
* `DUCKDNS_TOKEN`: Duck DNS account token (obtained from [Duck DNS](https://www.duckdns.org)) (*required*)
|
||||
* `DUCKDNS_DOMAIN`: Full Duck DNS domain (e.g. `test.duckdns.org`) (*required*)
|
||||
* `LETSENCRYPT_DOMAIN`: Domain to generate SSL cert for. By default the SSL certificate is generated for `DUCKDNS_DOMAIN` (optional)
|
||||
* `LETSENCRYPT_WILDCARD`: `true` or `false`, indicating whether the SSL certificate should be for subdomains *only* of `LETSENCRYPT_DOMAIN` (i.e. `*.test.duckdns.org`), or for the main domain *only* (i.e. `test.duckdns.org`) (optional, default: `false`)
|
||||
* `LETSENCRYPT_EMAIL`: Email used for certificate renewal notifications (optional)
|
||||
* `LETSENCRYPT_CHAIN`: Preferred certificate chain (e.g. `ISRG Root X1`, see [https://letsencrypt.org/certificates](https://letsencrypt.org/certificates/) for more details) (optional)
|
||||
* `TESTING`: `true` or `false`, indicating whether a staging SSL certificate should be generated or not (optional, default: `false`)
|
||||
* `UID`: User ID to apply to Let's Encrypt files generated (optional, recommended, default: `0` - root)
|
||||
* `GID`: Group ID to apply to Let's Encrypt files generated (optional, recommended, default: `0` - root)
|
||||
|
||||
## Notes
|
||||
|
||||
* The `DUCKDNS_DOMAIN` should already be pointing to the server with a dynamic IP. The [maksimstojkovic/duckdns](https://github.com/maksimstojkovic/docker-duckdns) image can be used to automatically update the IP address.
|
||||
* The format of `DUCKDNS_DOMAIN` should be `<subdomain>.duckdns.org`, regardless of the value of `LETSENCRYPT_WILDCARD`.
|
||||
* To use `LETSENCRYPT_DOMAIN` feature, the following DNS records need to be created for ACME authentication (records should not be proxied):
|
||||
|
||||
| Type | Name | Value | Condition |
|
||||
|-------|----------------------------------------|------------------------------------|-----------------------------------|
|
||||
| CNAME | `*.<LETSENCRYPT_DOMAIN>` | `<DUCKDNS_DOMAIN>` | `LETSENCRYPT_WILDCARD` == `true` |
|
||||
| CNAME | `<LETSENCRYPT_DOMAIN>` | `<DUCKDNS_DOMAIN>` | `LETSENCRYPT_WILDCARD` == `false` |
|
||||
| CNAME | `_acme-challenge.<LETSENCRYPT_DOMAIN>` | `_acme-challenge.<DUCKDNS_DOMAIN>` | |
|
||||
|
||||
## Volumes
|
||||
|
||||
* `<certs>:/etc/letsencrypt`: A named or host volume which allows SSL certificates to persist and be accessed by other containers
|
||||
|
||||
**Note:** To use the `<certs>` host volume in another container, mount it as read-only for those containers. The `<certs>` host volume should be read-write enabled for the Letsencrypt container.
|
27
docker-compose.yml
Normal file
27
docker-compose.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
version: '2.4'
|
||||
|
||||
services:
|
||||
duckdns:
|
||||
image: maksimstojkovic/duckdns
|
||||
container_name: duckdns
|
||||
environment:
|
||||
- DUCKDNS_TOKEN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
- DUCKDNS_DOMAIN=test.duckdns.org
|
||||
- DUCKDNS_DELAY=5 #optional
|
||||
restart: unless-stopped
|
||||
|
||||
letsencrypt:
|
||||
image: maksimstojkovic/letsencrypt
|
||||
container_name: letsencrypt
|
||||
volumes:
|
||||
- ./certs:/etc/letsencrypt
|
||||
environment:
|
||||
- DUCKDNS_TOKEN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
- DUCKDNS_DOMAIN=test.duckdns.org
|
||||
- LETSENCRYPT_DOMAIN= #optional
|
||||
- LETSENCRYPT_WILDCARD=false #optional
|
||||
- LETSENCRYPT_EMAIL= #optional
|
||||
- TESTING=false #optional
|
||||
- UID=0 #optional
|
||||
- GID=0 #optional
|
||||
restart: unless-stopped
|
3
scripts/auth.sh
Executable file
3
scripts/auth.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
[[ "$(curl -s "https://www.duckdns.org/update?domains=${DUCKDNS_DOMAIN%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}")" = "OK" ]]
|
||||
|
3
scripts/auth2.sh
Executable file
3
scripts/auth2.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
[[ "$(curl -s "https://www.duckdns.org/update?domains=${DUCKDNS_DOMAIN2%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}")" = "OK" ]]
|
||||
|
2
scripts/cleanup.sh
Executable file
2
scripts/cleanup.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
[[ "$(curl -s "https://www.duckdns.org/update?domains=${DUCKDNS_DOMAIN%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}&clear=true")" = "OK" ]]
|
2
scripts/cleanup2.sh
Executable file
2
scripts/cleanup2.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
[[ "$(curl -s "https://www.duckdns.org/update?domains=${DUCKDNS_DOMAIN2%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}&clear=true")" = "OK" ]]
|
17
scripts/script-post.sh
Executable file
17
scripts/script-post.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
#Get domainID:
|
||||
dns=$(curl -X GET https://api.dynu.com/v2/dns -H "accept: application/json" -H "API-Key: $DYNU_API_KEY")
|
||||
domainID=$(echo $dns | jq ".domains[] | select(.name==\"$CERTBOT_DOMAIN\")" | jq '.id')
|
||||
|
||||
while
|
||||
records=$(curl -s -X GET "https://api.dynu.com/v2/dns/$domainID/record" -H "accept: application/json" -H "API-Key: $DYNU_API_KEY")
|
||||
identifier=$(echo $records | jq '.dnsRecords[] | select(.nodeName=="_acme-challenge")' | jq '.id' | head -n 1)
|
||||
if [ ! -z "$identifier" ]
|
||||
then
|
||||
echo "Delete: $identifier"
|
||||
curl -s -X DELETE "https://api.dynu.com/v2/dns/$domainID/record/$identifier" -H "accept: application/json" -H "API-Key: $DYNU_API_KEY"
|
||||
fi
|
||||
[[ ! -z "$identifier" ]]
|
||||
do
|
||||
continue
|
||||
done
|
10
scripts/script-pre.sh
Executable file
10
scripts/script-pre.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
#Get domainID:
|
||||
dns=$(curl -X GET https://api.dynu.com/v2/dns -H "accept: application/json" -H "API-Key: $DYNU_API_KEY")
|
||||
domainID=$(echo $dns | jq ".domains[] | select(.name==\"$CERTBOT_DOMAIN\")" | jq '.id')
|
||||
|
||||
|
||||
#Create record
|
||||
resultCreate=$(curl -s -X POST "https://api.dynu.com/v2/dns/$domainID/record" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"nodeName\":\"_acme-challenge\",\"recordType\":\"TXT\",\"ttl\":60,\"state\":true,\"group\":\"\",\"textData\":\"$CERTBOT_VALIDATION\"}" -H "API-Key: $DYNU_API_KEY")
|
||||
echo $resultCreate
|
||||
sleep 30
|
190
scripts/start.sh
Executable file
190
scripts/start.sh
Executable file
|
@ -0,0 +1,190 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Check variables DUCKDNS_TOKEN, DUCKDNS_DOMAIN
|
||||
if [ -z "$DUCKDNS_TOKEN" ] || [ "$DUCKDNS_TOKEN" = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ]; then
|
||||
echo "ERROR: Variable DUCKDNS_TOKEN is unset or still its default value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$DUCKDNS_DOMAIN" ]; then
|
||||
echo "ERROR: Variable DUCKDNS_DOMAIN is unset or still its default value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Print email notice if applicable
|
||||
if [ -z "$LETSENCRYPT_EMAIL" ]; then
|
||||
echo "WARNING: You will not receive SSL certificate expiration notices"
|
||||
fi
|
||||
|
||||
# Set LETSENCRYPT_DOMAIN to DUCKDNS_DOMAIN if not specified
|
||||
if [ -z "$LETSENCRYPT_DOMAIN" ]; then
|
||||
echo "INFO: LETSENCRYPT_DOMAIN is unset, using DUCKDNS_DOMAIN"
|
||||
LETSENCRYPT_DOMAIN=$DUCKDNS_DOMAIN
|
||||
fi
|
||||
|
||||
# Set certificate url based on LETSENCRYPT_WILDCARD value
|
||||
if [ "$LETSENCRYPT_WILDCARD" = "true" ]; then
|
||||
echo "INFO: A wildcard SSL certificate will be created"
|
||||
LETSENCRYPT_DOMAIN="*.$LETSENCRYPT_DOMAIN"
|
||||
fi
|
||||
|
||||
# Set LETSENCRYPT_DOMAIN to DUCKDNS_DOMAIN if not specified
|
||||
if [ -z "$LETSENCRYPT_DOMAIN2" ]; then
|
||||
echo "INFO: LETSENCRYPT_DOMAIN2 is unset, using DUCKDNS_DOMAIN"
|
||||
LETSENCRYPT_DOMAIN2=$DUCKDNS_DOMAIN2
|
||||
fi
|
||||
|
||||
# Set certificate url based on LETSENCRYPT_WILDCARD value
|
||||
if [ "$LETSENCRYPT_WILDCARD" = "true" ]; then
|
||||
echo "INFO: A wildcard SSL certificate will be created"
|
||||
LETSENCRYPT_DOMAIN2="*.$LETSENCRYPT_DOMAIN2"
|
||||
else
|
||||
LETSENCRYPT_WILDCARD="false"
|
||||
fi
|
||||
|
||||
# Set default preferred chain if no value specified
|
||||
if [ -z "$LETSENCRYPT_CHAIN" ]; then
|
||||
echo "INFO: LETSENCRYPT_CHAIN is unset, using default chain"
|
||||
LETSENCRYPT_CHAIN="default"
|
||||
fi
|
||||
|
||||
# Set user and group ID's for files
|
||||
if [ -z "$UID" ]; then
|
||||
echo "INFO: No UID specified, using root UID of 0"
|
||||
UID=0
|
||||
fi
|
||||
|
||||
if [ -z "$GID" ]; then
|
||||
echo "INFO: No GID specified, using root GID of 0"
|
||||
GID=0
|
||||
fi
|
||||
|
||||
# Print variables
|
||||
echo "DUCKDNS_TOKEN: $DUCKDNS_TOKEN"
|
||||
echo "DUCKDNS_DOMAIN: $DUCKDNS_DOMAIN"
|
||||
echo "LETSENCRYPT_DOMAIN: $LETSENCRYPT_DOMAIN"
|
||||
echo "LETSENCRYPT_EMAIL: $LETSENCRYPT_EMAIL"
|
||||
echo "LETSENCRYPT_WILDCARD: $LETSENCRYPT_WILDCARD"
|
||||
echo "LETSENCRYPT_CHAIN: $LETSENCRYPT_CHAIN"
|
||||
echo "TESTING: $TESTING"
|
||||
echo "UID: $UID"
|
||||
echo "GID: $GID"
|
||||
|
||||
if [ -z "$LETSENCRYPT_EMAIL" ]; then
|
||||
EMAIL_PARAM="--register-unsafely-without-email"
|
||||
else
|
||||
EMAIL_PARAM="-m $LETSENCRYPT_EMAIL --no-eff-email"
|
||||
fi
|
||||
|
||||
if [ "$LETSENCRYPT_CHAIN" = "default" ]; then
|
||||
unset CHAIN_PARAM
|
||||
else
|
||||
CHAIN_PARAM=( --preferred-chain "$LETSENCRYPT_CHAIN" )
|
||||
fi
|
||||
|
||||
if [ "$TESTING" = "true" ]; then
|
||||
echo "INFO: Generating staging certificate"
|
||||
TEST_PARAM="--test-cert"
|
||||
else
|
||||
unset TEST_PARAM
|
||||
fi
|
||||
|
||||
echo "certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup.sh \
|
||||
${CHAIN_PARAM[@]} $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM"
|
||||
|
||||
# Create certificates
|
||||
certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup.sh \
|
||||
"${CHAIN_PARAM[@]}" $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM
|
||||
|
||||
echo "certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth2.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup2.sh \
|
||||
${CHAIN_PARAM[@]} $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN2 \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM"
|
||||
|
||||
# Create certificates
|
||||
certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth2.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup2.sh \
|
||||
"${CHAIN_PARAM[@]}" $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN2 \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM
|
||||
|
||||
chown -R $UID:$GID /etc/letsencrypt
|
||||
|
||||
echo "certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN -d *.$DYNU_DOMAIN"
|
||||
|
||||
certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN -d *.$DYNU_DOMAIN
|
||||
|
||||
echo "certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN2 -d *.$DYNU_DOMAIN2"
|
||||
|
||||
certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN2 -d *.$DYNU_DOMAIN2
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}"
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/fullchain.pem"
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/privkey.pem"
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${LETSENCRYPT_DOMAIN#\*\.}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${LETSENCRYPT_DOMAIN#\*\.}"
|
||||
fi
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN2#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN2#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN2#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${LETSENCRYPT_DOMAIN2#\*\.}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${LETSENCRYPT_DOMAIN2#\*\.}"
|
||||
fi
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${DYNU_DOMAIN#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DYNU_DOMAIN#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DYNU_DOMAIN#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${DYNU_DOMAIN}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${DYNU_DOMAIN}"
|
||||
fi
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${DYNU_DOMAIN2#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DYNU_DOMAIN2#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DYNU_DOMAIN2#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${DYNU_DOMAIN2}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${DYNU_DOMAIN2}"
|
||||
fi
|
||||
|
||||
# Check if certificates require renewal twice a day
|
||||
while :; do
|
||||
# Wait for a random period within the next 12 hours
|
||||
|
||||
LETSENCRYPT_DELAY=$(shuf -i 1-720 -n 1)
|
||||
echo "Sleeping for $(($LETSENCRYPT_DELAY / 60)) hour(s) and $(($LETSENCRYPT_DELAY % 60)) minute(s)"
|
||||
sleep $((${LETSENCRYPT_DELAY} * 60)) # Convert to seconds
|
||||
|
||||
echo "INFO: Attempting SSL certificate renewal"
|
||||
certbot --manual-public-ip-logging-ok renew
|
||||
chown -R $UID:$GID /etc/letsencrypt
|
||||
done
|
155
scripts/start_orig.sh
Executable file
155
scripts/start_orig.sh
Executable file
|
@ -0,0 +1,155 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Check variables DUCKDNS_TOKEN, DUCKDNS_DOMAIN
|
||||
if [ -z "$DUCKDNS_TOKEN" ] || [ "$DUCKDNS_TOKEN" = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ]; then
|
||||
echo "ERROR: Variable DUCKDNS_TOKEN is unset or still its default value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$DUCKDNS_DOMAIN" ]; then
|
||||
echo "ERROR: Variable DUCKDNS_DOMAIN is unset or still its default value"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Print email notice if applicable
|
||||
if [ -z "$LETSENCRYPT_EMAIL" ]; then
|
||||
echo "WARNING: You will not receive SSL certificate expiration notices"
|
||||
fi
|
||||
|
||||
# Set LETSENCRYPT_DOMAIN to DUCKDNS_DOMAIN if not specified
|
||||
if [ -z "$LETSENCRYPT_DOMAIN" ]; then
|
||||
echo "INFO: LETSENCRYPT_DOMAIN is unset, using DUCKDNS_DOMAIN"
|
||||
LETSENCRYPT_DOMAIN=$DUCKDNS_DOMAIN
|
||||
fi
|
||||
|
||||
# Set certificate url based on LETSENCRYPT_WILDCARD value
|
||||
if [ "$LETSENCRYPT_WILDCARD" = "true" ]; then
|
||||
echo "INFO: A wildcard SSL certificate will be created"
|
||||
LETSENCRYPT_DOMAIN="*.$LETSENCRYPT_DOMAIN"
|
||||
else
|
||||
LETSENCRYPT_WILDCARD="false"
|
||||
fi
|
||||
|
||||
# Set default preferred chain if no value specified
|
||||
if [ -z "$LETSENCRYPT_CHAIN" ]; then
|
||||
echo "INFO: LETSENCRYPT_CHAIN is unset, using default chain"
|
||||
LETSENCRYPT_CHAIN="default"
|
||||
fi
|
||||
|
||||
# Set user and group ID's for files
|
||||
if [ -z "$UID" ]; then
|
||||
echo "INFO: No UID specified, using root UID of 0"
|
||||
UID=0
|
||||
fi
|
||||
|
||||
if [ -z "$GID" ]; then
|
||||
echo "INFO: No GID specified, using root GID of 0"
|
||||
GID=0
|
||||
fi
|
||||
|
||||
# Print variables
|
||||
echo "DUCKDNS_TOKEN: $DUCKDNS_TOKEN"
|
||||
echo "DUCKDNS_DOMAIN: $DUCKDNS_DOMAIN"
|
||||
echo "LETSENCRYPT_DOMAIN: $LETSENCRYPT_DOMAIN"
|
||||
echo "LETSENCRYPT_EMAIL: $LETSENCRYPT_EMAIL"
|
||||
echo "LETSENCRYPT_WILDCARD: $LETSENCRYPT_WILDCARD"
|
||||
echo "LETSENCRYPT_CHAIN: $LETSENCRYPT_CHAIN"
|
||||
echo "TESTING: $TESTING"
|
||||
echo "UID: $UID"
|
||||
echo "GID: $GID"
|
||||
|
||||
if [ -z "$LETSENCRYPT_EMAIL" ]; then
|
||||
EMAIL_PARAM="--register-unsafely-without-email"
|
||||
else
|
||||
EMAIL_PARAM="-m $LETSENCRYPT_EMAIL --no-eff-email"
|
||||
fi
|
||||
|
||||
if [ "$LETSENCRYPT_CHAIN" = "default" ]; then
|
||||
unset CHAIN_PARAM
|
||||
else
|
||||
CHAIN_PARAM=( --preferred-chain "$LETSENCRYPT_CHAIN" )
|
||||
fi
|
||||
|
||||
if [ "$TESTING" = "true" ]; then
|
||||
echo "INFO: Generating staging certificate"
|
||||
TEST_PARAM="--test-cert"
|
||||
else
|
||||
unset TEST_PARAM
|
||||
fi
|
||||
|
||||
echo "certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup.sh \
|
||||
${CHAIN_PARAM[@]} $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM"
|
||||
|
||||
# Create certificates
|
||||
certbot certonly --manual --preferred-challenges dns \
|
||||
--manual-auth-hook /scripts/auth.sh \
|
||||
--manual-cleanup-hook /scripts/cleanup.sh \
|
||||
"${CHAIN_PARAM[@]}" $EMAIL_PARAM -d $LETSENCRYPT_DOMAIN \
|
||||
--agree-tos --manual-public-ip-logging-ok --keep $TEST_PARAM
|
||||
|
||||
chown -R $UID:$GID /etc/letsencrypt
|
||||
|
||||
echo "certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN -d *.$DYNU_DOMAIN"
|
||||
|
||||
certbot certonly --manual-public-ip-logging-ok --non-interactive --agree-tos \
|
||||
--email $EMAIL --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook /scripts/script-pre.sh --manual-cleanup-hook /scripts/script-post.sh \
|
||||
-d $DYNU_DOMAIN -d *.$DYNU_DOMAIN
|
||||
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}"
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/fullchain.pem"
|
||||
echo "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/privkey.pem"
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${LETSENCRYPT_DOMAIN}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${LETSENCRYPT_DOMAIN}"
|
||||
fi
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${LETSENCRYPT_DOMAIN}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${LETSENCRYPT_DOMAIN}"
|
||||
fi
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${DUCKDNS_DOMAIN#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DUCKDNS_DOMAIN#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DUCKDNS_DOMAIN#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${DUCKDNS_DOMAIN}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${DUCKDNS_DOMAIN}"
|
||||
fi
|
||||
|
||||
# Check for successful certificate generation
|
||||
if [ ! -d "/etc/letsencrypt/live/${DUCKDNS_DOMAIN2#\*\.}" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DUCKDNS_DOMAIN2#\*\.}/fullchain.pem" ] || \
|
||||
[ ! -f "/etc/letsencrypt/live/${DUCKDNS_DOMAIN2#\*\.}/privkey.pem" ]; then
|
||||
echo "ERROR: Failed to create SSL certificates for ${DUCKDNS2_DOMAIN}"
|
||||
else
|
||||
echo "SUCCESS: Create SSL certificates for ${DUCKDNS2_DOMAIN}"
|
||||
fi
|
||||
|
||||
# Check if certificates require renewal twice a day
|
||||
while :; do
|
||||
# Wait for a random period within the next 12 hours
|
||||
|
||||
LETSENCRYPT_DELAY=$(shuf -i 1-720 -n 1)
|
||||
echo "Sleeping for $(($LETSENCRYPT_DELAY / 60)) hour(s) and $(($LETSENCRYPT_DELAY % 60)) minute(s)"
|
||||
sleep $((${LETSENCRYPT_DELAY} * 60)) # Convert to seconds
|
||||
|
||||
echo "INFO: Attempting SSL certificate renewal"
|
||||
certbot --manual-public-ip-logging-ok renew
|
||||
chown -R $UID:$GID /etc/letsencrypt
|
||||
done
|
Loading…
Reference in a new issue