diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml new file mode 100644 index 0000000000..e3410aa1ea --- /dev/null +++ b/.github/workflows/release-publish.yml @@ -0,0 +1,36 @@ +name: Build and Publish Docker Image + +# Publosh upon releases +on: + release: + types: # This configuration does not affect the page_build event above + - created + - prereleased + +jobs: + + docker_build: + name: Run docker build + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Build Docker container + shell: sh + run: | + docker build --pull --no-cache --force-rm -t ${{ secrets.DOCKERHUB_USERNAME }}/guacamole-client:${{ github.ref_name }} . + + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Push Docker image + run: | + docker push ${{ secrets.DOCKERHUB_USERNAME }}/guacamole-client:${{ github.ref_name }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index b6c1c7d7fb..03f890d54e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -96,10 +96,12 @@ RUN useradd --system --create-home --shell /usr/sbin/nologin --uid $UID --gid $G # Run with user guacamole USER guacamole -# Environment variable defaults +# Environment variable defaults (JAVA_KEYSTORE_FILE is relative to guacamole home ) ENV BAN_ENABLED=true \ ENABLE_FILE_ENVIRONMENT_PROPERTIES=true \ - GUACAMOLE_HOME=/etc/guacamole + GUACAMOLE_HOME=/etc/guacamole \ + JAVA_KEYSTORE_FILE=cacert \ + JAVA_KEYSTORE_PASS=changeit # Start Guacamole under Tomcat, listening on 0.0.0.0:8080 EXPOSE 8080 diff --git a/guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh b/guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh index f02cef3d6c..a9f65f5c45 100644 --- a/guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh +++ b/guacamole-docker/entrypoint.d/100-generate-guacamole-home.sh @@ -59,8 +59,49 @@ is_property_set() { # Start with a fresh GUACAMOLE_HOME # -rm -rf /tmp/guacamole-home.* -GUACAMOLE_HOME="`mktemp -p /tmp -d guacamole-home.XXXXXXXXXX`" +if [[ -z "$WEBAPPS_BASE" ]]; then + # If WEBAPPS_BASE is not set, use a temporary directory for CATALINA_BASE + rm -rf /tmp/guacamole-home.* + GUACAMOLE_HOME="`mktemp -p /tmp -d guacamole-home.XXXXXXXXXX`" +else + # If WEBAPPS_BASE is set, GUACAMOLE_HOME = WEBAPPS_BASE/guacamole-home + # - ensure WEBAPPS_BASE is a directory + if [[ -e "$WEBAPPS_BASE" && ! -d "$WEBAPPS_BASE" ]]; then + echo "Error: WEBAPPS_BASE must be a directory." >&2 + exit 1 + fi + export GUACAMOLE_HOME="$WEBAPPS_BASE/guacamole-home" + # If GUACAMOLE_HOME does not exists, create it + if [[ ! -d "$GUACAMOLE_HOME" ]]; then + mkdir -p "$GUACAMOLE_HOME" + fi +fi +echo "Using GUACAMOLE_HOME: $GUACAMOLE_HOME" + +# Handle non-empty GUACAMOLE_HOME +if [[ "$(ls -A $GUACAMOLE_HOME)" ]]; then + if [[ -e $GUACAMOLE_HOME/guacamole.properties ]]; then + echo "Warning: GUACAMOLE_HOME seems to be already configured" + export SKIP_GUACAMOLE_HOME=1 + else + echo "Warning: GUACAMOLE_HOME is not empty, but does not contain a guacamole.properties file." + echo " The contents of GUACAMOLE_HOME will be erased." + rm -rf "$GUACAMOLE_HOME"/* + fi +fi + +# +# Create JVM keystore by copying the default in JAVA_HOME +# +export JAVA_KEYSTORE_FILE=$GUACAMOLE_HOME/$JAVA_KEYSTORE_FILE +keytool -importkeystore -srckeystore $JAVA_HOME/lib/security/cacerts -destkeystore $JAVA_KEYSTORE_FILE -deststorepass $JAVA_KEYSTORE_PASS -noprompt +export JAVA_OPTS="${JAVA_OPTS} -Djavax.net.ssl.trustStore=${JAVA_KEYSTORE_FILE} -Djavax.net.ssl.trustStorePassword=${JAVA_KEYSTORE_PASS}" + +if [[ ! -z "$SKIP_GUACAMOLE_HOME" && "$SKIP_GUACAMOLE_HOME" == 1 ]]; then + echo "Required links are already assumed to be in the pre-configured GUACAMOLE_HOME." + return 0 +fi + mkdir -p "$GUACAMOLE_HOME/"{lib,extensions} cat > "$GUACAMOLE_HOME/guacamole.properties" <> "$GUACAMOLE_HOME/guacamole.properties" <<'EOF' -# -# NOTE: The following was automatically added by the container entrypoint to -# allow Guacamole configuration property values to be automatically read from -# files specified by environment variables ending in _FILE. If this is not -# desired, you can override this behavior by specifying the -# "enable-file-environment-properties" variable yourself in your -# own guacamole.properties file. -# -enable-file-environment-properties: true -EOF -fi diff --git a/guacamole-docker/entrypoint.d/500-generate-tomcat-catalina-base.sh b/guacamole-docker/entrypoint.d/500-generate-tomcat-catalina-base.sh index cd869511f2..4541afc3b5 100644 --- a/guacamole-docker/entrypoint.d/500-generate-tomcat-catalina-base.sh +++ b/guacamole-docker/entrypoint.d/500-generate-tomcat-catalina-base.sh @@ -30,8 +30,36 @@ # Start with a fresh CATALINA_BASE # -rm -rf /tmp/catalina-base.* -export CATALINA_BASE="`mktemp -p /tmp -d catalina-base.XXXXXXXXXX`" +if [[ -z "$WEBAPPS_BASE" ]]; then + # If WEBAPPS_BASE is not set, use a temporary directory for CATALINA_BASE + rm -rf /tmp/catalina-base.* + export CATALINA_BASE="`mktemp -p /tmp -d catalina-base.XXXXXXXXXX`" +else + # If WEBAPPS_BASE is set, CATALINA_BASE = WEBAPPS_BASE/catalina-base + # - ensure WEBAPPS_BASE is a directory + if [[ -e "$WEBAPPS_BASE" && ! -d "$WEBAPPS_BASE" ]]; then + echo "Error: WEBAPPS_BASE must be a directory." >&2 + exit 1 + fi + export CATALINA_BASE="$WEBAPPS_BASE/catalina-base" + # If CATALINA_BASE does not exists, create it + if [[ ! -d "$CATALINA_BASE" ]]; then + mkdir -p "$CATALINA_BASE" + fi +fi +echo "Using CATALINA_BASE: $CATALINA_BASE" + +# Handle non-empty CATALINA_BASE +if [[ "$(ls -A $CATALINA_BASE)" ]]; then + if [[ -e $CATALINA_BASE/conf/catalina.properties ]]; then + echo "Warning: CATALINA_BASE seems to be already configured" + return 0 + else + echo "Warning: CATALINA_BASE is not empty, but does not contain a conf/catalina.properties file." + echo " The contents of CATALINA_BASE will be erased." + rm -rf "$CATALINA_BASE"/* + fi +fi # User-only writable CATALINA_BASE for dir in logs temp webapps work; do diff --git a/guacamole-docker/entrypoint.d/700-configure-features.sh b/guacamole-docker/entrypoint.d/700-configure-features.sh index cc7ad0e24e..4d9e7dff87 100644 --- a/guacamole-docker/entrypoint.d/700-configure-features.sh +++ b/guacamole-docker/entrypoint.d/700-configure-features.sh @@ -75,6 +75,11 @@ for VAR_BASE in /opt/guacamole/environment/*; do # Execute any associated configuration script [ ! -e "$VAR_BASE/configure.sh" ] || source "$VAR_BASE/configure.sh" + if [[ ! -z "$SKIP_GUACAMOLE_HOME" && "$SKIP_GUACAMOLE_HOME" == 1 ]]; then + echo "Required links for feature $(basename $VAR_BASE) are already assumed to be in the pre-configured GUACAMOLE_HOME." + continue + fi + # Add any required links for extensions/libraries associated with the # configured extension for SUBDIR in lib extensions; do diff --git a/guacamole-docker/environment/EXTRA_CACERT_/configure.sh b/guacamole-docker/environment/EXTRA_CACERT_/configure.sh new file mode 100644 index 0000000000..bbac7a9dd0 --- /dev/null +++ b/guacamole-docker/environment/EXTRA_CACERT_/configure.sh @@ -0,0 +1,36 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +## +## @fn EXTRA_CACERT_/configure.sh +## +## Configures Tomcat to import additional CA certificates if +## the EXTRA_CACERT_ENABLED environment variable is set to "true". +## + +## +## Search pach for additional CA certificates MUST be specified in +## EXTRA_CACERT_SEARCH_PATH environment variables. +## CA certificates MUST have an extension of .crt +## +CERT_PATH="EXTRA_CACERT_$(echo "searchPath" | sed 's/\([a-z]\)\([A-Z]\)/\1_\2/g' | tr 'a-z' 'A-Z')" + +for cert_fn in `find ${!CERT_PATH} -name "*.crt"`; do + keytool -importcert -file $cert_fn -alias $(basename $cert_fn) -keystore $JAVA_KEYSTORE_FILE -storepass $JAVA_KEYSTORE_PASS -noprompt || true +done \ No newline at end of file