Skip to content

Commit 9d50fc0

Browse files
authored
Merge pull request #334 from JrCs/dev
Merge dev into master (v1.8)
2 parents cf77c7e + d606704 commit 9d50fc0

File tree

9 files changed

+252
-113
lines changed

9 files changed

+252
-113
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ FROM alpine:3.7
33
LABEL maintainer="Yves Blusseau <[email protected]> (@blusseau)"
44

55
ENV DEBUG=false \
6-
DOCKER_GEN_VERSION=0.7.3 \
6+
DOCKER_GEN_VERSION=0.7.4 \
77
DOCKER_HOST=unix:///var/run/docker.sock
88

99
# Install packages required by the image

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,21 @@ If you want to create test certificates that don't have the 5 certs/week/domain
168168
Every hour (3600 seconds) the certificates are checked and every certificate that will expire in the next [30 days](https://github.com/kuba/simp_le/blob/ecf4290c4f7863bb5427b50cdd78bc3a5df79176/simp_le.py#L72) (90 days / 3) are renewed.
169169

170170
##### Force certificates renewal
171-
172171
If needed, you can force a running letsencrypt-nginx-proxy-companion container to renew all certificates that are currently in use. Replace `nginx-letsencrypt` with the name of your letsencrypt-nginx-proxy-companion container in the following command:
173172

174173
```bash
175174
$ docker exec nginx-letsencrypt /app/force_renew
176175
```
177176

177+
##### Force certificates renewal
178+
To display informations about your existing certificates, use the following command:
179+
180+
```bash
181+
$ docker exec nginx-letsencrypt /app/cert_status
182+
```
183+
184+
As for the forced renewal command, replace `nginx-letsencrypt` with the name of your letsencrypt-nginx-proxy-companion container.
185+
178186
##### ACME account keys
179187
By default the container will save the first ACME account key created for each ACME API endpoint used, and will reuse it for all subsequent authorizations and issuances requests made to this endpoint. This behavior is enabled by default to avoid running into Let's Encrypt account [rate limits](https://letsencrypt.org/docs/rate-limits/).
180188

@@ -213,8 +221,6 @@ $ docker run -d \
213221

214222
* The `com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen` label - set this label on the docker-gen container to tell the docker-letsencrypt-nginx-proxy-companion container to use it as the docker-gen when it's split from nginx (separate containers).
215223

216-
* `ACME_TOS_HASH` - Let´s you pass an alternative TOS hash to simp_le, to support other CA´s ACME implentation.
217-
218224
* `DOCKER_PROVIDER` - Set this to change behavior on container ID retrieval. Optional. Current supported values:
219225
* No value (empty, not set): no change in behavior.
220226
* `ecs` [Amazon ECS using ECS_CONTAINER_METADATA_FILE environment variable](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-metadata.html)

app/cert_status

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/bin/bash
2+
function print_cert_info {
3+
local enddate
4+
local subject
5+
local san_str
6+
7+
# Get the wanted informations with OpenSSL.
8+
issuer="$(openssl x509 -noout -issuer -in "$1" | sed -n 's/.*CN=\(.*\)/\1/p')"
9+
enddate="$(openssl x509 -noout -enddate -in "$1" | sed -n 's/notAfter=\(.*$\)/\1/p')"
10+
subject="$(openssl x509 -noout -subject -in "$1" | sed -n 's/.*CN=\([a-z0-9.-]*\)/- \1/p')"
11+
san_str="$(openssl x509 -text -in "$1" | grep 'DNS:')"
12+
13+
echo "Certificate was issued by $issuer"
14+
echo "Certificate is valid until $enddate"
15+
echo "Subject Name:"
16+
echo "$subject"
17+
18+
# Display the SAN info only if there is more than one SAN domain.
19+
while IFS=',' read -ra SAN; do
20+
if [[ ${#SAN[@]} -gt 1 ]]; then
21+
echo "Subject Alternative Name:"
22+
for domain in "${SAN[@]}"; do
23+
echo "$domain" | sed -n 's/.*DNS:\([a-z0-9.-]*\)/- \1/p'
24+
done
25+
fi
26+
done <<< "$san_str"
27+
}
28+
29+
echo '##### Certificate status #####'
30+
for cert in /etc/nginx/certs/*/fullchain.pem; do
31+
[[ -e "$cert" ]] || continue
32+
# Verify the certificate with OpenSSL.
33+
openssl verify -CAfile "${cert%fullchain.pem}chain.pem" "$cert"
34+
35+
# Print certificate info.
36+
print_cert_info "$cert"
37+
38+
# Find the .crt files in /etc/nginx/certs which are
39+
# symlinks pointing to the current certificate.
40+
unset symlinked_domains
41+
for symlink in /etc/nginx/certs/*.crt; do
42+
[[ -e "$symlink" ]] || continue
43+
if [[ "$(readlink -f "$symlink")" == "$cert" ]]; then
44+
domain="$(echo "${symlink%.crt}" | sed 's#/etc/nginx/certs/##g')"
45+
symlinked_domains+=("$domain")
46+
fi
47+
done
48+
49+
# Display symlinks pointing to the current cert if there is any.
50+
if [[ ${#symlinked_domains[@]} -gt 0 ]]; then
51+
echo "Certificate is used by the following domain(s):"
52+
for domain in "${symlinked_domains[@]}"; do
53+
echo "- $domain"
54+
done
55+
fi
56+
57+
echo '##############################'
58+
done

app/entrypoint.sh

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
set -u
55

6+
if [[ -n "${ACME_TOS_HASH:-}" ]]; then
7+
echo "Info: the ACME_TOS_HASH environment variable is no longer used by simp_le and has been deprecated."
8+
echo "simp_le now implicitly agree to the ACME CA ToS."
9+
fi
10+
611
DOCKER_PROVIDER=${DOCKER_PROVIDER:-docker}
712

813
case "${DOCKER_PROVIDER}" in
@@ -29,33 +34,13 @@ function check_docker_socket {
2934
if [[ $DOCKER_HOST == unix://* ]]; then
3035
socket_file=${DOCKER_HOST#unix://}
3136
if [[ ! -S $socket_file ]]; then
32-
cat >&2 <<-EOT
33-
ERROR: you need to share your Docker host socket with a volume at $socket_file
34-
Typically you should run your container with: \`-v /var/run/docker.sock:$socket_file:ro\`
35-
See the documentation at http://git.io/vZaGJ
36-
EOT
37+
echo "Error: you need to share your Docker host socket with a volume at $socket_file" >&2
38+
echo "Typically you should run your container with: '-v /var/run/docker.sock:$socket_file:ro'" >&2
3739
exit 1
3840
fi
3941
fi
4042
}
4143

42-
function get_nginx_proxy_cid {
43-
# Look for a NGINX_VERSION environment variable in containers that we have mount volumes from.
44-
local volumes_from=$(docker_api "/containers/$CONTAINER_ID/json" | jq -r '.HostConfig.VolumesFrom[]' 2>/dev/null)
45-
for cid in $volumes_from; do
46-
cid=${cid%:*} # Remove leading :ro or :rw set by remote docker-compose (thx anoopr)
47-
if [[ $(docker_api "/containers/$cid/json" | jq -r '.Config.Env[]' | egrep -c '^NGINX_VERSION=') = "1" ]];then
48-
export NGINX_PROXY_CONTAINER=$cid
49-
break
50-
fi
51-
done
52-
if [[ -z "$(nginx_proxy_container)" ]]; then
53-
echo "Error: can't get nginx-proxy container id !" >&2
54-
echo "Check that you use the --volumes-from option to mount volumes from the nginx-proxy or label the nginx proxy container to use with 'com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true'." >&2
55-
exit 1
56-
fi
57-
}
58-
5944
function check_writable_directory {
6045
local dir="$1"
6146
docker_api "/containers/$CONTAINER_ID/json" | jq ".Mounts[].Destination" | grep -q "^\"$dir\"$"
@@ -96,8 +81,19 @@ source /app/functions.sh
9681

9782
if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
9883
check_docker_socket
99-
if [[ -z "$(docker_gen_container)" ]]; then
100-
[[ -z "${NGINX_PROXY_CONTAINER:-}" ]] && get_nginx_proxy_cid
84+
if [[ -z "$(get_nginx_proxy_container)" ]]; then
85+
echo "Error: can't get nginx-proxy container ID !" >&2
86+
echo "Check that you are doing one of the following :" >&2
87+
echo -e "\t- Use the --volumes-from option to mount volumes from the nginx-proxy container." >&2
88+
echo -e "\t- Set the NGINX_PROXY_CONTAINER env var on the letsencrypt-companion container to the name of the nginx-proxy container." >&2
89+
echo -e "\t- Label the nginx-proxy container to use with 'com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy'." >&2
90+
exit 1
91+
elif [[ -z "$(get_docker_gen_container)" ]] && ! is_docker_gen_container "$(get_nginx_proxy_container)"; then
92+
echo "Error: can't get docker-gen container id !" >&2
93+
echo "If you are running a three containers setup, check that you are doing one of the following :" >&2
94+
echo -e "\t- Set the NGINX_DOCKER_GEN_CONTAINER env var on the letsencrypt-companion container to the name of the docker-gen container." >&2
95+
echo -e "\t- Label the docker-gen container to use with 'com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen.'" >&2
96+
exit 1
10197
fi
10298
check_writable_directory '/etc/nginx/certs'
10399
check_writable_directory '/etc/nginx/vhost.d'

app/functions.sh

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
declare -r END_HEADER='## End of configuration add by letsencrypt container'
1010

1111
function check_nginx_proxy_container_run {
12-
local _nginx_proxy_container=$(nginx_proxy_container)
12+
local _nginx_proxy_container=$(get_nginx_proxy_container)
1313
if [[ $(docker_api "/containers/${_nginx_proxy_container}/json" | jq -r '.State.Status') = "running" ]];then
1414
return 0
1515
fi
@@ -18,16 +18,7 @@ function check_nginx_proxy_container_run {
1818
return 1
1919
}
2020

21-
function check_two_containers_case() {
22-
local _docker_gen_container=$(docker_gen_container)
23-
if [[ -n "${_docker_gen_container:-}" ]]; then #case with 3 containers
24-
return 1
25-
fi
26-
27-
return 0
28-
}
29-
30-
add_location_configuration() {
21+
function add_location_configuration {
3122
local domain="${1:-}"
3223
[[ -z "$domain" || ! -f "${VHOST_DIR}/${domain}" ]] && domain=default
3324
[[ -f "${VHOST_DIR}/${domain}" && \
@@ -40,7 +31,7 @@ add_location_configuration() {
4031
return 1
4132
}
4233

43-
remove_all_location_configurations() {
34+
function remove_all_location_configurations {
4435
local old_shopt_options=$(shopt -p) # Backup shopt options
4536
shopt -s nullglob
4637
for file in "${VHOST_DIR}"/*; do
@@ -96,18 +87,59 @@ function labeled_cid {
9687
docker_api "/containers/json" | jq -r '.[] | select(.Labels["'$1'"])|.Id'
9788
}
9889

99-
function docker_gen_container {
100-
echo ${NGINX_DOCKER_GEN_CONTAINER:-$(labeled_cid com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen)}
90+
function is_docker_gen_container {
91+
local id="${1?missing id}"
92+
if [[ $(docker_api "/containers/$id/json" | jq -r '.Config.Env[]' | egrep -c '^DOCKER_GEN_VERSION=') = "1" ]]; then
93+
return 0
94+
else
95+
return 1
96+
fi
97+
}
98+
99+
function get_docker_gen_container {
100+
# First try to get the docker-gen container ID from the container label.
101+
local docker_gen_cid="$(labeled_cid com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen)"
102+
103+
# If the labeled_cid function dit not return anything and the env var is set, use it.
104+
if [[ -z "$docker_gen_cid" ]] && [[ -n "${NGINX_DOCKER_GEN_CONTAINER:-}" ]]; then
105+
docker_gen_cid="$NGINX_DOCKER_GEN_CONTAINER"
106+
fi
107+
108+
# If a container ID was found, output it. The function will return 1 otherwise.
109+
[[ -n "$docker_gen_cid" ]] && echo "$docker_gen_cid"
101110
}
102111

103-
function nginx_proxy_container {
104-
echo ${NGINX_PROXY_CONTAINER:-$(labeled_cid com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy)}
112+
function get_nginx_proxy_container {
113+
local volumes_from
114+
# First try to get the nginx container ID from the container label.
115+
local nginx_cid="$(labeled_cid com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy)"
116+
117+
# If the labeled_cid function dit not return anything ...
118+
if [[ -z "${nginx_cid}" ]]; then
119+
# ... and the env var is set, use it ...
120+
if [[ -n "${NGINX_PROXY_CONTAINER:-}" ]]; then
121+
nginx_cid="$NGINX_PROXY_CONTAINER"
122+
# ... else try to get the container ID with the volumes_from method.
123+
else
124+
volumes_from=$(docker_api "/containers/$CONTAINER_ID/json" | jq -r '.HostConfig.VolumesFrom[]' 2>/dev/null)
125+
for cid in $volumes_from; do
126+
cid="${cid%:*}" # Remove leading :ro or :rw set by remote docker-compose (thx anoopr)
127+
if [[ $(docker_api "/containers/$cid/json" | jq -r '.Config.Env[]' | egrep -c '^NGINX_VERSION=') = "1" ]];then
128+
nginx_cid="$cid"
129+
break
130+
fi
131+
done
132+
fi
133+
fi
134+
135+
# If a container ID was found, output it. The function will return 1 otherwise.
136+
[[ -n "$nginx_cid" ]] && echo "$nginx_cid"
105137
}
106138

107139
## Nginx
108-
reload_nginx() {
109-
local _docker_gen_container=$(docker_gen_container)
110-
local _nginx_proxy_container=$(nginx_proxy_container)
140+
function reload_nginx {
141+
local _docker_gen_container=$(get_docker_gen_container)
142+
local _nginx_proxy_container=$(get_nginx_proxy_container)
111143

112144
if [[ -n "${_docker_gen_container:-}" ]]; then
113145
# Using docker-gen and nginx in separate container
@@ -130,6 +162,6 @@ reload_nginx() {
130162
}
131163

132164
# Convert argument to lowercase (bash 4 only)
133-
function lc() {
165+
function lc {
134166
echo "${@,,}"
135167
}

0 commit comments

Comments
 (0)