← Back to team overview

wordpress-charmers team mailing list archive

[Merge] ~tcuthbert/charm-k8s-wordpress:container-hardening into charm-k8s-wordpress:container-hardening

 

Thomas Cuthbert has proposed merging ~tcuthbert/charm-k8s-wordpress:container-hardening into charm-k8s-wordpress:container-hardening.

Requested reviews:
  Wordpress Charmers (wordpress-charmers)

For more details, see:
https://code.launchpad.net/~tcuthbert/charm-k8s-wordpress/+git/charm-k8s-wordpress-1/+merge/426107
-- 
Your team Wordpress Charmers is requested to review the proposed merge of ~tcuthbert/charm-k8s-wordpress:container-hardening into charm-k8s-wordpress:container-hardening.
diff --git a/Dockerfile b/Dockerfile
index e2451e0..325ed05 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,6 +19,8 @@ ARG HTTPS_PROXY
 
 ENV APACHE_CONFDIR=/etc/apache2
 ENV APACHE_ENVVARS=/etc/apache2/envvars
+ENV APACHE_RUN_USER=$USERNAME
+ENV APACHE_RUN_GROUP=$GROUPNAME
 ENV PYTHONUNBUFFERED="1"
 
 # Avoid interactive prompts
@@ -27,7 +29,6 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio
 # Update all packages, remove cruft, install required packages, configure apache
 RUN set -eux; \
         apt-get update; apt-get -y dist-upgrade; \
-        apt-get --purge autoremove -y; \
         apt-get install -y \
             apache2 \
             bzr \
@@ -49,14 +50,13 @@ RUN set -eux; \
             python3-urllib3 \
             python3-yaml \
             ssl-cert \
-            wget
+            wget; \
+      apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
+      rm -rf /var/lib/apt/lists/* /var/cache/apt/**/*||true;
 
 # Reconfigure apache so it can be run as non-root
 RUN set -eux; \
-        sed -i \
-          -e "s/APACHE_RUN_USER=.*$/APACHE_RUN_USER=$USERNAME/" \
-          -e "s/APACHE_RUN_GROUP=.*$/APACHE_RUN_GROUP=$GROUPNAME/" \
-          "$APACHE_ENVVARS"; \
+        sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
         . "$APACHE_ENVVARS"; \
         sed -i \
           -e 's/Listen 80/Listen 8000/' \
@@ -66,16 +66,12 @@ RUN set -eux; \
             /etc/apache2/ports.conf \
             /etc/apache2/sites-available/000-default.conf; \
         for dir in "$APACHE_LOCK_DIR" "$APACHE_RUN_DIR" "$APACHE_LOG_DIR"; do \
-          rm -rvf "$dir"; \
-          mkdir -p "$dir"; \
-          chmod 2750 "$dir"; \
+          chmod 2770 "$dir"; \
           chown -R "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
         done; \
-        chown -R "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_CONFDIR" ; \
         ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
         ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
-        ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
-        chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
+        ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log";
 
 # Test apache configuration works
 RUN set -eux; /usr/sbin/apache2ctl -S;
@@ -121,9 +117,8 @@ RUN set -eux; \
         rm /wordpress.tar.gz
 
 RUN set -eux; \
-        install --owner="$USERNAME" --group="$GROUPNAME" -d /srv/wordpress-helpers; \
-        install --mode="700" --owner="$USERNAME" --group="$GROUPNAME" /files/wp-config.php /var/www/html/wp-config.php; \
-        install --mode="700" --owner="$USERNAME" --group="$GROUPNAME" -t /srv/wordpress-helpers/ -D \
+        install --mode="770" --owner="$USERNAME" --group="$GROUPNAME" -d /srv/wordpress-helpers; \
+        install --mode="550" --owner="$USERNAME" --group="$GROUPNAME" -t /srv/wordpress-helpers/ -D \
             /files/_add_option.php \
             /files/_enable_plugin.php \
             /files/_get_option.php \
@@ -145,38 +140,28 @@ COPY --chown="$USERNAME":"$GROUPNAME" --from=plugins /var/www/html/wp-content/th
 
 # Copy our helper scripts and their wrapper into their own directory
 COPY --chown="$USERNAME":"$GROUPNAME" ./image-builder/files/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
+COPY --chown="$USERNAME":"$GROUPNAME" ./image-builder/files/wp-config.php /var/www/html/wp-config.php
 COPY --chown="$USERNAME":"$GROUPNAME" ./image-builder/files/wp-info.php /var/www/html/wp-info.php
 
-# Make the wrapper executable
-RUN chmod 0500 /srv/wordpress-helpers/plugin_handler.py
-RUN chmod 0500 /srv/wordpress-helpers/ready.sh
-RUN chmod 0500 /usr/local/bin/docker-entrypoint.sh
-
 RUN set -eux; \
-        chmod 0500 /usr/local/bin/docker-entrypoint.sh; \
+        bash -c "chmod ug=rx /usr/local/bin/docker-entrypoint.sh; chown $USERNAME:$GROUPNAME \$_"\
         sed -i -e 's/max_execution_time = 30/max_execution_time = 300/' \
             -i -e 's/upload_max_filesize = 2M/upload_max_filesize = 10M/' \
-              /etc/php/7.[24]/apache2/php.ini
+              /etc/php/7.[24]/apache2/php.ini; \
+        install --owner=$USERNAME --group=$GROUPNAME --mode=600 /dev/null /var/log/wordpress-plugin-handler.log;
 
 # Ensure remote users are unable to upload potentially malicious content into the container
 RUN set -eux; \
         find /var/www/html \
-          -exec chown "$USERNAME:$GROUPNAME" {} \+ \
-          -exec chmod o-rxw {} \+ \
-          -type d -exec chmod g=srx {} \; \
-          -or \
-          -type f -name '*.php' -exec chmod u=rx,g=r {} \;; \
-        chmod u+w /var/www/html/wp-includes/functions.php /var/www/html/wp-info.php; \
-        touch /var/log/wordpress-plugin-handler.log; \
-        chown "$USERNAME:$GROUPNAME" /var/log/wordpress-plugin-handler.log
-
-# Make sure we don't leave any build run time state behind
-RUN set -eux; . "$APACHE_ENVVARS"; \
-      for dir in "$APACHE_LOCK_DIR" "$APACHE_RUN_DIR"; do \
-          rm -rvf "$dir/*"; \
-      done; \
-      apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
-      rm -rf /var/lib/apt/lists/*;
+          -exec chown $USERNAME:$GROUPNAME {} \; \
+          -exec chmod a-rwx,ug+rX {} \; \
+        ;
+
+RUN set -eux; \
+        chmod ug+rw /var/www/html/wp-includes/functions.php /var/www/html/wp-info.php; \
+        chown -R :$GROUPNAME /etc/apache2 /var/lib/apache2; chmod -R g+rwX /etc/apache2/conf* /var/lib/apache2/conf*
+
+STOPSIGNAL SIGWINCH
 
 # Unprivileged port 8000 only, TLS will terminate elsewhere
 EXPOSE 8000
diff --git a/image-builder/files/_get_option.php b/image-builder/files/_get_option.php
index 4168301..fb9938d 100644
--- a/image-builder/files/_get_option.php
+++ b/image-builder/files/_get_option.php
@@ -5,6 +5,7 @@
 # Example use:
 # php ./_get_option.php akismet_strictness
 
+@include "wp-info.php";
 @include "wp-config.php";
 @include_once "wp-includes/option.php";
 @include_once "/usr/share/php/Symfony/Component/Yaml/autoload.php";
diff --git a/image-builder/files/docker-entrypoint.sh b/image-builder/files/docker-entrypoint.sh
index 3de9bc0..2938af4 100644
--- a/image-builder/files/docker-entrypoint.sh
+++ b/image-builder/files/docker-entrypoint.sh
@@ -1,5 +1,7 @@
 #!/bin/bash
 set -eu
+: "${APACHE_RUN_USER:=wordpress}"
+: "${APACHE_RUN_GROUP:=wordpress}"
 
 printf "remove_filter('template_redirect', 'redirect_canonical');" >> /var/www/html/wp-includes/functions.php
 
@@ -8,6 +10,23 @@ envsubst "$(printf "'$%s'" $(printenv|grep -P 'WORD|_KEY|_AUTH'))" < /files/wp-i
 # If we have passed in SWIFT_URL, then append swift proxy config.
 [ -z "${SWIFT_URL-}" ] || a2enconf docker-php-swift-proxy
 
-nohup bash -c "/srv/wordpress-helpers/plugin_handler.py &"
+nohup bash -c "/srv/wordpress-helpers/plugin_handler.py &" > /dev/null
+
+# Fix apache2 logging issues: https://github.com/bitnami/bitnami-docker-wordpress/blob/master/6/debian-11/rootfs/opt/bitnami/scripts/apache/setup.sh#L63
+chmod o+w "$(readlink /dev/stdout)" "$(readlink /dev/stderr)"
+
+: "${APACHE_CONFDIR:=/etc/apache2}"
+: "${APACHE_ENVVARS:=$APACHE_CONFDIR/envvars}"
+if [ -f "$APACHE_ENVVARS" ]; then
+	. "$APACHE_ENVVARS"
+fi
+
+# Apache gets grumpy about PID files pre-existing
+: "${APACHE_RUN_DIR:=/var/run/apache2}"
+: "${APACHE_LOCK_DIR:=/var/lock/apache2}"
+for dir in "$APACHE_LOCK_DIR"/* "$APACHE_RUN_DIR"/*; do
+    echo "cleaning ${dir}..."
+    rm -rvf "${dir}"/*;
+done
 
 exec "$@"
diff --git a/image-builder/files/plugin_handler.py b/image-builder/files/plugin_handler.py
index 94403ec..05c5818 100644
--- a/image-builder/files/plugin_handler.py
+++ b/image-builder/files/plugin_handler.py
@@ -89,8 +89,12 @@ def enable_swift(swift_config):
         add_option("object_storage_{}".format(k), v)
 
 
-def configure_wordpress():
-    url = "http://localhost";
+def configure_wordpress(hostname="localhost", http_port=8000, schema="http"):
+    url = "{schema}://{hostname}:{http_port}".format(**{
+        "schema":  schema,
+        "hostname":  hostname,
+        "http_port": http_port,
+    })
     sleep_time = 10
     total_sleep_time = 0
     max_sleep_time = 600
diff --git a/image-builder/files/ready.sh b/image-builder/files/ready.sh
index a676bc2..28afbd6 100644
--- a/image-builder/files/ready.sh
+++ b/image-builder/files/ready.sh
@@ -8,7 +8,7 @@ READY=/srv/wordpress-helpers/.ready
 # return a failure, replace the shell with whatever curl
 # returns for checking that the website is alive.
 if [ -f "$READY" ]; then
-    exec /usr/bin/curl --silent http://localhost
+    exec /usr/bin/curl --silent http://localhost:8000
 fi
 
 exit 1

Follow ups