GUACAMOLE-374: Support absolutely all properties and extensions.

This commit is contained in:
Michael Jumper
2024-02-18 00:43:21 -08:00
parent 83111616e5
commit 9580dd4f82
15 changed files with 887 additions and 1414 deletions

View File

@@ -61,6 +61,9 @@ ENV \
# Add configuration scripts # Add configuration scripts
COPY guacamole-docker/bin/ /opt/guacamole/bin/ COPY guacamole-docker/bin/ /opt/guacamole/bin/
COPY guacamole-docker/build.d/ /opt/guacamole/build.d/
COPY guacamole-docker/entrypoint.d/ /opt/guacamole/entrypoint.d/
COPY guacamole-docker/environment/ /opt/guacamole/environment/
# Copy source to container for sake of build # Copy source to container for sake of build
COPY . "$BUILD_DIR" COPY . "$BUILD_DIR"
@@ -68,6 +71,8 @@ COPY . "$BUILD_DIR"
# Run the build itself # Run the build itself
RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole
RUN rm -rf /opt/guacamole/build.d /opt/guacamole/bin/build-guacamole.sh
# For the runtime image, we start with the official Tomcat distribution # For the runtime image, we start with the official Tomcat distribution
FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE} FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE}
@@ -91,6 +96,9 @@ RUN useradd --system --create-home --shell /usr/sbin/nologin --uid $UID --gid $G
# Run with user guacamole # Run with user guacamole
USER guacamole USER guacamole
# Environment variable defaults
ENV GUACAMOLE_HOME=/etc/guacamole
# Start Guacamole under Tomcat, listening on 0.0.0.0:8080 # Start Guacamole under Tomcat, listening on 0.0.0.0:8080
EXPOSE 8080 EXPOSE 8080
CMD ["/opt/guacamole/bin/start.sh" ] CMD ["/opt/guacamole/bin/entrypoint.sh" ]

View File

@@ -1,4 +1,4 @@
#!/bin/sh -e #!/bin/bash -e
# #
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
@@ -23,10 +23,15 @@
## ##
## Builds Guacamole, saving "guacamole.war" and all applicable extension .jars ## Builds Guacamole, saving "guacamole.war" and all applicable extension .jars
## using the guacamole-client source contained within the given directory. ## using the guacamole-client source contained within the given directory.
## Extension files will be grouped by their associated type, with all MySQL ## Extension files will be grouped by their associated type, identical to
## files being placed within the "mysql/" subdirectory of the destination, all ## extracting the .tar.gz files included with each Guacamole release except
## PostgreSQL files being placed within the "postgresql/" subdirectory of the ## that version numbers are stripped from directory and .jar file names.
## destination, etc. ##
## The build process is split across multiple scripts within the
## /opt/guacamole/build.d directory. Additional steps may be added to the
## build process by adding .sh scripts to this directory. Any such scripts MUST
## be shell scripts ending with a ".sh" extension and MUST be written for bash
## (the shell used by this entrypoint).
## ##
## @param BUILD_DIR ## @param BUILD_DIR
## The directory which currently contains the guacamole-client source and ## The directory which currently contains the guacamole-client source and
@@ -39,164 +44,21 @@
## extension type. ## extension type.
## ##
##
## The directory which currently contains the guacamole-client source and in
## which the build should be performed.
##
BUILD_DIR="$1" BUILD_DIR="$1"
##
## The directory to save guacamole.war within, along with all extension .jars.
## Note that this script will create extension-specific subdirectories within
## this directory, and files will thus be grouped by extension type.
##
DESTINATION="$2" DESTINATION="$2"
# # Run all scripts within the "build.d" directory
# Create destination, if it does not yet exist for SCRIPT in /opt/guacamole/build.d/*.sh; do
# source "$SCRIPT"
done
mkdir -p "$DESTINATION"
#
# Build guacamole.war and all extensions
#
cd "$BUILD_DIR"
#
# Run the maven build, applying any arbitrary provided maven arguments.
#
mvn $MAVEN_ARGUMENTS package
#
# Copy guacamole.war to destination
#
cp guacamole/target/*.war "$DESTINATION/guacamole.war"
#
# Copy JDBC auth extensions and SQL scripts
#
tar -xzf extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/target/*.tar.gz \
-C "$DESTINATION" \
--wildcards \
--no-anchored \
--strip-components=1 \
"*.jar" \
"*.sql"
#
# Download MySQL JDBC driver
#
echo "Downloading MySQL Connector/J ..."
curl -L "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-$MYSQL_JDBC_VERSION.tar.gz" | \
tar -xz \
-C "$DESTINATION/mysql/" \
--wildcards \
--no-anchored \
--no-wildcards-match-slash \
--strip-components=1 \
"mysql-connector-*.jar"
#
# Download PostgreSQL JDBC driver
#
echo "Downloading PostgreSQL JDBC driver ..."
curl -L "https://jdbc.postgresql.org/download/postgresql-$PGSQL_JDBC_VERSION.jar" \
> "$DESTINATION/postgresql/postgresql-$PGSQL_JDBC_VERSION.jar"
#
# Copy SSO auth extensions
#
tar -xzf extensions/guacamole-auth-sso/modules/guacamole-auth-sso-dist/target/*.tar.gz \
-C "$DESTINATION" \
--wildcards \
--no-anchored \
--strip-components=1 \
"*.jar"
#
# Download SQL Server JDBC driver
#
echo "Downloading SQL Server JDBC driver ..."
curl -L "https://github.com/microsoft/mssql-jdbc/releases/download/v$MSSQL_JDBC_VERSION/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
> "$DESTINATION/sqlserver/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
#
# Copy LDAP auth extension and schema modifications
#
mkdir -p "$DESTINATION/ldap"
tar -xzf extensions/guacamole-auth-ldap/target/*.tar.gz \
-C "$DESTINATION/ldap" \
--wildcards \
--no-anchored \
--xform="s#.*/##" \
"*.jar" \
"*.ldif"
#
# Copy Radius auth extension if it was build
#
if [ -f extensions/guacamole-auth-radius/target/guacamole-auth-radius*.jar ]; then
mkdir -p "$DESTINATION/radius"
cp extensions/guacamole-auth-radius/target/guacamole-auth-radius*.jar "$DESTINATION/radius"
fi
#
# Copy TOTP auth extension if it was built
#
if [ -f extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar ]; then
mkdir -p "$DESTINATION/totp"
cp extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar "$DESTINATION/totp"
fi
#
# Copy Duo auth extension if it was built
#
if [ -f extensions/guacamole-auth-duo/target/*.tar.gz ]; then
mkdir -p "$DESTINATION/duo"
tar -xzf extensions/guacamole-auth-duo/target/*.tar.gz \
-C "$DESTINATION/duo/" \
--wildcards \
--no-anchored \
--no-wildcards-match-slash \
--strip-components=1 \
"*.jar"
fi
#
# Copy header auth extension if it was built
#
if [ -f extensions/guacamole-auth-header/target/guacamole-auth-header*.jar ]; then
mkdir -p "$DESTINATION/header"
cp extensions/guacamole-auth-header/target/guacamole-auth-header*.jar "$DESTINATION/header"
fi
#
# Copy json auth extension if it was built
#
if [ -f extensions/guacamole-auth-json/target/guacamole-auth-json*.jar ]; then
mkdir -p "$DESTINATION/json"
cp extensions/guacamole-auth-json/target/guacamole-auth-json*.jar "$DESTINATION/json"
fi
#
# Copy automatic brute-force banning auth extension if it was built
#
if [ -f extensions/guacamole-auth-ban/target/guacamole-auth-ban*.jar ]; then
mkdir -p "$DESTINATION/ban"
cp extensions/guacamole-auth-ban/target/guacamole-auth-ban*.jar "$DESTINATION/ban"
fi
#
# Copy history recording storage extension if it was built
#
if [ -f extensions/guacamole-history-recording-storage/target/guacamole-history-recording-storage*.jar ]; then
mkdir -p "$DESTINATION/recordings"
cp extensions/guacamole-history-recording-storage/target/guacamole-history-recording-storage*.jar "$DESTINATION/recordings"
fi

View File

@@ -0,0 +1,39 @@
#!/bin/bash -e
#
# 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 entrypoint.sh
##
## (Re-)configures the Apache Guacamole web application based on the values of
## environment variables, deploys the web application beneath a bundled copy of
## Apache Tomcat, and starts Tomcat.
##
## The startup process is split across multiple scripts within the
## /opt/guacamole/entrypoint.d directory. Additional steps may be added to the
## startup process by adding .sh scripts to this directory. Any such scripts
## MUST be shell scripts ending with a ".sh" extension and MUST be written for
## bash (the shell used by this entrypoint).
##
# Run all scripts within the "entrypoint.d" directory
for SCRIPT in /opt/guacamole/entrypoint.d/*.sh; do
source "$SCRIPT"
done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
#
# 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 010-build-and-install-guacamole.sh
##
## Builds the Guacamole web application and all main extensions, installing the
## resulting binaries to standard locations within the Docker image. After the
## build and install process, the resulting binaries can be found beneath:
##
## /opt/guacamole/webapp:
## The web application, "guacamole.war".
##
## /opt/guacamole/extensions:
## All extensions, each within their own subdirectory and identical to the
## result of extracting a released .tar.gz except that version numbers of been
## stripped.
##
#
# Build guacamole.war and all extensions, applying any provided Maven build
# arguments
#
cd "$BUILD_DIR"
mvn $MAVEN_ARGUMENTS package
#
# Copy built web application (guacamole.war) to destination location
#
mkdir -p "$DESTINATION/webapp"
cp guacamole/target/*.war "$DESTINATION/webapp/guacamole.war"
#
# Extract all extensions to destination location, stripping version number
# suffix from .jar files and top-level directory name
#
mkdir -p "$DESTINATION/extensions"
find extensions/ -path "**/target/*.tar.gz" -exec tar -xzf "{}" \
-C "$DESTINATION/extensions" \
--xform='s#^\([^/]*\)-[0-9]\+\.[0-9]\+\.[0-9]\+#\1#g' \
--xform='s#-[0-9]\+\.[0-9]\+\.[0-9]\+\(\.jar$\)#\1#g' \
";"

View File

@@ -0,0 +1,118 @@
#
# 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 020-map-guacamole-extensions.sh
##
## Maps all installed Guacamole extensions (built in a previous step) to their
## corresponding environment variable prefixes, adding symbolic links so that
## the changes to the contents of GUACAMOLE_HOME can be easily made by the
## container's entrypoint based on which environment variables are set, without
## requiring that the entrypoint be specifically aware of all supported
## environment variables.
##
##
## Reads a mapping of Guacamole extension to environment variable prefix from
## STDIN, creating a hierarchy of directories and symbolic links on the
## filesystem that can be easily consumed by the container's entrypoint later.
##
## Each mapping consists of a single line with two values separated by
## whitespace, where the first (leftmost) value is the path to the directory
## containing the extension .jar file (relative to /opt/guacamole/extensions)
## and the second (rightmost) value is the environment variable prefix used by
## that extension. For readability, periods may be used in lieu of spaces.
##
## After mapping has occurred, the resulting mappings are located beneath
## /opt/guacamole/environment. They consist of directories named after the
## provided environment variable prefixes, where the contents of those
## directories are subsets of the contents of GUACAMOLE_HOME that would need to
## be added to the actual GUACAMOLE_HOME to enable that extension.
##
map_extensions() {
# Read through each provided path/prefix mapping pair
mkdir -p "$DESTINATION/environment"
tr . ' ' | while read -r EXT_PATH VAR_PREFIX; do
# Add mappings only for extensions that were actually built as part of
# the build process (some extensions, like the RADIUS support, will
# only be built if specific build arguments are provided)
if [ -d "$DESTINATION/extensions/$EXT_PATH/" ]; then
echo "Mapped: $EXT_PATH -> $VAR_PREFIX"
mkdir -p "$DESTINATION/environment/$VAR_PREFIX/extensions"
ln -s "$DESTINATION/extensions/$EXT_PATH"/*.jar "$DESTINATION/environment/$VAR_PREFIX/extensions/"
else
echo "Skipped: $EXT_PATH (not built)"
fi
done
}
#
# This section is a mapping of all bundled extensions to their corresponding
# variable prefixes. Each line consists of a whitespace-separated pair of
# extension path (the relative directory containing the .jar file) to that
# extension's variable prefix. For readability, a period may be used in lieu of
# a space.
#
# NOTES:
#
# (1) The actual variables used by each extension are not determined here, but
# rather by the transformation of their configuration properties to variables
# ("lowercase-with-dashes" to "UPPERCASE_WITH_UNDERSCORES"). The variable
# prefixes listed here should be chosen to match the prefixes resulting from
# that transformation of the extensions' properties.
#
# (2) The paths on the left side of this mapping are the paths of the extension
# .jar files relative to the "/opt/guacamole/extensions" directory used by the
# container to store extensions prior to use. They are identical to the paths
# used by the distribution .tar.gz files provided with each Guacamole release,
# except that the version numbers have been stripped from the top-level path.
#
# (3) The script processing this file uses these prefixes to define and process
# an additional "ENABLED" variable (ie: "BAN_ENABLED", "TOTP_ENABLED", etc.)
# that can be used to enable/disable an extension entirely regardless of the
# presence/absence of other variables with the prefix. This allows extensions
# that need no configuration to be easily enabled. It also allows extensions
# that already have configuration present to be easily disabled without
# requiring that all other configuration be removed.
#
map_extensions <<'EOF'
guacamole-auth-ban..........................BAN_
guacamole-auth-duo..........................DUO_
guacamole-auth-header.......................HTTP_AUTH_
guacamole-auth-jdbc/mysql...................MYSQL_
guacamole-auth-jdbc/postgresql..............POSTGRESQL_
guacamole-auth-jdbc/sqlserver...............SQLSERVER_
guacamole-auth-json.........................JSON_
guacamole-auth-ldap.........................LDAP_
guacamole-auth-quickconnect.................QUICKCONNECT_
guacamole-auth-radius.......................RADIUS_
guacamole-auth-sso/cas......................CAS_
guacamole-auth-sso/openid...................OPENID_
guacamole-auth-sso/saml.....................SAML_
guacamole-auth-sso/ssl......................SSL_
guacamole-auth-totp.........................TOTP_
guacamole-display-statistics................DISPLAY_STATISTICS_
guacamole-history-recording-storage.........RECORDING_
guacamole-vault/ksm.........................KSM_
EOF

View File

@@ -0,0 +1,99 @@
#
# 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 030-download-drivers.sh
##
## Downloads all JDBC drivers required by the various supported databases. Each
## downloaded driver is stored beneath /opt/guacamole/drivers, with symbolic
## links added to the mappings beneath /opt/guacamole/environment to ensure any
## required drivers are added to GUACAMOLE_HOME if necessary to support a
## requested database.
##
##
## Downloads the JDBC driver at the given URL, storing the driver's .jar file
## under the given name and environment variable prefix. The downloaded .jar
## file is stored such that it is pulled into GUACAMOLE_HOME automatically if
## environment variables with that prefix are used.
##
## If the URL is for a .tar.gz file and not a .jar file, the .jar will be
## automatically extracted from the .tar.gz as it is downloaded.
##
## @param VAR_PREFIX
## The environment variable prefix used by the extension that requires the
## driver.
##
## @param URL
## The URL that the driver should be downloaded from.
##
## @param DEST_JAR
## The filename to assign to the downloaded .jar file. This is mainly
## needed to ensure that the drivers bundled with the image have names that
## are predictable and reliable enough that they can be consumed by
## third-party use of this image.
##
download_driver() {
local VAR_PREFIX="$1"
local URL="$2"
local DEST_JAR="$3"
# Ensure primary destination path for .jar file exists
local DEST_PATH="$DESTINATION/drivers/"
mkdir -p "$DEST_PATH"
# Download requested .jar file, extracting from .tar.gz if necessary
if [[ "$URL" == *.tar.gz ]]; then
curl -L "$URL" | tar -xz \
--wildcards \
--no-anchored \
--no-wildcards-match-slash \
--to-stdout \
"*.jar" > "$DEST_PATH/$DEST_JAR"
else
curl -L "$URL" > "$DEST_PATH/$DEST_JAR"
fi
# Add any required link to ensure the .jar file is loaded along with the
# extension that requires it
mkdir -p "$DESTINATION/environment/$VAR_PREFIX/lib"
ln -s "$DEST_PATH/$DEST_JAR" "$DESTINATION/environment/$VAR_PREFIX/lib/"
}
#
# Download and link any required JDBC drivers
#
# MySQL JDBC driver
download_driver "MYSQL_" \
"https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-$MYSQL_JDBC_VERSION.tar.gz" \
"mysql-jdbc.jar"
# PostgreSQL JDBC driver
download_driver "POSTGRESQL_" \
"https://jdbc.postgresql.org/download/postgresql-$PGSQL_JDBC_VERSION.jar" \
"postgresql-jdbc.jar"
# SQL Server JDBC driver
download_driver "SQLSERVER_" \
"https://github.com/microsoft/mssql-jdbc/releases/download/v$MSSQL_JDBC_VERSION/mssql-jdbc-$MSSQL_JDBC_VERSION.jre8.jar" \
"mssql-jdbc.jar"

View File

@@ -0,0 +1,47 @@
#
# 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 999-verify-sanity.sh
##
## Performs sanity checks on the results of the build that verify the image
## contains everything it is expected to contain, including all built
## extensions. If symbolic links were not correctly constructed, or some built
## extensions were not mapped to environment variable prefixes, this script
## will log errors and fail the build.
##
# Perform basic sanity checks that the symbolic links used to associated
# environment variables with extensions/libraries have been correctly created,
# bailing out if any problems are found.
(
# Search for any broken symbolic links intended to map files for
# environment variables
find "$DESTINATION/environment/" -xtype l | sed 's/^/Broken link: /'
# Search for extensions that have not been mapped to any environment
# variables at all
comm -23 \
<(find "$DESTINATION/extensions/" -name "*.jar" -exec realpath "{}" ";" | sort -u) \
<(find "$DESTINATION/environment/" -path "**/extensions/*.jar" -exec realpath "{}" ";" | sort -u) \
| sed 's/^/Unmapped extension: /'
) | sed 's/^/ERROR: /' | (! grep .) >&2 || exit 1

View File

@@ -0,0 +1,105 @@
#
# 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 000-migrate-legacy-variables.sh
##
## Checks for usage of any environment variables that were formerly supported
## but are now deprecated, warning when any deprecated variables are
## encountered. Until support for a deprecated variable is entirely removed,
## the value provided for the deprecated variable is automatically assigned to
## the currently-supported variable.
##
##
## Checks for usage of the given deprecated environment variable, automatically
## assigning its value to the given currently-supported environment variable.
## If usage of the deprecated variable is found, a warning is printed to
## STDERR.
##
## @param LEGACY_VAR_NAME
## The name of the environment variable that's deprecated.
##
## @param CURRENT_VAR_NAME
## The name of the environment variable that is currently supported and
## replaces the deprecated variable.
##
deprecate_variable() {
local LEGACY_VAR_NAME="$1"
local CURRENT_VAR_NAME="$2"
if [ -n "${!LEGACY_VAR_NAME}" ]; then
echo "WARNING: The \"$LEGACY_VAR_NAME\" environment variable has been deprecated in favor of \"$CURRENT_VAR_NAME\". Please migrate your configuration when possible, as support for the older name may be removed in future releases." >&2
export "$CURRENT_VAR_NAME"="${!LEGACY_VAR_NAME}"
fi
}
##
## Checks for usage of any environment variables using the given deprecated
## prefix, automatically assigning their values to corresponding environment
## variables having the given currently-supported prefix. If usage of the
## deprecated prefix is found, a warning is printed to STDERR.
##
## @param LEGACY_VAR_PREFIX
## The environment variable prefix that's deprecated.
##
## @param CURRENT_VAR_PREFIX
## The environment variable prefix that is currently supported and
## replaces the deprecated variable prefix.
##
deprecate_variable_prefix() {
local LEGACY_VAR_PREFIX="$1"
local CURRENT_VAR_PREFIX="$2"
local LEGACY_VAR_NAME
local CURRENT_VAR_NAME
local HAS_LEGACY_VARIABLES=0
# Automatically reassign all "POSTGRES_*" variables to "POSTGRESQL_*"
while read -r LEGACY_VAR_NAME; do
HAS_LEGACY_VARIABLES=1
CURRENT_VAR_NAME="$CURRENT_VAR_PREFIX${LEGACY_VAR_NAME#$LEGACY_VAR_PREFIX}"
export "$CURRENT_VAR_NAME"="${!LEGACY_VAR_NAME}"
unset "$LEGACY_VAR_NAME"
done < <(awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^$LEGACY_VAR_PREFIX")
if [ "$HAS_LEGACY_VARIABLES" = "1" ]; then
echo "WARNING: The \"$LEGACY_VAR_PREFIX\" prefix for environment variables has been deprecated in favor of the \"$CURRENT_VAR_PREFIX\" prefix. Please migrate your configuration when possible, as support for the older prefix may be removed in future releases." >&2
export "$CURRENT_VAR_NAME"="$LEGACY_VAR_NAME"
fi
}
# The old "*_USER" style for configuring the user account to be used to access
# the database is being replaced with "*_USERNAME" such that all environment
# variables exactly correspond to the names of configuration properties from
# guacamole.properties.
deprecate_variable "MYSQL_USER" "MYSQL_USERNAME"
deprecate_variable "POSTGRES_USER" "POSTGRESQL_USERNAME"
deprecate_variable "SQLSERVER_USER" "SQLSERVER_USERNAME"
# The old "POSTGRES_" prefix for configuring usage of PostgreSQL is being
# replaced with "POSTGRESQL_" such that all environment variables exactly
# correspond to the names of configuration properties from
# guacamole.properties.
deprecate_variable_prefix "POSTGRES_" "POSTGRESQL_"

View File

@@ -0,0 +1,111 @@
#
# 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 010-generate-guacamole-home.sh
##
## Automatically generates a temporary, skeleton GUACAMOLE_HOME to be used for
## this run of the container. GUACAMOLE_HOMEs from previous runs are
## automatically deleted prior to creating the new skeleton. A
## randomly-generated temporary directory is used instead of a standard
## directory like "/etc/guacamole" to allow users to use "/etc/guacamole" as a
## basis for their own configuration.
##
##
## The directory to copy/link over as a basis for the GUACAMOLE_HOME actually
## used by the Guacamole web application. Any configuration generated by this
## container will be overlaid on top of this configuration. To achieve the
## overlay, symbolic links will be created for all files inside and beneath
## this directory. Only the guacamole.properties file will be copied instead of
## using symbolic links (to ensure property generation performed by the
## container does not potentially modify an external file).
##
GUACAMOLE_HOME_TEMPLATE="$GUACAMOLE_HOME"
##
## Tests whether a given property is set within the guacamole.properties file
## in GUACAMOLE_HOME.
##
## @param PROPERTY_NAME
## The name of the property to check.
##
## @returns
## Zero if the given property is set to any value within
## guacamole.properties, non-zero otherwise.
##
is_property_set() {
local PROPERTY_NAME="$1"
grep "^[[:space:]]*$PROPERTY_NAME\>" "$GUACAMOLE_HOME/guacamole.properties" &> /dev/null
}
#
# Start with a fresh GUACAMOLE_HOME
#
rm -rf /tmp/guacamole-home.*
GUACAMOLE_HOME="`mktemp -p /tmp -d guacamole-home.XXXXXXXXXX`"
mkdir -p "$GUACAMOLE_HOME/"{lib,extensions}
cat > "$GUACAMOLE_HOME/guacamole.properties" <<EOF
# guacamole.properties - generated `date`
EOF
#
# Copy contents of provided GUACAMOLE_HOME template, if any
#
if [ -e "$GUACAMOLE_HOME_TEMPLATE" ]; then
# Create links for any libraries provided in the template GUACAMOLE_HOME
find "$GUACAMOLE_HOME_TEMPLATE/lib" -mindepth 1 -maxdepth 1 \
-exec ln -sv "{}" "$GUACAMOLE_HOME/lib/" ";"
# Create links for any extensions provided in the template GUACAMOLE_HOME
find "$GUACAMOLE_HOME_TEMPLATE/extensions" -mindepth 1 -maxdepth 1 \
-exec ln -sv "{}" "$GUACAMOLE_HOME/extensions/" ";"
# Create links for all other files directly within the template
# GUACAMOLE_HOME
find "$GUACAMOLE_HOME_TEMPLATE" -mindepth 1 -maxdepth 1 \
-name guacamole.properties -o -name lib -o -name extensions -prune \
-o -exec ln -sv "{}" "$GUACAMOLE_HOME/" ";"
# Add any properties provided within template GUACAMOLE_HOME
if [ -e "$GUACAMOLE_HOME_TEMPLATE/guacamole.properties" ]; then
cat "$GUACAMOLE_HOME_TEMPLATE/guacamole.properties" >> "$GUACAMOLE_HOME/guacamole.properties"
fi
fi
# Enable reading of properties directly from environment variables unless
# overridden
if ! is_property_set "enable-environment-properties"; then
cat >> "$GUACAMOLE_HOME/guacamole.properties" <<'EOF'
#
# NOTE: The following was automatically added by the container entrypoint to
# allow all Guacamole configuration properties to be automatically read from
# environment variables. If this is not desired, you can override this behavior
# by specifying the "enable-environment-properties" variable yourself in your
# own guacamole.properties file.
#
enable-environment-properties: true
EOF
fi

View File

@@ -0,0 +1,33 @@
#
# 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 030-configure-guacamole-logging.sh
##
## Checks the value of the LOGBACK_LEVEL environment variable, producing a
## corresponding logback.xml file within GUACAMOLE_HOME if a log level has been
## explicitly specified.
##
# Set logback level if specified
if [ -n "$LOGBACK_LEVEL" ]; then
unzip -o -j /opt/guacamole/guacamole.war WEB-INF/classes/logback.xml -d $GUACAMOLE_HOME
sed -i "s/level=\"info\"/level=\"$LOGBACK_LEVEL\"/" $GUACAMOLE_HOME/logback.xml
fi

View File

@@ -0,0 +1,50 @@
#
# 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.
#
##
## 500-generate-tomcat-catalina-base.sh
##
## Automcatically generates a fresh, temporary CATALINA_BASE for Apache Tomcat.
## This allows Tomcat to run as a reduced-privilege user, and allows its
## configuration to be dynamically generated by the container entrypoint at
## startup.
##
#
# Start with a fresh CATALINA_BASE
#
rm -rf /tmp/catalina-base.*
export CATALINA_BASE="`mktemp -p /tmp -d catalina-base.XXXXXXXXXX`"
# User-only writable CATALINA_BASE
for dir in logs temp webapps work; do
mkdir -p $CATALINA_BASE/$dir
done
cp -R /usr/local/tomcat/conf $CATALINA_BASE
cat >> "$CATALINA_BASE/conf/catalina.properties" <<EOF
# Point Guacamole at automatically-generated, temporary GUACAMOLE_HOME
guacamole.home=$GUACAMOLE_HOME
EOF
# Install webapp
ln -sf /opt/guacamole/webapp/guacamole.war $CATALINA_BASE/webapps/${WEBAPP_CONTEXT:-guacamole}.war

View File

@@ -0,0 +1,88 @@
#
# 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 800-configure-features.sh
##
## Automatically checks all environment variables currently set and performs
## configuration tasks related to those variabels, including installing any
## extensions and external libraries associated with those variables to
## GUACAMOLE_HOME. Only environment variable prefixes are considered; this
## script is not aware of whether an extension actually uses an environment
## variable.
##
##
## Returns whether the feature associated with a particular environment
## variable prefix has configuration values set. Only the presence of
## environment variables having that prefix is checked. Features can also be
## entirely enabled/disabled through setting the [PREFIX_]ENABLED variable to
## true/false respectively, where "[PREFIX_]" is the specified environment
## variable prefix (including trailing underscore).
##
## @param VAR_BASE
## The environment variable prefix to check, including trailing underscore.
##
## @returns
## Zero if the feature associated with the given environment variable
## prefix is enabled, non-zero otherwise.
##
is_feature_enabled() {
local VAR_BASE="$1"
# Allow any feature to be explicitly enabled/disabled using a
# [PREFIX_]ENABLED variable
local ENABLED_VAR="${VAR_BASE}ENABLED"
if [ "${!ENABLED_VAR}" = "true" ]; then
return 0
elif [ "${!ENABLED_VAR}" = "false" ]; then
return 1
fi
# Lacking an explicit request to enable/disable the feature, rely on
# implicit enable/disable via presence of any other variables having the
# given prefix
awk 'BEGIN{for(v in ENVIRON) print v}' | grep "^${VAR_BASE}" > /dev/null
}
# Search environment for enabled extensions/features based on environment
# variable prefixes
for VAR_BASE in /opt/guacamole/environment/*; do
# Skip any directories without at least one corresponding environment
# variable set
is_feature_enabled "$(basename "$VAR_BASE")" || continue
# Execute any associated configuration script
[ ! -e "$VAR_BASE/configure.sh" ] || source "$VAR_BASE/configure.sh"
# Add any required links for extensions/libraries associated with the
# configured extension
for SUBDIR in lib extensions; do
if [ -d "$VAR_BASE/$SUBDIR" ]; then
mkdir -p "$GUACAMOLE_HOME/$SUBDIR/"
ln -s "$VAR_BASE/$SUBDIR"/* "$GUACAMOLE_HOME/$SUBDIR/"
fi
done
done

View File

@@ -0,0 +1,30 @@
#
# 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 999-start-tomcat.sh
##
## Starts Tomcat. This script replaces the current process with the Tomcat
## process and does not exit.
##
# Start tomcat
cd /usr/local/tomcat
exec catalina.sh run

View File

@@ -0,0 +1,72 @@
#
# 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 REMOTE_IP_VALVE_/configure.sh
##
## Configures Tomcat to forward the IP addresses of clients behind a proxy if
## the REMOTE_IP_VALVE_ENABLED environment variable is set to "true".
##
# Add <Valve> element
xmlstarlet edit --inplace \
--insert '/Server/Service/Engine/Host/*' --type elem -n Valve \
--insert '/Server/Service/Engine/Host/Valve[not(@className)]' --type attr -n className -v org.apache.catalina.valves.RemoteIpValve \
$CATALINA_BASE/conf/server.xml
# Allowed IPs
if [ -z "$PROXY_ALLOWED_IPS_REGEX" ]; then
echo "Using default Tomcat allowed IPs regex"
else
xmlstarlet edit --inplace \
--insert '/Server/Service/Engine/Host/Valve[@className="org.apache.catalina.valves.RemoteIpValve"]' \
--type attr -n internalProxies -v "$PROXY_ALLOWED_IPS_REGEX" \
$CATALINA_BASE/conf/server.xml
fi
# X-Forwarded-For
if [ -z "$PROXY_IP_HEADER" ]; then
echo "Using default Tomcat proxy IP header"
else
xmlstarlet edit --inplace \
--insert "/Server/Service/Engine/Host/Valve[@className='org.apache.catalina.valves.RemoteIpValve']" \
--type attr -n remoteIpHeader -v "$PROXY_IP_HEADER" \
$CATALINA_BASE/conf/server.xml
fi
# X-Forwarded-Proto
if [ -z "$PROXY_PROTOCOL_HEADER" ]; then
echo "Using default Tomcat proxy protocol header"
else
xmlstarlet edit --inplace \
--insert "/Server/Service/Engine/Host/Valve[@className='org.apache.catalina.valves.RemoteIpValve']" \
--type attr -n protocolHeader -v "$PROXY_PROTOCOL_HEADER" \
$CATALINA_BASE/conf/server.xml
fi
# X-Forwarded-By
if [ -z "$PROXY_BY_HEADER" ]; then
echo "Using default Tomcat proxy forwarded by header"
else
xmlstarlet edit --inplace \
--insert "/Server/Service/Engine/Host/Valve[@className='org.apache.catalina.valves.RemoteIpValve']" \
--type attr -n remoteIpProxiesHeader -v "$PROXY_BY_HEADER" \
$CATALINA_BASE/conf/server.xml
fi