refactor bash, dockerfile, and CI (#1)
parent
51ce56407a
commit
ad5ae6bb05
|
@ -1,16 +1,16 @@
|
|||
name: test
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
# workflow_dispatch:
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - master
|
||||
push:
|
||||
|
||||
jobs:
|
||||
sanity-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Get machine's first IPv4 address for eth0
|
||||
id: ip
|
||||
run: |
|
||||
|
@ -25,56 +25,31 @@ jobs:
|
|||
|
||||
# We use buildx instead of regular build so we can take advantage of Docker layer cache via Github Actions' cache
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
# Setup the Github Actions cache.
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildxarch-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildxarch-
|
||||
|
||||
- name: Build amd64 release image locally to Docker
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
build-args: |
|
||||
DEBUG_BUILD=0
|
||||
BASE_IMAGE_SUFFIX=
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64
|
||||
tags: sanity-check/docker-registry-proxy:latest
|
||||
push: false
|
||||
load: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache/release
|
||||
# this only reads from the cache
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max # this only reads from the cache
|
||||
|
||||
- name: Start proxy instance in docker (ENABLE_MANIFEST_CACHE=false)
|
||||
run: |
|
||||
docker run -d --rm --name docker_registry_proxy \
|
||||
docker run -d --name docker_registry_proxy \
|
||||
-p 0.0.0.0:3128:3128 -e ENABLE_MANIFEST_CACHE=false \
|
||||
-v $(pwd)/docker_mirror_cache:/docker_mirror_cache \
|
||||
-v $(pwd)/docker_mirror_certs:/ca \
|
||||
sanity-check/docker-registry-proxy:latest
|
||||
|
||||
- name: Get the initial logs for the container into a file after 10s
|
||||
run: |
|
||||
echo "Sleeping 10s..."
|
||||
sleep 10
|
||||
docker logs docker_registry_proxy > initial_logs.txt
|
||||
|
||||
- name: Upload artifact initial_logs
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: initial_logs
|
||||
path: initial_logs.txt
|
||||
|
||||
- name: Wait for container to be up
|
||||
timeout-minutes: 1
|
||||
timeout-minutes: 2
|
||||
run: |
|
||||
declare -i IS_UP=0
|
||||
while [[ $IS_UP -lt 1 ]]; do
|
||||
|
@ -84,14 +59,18 @@ jobs:
|
|||
done
|
||||
echo "Container is up..."
|
||||
|
||||
- name: Sleep to startup nginx
|
||||
run: |
|
||||
echo "Sleeping 10s..."
|
||||
sleep 20
|
||||
|
||||
- name: Grab the CA cert from running container via curl
|
||||
run: |
|
||||
curl http://${{ steps.ip.outputs.ETHER }}:3128/ca.crt | sudo tee /usr/share/ca-certificates/docker_registry_proxy.crt
|
||||
|
||||
- name: Stop proxy instance in docker
|
||||
timeout-minutes: 1
|
||||
run: |
|
||||
timeout 58 docker stop docker_registry_proxy
|
||||
docker rm -f docker_registry_proxy
|
||||
|
||||
- name: Refresh system-wide CA store
|
||||
run: |
|
||||
|
@ -107,17 +86,14 @@ jobs:
|
|||
Environment="HTTPS_PROXY=http://${{ steps.ip.outputs.ETHER }}:3128/"
|
||||
EOD
|
||||
|
||||
- name: Reload systemd from disk
|
||||
- name: Reload systemd from disk & dockerd via systemd
|
||||
run: |
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
- name: Restart dockerd via systemd
|
||||
run: |
|
||||
sudo systemctl restart docker.service
|
||||
|
||||
- name: Start proxy instance in docker again (ENABLE_MANIFEST_CACHE=true)
|
||||
run: |
|
||||
docker run -d --rm --name docker_registry_proxy \
|
||||
docker run -d --name docker_registry_proxy \
|
||||
-p 0.0.0.0:3128:3128 -e ENABLE_MANIFEST_CACHE=true \
|
||||
-v $(pwd)/docker_mirror_cache:/docker_mirror_cache \
|
||||
-v $(pwd)/docker_mirror_certs:/ca \
|
||||
|
@ -135,49 +111,27 @@ jobs:
|
|||
echo "Container is up again..."
|
||||
|
||||
# This can be quite slow, since Github Actions runner Docker comes preloaded with a lot of images.
|
||||
- name: Initial prune of all unused images from docker cache (slow)
|
||||
timeout-minutes: 2
|
||||
- name: Remove images
|
||||
run: |
|
||||
docker image prune --all --force
|
||||
docker rmi -f alpine:3.6
|
||||
docker rmi -f k8s.gcr.io/pause:3.3
|
||||
|
||||
- name: First round of pulls
|
||||
timeout-minutes: 2
|
||||
run: |
|
||||
docker pull alpine:3.6
|
||||
docker pull k8s.gcr.io/pause:3.3
|
||||
|
||||
- name: Get the cold cache logs for the container into a file
|
||||
- name: Remove images 2
|
||||
run: |
|
||||
docker logs docker_registry_proxy > cold_cache.txt
|
||||
|
||||
- name: Upload artifact cold_cache
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cold_cache
|
||||
path: cold_cache.txt
|
||||
|
||||
- name: prune all unused images from docker cache again
|
||||
timeout-minutes: 1
|
||||
run: |
|
||||
docker image prune --all --force
|
||||
docker rmi -f alpine:3.6
|
||||
docker rmi -f k8s.gcr.io/pause:3.3
|
||||
|
||||
- name: sleep 2s to allow cache to stale a bit
|
||||
run: |
|
||||
sleep 2
|
||||
|
||||
- name: Second round of pulls
|
||||
timeout-minutes: 2
|
||||
- name: Get the logs
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
docker pull alpine:3.6
|
||||
docker pull k8s.gcr.io/pause:3.3
|
||||
|
||||
- name: Get the warm cache docker logs for the container into a file
|
||||
run: |
|
||||
docker logs docker_registry_proxy > warm_cache.txt
|
||||
|
||||
- name: Upload artifact warm_cache
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: warm_cache
|
||||
path: warm_cache.txt
|
||||
|
||||
docker logs docker_registry_proxy || true
|
||||
docker ps -a
|
||||
|
|
|
@ -47,8 +47,7 @@ ADD nginx.manifest.stale.conf /etc/nginx/nginx.manifest.stale.conf
|
|||
|
||||
# Add our very hackish entrypoint and ca-building scripts, make them executable
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
ADD create_ca_cert.sh /create_ca_cert.sh
|
||||
RUN chmod +x /create_ca_cert.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
# Clients should only use 3128, not anything else.
|
||||
EXPOSE 3128
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
declare -i DEBUG=0
|
||||
|
||||
logInfo() {
|
||||
echo "INFO: $@"
|
||||
}
|
||||
|
||||
PROJ_NAME=DockerMirrorBox
|
||||
logInfo "Will create certificate with names $ALLDOMAINS"
|
||||
|
||||
CADATE=$(date "+%Y.%m.%d %H:%M")
|
||||
CAID="$(hostname -f) ${CADATE}"
|
||||
|
||||
CN_CA="${PROJ_NAME} CA Root ${CAID}"
|
||||
CN_IA="${PROJ_NAME} Intermediate IA ${CAID}"
|
||||
CN_WEB="${PROJ_NAME} Web Cert ${CAID}"
|
||||
|
||||
CN_CA=${CN_CA:0:64}
|
||||
CN_IA=${CN_IA:0:64}
|
||||
CN_WEB=${CN_WEB:0:64}
|
||||
|
||||
mkdir -p /certs /ca
|
||||
cd /ca
|
||||
|
||||
CA_KEY_FILE=${CA_KEY_FILE:-/ca/ca.key}
|
||||
CA_CRT_FILE=${CA_CRT_FILE:-/ca/ca.crt}
|
||||
CA_SRL_FILE=${CA_SRL_FILE:-/ca/ca.srl}
|
||||
|
||||
if [ -f "$CA_CRT_FILE" ] ; then
|
||||
logInfo "CA already exists. Good. We'll reuse it."
|
||||
if [ ! -f "$CA_SRL_FILE" ] ; then
|
||||
echo 01 > ${CA_SRL_FILE}
|
||||
fi
|
||||
else
|
||||
logInfo "No CA was found. Generating one."
|
||||
logInfo "*** Please *** make sure to mount /ca as a volume -- if not, everytime this container starts, it will regenerate the CA and nothing will work."
|
||||
|
||||
openssl genrsa -des3 -passout pass:foobar -out ${CA_KEY_FILE} 4096
|
||||
|
||||
logInfo "generate CA cert with key and self sign it: ${CAID}"
|
||||
openssl req -new -x509 -days 1300 -sha256 -key ${CA_KEY_FILE} -out ${CA_CRT_FILE} -passin pass:foobar -subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_CA}" -extensions IA -config <(
|
||||
cat <<-EOF
|
||||
[req]
|
||||
distinguished_name = dn
|
||||
[dn]
|
||||
[IA]
|
||||
basicConstraints = critical,CA:TRUE
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
subjectKeyIdentifier = hash
|
||||
EOF
|
||||
)
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logInfo "show the CA cert details"
|
||||
[[ ${DEBUG} -gt 0 ]] && openssl x509 -noout -text -in ${CA_CRT_FILE}
|
||||
|
||||
echo 01 > ${CA_SRL_FILE}
|
||||
|
||||
fi
|
||||
|
||||
cd /certs
|
||||
|
||||
logInfo "Generate IA key"
|
||||
openssl genrsa -des3 -passout pass:foobar -out ia.key 4096 &> /dev/null
|
||||
|
||||
logInfo "Create a signing request for the IA: ${CAID}"
|
||||
openssl req -new -key ia.key -out ia.csr -passin pass:foobar -subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_IA}" -reqexts IA -config <(
|
||||
cat <<-EOF
|
||||
[req]
|
||||
distinguished_name = dn
|
||||
[dn]
|
||||
[IA]
|
||||
basicConstraints = critical,CA:TRUE,pathlen:0
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
subjectKeyIdentifier = hash
|
||||
EOF
|
||||
)
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logInfo "Show the singing request, to make sure extensions are there"
|
||||
[[ ${DEBUG} -gt 0 ]] && openssl req -in ia.csr -noout -text
|
||||
|
||||
logInfo "Sign the IA request with the CA cert and key, producing the IA cert"
|
||||
openssl x509 -req -days 730 -in ia.csr -CA ${CA_CRT_FILE} -CAkey ${CA_KEY_FILE} -CAserial ${CA_SRL_FILE} -out ia.crt -passin pass:foobar -extensions IA -extfile <(
|
||||
cat <<-EOF
|
||||
[req]
|
||||
distinguished_name = dn
|
||||
[dn]
|
||||
[IA]
|
||||
basicConstraints = critical,CA:TRUE,pathlen:0
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
subjectKeyIdentifier = hash
|
||||
EOF
|
||||
) &> /dev/null
|
||||
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logInfo "show the IA cert details"
|
||||
[[ ${DEBUG} -gt 0 ]] && openssl x509 -noout -text -in ia.crt
|
||||
|
||||
logInfo "Initialize the serial number for signed certificates"
|
||||
echo 01 > ia.srl
|
||||
|
||||
logInfo "Create the key (w/o passphrase..)"
|
||||
openssl genrsa -des3 -passout pass:foobar -out web.orig.key 2048 &> /dev/null
|
||||
openssl rsa -passin pass:foobar -in web.orig.key -out web.key &> /dev/null
|
||||
|
||||
logInfo "Create the signing request, using extensions"
|
||||
openssl req -new -key web.key -sha256 -out web.csr -passin pass:foobar -subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_WEB}" -reqexts SAN -config <(cat <(printf "[req]\ndistinguished_name = dn\n[dn]\n[SAN]\nsubjectAltName=${ALLDOMAINS}"))
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logInfo "Show the singing request, to make sure extensions are there"
|
||||
[[ ${DEBUG} -gt 0 ]] && openssl req -in web.csr -noout -text
|
||||
|
||||
logInfo "Sign the request, using the intermediate cert and key"
|
||||
openssl x509 -req -days 365 -in web.csr -CA ia.crt -CAkey ia.key -out web.crt -passin pass:foobar -extensions SAN -extfile <(cat <(printf "[req]\ndistinguished_name = dn\n[dn]\n[SAN]\nsubjectAltName=${ALLDOMAINS}")) &> /dev/null
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logInfo "Show the final cert details"
|
||||
[[ ${DEBUG} -gt 0 ]] && openssl x509 -noout -text -in web.crt
|
||||
|
||||
logInfo "Concatenating fullchain.pem..."
|
||||
cat web.crt ia.crt ${CA_CRT_FILE} > fullchain.pem
|
||||
|
||||
logInfo "Concatenating fullchain_with_key.pem"
|
||||
cat fullchain.pem web.key > fullchain_with_key.pem
|
368
entrypoint.sh
368
entrypoint.sh
|
@ -1,41 +1,188 @@
|
|||
#! /bin/bash
|
||||
#!/bin/bash
|
||||
|
||||
echo "Entrypoint starting."
|
||||
|
||||
set -Eeuo pipefail
|
||||
trap "echo TRAPed signal" HUP INT QUIT TERM
|
||||
|
||||
logInfo() {
|
||||
echo "INFO: $*"
|
||||
}
|
||||
|
||||
logErr() {
|
||||
echo "ERR: $*" >&2
|
||||
}
|
||||
|
||||
function creatCa() {
|
||||
declare -i DEBUG=0
|
||||
|
||||
PROJ_NAME=DockerMirrorBox
|
||||
logInfo "Will create certificate with names ${1}"
|
||||
|
||||
CADATE=$(date "+%Y.%m.%d %H:%M")
|
||||
CAID="$(hostname -f) ${CADATE}"
|
||||
|
||||
CN_CA="${PROJ_NAME} CA Root ${CAID}"
|
||||
CN_IA="${PROJ_NAME} Intermediate IA ${CAID}"
|
||||
CN_WEB="${PROJ_NAME} Web Cert ${CAID}"
|
||||
|
||||
CN_CA=${CN_CA:0:64}
|
||||
CN_IA=${CN_IA:0:64}
|
||||
CN_WEB=${CN_WEB:0:64}
|
||||
|
||||
mkdir -p /certs /ca
|
||||
cd /ca
|
||||
|
||||
CA_KEY_FILE=${CA_KEY_FILE:-/ca/ca.key}
|
||||
CA_CRT_FILE=${CA_CRT_FILE:-/ca/ca.crt}
|
||||
CA_SRL_FILE=${CA_SRL_FILE:-/ca/ca.srl}
|
||||
|
||||
if [[ -f "${CA_CRT_FILE}" ]]; then
|
||||
logInfo "CA already exists. Good. We'll reuse it."
|
||||
if [[ ! -f "${CA_SRL_FILE}" ]]; then
|
||||
echo 01 >"${CA_SRL_FILE}"
|
||||
fi
|
||||
else
|
||||
logInfo "No CA was found. Generating one."
|
||||
logInfo "*** Please *** make sure to mount /ca as a volume -- if not, everytime this container starts, it will regenerate the CA and nothing will work."
|
||||
|
||||
openssl genrsa -des3 -passout pass:foobar -out "${CA_KEY_FILE}" 4096
|
||||
|
||||
logInfo "generate CA cert with key and self sign it: ${CAID}"
|
||||
openssl req \
|
||||
-new \
|
||||
-x509 \
|
||||
-days 1300 \
|
||||
-sha256 \
|
||||
-key "${CA_KEY_FILE}" \
|
||||
-out "${CA_CRT_FILE}" \
|
||||
-passin pass:foobar \
|
||||
-subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_CA}" \
|
||||
-extensions IA \
|
||||
-config <(printf '[req]\ndistinguished_name = dn\n[dn]\n[IA]\nbasicConstraints = critical,CA:TRUE\nkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\nsubjectKeyIdentifier = hash')
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
logInfo "show the CA cert details"
|
||||
openssl x509 -noout -text -in "${CA_CRT_FILE}"
|
||||
fi
|
||||
echo 01 >"${CA_SRL_FILE}"
|
||||
fi
|
||||
|
||||
cd /certs
|
||||
|
||||
logInfo "Generate IA key"
|
||||
openssl genrsa -des3 -passout pass:foobar -out ia.key 4096 &>/dev/null
|
||||
|
||||
logInfo "Create a signing request for the IA: ${CAID}"
|
||||
openssl req \
|
||||
-new \
|
||||
-key ia.key \
|
||||
-out ia.csr \
|
||||
-passin pass:foobar \
|
||||
-subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_IA}" \
|
||||
-reqexts IA \
|
||||
-config <(printf '[req]\ndistinguished_name = dn\n[dn]\n[IA]\nbasicConstraints = critical,CA:TRUE,pathlen:0\nkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\nsubjectKeyIdentifier = hash')
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
logInfo "Show the singing request, to make sure extensions are there"
|
||||
openssl req -in ia.csr -noout -text
|
||||
fi
|
||||
|
||||
logInfo "Sign the IA request with the CA cert and key, producing the IA cert"
|
||||
openssl x509 \
|
||||
-req \
|
||||
-days 730 \
|
||||
-in ia.csr \
|
||||
-CA "${CA_CRT_FILE}" \
|
||||
-CAkey "${CA_KEY_FILE}" \
|
||||
-CAserial "${CA_SRL_FILE}" \
|
||||
-out ia.crt \
|
||||
-passin pass:foobar \
|
||||
-extensions IA \
|
||||
-extfile <(printf '[req]\ndistinguished_name = dn\n[dn]\n[IA]\nbasicConstraints = critical,CA:TRUE,pathlen:0\nkeyUsage = critical, digitalSignature, cRLSign, keyCertSign\nsubjectKeyIdentifier = hash') &>/dev/null
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
logInfo "show the IA cert details"
|
||||
openssl x509 -noout -text -in ia.crt
|
||||
fi
|
||||
|
||||
logInfo "Initialize the serial number for signed certificates"
|
||||
echo 01 >ia.srl
|
||||
|
||||
logInfo "Create the key (w/o passphrase..)"
|
||||
openssl genrsa -des3 -passout pass:foobar -out web.orig.key 2048 &>/dev/null
|
||||
openssl rsa -passin pass:foobar -in web.orig.key -out web.key &>/dev/null
|
||||
|
||||
logInfo "Create the signing request, using extensions"
|
||||
openssl req \
|
||||
-new \
|
||||
-key web.key \
|
||||
-sha256 \
|
||||
-out web.csr \
|
||||
-passin pass:foobar \
|
||||
-subj "/C=NL/ST=Noord Holland/L=Amsterdam/O=ME/OU=IT/CN=${CN_WEB}" \
|
||||
-reqexts SAN \
|
||||
-config <(printf '[req]\ndistinguished_name = dn\n[dn]\n[SAN]\nsubjectAltName=%s' "${1}")
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
logInfo "Show the singing request, to make sure extensions are there"
|
||||
openssl req -in web.csr -noout -text
|
||||
fi
|
||||
|
||||
logInfo "Sign the request, using the intermediate cert and key"
|
||||
openssl x509 \
|
||||
-req \
|
||||
-days 365 \
|
||||
-in web.csr \
|
||||
-CA ia.crt \
|
||||
-CAkey ia.key \
|
||||
-out web.crt \
|
||||
-passin pass:foobar \
|
||||
-extensions SAN \
|
||||
-extfile <(printf '[req]\ndistinguished_name = dn\n[dn]\n[SAN]\nsubjectAltName=%s' "${1}") &>/dev/null
|
||||
|
||||
if [[ "${DEBUG}" ]]; then
|
||||
logInfo "Show the final cert details"
|
||||
openssl x509 -noout -text -in web.crt
|
||||
fi
|
||||
|
||||
logInfo "Concatenating fullchain.pem..."
|
||||
cat web.crt ia.crt "${CA_CRT_FILE}" >fullchain.pem
|
||||
|
||||
logInfo "Concatenating fullchain_with_key.pem"
|
||||
cat fullchain.pem web.key >fullchain_with_key.pem
|
||||
|
||||
}
|
||||
# configure nginx DNS settings to match host, why must we do that nginx?
|
||||
# this leads to a world of problems. ipv6 format being different, etc.
|
||||
# below is a collection of hacks contributed over the years.
|
||||
|
||||
echo "-- resolv.conf:"
|
||||
logInfo "-- resolv.conf:"
|
||||
cat /etc/resolv.conf
|
||||
echo "-- end resolv"
|
||||
logInfo "-- end resolv"
|
||||
|
||||
# Podman adds a "%3" to the end of the last resolver? I don't get it. Strip it out.
|
||||
export RESOLVERS=$(cat /etc/resolv.conf | sed -e 's/%3//g' | awk '$1 == "nameserver" {print ($2 ~ ":")? "["$2"]": $2}' ORS=' ' | sed 's/ *$//g')
|
||||
if [ "x$RESOLVERS" = "x" ]; then
|
||||
echo "Warning: unable to determine DNS resolvers for nginx" >&2
|
||||
RESOLVERS=$(sed -e 's/%3//g' /etc/resolv.conf | awk '$1 == "nameserver" {print ($2 ~ ":")? "["$2"]": $2}' ORS=' ' | sed 's/ *$//g')
|
||||
if [[ -z "${RESOLVERS}" ]]; then
|
||||
logErr "Unable to determine DNS resolvers for nginx"
|
||||
exit 66
|
||||
fi
|
||||
|
||||
echo "DEBUG, determined RESOLVERS from /etc/resolv.conf: '$RESOLVERS'"
|
||||
logInfo "DEBUG, determined RESOLVERS from /etc/resolv.conf: '${RESOLVERS}'"
|
||||
|
||||
conf=""
|
||||
for ONE_RESOLVER in ${RESOLVERS}; do
|
||||
echo "Possible resolver: $ONE_RESOLVER"
|
||||
conf="resolver $ONE_RESOLVER; "
|
||||
for RESOLVER in ${RESOLVERS}; do
|
||||
logInfo "Possible resolver: ${RESOLVER}"
|
||||
conf="resolver ${RESOLVER}; "
|
||||
done
|
||||
|
||||
echo "Final chosen resolver: $conf"
|
||||
confpath=/etc/nginx/resolvers.conf
|
||||
if [ ! -e $confpath ]
|
||||
then
|
||||
echo "Using auto-determined resolver '$conf' via '$confpath'"
|
||||
echo "$conf" > $confpath
|
||||
logInfo "Final chosen resolver: ${conf}"
|
||||
confpath="/etc/nginx/resolvers.conf"
|
||||
if [[ ! -f ${confpath} ]]; then
|
||||
logInfo "Using auto-determined resolver '${conf}' via '${confpath}'"
|
||||
echo "${conf}" >${confpath}
|
||||
else
|
||||
echo "Not using resolver config, keep existing '$confpath' -- mounted by user?"
|
||||
logInfo "Not using resolver config, keep existing '${confpath}' -- mounted by user?"
|
||||
fi
|
||||
|
||||
# The list of SAN (Subject Alternative Names) for which we will create a TLS certificate.
|
||||
|
@ -43,71 +190,74 @@ ALLDOMAINS=""
|
|||
|
||||
# Interceptions map, which are the hosts that will be handled by the caching part.
|
||||
# It should list exactly the same hosts we have created certificates for -- if not, Docker will get TLS errors, of course.
|
||||
echo -n "" > /etc/nginx/docker.intercept.map
|
||||
touch /etc/nginx/docker.intercept.map
|
||||
|
||||
# Some hosts/registries are always needed, but others can be configured in env var REGISTRIES
|
||||
for ONEREGISTRYIN in docker.caching.proxy.internal registry-1.docker.io auth.docker.io ${REGISTRIES}; do
|
||||
ONEREGISTRY=$(echo ${ONEREGISTRYIN} | xargs) # Remove whitespace
|
||||
echo "Adding certificate for registry: $ONEREGISTRY"
|
||||
ONEREGISTRY=$(echo "${ONEREGISTRYIN}" | xargs) # Remove whitespace
|
||||
logInfo "Adding certificate for registry: ${ONEREGISTRY}"
|
||||
ALLDOMAINS="${ALLDOMAINS},DNS:${ONEREGISTRY}"
|
||||
echo "${ONEREGISTRY} 127.0.0.1:443;" >> /etc/nginx/docker.intercept.map
|
||||
echo "${ONEREGISTRY} 127.0.0.1:443;" >>/etc/nginx/docker.intercept.map
|
||||
done
|
||||
|
||||
# Clean the list and generate certificates.
|
||||
export ALLDOMAINS=${ALLDOMAINS:1} # remove the first comma and export
|
||||
/create_ca_cert.sh # This uses ALLDOMAINS to generate the certificates.
|
||||
# export ALLDOMAINS=${ALLDOMAINS:1} # remove the first comma and export
|
||||
creatCa "${ALLDOMAINS:1}" # This uses ALLDOMAINS to generate the certificates.
|
||||
|
||||
# Target host interception. Empty by default. Used to intercept outgoing requests
|
||||
# from the proxy to the registries.
|
||||
echo -n "" > /etc/nginx/docker.targetHost.map
|
||||
touch /etc/nginx/docker.targetHost.map
|
||||
|
||||
# Now handle the auth part.
|
||||
echo -n "" > /etc/nginx/docker.auth.map
|
||||
touch /etc/nginx/docker.auth.map
|
||||
|
||||
# Only configure auth registries if the env var contains values
|
||||
if [ "$AUTH_REGISTRIES" ]; then
|
||||
if [[ "${AUTH_REGISTRIES}" ]]; then
|
||||
# Ref: https://stackoverflow.com/a/47633817/219530
|
||||
AUTH_REGISTRIES_DELIMITER=${AUTH_REGISTRIES_DELIMITER:-" "}
|
||||
s=$AUTH_REGISTRIES$AUTH_REGISTRIES_DELIMITER
|
||||
auth_array=();
|
||||
while [[ $s ]]; do
|
||||
auth_array+=( "${s%%"$AUTH_REGISTRIES_DELIMITER"*}" );
|
||||
s=${s#*"$AUTH_REGISTRIES_DELIMITER"};
|
||||
s=${AUTH_REGISTRIES}${AUTH_REGISTRIES_DELIMITER}
|
||||
auth_array=()
|
||||
while [[ ${s} ]]; do
|
||||
auth_array+=("${s%%"$AUTH_REGISTRIES_DELIMITER"*}")
|
||||
s=${s#*"$AUTH_REGISTRIES_DELIMITER"}
|
||||
done
|
||||
|
||||
AUTH_REGISTRY_DELIMITER=${AUTH_REGISTRY_DELIMITER:-":"}
|
||||
|
||||
for ONEREGISTRY in "${auth_array[@]}"; do
|
||||
s=$ONEREGISTRY$AUTH_REGISTRY_DELIMITER
|
||||
registry_array=();
|
||||
while [[ $s ]]; do
|
||||
registry_array+=( "${s%%"$AUTH_REGISTRY_DELIMITER"*}" );
|
||||
s=${s#*"$AUTH_REGISTRY_DELIMITER"};
|
||||
s=${ONEREGISTRY}${AUTH_REGISTRY_DELIMITER}
|
||||
|
||||
registry_array=()
|
||||
while [[ ${s} ]]; do
|
||||
registry_array+=("${s%%"$AUTH_REGISTRY_DELIMITER"*}")
|
||||
s=${s#*"$AUTH_REGISTRY_DELIMITER"}
|
||||
done
|
||||
AUTH_HOST="${registry_array[0]}"
|
||||
AUTH_USER="${registry_array[1]}"
|
||||
AUTH_PASS="${registry_array[2]}"
|
||||
AUTH_BASE64=$(echo -n ${AUTH_USER}:${AUTH_PASS} | base64 -w0 | xargs)
|
||||
echo "Adding Auth for registry '${AUTH_HOST}' with user '${AUTH_USER}'."
|
||||
echo "\"${AUTH_HOST}\" \"${AUTH_BASE64}\";" >> /etc/nginx/docker.auth.map
|
||||
AUTH_BASE64=$(echo -n "${AUTH_USER}:${AUTH_PASS}" | base64 -w0 | xargs)
|
||||
logInfo "Adding Auth for registry '${AUTH_HOST}' with user '${AUTH_USER}'."
|
||||
printf '"%s" "%s";' "${AUTH_HOST}" "${AUTH_BASE64}" >>/etc/nginx/docker.auth.map
|
||||
done
|
||||
fi
|
||||
|
||||
# create default config for the caching layer to listen on 443.
|
||||
echo " listen 443 ssl default_server;" > /etc/nginx/caching.layer.listen
|
||||
echo "error_log /var/log/nginx/error.log warn;" > /etc/nginx/error.log.debug.warn
|
||||
echo " listen 443 ssl default_server;" >/etc/nginx/caching.layer.listen
|
||||
echo "error_log /var/log/nginx/error.log warn;" >/etc/nginx/error.log.debug.warn
|
||||
|
||||
# Set Docker Registry cache size, by default, 32 GB ('32g')
|
||||
CACHE_MAX_SIZE=${CACHE_MAX_SIZE:-32g}
|
||||
|
||||
# The cache directory. This can get huge. Better to use a Docker volume pointing here!
|
||||
# Set to 32gb which should be enough
|
||||
echo "proxy_cache_path /docker_mirror_cache levels=1:2 max_size=$CACHE_MAX_SIZE inactive=60d keys_zone=cache:10m use_temp_path=off;" > /etc/nginx/conf.d/cache_max_size.conf
|
||||
echo "proxy_cache_path /docker_mirror_cache levels=1:2 max_size=${CACHE_MAX_SIZE} inactive=60d keys_zone=cache:10m use_temp_path=off;" >/etc/nginx/conf.d/cache_max_size.conf
|
||||
|
||||
# Manifest caching configuration. We generate config based on the environment vars.
|
||||
echo -n "" >/etc/nginx/nginx.manifest.caching.config.conf
|
||||
touch /etc/nginx/nginx.manifest.caching.config.conf
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && [[ "a${MANIFEST_CACHE_PRIMARY_REGEX}" != "a" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
if [[ "${ENABLE_MANIFEST_CACHE}" == true ]]; then
|
||||
if [[ -n "${MANIFEST_CACHE_PRIMARY_REGEX}" ]]; then
|
||||
cat >>/etc/nginx/nginx.manifest.caching.config.conf <<EOD
|
||||
# First tier caching of manifests; configure via MANIFEST_CACHE_PRIMARY_REGEX and MANIFEST_CACHE_PRIMARY_TIME
|
||||
location ~ ^/v2/(.*)/manifests/${MANIFEST_CACHE_PRIMARY_REGEX} {
|
||||
set \$docker_proxy_request_type "manifest-primary";
|
||||
|
@ -115,8 +265,9 @@ echo -n "" >/etc/nginx/nginx.manifest.caching.config.conf
|
|||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && [[ "a${MANIFEST_CACHE_SECONDARY_REGEX}" != "a" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
fi
|
||||
if [[ -n "${MANIFEST_CACHE_SECONDARY_REGEX}" ]]; then
|
||||
cat >>/etc/nginx/nginx.manifest.caching.config.conf <<EOD
|
||||
# Secondary tier caching of manifests; configure via MANIFEST_CACHE_SECONDARY_REGEX and MANIFEST_CACHE_SECONDARY_TIME
|
||||
location ~ ^/v2/(.*)/manifests/${MANIFEST_CACHE_SECONDARY_REGEX} {
|
||||
set \$docker_proxy_request_type "manifest-secondary";
|
||||
|
@ -124,8 +275,8 @@ EOD
|
|||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" == "atrue" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
fi
|
||||
cat >>/etc/nginx/nginx.manifest.caching.config.conf <<EOD
|
||||
# Default tier caching for manifests. Caches for ${MANIFEST_CACHE_DEFAULT_TIME} (from MANIFEST_CACHE_DEFAULT_TIME)
|
||||
location ~ ^/v2/(.*)/manifests/ {
|
||||
set \$docker_proxy_request_type "manifest-default";
|
||||
|
@ -133,8 +284,8 @@ EOD
|
|||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
|
||||
[[ "a${ENABLE_MANIFEST_CACHE}" != "atrue" ]] && cat <<EOD >>/etc/nginx/nginx.manifest.caching.config.conf
|
||||
else
|
||||
cat >>/etc/nginx/nginx.manifest.caching.config.conf <<EOD
|
||||
# Manifest caching is disabled. Enable it with ENABLE_MANIFEST_CACHE=true
|
||||
location ~ ^/v2/(.*)/manifests/ {
|
||||
set \$docker_proxy_request_type "manifest-default-disabled";
|
||||
|
@ -142,13 +293,14 @@ EOD
|
|||
include "/etc/nginx/nginx.manifest.stale.conf";
|
||||
}
|
||||
EOD
|
||||
fi
|
||||
|
||||
echo -e "\nManifest caching config: ---\n"
|
||||
logInfo "Manifest caching config: ---"
|
||||
cat /etc/nginx/nginx.manifest.caching.config.conf
|
||||
echo "---"
|
||||
logInfo "---"
|
||||
|
||||
if [[ "a${ALLOW_PUSH}" == "atrue" ]]; then
|
||||
cat <<EOF > /etc/nginx/conf.d/allowed.methods.conf
|
||||
if [[ "${ALLOW_PUSH}" == true ]]; then
|
||||
cat <<EOF >/etc/nginx/conf.d/allowed.methods.conf
|
||||
# allow to upload big layers
|
||||
client_max_body_size 0;
|
||||
|
||||
|
@ -156,7 +308,7 @@ if [[ "a${ALLOW_PUSH}" == "atrue" ]]; then
|
|||
proxy_cache_methods GET;
|
||||
EOF
|
||||
else
|
||||
cat << 'EOF' > /etc/nginx/conf.d/allowed.methods.conf
|
||||
cat <<'EOF' >/etc/nginx/conf.d/allowed.methods.conf
|
||||
# Block POST/PUT/DELETE. Don't use this proxy for pushing.
|
||||
if ($request_method = POST) {
|
||||
return 405 "POST method is not allowed";
|
||||
|
@ -173,63 +325,59 @@ fi
|
|||
# normally use non-debug version of nginx
|
||||
NGINX_BIN="/usr/sbin/nginx"
|
||||
|
||||
if [[ "a${DEBUG}" == "atrue" ]]; then
|
||||
if [[ ! -f /usr/bin/mitmweb ]]; then
|
||||
echo "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 3
|
||||
fi
|
||||
if [[ "${DEBUG}" == true ]]; then
|
||||
if [[ ! -f /usr/bin/mitmweb ]]; then
|
||||
logErr "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# in debug mode, change caching layer to listen on 444, so that mitmproxy can sit in the middle.
|
||||
echo " listen 444 ssl default_server;" > /etc/nginx/caching.layer.listen
|
||||
# in debug mode, change caching layer to listen on 444, so that mitmproxy can sit in the middle.
|
||||
echo " listen 444 ssl default_server;" >/etc/nginx/caching.layer.listen
|
||||
|
||||
echo "Starting in DEBUG MODE (mitmproxy)." >&2
|
||||
echo "Run mitmproxy with reverse pointing to the same certs..."
|
||||
mitmweb --no-web-open-browser --set web_host=0.0.0.0 --set confdir=~/.mitmproxy-incoming \
|
||||
--set termlog_verbosity=error --set stream_large_bodies=128k --web-port 8081 \
|
||||
--set keep_host_header=true --set ssl_insecure=true \
|
||||
--mode reverse:https://127.0.0.1:444 --listen-host 0.0.0.0 \
|
||||
--listen-port 443 --certs /certs/fullchain_with_key.pem &
|
||||
echo "Access mitmweb via http://127.0.0.1:8081/ "
|
||||
logErr "Starting in DEBUG MODE (mitmproxy)."
|
||||
logInfo "Run mitmproxy with reverse pointing to the same certs..."
|
||||
mitmweb --no-web-open-browser --set web_host=0.0.0.0 --set confdir=~/.mitmproxy-incoming \
|
||||
--set termlog_verbosity=error --set stream_large_bodies=128k --web-port 8081 \
|
||||
--set keep_host_header=true --set ssl_insecure=true \
|
||||
--mode reverse:https://127.0.0.1:444 --listen-host 0.0.0.0 \
|
||||
--listen-port 443 --certs /certs/fullchain_with_key.pem &
|
||||
logInfo "Access mitmweb via http://127.0.0.1:8081/ "
|
||||
fi
|
||||
|
||||
if [[ "a${DEBUG_HUB}" == "atrue" ]]; then
|
||||
if [[ ! -f /usr/bin/mitmweb ]]; then
|
||||
echo "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 3
|
||||
fi
|
||||
if [[ "${DEBUG_HUB}" == true ]]; then
|
||||
if [[ ! -f /usr/bin/mitmweb ]]; then
|
||||
logErr "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# in debug hub mode, we remap targetHost to point to mitmproxy below
|
||||
echo "\"registry-1.docker.io\" \"127.0.0.1:445\";" > /etc/nginx/docker.targetHost.map
|
||||
# in debug hub mode, we remap targetHost to point to mitmproxy below
|
||||
echo '"registry-1.docker.io" "127.0.0.1:445";' >/etc/nginx/docker.targetHost.map
|
||||
|
||||
echo "Debugging outgoing DockerHub connections via mitmproxy on 8082." >&2
|
||||
# this one has keep_host_header=false so we don't need to modify nginx config
|
||||
mitmweb --no-web-open-browser --set web_host=0.0.0.0 --set confdir=~/.mitmproxy-outgoing-hub \
|
||||
--set termlog_verbosity=error --set stream_large_bodies=128k --web-port 8082 \
|
||||
--set keep_host_header=false --set ssl_insecure=true \
|
||||
--mode reverse:https://registry-1.docker.io --listen-host 0.0.0.0 \
|
||||
--listen-port 445 --certs /certs/fullchain_with_key.pem &
|
||||
logErr "Debugging outgoing DockerHub connections via mitmproxy on 8082."
|
||||
# this one has keep_host_header=false so we don't need to modify nginx config
|
||||
mitmweb --no-web-open-browser --set web_host=0.0.0.0 --set confdir=~/.mitmproxy-outgoing-hub \
|
||||
--set termlog_verbosity=error --set stream_large_bodies=128k --web-port 8082 \
|
||||
--set keep_host_header=false --set ssl_insecure=true \
|
||||
--mode reverse:https://registry-1.docker.io --listen-host 0.0.0.0 \
|
||||
--listen-port 445 --certs /certs/fullchain_with_key.pem &
|
||||
|
||||
echo "Warning, DockerHub outgoing debugging disables upstream SSL verification for all upstreams." >&2
|
||||
VERIFY_SSL=false
|
||||
logErr "Warning, DockerHub outgoing debugging disables upstream SSL verification for all upstreams."
|
||||
VERIFY_SSL=false
|
||||
|
||||
echo "Access mitmweb for outgoing DockerHub requests via http://127.0.0.1:8082/ "
|
||||
logInfo "Access mitmweb for outgoing DockerHub requests via http://127.0.0.1:8082/"
|
||||
if [[ ! -f /usr/sbin/nginx-debug ]]; then
|
||||
logErr "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
logInfo "Starting in DEBUG MODE (nginx)."
|
||||
echo "error_log /var/log/nginx/error.log debug;" >/etc/nginx/error.log.debug.warn
|
||||
# use debug binary
|
||||
NGINX_BIN="/usr/sbin/nginx-debug"
|
||||
fi
|
||||
|
||||
if [[ "a${DEBUG_NGINX}" == "atrue" ]]; then
|
||||
if [[ ! -f /usr/sbin/nginx-debug ]]; then
|
||||
echo "To debug, you need the -debug version of this image, eg: :latest-debug"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
echo "Starting in DEBUG MODE (nginx)."
|
||||
echo "error_log /var/log/nginx/error.log debug;" > /etc/nginx/error.log.debug.warn
|
||||
# use debug binary
|
||||
NGINX_BIN="/usr/sbin/nginx-debug"
|
||||
fi
|
||||
|
||||
|
||||
# Timeout configurations
|
||||
echo "" > /etc/nginx/nginx.timeouts.config.conf
|
||||
touch /etc/nginx/nginx.timeouts.config.conf
|
||||
cat <<EOD >>/etc/nginx/nginx.timeouts.config.conf
|
||||
# Timeouts
|
||||
|
||||
|
@ -250,14 +398,14 @@ cat <<EOD >>/etc/nginx/nginx.timeouts.config.conf
|
|||
proxy_connect_send_timeout ${PROXY_CONNECT_SEND_TIMEOUT};
|
||||
EOD
|
||||
|
||||
echo -e "\nTimeout configs: ---"
|
||||
logInfo "Timeout configs: ---"
|
||||
cat /etc/nginx/nginx.timeouts.config.conf
|
||||
echo -e "---\n"
|
||||
logInfo "---"
|
||||
|
||||
# Upstream SSL verification.
|
||||
echo "" > /etc/nginx/docker.verify.ssl.conf
|
||||
if [[ "a${VERIFY_SSL}" == "atrue" ]]; then
|
||||
cat << EOD > /etc/nginx/docker.verify.ssl.conf
|
||||
touch /etc/nginx/docker.verify.ssl.conf
|
||||
if [[ "${VERIFY_SSL}" == true ]]; then
|
||||
cat <<EOD >/etc/nginx/docker.verify.ssl.conf
|
||||
# We actually wanna be secure and avoid mitm attacks.
|
||||
# Fitting, since this whole thing is a mitm...
|
||||
# We'll accept any cert signed by a CA trusted by Mozilla (ca-certificates-bundle in alpine)
|
||||
|
@ -265,13 +413,13 @@ if [[ "a${VERIFY_SSL}" == "atrue" ]]; then
|
|||
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
proxy_ssl_verify_depth 2;
|
||||
EOD
|
||||
echo "Upstream SSL certificate verification enabled."
|
||||
logInfo "Upstream SSL certificate verification enabled."
|
||||
else
|
||||
echo "Upstream SSL certificate verification is DISABLED."
|
||||
logInfo "Upstream SSL certificate verification is DISABLED."
|
||||
fi
|
||||
|
||||
echo "Testing nginx config..."
|
||||
logInfo "Testing nginx config..."
|
||||
${NGINX_BIN} -t
|
||||
|
||||
echo "Starting nginx! Have a nice day."
|
||||
logInfo "Starting nginx! Have a nice day."
|
||||
${NGINX_BIN} -g "daemon off;"
|
||||
|
|
Loading…
Reference in New Issue