Skip to content

Commit 0b10bb4

Browse files
authored
Merge pull request #612 from hiqdev/networks_segregation
Implemented segregation by network
2 parents c79c8c5 + ca73d24 commit 0b10bb4

File tree

4 files changed

+134
-25
lines changed

4 files changed

+134
-25
lines changed

app/letsencrypt_service_data.tmpl

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
1+
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
2+
{{ $scopedContainersString := "" }}
3+
4+
{{ range $hosts, $containers := groupBy $ "Env.LETSENCRYPT_HOST" }}
5+
{{ if trim $hosts }}
6+
{{ range $container := $containers }}
7+
{{ $cid := printf "%.12s" $container.ID }}
8+
{{ if $CurrentContainer.Env.NETWORK_SCOPE }}
9+
{{ range $containerNetwork := $container.Networks }}
10+
{{ if eq $CurrentContainer.Env.NETWORK_SCOPE $containerNetwork.Name }}
11+
{{ $scopedContainersString = (printf "%s %s" $scopedContainersString $cid) }}
12+
{{ end }}
13+
{{ end }}
14+
{{ else }}
15+
{{ $scopedContainersString = (printf "%s %s" $scopedContainersString $cid) }}
16+
{{ end }}
17+
{{ end }}
18+
{{ end }}
19+
{{ end }}
20+
21+
{{ $scopedContainersSlice := split (trim $scopedContainersString) " " }}
22+
123
LETSENCRYPT_CONTAINERS=(
224
{{ range $hosts, $containers := groupBy $ "Env.LETSENCRYPT_HOST" }}
325
{{ if trim $hosts }}
426
{{ range $container := $containers }}
5-
{{ if parseBool (coalesce $container.Env.LETSENCRYPT_SINGLE_DOMAIN_CERTS "false") }}
6-
{{ range $host := split $hosts "," }}
7-
{{ $host := trim $host }}
8-
'{{ printf "%.12s" $container.ID }}_{{ sha1 $host }}'
27+
{{ $cid := printf "%.12s" $container.ID }}
28+
{{ if intersect $scopedContainersSlice (split $cid " ") }}
29+
{{ if parseBool (coalesce $container.Env.LETSENCRYPT_SINGLE_DOMAIN_CERTS "false") }}
30+
{{ range $host := split $hosts "," }}
31+
'{{ printf "%s_%s" $cid (sha1 (trim $host)) }}'
32+
{{ end }}
33+
{{ else }}
34+
'{{ $cid }}'
935
{{ end }}
10-
{{ else }}
11-
'{{ printf "%.12s" $container.ID }}'
1236
{{ end }}
1337
{{ end }}
1438
{{ end }}
@@ -19,26 +43,28 @@ LETSENCRYPT_CONTAINERS=(
1943
{{ $hosts := trimSuffix "," $hosts }}
2044
{{ range $container := $containers }}
2145
{{ $cid := printf "%.12s" $container.ID }}
22-
{{ if parseBool (coalesce $container.Env.LETSENCRYPT_SINGLE_DOMAIN_CERTS "false") }}
23-
{{ range $host := split $hosts "," }}
24-
{{ $host := trim $host }}
25-
{{ $hostHash := sha1 $host }}
26-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_HOST=('{{ $host }}')
27-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
28-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
29-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
30-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
31-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
32-
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_MIN_VALIDITY="{{ $container.Env.LETSENCRYPT_MIN_VALIDITY }}"
46+
{{ if intersect $scopedContainersSlice (split $cid " ") }}
47+
{{ if parseBool (coalesce $container.Env.LETSENCRYPT_SINGLE_DOMAIN_CERTS "false") }}
48+
{{ range $host := split $hosts "," }}
49+
{{ $host := trim $host }}
50+
{{ $hostHash := sha1 $host }}
51+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_HOST=('{{ $host }}')
52+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
53+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
54+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
55+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
56+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
57+
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_MIN_VALIDITY="{{ $container.Env.LETSENCRYPT_MIN_VALIDITY }}"
58+
{{ end }}
59+
{{ else }}
60+
LETSENCRYPT_{{ $cid }}_HOST=( {{ range $host := split $hosts "," }}{{ $host := trim $host }}'{{ $host }}' {{ end }})
61+
LETSENCRYPT_{{ $cid }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
62+
LETSENCRYPT_{{ $cid }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
63+
LETSENCRYPT_{{ $cid }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
64+
LETSENCRYPT_{{ $cid }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
65+
LETSENCRYPT_{{ $cid }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
66+
LETSENCRYPT_{{ $cid }}_MIN_VALIDITY="{{ $container.Env.LETSENCRYPT_MIN_VALIDITY }}"
3367
{{ end }}
34-
{{ else }}
35-
LETSENCRYPT_{{ $cid }}_HOST=( {{ range $host := split $hosts "," }}{{ $host := trim $host }}'{{ $host }}' {{ end }})
36-
LETSENCRYPT_{{ $cid }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
37-
LETSENCRYPT_{{ $cid }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
38-
LETSENCRYPT_{{ $cid }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
39-
LETSENCRYPT_{{ $cid }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
40-
LETSENCRYPT_{{ $cid }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
41-
LETSENCRYPT_{{ $cid }}_MIN_VALIDITY="{{ $container.Env.LETSENCRYPT_MIN_VALIDITY }}"
4268
{{ end }}
4369
{{ end }}
4470
{{ end }}

test/config.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ imageTests+=(
2020
permissions_default
2121
permissions_custom
2222
symlinks
23+
networks_segregation
2324
'
2425
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Started letsencrypt container for test networks_segregation
2+
Started test web server for le1.wtf in net boulder_bluenet
3+
Started test web server for le2.wtf in net le_test_other_net1
4+
Started test web server for le3.wtf in net le_test_other_net2
5+
le1.wtf is in boulder_bluenet, cert should be generated
6+
Symlink to le1.wtf certificate has been generated.
7+
The link is pointing to the file ./le1.wtf/fullchain.pem
8+
le2.wtf is not in boulder_bluenet, cert should not be generated
9+
Domain le2.wtf was not included in the service_data.
10+
le3.wtf is not in boulder_bluenet, cert should not be generated
11+
Domain le3.wtf was not included in the service_data.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/bash
2+
3+
## Test for single domain certificates.
4+
5+
if [[ -z $TRAVIS ]]; then
6+
le_container_name="$(basename ${0%/*})_$(date "+%Y-%m-%d_%H.%M.%S")"
7+
else
8+
le_container_name="$(basename ${0%/*})"
9+
fi
10+
desired_network="boulder_bluenet"
11+
run_le_container ${1:?} "$le_container_name" "--env NETWORK_SCOPE=$desired_network"
12+
13+
# Create the $domains array from comma separated domains in TEST_DOMAINS.
14+
IFS=',' read -r -a domains <<< "$TEST_DOMAINS"
15+
16+
# Cleanup function with EXIT trap
17+
function cleanup {
18+
# Remove any remaining Nginx container(s) silently.
19+
for domain in "${domains[@]}"; do
20+
docker rm --force "$domain" > /dev/null 2>&1
21+
done
22+
# Cleanup the files created by this run of the test to avoid foiling following test(s).
23+
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf*'
24+
# Stop the LE container
25+
docker stop "$le_container_name" > /dev/null
26+
# Drop temp network
27+
docker network rm "le_test_other_net1" > /dev/null
28+
docker network rm "le_test_other_net2" > /dev/null
29+
}
30+
trap cleanup EXIT
31+
32+
docker network create "le_test_other_net1" > /dev/null
33+
docker network create "le_test_other_net2" > /dev/null
34+
35+
networks_map=("$desired_network" le_test_other_net1 le_test_other_net2)
36+
37+
# Run a separate nginx container for each domain in the $domains array.
38+
# Start all the containers in a row so that docker-gen debounce timers fire only once.
39+
i=0
40+
for domain in "${domains[@]}"; do
41+
docker run --rm -d \
42+
--name "$domain" \
43+
-e "VIRTUAL_HOST=${domain}" \
44+
-e "LETSENCRYPT_HOST=${domain}" \
45+
--network "${networks_map[i]}" \
46+
nginx:alpine > /dev/null && echo "Started test web server for $domain in net ${networks_map[${i}]}"
47+
48+
i=$(( $i + 1 ))
49+
done
50+
51+
i=0
52+
for domain in "${domains[@]}"; do
53+
if [ "${networks_map[i]}" != "$desired_network" ]; then
54+
echo "$domain is not in $desired_network, cert should not be generated";
55+
56+
service_data="$(docker exec "$le_container_name" cat /app/letsencrypt_service_data)"
57+
if grep -q "$domain" <<< "$service_data"; then
58+
echo "Domain $domain is on data list, but MUST not!"
59+
else
60+
echo "Domain $domain was not included in the service_data."
61+
fi
62+
else
63+
echo "$domain is in $desired_network, cert should be generated";
64+
65+
# Wait for a symlink at /etc/nginx/certs/$domain.crt
66+
wait_for_symlink "$domain" "$le_container_name"
67+
fi
68+
# Stop the Nginx container silently.
69+
docker stop "$domain" > /dev/null
70+
i=$(( $i + 1 ))
71+
done

0 commit comments

Comments
 (0)