From b7b167e37817e0c89efe3ce1fc4ec7cc959dff96 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Thu, 2 Apr 2020 09:21:03 +0200 Subject: [PATCH 1/7] GUACAMOLE-1005: Docker, configure RemoteIPValve --- guacamole-docker/bin/start.sh | 65 ++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh index 24b7a2fe7..205d9cf85 100755 --- a/guacamole-docker/bin/start.sh +++ b/guacamole-docker/bin/start.sh @@ -708,6 +708,65 @@ associate_json() { # Add required .jar files to GUACAMOLE_EXT ln -s /opt/guacamole/json/guacamole-auth-*.jar "$GUACAMOLE_EXT" } +## +## Sets up Tomcat's remote IP valve that allows gathering the remote IP +## from headers set by a remote proxy +## +enable_remote_ip_valve() { + # Check the required variables + if [ -z "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then + cat < /tmp/valve.xml < +EOF + + # Get the line where the Host configuration ends + LINEN=$(grep -n '' /usr/local/tomcat/conf/server.xml | cut -d ':' -f 1) + + # Split the file in 2 around the Host configuration + head -n "$(( LINEN - 1 ))" < /usr/local/tomcat/conf/server.xml > /tmp/head.xml + tail -n "+$LINEN" < /usr/local/tomcat/conf/server.xml > /tmp/tail.xml + + # Reassemble the file + cat /tmp/head.xml /tmp/valve.xml /tmp/tail.xml > /usr/local/tomcat/conf/server.xml + + # Cleanup + rm -f \ + /tmp/head.xml \ + /tmp/tail.xml \ + /tmp/valve.xml +} ## ## Starts Guacamole under Tomcat, replacing the current process with the @@ -794,6 +853,11 @@ fi set_property "guacd-hostname" "$GUACD_HOSTNAME" set_property "guacd-port" "$GUACD_PORT" +# Set up Tomcat RemoteIPValve +if [ -n "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then + enable_remote_ip_valve +fi + # # Track which authentication backends are installed # @@ -883,4 +947,3 @@ fi # start_guacamole - From 205cf1797d3532a6aa882f4b437837c57c037362 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Wed, 23 Sep 2020 09:20:56 +0200 Subject: [PATCH 2/7] GUACAMOLE-1005: Docker, configure RemoteIPValve inplace --- guacamole-docker/bin/start.sh | 67 ++++++++++++----------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh index 205d9cf85..fd84c0915 100755 --- a/guacamole-docker/bin/start.sh +++ b/guacamole-docker/bin/start.sh @@ -711,61 +711,38 @@ associate_json() { ## ## Sets up Tomcat's remote IP valve that allows gathering the remote IP ## from headers set by a remote proxy +## Upstream documentation: https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/valves/RemoteIpValve.html ## enable_remote_ip_valve() { - # Check the required variables + # Use Tomcat defaults if optional variables have not been provided if [ -z "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then - cat < /tmp/valve.xml < -EOF - - # Get the line where the Host configuration ends - LINEN=$(grep -n '' /usr/local/tomcat/conf/server.xml | cut -d ':' -f 1) - - # Split the file in 2 around the Host configuration - head -n "$(( LINEN - 1 ))" < /usr/local/tomcat/conf/server.xml > /tmp/head.xml - tail -n "+$LINEN" < /usr/local/tomcat/conf/server.xml > /tmp/tail.xml - - # Reassemble the file - cat /tmp/head.xml /tmp/valve.xml /tmp/tail.xml > /usr/local/tomcat/conf/server.xml - - # Cleanup - rm -f \ - /tmp/head.xml \ - /tmp/tail.xml \ - /tmp/valve.xml + # Build the new Tomcat configuration inplace + ## Explaination: + ## The initial regex ((\s)+) + ## Matches the spaces before as \1 and individual spaces as \2, ... + ## The replacement will be located at \1\2\2 (original + 2 spaces) + ## ${VAR:+expr} expressions yield either empty (thus using Tomcat's default) or our setting + ## The last line restores the configuration file original tag at its original indentation + sed -i "s|^\(\(\s\)\+\)|\1\2\2\n\1|" \ + /usr/local/tomcat/conf/server.xml } ## @@ -854,7 +831,7 @@ set_property "guacd-hostname" "$GUACD_HOSTNAME" set_property "guacd-port" "$GUACD_PORT" # Set up Tomcat RemoteIPValve -if [ -n "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then +if [ "$REMOTE_IP_VALVE_ENABLED" = "true" ]; then enable_remote_ip_valve fi From d91bfc9c9c231b80e87e5e5da94012d4ed4947db Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Sat, 6 Mar 2021 22:08:49 +0100 Subject: [PATCH 3/7] GUACAMOLE-1005: Docker, correct RemoteIPValve configuration file path --- guacamole-docker/bin/start.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh index fd84c0915..9f5008013 100755 --- a/guacamole-docker/bin/start.sh +++ b/guacamole-docker/bin/start.sh @@ -742,7 +742,7 @@ enable_remote_ip_valve() { ${GUACAMOLE_PROXY_BY_HEADER:+remoteIpProxiesHeader=\"$GUACAMOLE_PROXY_BY_HEADER\"} \ ${GUACAMOLE_PROXY_PROTOCOL_HEADER:+protocolHeader=\"$GUACAMOLE_PROXY_PROTOCOL_HEADER\"} \ />\n\1|" \ - /usr/local/tomcat/conf/server.xml + $CATALINA_BASE/conf/server.xml } ## @@ -759,6 +759,11 @@ start_guacamole() { done cp -R /usr/local/tomcat/conf $CATALINA_BASE + # Set up Tomcat RemoteIPValve + if [ "$REMOTE_IP_VALVE_ENABLED" = "true" ]; then + enable_remote_ip_valve + fi + # Install webapp ln -sf /opt/guacamole/guacamole.war $CATALINA_BASE/webapps/${WEBAPP_CONTEXT:-guacamole}.war @@ -830,11 +835,6 @@ fi set_property "guacd-hostname" "$GUACD_HOSTNAME" set_property "guacd-port" "$GUACD_PORT" -# Set up Tomcat RemoteIPValve -if [ "$REMOTE_IP_VALVE_ENABLED" = "true" ]; then - enable_remote_ip_valve -fi - # # Track which authentication backends are installed # From e25be1960da4b88b75f9c0037050d54aa35104d2 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Sat, 6 Mar 2021 23:12:12 +0100 Subject: [PATCH 4/7] GUACAMOLE-1005: Docker, configure RemoteIPValve with xmlstarlet --- Dockerfile | 4 ++- guacamole-docker/bin/start.sh | 66 ++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1b6e9be17..be6060375 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,9 @@ RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole "$BUILD_PR # For the runtime image, we start with the official Tomcat distribution FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE} +# Install XMLStarlet for server.conf alterations +RUN apt-get update -qq && apt-get install -y xmlstarlet + # This is where the build artifacts go in the runtime image WORKDIR /opt/guacamole @@ -68,4 +71,3 @@ USER guacamole # Start Guacamole under Tomcat, listening on 0.0.0.0:8080 EXPOSE 8080 CMD ["/opt/guacamole/bin/start.sh" ] - diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh index 9f5008013..c79fafc89 100755 --- a/guacamole-docker/bin/start.sh +++ b/guacamole-docker/bin/start.sh @@ -714,35 +714,51 @@ associate_json() { ## Upstream documentation: https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/catalina/valves/RemoteIpValve.html ## enable_remote_ip_valve() { - # Use Tomcat defaults if optional variables have not been provided + # Add 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 "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then echo "Using default Tomcat allowed IPs regex" - fi - if [ -z "$GUACAMOLE_PROXY_IP_HEADER" ]; then - echo "Using default Tomcat proxy IP header" - fi - if [ -z "$GUACAMOLE_PROXY_PROTOCOL_HEADER" ]; then - echo "Using default Tomcat proxy protocol header" - fi - if [ -z "$GUACAMOLE_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 internalProxies -v "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" \ + $CATALINA_BASE/conf/server.xml fi - # Build the new Tomcat configuration inplace - ## Explaination: - ## The initial regex ((\s)+) - ## Matches the spaces before as \1 and individual spaces as \2, ... - ## The replacement will be located at \1\2\2 (original + 2 spaces) - ## ${VAR:+expr} expressions yield either empty (thus using Tomcat's default) or our setting - ## The last line restores the configuration file original tag at its original indentation - sed -i "s|^\(\(\s\)\+\)|\1\2\2\n\1|" \ - $CATALINA_BASE/conf/server.xml + # X-Forwarded-For + if [ -z "$GUACAMOLE_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 "$GUACAMOLE_PROXY_IP_HEADER" \ + $CATALINA_BASE/conf/server.xml + fi + + # X-Forwarded-Proto + if [ -z "$GUACAMOLE_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 "$GUACAMOLE_PROXY_PROTOCOL_HEADER" \ + $CATALINA_BASE/conf/server.xml + fi + + # X-Forwarded-By + if [ -z "$GUACAMOLE_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 "$GUACAMOLE_PROXY_BY_HEADER" \ + $CATALINA_BASE/conf/server.xml + fi } ## From 88c47dee267c29a8f97a0045ca22946e1bac5940 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Sat, 12 Jun 2021 12:09:33 +0200 Subject: [PATCH 5/7] GUACAMOLE-1005: Drop GUACAMOLE_ environment variable prefix --- guacamole-docker/bin/start.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh index c79fafc89..c13d2407d 100755 --- a/guacamole-docker/bin/start.sh +++ b/guacamole-docker/bin/start.sh @@ -721,42 +721,42 @@ enable_remote_ip_valve() { $CATALINA_BASE/conf/server.xml # Allowed IPs - if [ -z "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" ]; then - echo "Using default Tomcat allowed IPs regex" + 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 "$GUACAMOLE_PROXY_ALLOWED_IPS_REGEX" \ + --type attr -n internalProxies -v "$PROXY_ALLOWED_IPS_REGEX" \ $CATALINA_BASE/conf/server.xml fi # X-Forwarded-For - if [ -z "$GUACAMOLE_PROXY_IP_HEADER" ]; then + 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 "$GUACAMOLE_PROXY_IP_HEADER" \ + --type attr -n remoteIpHeader -v "$PROXY_IP_HEADER" \ $CATALINA_BASE/conf/server.xml fi # X-Forwarded-Proto - if [ -z "$GUACAMOLE_PROXY_PROTOCOL_HEADER" ]; then + 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 "$GUACAMOLE_PROXY_PROTOCOL_HEADER" \ + --type attr -n protocolHeader -v "$PROXY_PROTOCOL_HEADER" \ $CATALINA_BASE/conf/server.xml fi # X-Forwarded-By - if [ -z "$GUACAMOLE_PROXY_BY_HEADER" ]; then + 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 "$GUACAMOLE_PROXY_BY_HEADER" \ + --type attr -n remoteIpProxiesHeader -v "$PROXY_BY_HEADER" \ $CATALINA_BASE/conf/server.xml fi } From 4ebfe541a00cb4af44fe6859a1efb73fef31b860 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Sat, 12 Jun 2021 12:10:04 +0200 Subject: [PATCH 6/7] GUACAMOLE-1005: Rectify misleading description --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index be6060375..781e55c2f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,7 @@ RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole "$BUILD_PR # For the runtime image, we start with the official Tomcat distribution FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE} -# Install XMLStarlet for server.conf alterations +# Install XMLStarlet for server.xml alterations RUN apt-get update -qq && apt-get install -y xmlstarlet # This is where the build artifacts go in the runtime image From 65074cb1e46e905373a449df71caa1ca6657ee39 Mon Sep 17 00:00:00 2001 From: Giacomo Longo Date: Sat, 12 Jun 2021 12:11:29 +0200 Subject: [PATCH 7/7] GUACAMOLE-1005: Cleanup apt cache after package installation --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 781e55c2f..5af326bb3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,7 +51,9 @@ RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole "$BUILD_PR FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE} # Install XMLStarlet for server.xml alterations -RUN apt-get update -qq && apt-get install -y xmlstarlet +RUN apt-get update -qq \ + && apt-get install -y xmlstarlet \ + && rm -rf /var/lib/apt/lists/* # This is where the build artifacts go in the runtime image WORKDIR /opt/guacamole