diff --git a/README.md b/README.md index b1d54cb..dd2a194 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A docker image of [sciguy14/Remote-Wake-Sleep-On-LAN-Server](https://github.com/ Dockerhub: https://hub.docker.com/r/ex0nuss/remote-wake-sleep-on-lan-docker +> **Security:** The image is based on PHP 8.5.12 or newer (Apache) and includes fixes for the critical remote code execution vulnerabilities [CVE-2026-109618](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [CVE-2026-109619](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp). Rebuild the image regularly (for example with `docker build --pull`) to receive future PHP security updates. + Weekly updated :) ## Summary diff --git a/build/000-default.conf b/build/000-default.conf index bc27fcc..f4a5eb7 100644 --- a/build/000-default.conf +++ b/build/000-default.conf @@ -1,7 +1,7 @@ - # TLS/SSL configuration, this is for the use of crypto. ServerAdmin webmaster@localhost + ServerName localhost SSLEngine On SSLCertificateFile /etc/apache2/ssl/wol.crt @@ -10,15 +10,12 @@ DocumentRoot /var/www/html AllowOverride AuthConfig FileInfo - Order allow,deny - allow from all Options -Indexes + Require all granted ErrorLog ${APACHE_LOG_DIR}/ssl_error.log - # Possible values include: debug, info, notice, warn, error, crit, - # alert, emerg. LogLevel error CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined @@ -26,22 +23,19 @@ - - # Non-TLS/SSL configuration. + ServerAdmin webmaster@localhost + ServerName localhost DocumentRoot /var/www/html AllowOverride AuthConfig FileInfo - Order allow,deny - allow from all Options -Indexes + Require all granted ErrorLog ${APACHE_LOG_DIR}/error.log - # Possible values include: debug, info, notice, warn, error, crit, - # alert, emerg. LogLevel error CustomLog ${APACHE_LOG_DIR}/access.log combined diff --git a/build/Dockerfile b/build/Dockerfile index f10c46d..c0e6bc0 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,42 +1,34 @@ -FROM ubuntu:latest -MAINTAINER ex0nuss +FROM php:8.5-apache -## for apt to be noninteractive -ENV DEBIAN_FRONTEND noninteractive -ENV DEBCONF_NONINTERACTIVE_SEEN true +RUN php -r 'if (version_compare(PHP_VERSION, "8.5.12", "<")) { fwrite(STDERR, "PHP 8.5.12 or newer is required\n"); exit(1); }' -RUN apt-get -y update && \ - apt install -y \ - apache2 \ - php \ - libapache2-mod-php \ - libcurl4-gnutls-dev \ - iputils-ping \ - wakeonlan \ - git +ENV DEBIAN_FRONTEND=noninteractive -WORKDIR /root -RUN git clone https://github.com/sciguy14/Remote-Wake-Sleep-On-LAN-Server.git &&\ - chown root: /var/www/html &&\ - chmod u+s `which ping` +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + git \ + iputils-ping \ + wakeonlan && \ + rm -rf /var/lib/apt/lists/* && \ + chmod u+s "$(command -v ping)" -COPY ports.conf /etc/apache2/ +RUN git clone --depth 1 --branch 3.5.0 https://github.com/sciguy14/Remote-Wake-Sleep-On-LAN-Server.git /tmp/rwsols && \ + cp -a /tmp/rwsols/www/html/. /var/www/html/ && \ + rm -rf /tmp/rwsols && \ + rm -f /var/www/html/config_sample.php /var/www/html/index.html && \ + sed -i '/curl_close(/d' /var/www/html/index.php -RUN a2enmod headers &&\ - service apache2 restart &&\ - mv -f Remote-Wake-Sleep-On-LAN-Server/000-default.conf /etc/apache2/sites-available/000-default.conf &&\ - sed -i.bak "s/expose_php = On/expose_php = Off/g" /etc/php/7.4/apache2/php.ini &&\ - sed -i.bak "s/E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED/error_reporting = E_ERROR/g" /etc/php/7.4/apache2/php.ini &&\ - sed -i.bak "s/ServerSignature On/ServerSignature Off/g" /etc/apache2/conf-available/security.conf &&\ - sed -i.bak "s/ServerTokens OS/ServerTokens Prod/g" /etc/apache2/conf-available/security.conf &&\ - service apache2 restart &&\ - mv Remote-Wake-Sleep-On-LAN-Server/* /var/www/html &&\ - mv Remote-Wake-Sleep-On-LAN-Server/.htaccess /var/www/html &&\ - rm -rf Remote-Wake-Sleep-On-LAN-Server/ &&\ - rm -f /var/www/html/index.html +COPY 000-default.conf /etc/apache2/sites-available/000-default.conf +COPY ports.conf /etc/apache2/ports.conf +COPY php-security.ini /usr/local/etc/php/conf.d/zz-security.ini +COPY config.php /usr/local/share/rwsols-config.php +COPY entrypoint.sh /entrypoint.sh -COPY config.php /var/www/html/config.php -COPY entrypoint.sh / +RUN chmod +x /entrypoint.sh && \ + a2enmod headers && \ + sed -i 's/^ServerTokens .*/ServerTokens Prod/; s/^ServerSignature .*/ServerSignature Off/' /etc/apache2/conf-available/security.conf && \ + echo 'ServerName localhost' >> /etc/apache2/apache2.conf ENV APACHE2_PORT=80 ENV PASSPHRASE=admin diff --git a/build/config.php b/build/config.php index f53e72b..063ef2a 100644 --- a/build/config.php +++ b/build/config.php @@ -12,10 +12,9 @@ // Set the below to "true" (no quotes) to enforce HTTPS connections (don't forget to create a self-signed cert and enable it in Apache2) $USE_HTTPS = false; - // Choose a passphrase and find the sha256 hash of that passphrase. - // You can use an online calculator to generate the hash: http://www.xorbin.com/tools/sha256-hash-calculator. + // The password hash is generated automatically at container startup from the PASSPHRASE environment variable. // Unless you are using an SSL connection to your server, remember that passphrases can still be obtained via a man-in-the-middle attack. - $APPROVED_HASH = "RWSOLS_HASH"; + $APPROVED_HASH = 'REPLACE_APPROVED_HASH'; // This is the number of times that the WOL server will try to ping the target computer to check if it has woken up. Default = 15. $MAX_PINGS = REPLACE_RWSOLS_MAX_PINGS; diff --git a/build/entrypoint.sh b/build/entrypoint.sh index 8ea9f41..b823bc0 100755 --- a/build/entrypoint.sh +++ b/build/entrypoint.sh @@ -1,33 +1,39 @@ #!/bin/bash -#File to edit +set -eu + +template='/usr/local/share/rwsols-config.php' file='/var/www/html/config.php' -#Searches $1 and replaces with $2 in $file -function search_and_replace { - sed -i 's|'$1'|'$2'|g' "$file" +cp "$template" "$file" + +search_and_replace() { + local search="$1" + local replace="$2" + local escaped + + escaped=$(printf '%s' "$replace" | sed -e 's/[&|\\]/\\&/g') + sed -i "s|$search|$escaped|g" "$file" } -#RWSOLS -#Does everything for ENV-vars with RWSOLS_* -compgen -A variable RWSOLS_ | while read v; do - #Checks if REPLACE_envvar is in $file +for v in $(compgen -A variable RWSOLS_); do if grep -q "REPLACE_$v" "$file"; then echo "search_and_replace REPLACE_$v with ${!v}" - search_and_replace REPLACE_$v ${!v} + search_and_replace "REPLACE_$v" "${!v}" fi done -#Settings RWSOLS_HASH for keyphrase -RWSOLS_HASH=$(echo -n $PASSPHRASE | sha256sum | cut -d " " -f 1) -search_and_replace RWSOLS_HASH $RWSOLS_HASH +RWSOLS_HASH=$(php -r '$p = getenv("PASSPHRASE"); echo password_hash($p === false ? "" : $p, PASSWORD_DEFAULT);') +search_and_replace "REPLACE_APPROVED_HASH" "$RWSOLS_HASH" +case "${APACHE2_PORT:-}" in + ''|*[!0-9]*) + echo "APACHE2_PORT must be a numeric port" >&2 + exit 1 + ;; +esac -#APACHE2 port mapping -echo "search_and_replace port 8080 with $APACHE2_PORT" -sed -i 's|'8080'|'$APACHE2_PORT'|g' '/etc/apache2/ports.conf' +echo "Starting Apache2 on port $APACHE2_PORT" +sed -i "s|8080|$APACHE2_PORT|g" /etc/apache2/ports.conf /etc/apache2/sites-available/000-default.conf - -#Starting apache2 -echo "Starting Apache2: /usr/sbin/apache2ctl -D FOREGROUND" -/usr/sbin/apache2ctl -D FOREGROUND +exec apache2-foreground diff --git a/build/php-security.ini b/build/php-security.ini new file mode 100644 index 0000000..1de2087 --- /dev/null +++ b/build/php-security.ini @@ -0,0 +1,13 @@ +expose_php = Off +display_errors = Off +display_startup_errors = Off +log_errors = On +error_reporting = E_ALL & ~E_DEPRECATED +output_buffering = 4096 + +session.upload_progress.enabled = Off +session.use_strict_mode = On +fatal_error_backtraces = 0 + +post_max_size = 8M +upload_max_filesize = 2M