From a2a1458710032e9aef2581f8724b1970e58f436a Mon Sep 17 00:00:00 2001 From: Sando Date: Sun, 11 Sep 2022 11:53:09 +0200 Subject: [PATCH] Update Dockerfile and include cronjob including s6 overlay to docker image plus implementing the cronjob to update certs in eturnal turn server. eturnal reloads certificates without interrupting/closing existing sessions. --- docker-compose.yml | 2 + eturnal/Dockerfile | 30 ++++----- .../sbin/run.sh => etc/cont-init.d/10-config} | 62 +++---------------- eturnal/rootfs/etc/services.d/cron/run | 47 ++++++++++++++ eturnal/rootfs/etc/services.d/eturnal/run | 43 +++++++++++++ 5 files changed, 116 insertions(+), 68 deletions(-) rename eturnal/rootfs/{usr/sbin/run.sh => etc/cont-init.d/10-config} (54%) create mode 100644 eturnal/rootfs/etc/services.d/cron/run create mode 100644 eturnal/rootfs/etc/services.d/eturnal/run diff --git a/docker-compose.yml b/docker-compose.yml index 13f8f49a44..b3eb365b55 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -345,6 +345,8 @@ services: restart: ${RESTART_POLICY:-unless-stopped} ports: - '${TURN_RELAY_MIN_PORT:-50000}-${TURN_RELAY_MAX_PORT:-50500}:${TURN_RELAY_MIN_PORT:-50000}-${TURN_RELAY_MAX_PORT:-50500}/udp' + security_opt: + - no-new-privileges:true volumes: - ${CONFIG}/eturnal:/opt/eturnal/etc:Z - ${CONFIG}/web/acme-certs:/etc/eturnal/tls:Z diff --git a/eturnal/Dockerfile b/eturnal/Dockerfile index 3617d2a7cd..d6bfce4ce0 100644 --- a/eturnal/Dockerfile +++ b/eturnal/Dockerfile @@ -2,9 +2,10 @@ FROM debian:bullseye-slim as prepare # BUILD: define image build arguments ARG ETURNAL_VERSION=1.10.1 ARG TINI_VERSION=0.19.0 +ARG S6_VERSION=v3.1.2.1 RUN set -x \ - && apt-get update && apt-get install curl -y \ + && apt-get update && apt-get install apt-transport-https apt-utils ca-certificates curl wget xz-utils -y \ # RUNTIME: install eturnal binary with installer && ARCH=$(uname -m | sed -e 's/x86_64/x64/;s/aarch64/arm64/;s/armv7l/arm/;s/s390x/s390x/;s/ppc64le/ppc64le/') \ && curl -O https://eturnal.net/download/linux/installer/eturnal-$ETURNAL_VERSION-linux-$ARCH.run \ @@ -15,15 +16,16 @@ RUN set -x \ && mkdir -p /rootfs/opt/eturnal/log /rootfs/opt/eturnal/run /rootfs/opt/eturnal/tls \ && cp -r /opt/eturnal /rootfs/opt \ # RUNTIME: install runtime init - && ARCH=$(uname -m | sed -e 's/x86_64/amd64/;s/aarch64/arm64/;s/armv7l/arm/;s/s390x/s390x/;s/ppc64le/ppc64le/') \ - && curl -fL -o /rootfs/tini https://github.com/krallin/tini/releases/download/v$TINI_VERSION/tini-$ARCH \ - && chmod +x /rootfs/tini -# RUNTIME: copy entrypoint script + && ARCH=$(uname -m) \ + && wget -qO - https://github.com/just-containers/s6-overlay/releases/download/$S6_VERSION/s6-overlay-noarch.tar.xz | tar xfJ - -C /rootfs \ + && wget -qO - https://github.com/just-containers/s6-overlay/releases/download/$S6_VERSION/s6-overlay-$ARCH.tar.xz | tar xfJ - -C /rootfs +# RUNTIME: copy s6 scripts COPY rootfs /rootfs -FROM busybox:stable-glibc AS eturnal +FROM gcr.io/distroless/base-debian11 AS eturnal # BUILD: copy eturnal COPY --from=prepare --chown=9000:9000 /rootfs / +COPY --from=busybox:stable-glibc /bin /bin ARG HOME=/opt/eturnal RUN set -x \ @@ -33,11 +35,8 @@ RUN set -x \ # RUNTIME: create symbolic links, entrypoint script and minimal configuration file && ln -s $HOME/bin/eturnalctl /usr/sbin/eturnalctl \ && ln -s $HOME/bin/stun /usr/sbin/stun \ - && chmod +x /usr/sbin/* + && chmod +x /etc/cont-init.d/* /etc/services.d/*/run -FROM gcr.io/distroless/base-debian11 AS cleanup -# BUILD: copy eturnal -COPY --from=eturnal --chown=9000:9000 / / # remove libssl and openssl from distroless image # as they are statically built within eturnal binary RUN find -type f -name 'libcrypt*' -exec rm -rv {} + \ @@ -49,10 +48,11 @@ RUN find -type f -name 'libcrypt*' -exec rm -rv {} + \ FROM scratch AS runtime # BUILD: copy eturnal -COPY --from=cleanup --chown=9000:9000 / / +COPY --from=eturnal / / ARG HOME=/opt/eturnal -# RUNTIME: define container runtime environment variables -ENV ERL_DIST_PORT=3470 \ +# RUNTIME: define environment variables +ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \ + ERL_DIST_PORT=3470 \ PIPE_DIR=$HOME/run/pipe/ \ STUN_SERVICE="stun.conversations.im 3478" @@ -61,5 +61,5 @@ WORKDIR $HOME #USER eturnal VOLUME ["$HOME"] EXPOSE 3478 3478/udp -ENTRYPOINT ["/tini","--","run.sh"] -CMD ["eturnalctl", "foreground"] \ No newline at end of file +ENTRYPOINT ["/init"] +#CMD ["eturnalctl", "foreground"] \ No newline at end of file diff --git a/eturnal/rootfs/usr/sbin/run.sh b/eturnal/rootfs/etc/cont-init.d/10-config similarity index 54% rename from eturnal/rootfs/usr/sbin/run.sh rename to eturnal/rootfs/etc/cont-init.d/10-config index 81b06325ea..6baf4cc944 100644 --- a/eturnal/rootfs/usr/sbin/run.sh +++ b/eturnal/rootfs/etc/cont-init.d/10-config @@ -1,4 +1,4 @@ -#!/bin/sh +#!/command/with-contenv /bin/sh # eturnal config #DOCKER_INTERNAL_IP=$(cat /etc/hosts | grep $(hostname) | awk '{ print $1 }') cat > /opt/eturnal/etc/eturnal.yml <> /opt/eturnal/etc/eturnal.yml if [ ! -z $TLS_CERT_FILE ]; then cp -p $TLS_CERT_FILE /opt/eturnal/tls - echo " tls_crt_file: /opt/eturnal/tls/fullchain.pem" >> /opt/eturnal/etc/eturnal.yml + sed -i -e "s|#tls_crt_file:|tls_crt_file:|g" /opt/eturnal/etc/eturnal.yml fi if [ ! -z $TLS_KEY_FILE ]; then cp -p $TLS_KEY_FILE /opt/eturnal/tls - echo " tls_key_file: /opt/eturnal/tls/key.pem" >> /opt/eturnal/etc/eturnal.yml + sed -i -e "s|#tls_key_file:|tls_key_file:|g" /opt/eturnal/etc/eturnal.yml fi + chown 9000:9000 /opt/eturnal/tls/* fi # change file permissions -chown 9000:9000 /opt/eturnal/etc/eturnal.yml +chown -R 9000:9000 /opt/eturnal/etc chmod 640 /opt/eturnal/etc/eturnal.yml -chown 9000:9000 /opt/eturnal/tls/* - -# start certificate renewal cronjob -#if [ ! -z $TURNS_HOST ] -#then -# crond -b -d -#fi - -# TURN credentials -if [ ! -z $TURN_CREDENTIALS ] -then -export ETURNAL_SECRET=$TURN_CREDENTIALS -fi - -# TURN relay port range -if [ ! -z $TURN_RELAY_MIN_PORT ] || [ ! -z $TURN_RELAY_MAX_PORT ] -then - if [ ${TURN_RELAY_MIN_PORT-50000} \< ${TURN_RELAY_MAX_PORT-50500} ] - then - export ETURNAL_RELAY_MIN_PORT=${TURN_RELAY_MIN_PORT-50000} - export ETURNAL_RELAY_MAX_PORT=${TURN_RELAY_MAX_PORT-50500} - else - echo "" - echo " Configuration check:" - echo "" - echo " [WARNING] Defined TURN range minimum port -> ${TURN_RELAY_MIN_PORT-50000} is greater or equal than maximum port -> ${TURN_RELAY_MAX_PORT-50500}" - echo " [INFO] Starting eturnal with relay port range 50000 - 50500" - echo "" - export ETURNAL_RELAY_MIN_PORT=50000 - export ETURNAL_RELAY_MAX_PORT=50500 - fi -else - export ETURNAL_RELAY_MIN_PORT=50000 - export ETURNAL_RELAY_MAX_PORT=50500 -fi - -# discover public IP addresses -if [ ! -z $DOCKER_HOST_ADDRESS ] -then - export ETURNAL_RELAY_IPV4_ADDR=$DOCKER_HOST_ADDRESS -else - if [ -z "$JVB_DISABLE_STUN" ] - then - export ETURNAL_RELAY_IPV4_ADDR=${ETURNAL_RELAY_IPV4_ADDR-$(stun -4 $STUN_SERVICE)} - fi -fi -exec "$@" \ No newline at end of file diff --git a/eturnal/rootfs/etc/services.d/cron/run b/eturnal/rootfs/etc/services.d/cron/run new file mode 100644 index 0000000000..a888b8a904 --- /dev/null +++ b/eturnal/rootfs/etc/services.d/cron/run @@ -0,0 +1,47 @@ +#!/command/with-contenv /bin/sh + +# only run the script if TURNS is enabled (and if acme.sh is used in web container) +if [ ! -z $TURNS_HOST ] || ([ ! -z $TURNS_HOST ] && [ $ENABLE_LETSENCRYPT -eq 1 ]); then + + while true; do + # sleep a sufficient time to give the web container's acme.sh script a chance to obtain certificates + sleep 60s + + # mounted certs from web container + TLS_CERT_FILE=$(find /etc/ -name fullchain.pem) + TLS_KEY_FILE=$(find /etc/ -name key.pem) + + # check if files have changed + if [ ! -z $TLS_CERT_FILE ] || [ ! -z $TLS_KEY_FILE ]; then + current=$(md5sum /opt/eturnal/tls/fullchain.pem | awk '{ print $1 }') + last_modified=$(md5sum $TLS_CERT_FILE | awk '{ print $1 }') + + # copy certs to eturnal, adjust configuration file + if [ "$current" != "$last_modified" ]; then + echo " $(date) [Info] TLS certificates have been renewed, copy certs to eturnal and reload" + + if [ ! -z $TLS_CERT_FILE ]; then + cp -p $TLS_CERT_FILE /opt/eturnal/tls + sed -i -e "s|#tls_crt_file:|tls_crt_file:|g" /opt/eturnal/etc/eturnal.yml + fi + + if [ ! -z $TLS_KEY_FILE ]; then + cp -p $TLS_KEY_FILE /opt/eturnal/tls + sed -i -e "s|#tls_key_file:|tls_key_file:|g" /opt/eturnal/etc/eturnal.yml + fi + + # fix ownership and reload the service (reloading eturnal does not stop/break any active sessions) + chown 9000:9000 /opt/eturnal/tls/* + eturnalctl reload + + else + echo " $(date) [Info] CronJob: TLS certificates have not been renewed, check again in 5 minutes" + fi + sleep 240s + fi + done + +# don't repeatedly run the cron job, if eturnal does not serve TURNS +else + s6-svc -O /var/run/s6/legacy-services/cron +fi \ No newline at end of file diff --git a/eturnal/rootfs/etc/services.d/eturnal/run b/eturnal/rootfs/etc/services.d/eturnal/run new file mode 100644 index 0000000000..ba7572356a --- /dev/null +++ b/eturnal/rootfs/etc/services.d/eturnal/run @@ -0,0 +1,43 @@ +#!/command/with-contenv /bin/sh + +# TURN credentials +if [ ! -z $TURN_CREDENTIALS ] +then +export ETURNAL_SECRET=$TURN_CREDENTIALS +fi + +# TURN relay port range +if [ ! -z $TURN_RELAY_MIN_PORT ] || [ ! -z $TURN_RELAY_MAX_PORT ] +then + if [ ${TURN_RELAY_MIN_PORT-50000} \< ${TURN_RELAY_MAX_PORT-50500} ] + then + export ETURNAL_RELAY_MIN_PORT=${TURN_RELAY_MIN_PORT-50000} + export ETURNAL_RELAY_MAX_PORT=${TURN_RELAY_MAX_PORT-50500} + else + echo "" + echo " $(date) [INFO] Configuration check:" + echo "" + echo " $(date) [WARNING] Defined TURN range minimum port -> ${TURN_RELAY_MIN_PORT-50000} is greater or equal than maximum port -> ${TURN_RELAY_MAX_PORT-50500}" + echo " $(date) [INFO] Starting eturnal with relay port range 50000 - 50500" + echo "" + export ETURNAL_RELAY_MIN_PORT=50000 + export ETURNAL_RELAY_MAX_PORT=50500 + fi +else + export ETURNAL_RELAY_MIN_PORT=50000 + export ETURNAL_RELAY_MAX_PORT=50500 +fi + +# discover public IP addresses +if [ ! -z $DOCKER_HOST_ADDRESS ] +then + export ETURNAL_RELAY_IPV4_ADDR=$DOCKER_HOST_ADDRESS +else + if [ -z "$JVB_DISABLE_STUN" ] + then + export ETURNAL_RELAY_IPV4_ADDR=${ETURNAL_RELAY_IPV4_ADDR-$(stun -4 $STUN_SERVICE)} + export ETURNAL_RELAY_IPV6_ADDR=${ETURNAL_RELAY_IPV6_ADDR-$(stun -6 $STUN_SERVICE)} + fi +fi + +exec eturnalctl foreground