From 46097bb6e88d5182db95b30665dfbd5112f9eb15 Mon Sep 17 00:00:00 2001 From: Adam Outler Date: Sat, 27 Sep 2025 19:15:07 -0400 Subject: [PATCH] solid hardened config --- .devcontainer/scripts/setup.sh | 92 +++---------------- Dockerfile | 50 ++++++---- .../config}/nginx/fastcgi_params | 0 .../config}/nginx/netalertx.conf | 0 .../config}/nginx/nginx.conf | 4 +- install/alpine-docker/services/healthcheck.sh | 0 .../alpine-docker/services/start-backend.sh | 2 +- install/alpine-docker/services/start-crond.sh | 0 install/alpine-docker/services/start-nginx.sh | 0 .../alpine-docker/services/start-php-fpm.sh | 0 10 files changed, 50 insertions(+), 98 deletions(-) rename install/alpine-docker/{app/services => services/config}/nginx/fastcgi_params (100%) rename install/alpine-docker/{app/services => services/config}/nginx/netalertx.conf (100%) mode change 100755 => 100644 rename install/alpine-docker/{app/services => services/config}/nginx/nginx.conf (97%) mode change 100644 => 100755 install/alpine-docker/services/healthcheck.sh mode change 100644 => 100755 install/alpine-docker/services/start-backend.sh mode change 100644 => 100755 install/alpine-docker/services/start-crond.sh mode change 100644 => 100755 install/alpine-docker/services/start-nginx.sh mode change 100644 => 100755 install/alpine-docker/services/start-php-fpm.sh diff --git a/.devcontainer/scripts/setup.sh b/.devcontainer/scripts/setup.sh index fe282c15..aae220ff 100755 --- a/.devcontainer/scripts/setup.sh +++ b/.devcontainer/scripts/setup.sh @@ -44,73 +44,49 @@ main() { start_services } -# safe_link: create a symlink from source to target, removing existing target if necessary -# bypassing the default behavior of symlinking the directory into the target directory if it is a directory -safe_link() { - # usage: safe_link - local src="$1" - local dst="$2" - - # Ensure parent directory exists - install -d -m 775 "$(dirname "$dst")" >/dev/null 2>&1 || true - - # If target exists, remove it without dereferencing symlinks - if [ -L "$dst" ] || [ -e "$dst" ]; then - rm -rf "$dst" - fi - - # Create link; -n prevents deref, -f replaces if somehow still exists - ln -sfn "$src" "$dst" -} # Setup source directory configure_source() { echo "[1/3] Configuring Source..." - echo " -> Linking source to ${INSTALL_DIR}" + echo " -> Cleaning up previous instances" sudo umount "${INSTALL_DIR}/log" 2>/dev/null sudo umount "${INSTALL_DIR}/api" 2>/dev/null sudo rm -Rf ${INSTALL_DIR} || true + + echo " -> Linking source to ${INSTALL_DIR}" sudo ln -s ${SOURCE_DIR} ${INSTALL_DIR} echo " -> Mounting ramdisks for /log and /api" - sudo mkdir -p /tmp/log /tmp/api || true - sudo cp -R ${SOURCE_DIR}/log/ /tmp/log/ || true - sudo cp -R ${SOURCE_DIR}/api/ /tmp/api/ || true - sudo mkdir -p ${NETALERTX_API} ${NETALERTX_LOG} - # mount tmpfs with netalertx:netalertx ownership and 775 permissions sudo mount -o uid=$(id -u netalertx),gid=$(id -g netalertx),mode=775 -t tmpfs -o size=256M tmpfs "${NETALERTX_LOG}" sudo mount -o uid=$(id -u netalertx),gid=$(id -g netalertx),mode=775 -t tmpfs -o size=256M tmpfs "${NETALERTX_API}" + mkdir -p ${NETALERTX_PLUGINS_LOG} + touch ${NETALERTX_PLUGINS_LOG}/.git-placeholder ${NETALERTX_API}/.git-placeholder # mount tmpfs with root:root ownership and 755 permissions - sudo cp -R /tmp/log/* ${NETALERTX_LOG} 2>/dev/null || true - sudo cp -R /tmp/api/* ${NETALERTX_API} 2>/dev/null || true - sudo rm -Rf /tmp/log /tmp/api || true - echo "Dev">${INSTALL_DIR}/.VERSION - - - - - echo " -> Setting ownership and permissions" - chmod +x /workspaces/NetAlertX/.devcontainer/scripts/start-nginx.sh - sudo date +%s > "${INSTALL_DIR}/front/buildtimestamp.txt" - echo " -> Empty log"|tee ${INSTALL_DIR}/log/app.log \ ${INSTALL_DIR}/log/app_front.log \ ${INSTALL_DIR}/log/stdout.log touch ${INSTALL_DIR}/log/stderr.log \ - ${INSTALL_DIR}/log/execution_queue.log + ${INSTALL_DIR}/log/execution_queue.log echo 0>${INSTALL_DIR}/log/db_is_locked.log mkdir -p /app/log/plugins sudo chown -R netalertx:www-data ${INSTALL_DIR} - date +%s > /app/front/buildtimestamp.txt + killall python &>/dev/null sleep 1 } -# +# configure_php: configure PHP-FPM and enable dev debug options +configure_php() { + echo "[2/3] Configuring PHP-FPM..." + sudo killall php-fpm83 &>/dev/null || true + sudo chown netalertx:netalertx /run/php/ 2>/dev/null || true + sudo cp /workspaces/NetAlertX/.devcontainer/resources/99-xdebug.ini /etc/php83/conf.d/99-xdebug.ini + +} # start_services: start crond, PHP-FPM, nginx and the application start_services() { @@ -144,44 +120,6 @@ start_services() { sleep 2 } -# configure_php: configure PHP-FPM and enable dev debug options -configure_php() { - echo "[2/3] Configuring PHP-FPM..." - sudo killall php-fpm83 &>/dev/null || true - install -d -o netalertx -g www-data /run/php/ &>/dev/null - sudo sed -i "/^;pid/c\pid = /run/php/php8.3-fpm.pid" /etc/php83/php-fpm.conf - sudo sed -i 's|^listen = .*|listen = 127.0.0.1:9000|' /etc/php83/php-fpm.d/www.conf - sudo sed -i 's|fastcgi_pass .*|fastcgi_pass 127.0.0.1:9000;|' /etc/nginx/http.d/*.conf - - - #increase max child process count to 10 - sudo sed -i -e 's/pm.max_children = 5/pm.max_children = 10/' /etc/php83/php-fpm.d/www.conf - - # find any line in php-fmp that starts with either ;error_log or error_log = and replace it with error_log = /app/log/app.php_errors.log - sudo sed -i '/^;*error_log\s*=/c\error_log = /app/log/app.php_errors.log' /etc/php83/php-fpm.conf - # If the line was not found, append it to the end of the file - if ! grep -q '^error_log\s*=' /etc/php83/php-fpm.conf; then - echo 'error_log = /app/log/app.php_errors.log' | sudo tee -a /etc/php83/php-fpm.conf - fi - - sudo mkdir -p /etc/php83/conf.d - sudo cp /workspaces/NetAlertX/.devcontainer/resources/99-xdebug.ini /etc/php83/conf.d/99-xdebug.ini - - sudo rm -R /var/log/php83 &>/dev/null || true - install -d -o netalertx -g www-data -m 755 var/log/php83; - - sudo chmod 644 /etc/php83/conf.d/99-xdebug.ini || true - sudo install -d -o netalertx -g www-data -m 775 /run/php - - sudo rm /var/lib/nginx/logs/ && sudo install -d -o netalertx -g www-data /var/lib/nginx/logs/ - sudo rm /var/log/nginx && sudo install -d -o netalertx -g www-data /var/log/nginx - sudo chown -R netalertx:www-data /var/log/nginx - sudo chown -R netalertx:www-data /run/nginx - -} - -# (duplicate start_services removed) - echo "$(git rev-parse --short=8 HEAD)">/app/.VERSION diff --git a/Dockerfile b/Dockerfile index ecf9f211..c92f9b1f 100755 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ ARG INSTALL_DIR=/app ENV PATH="/opt/venv/bin:/usr/bin:/sbin:/bin:$PATH" # NetAlertX app directories -ENV NETALERTX_APP=/app +ENV NETALERTX_APP=${INSTALL_DIR} ENV NETALERTX_CONFIG=${NETALERTX_APP}/config ENV NETALERTX_FRONT=${NETALERTX_APP}/front ENV NETALERTX_SERVER=${NETALERTX_APP}/server @@ -32,8 +32,6 @@ ENV NETALERTX_DB=${NETALERTX_APP}/db ENV NETALERTX_BACK=${NETALERTX_APP}/back ENV NETALERTX_LOG=${NETALERTX_APP}/log ENV NETALERTX_PLUGINS_LOG=${NETALERTX_LOG}/plugins -ENV NETALERTX_NGINIX_CONFIG=${NETALERTX_APP}/services/nginx -ENV NETALERTX_SERVICES=${NETALERTX_APP}/services # NetAlertX log files ENV LOG_IP_CHANGES=${NETALERTX_LOG}/IP_changes.log @@ -49,20 +47,24 @@ ENV LOG_REPORT_OUTPUT_JSON=${NETALERTX_LOG}/report_output.json ENV LOG_STDOUT=${NETALERTX_LOG}/stdout.log ENV LOG_CROND=${NETALERTX_LOG}/crond.log -# Important configuration files -ENV NGINX_CONFIG_FILE=${NETALERTX_NGINIX_CONFIG}/nginx.conf +# System Services configuration files +ENV SYSTEM_SERVICES=/services +ENV SYSTEM_SERVICES_CONFIG=${SYSTEM_SERVICES}/config +ENV SYSTEM_NGINIX_CONFIG=${SYSTEM_SERVICES_CONFIG}/nginx +ENV NGINX_CONFIG_FILE=${SYSTEM_NGINIX_CONFIG}/nginx.conf ENV NETALERTX_CONFIG_FILE=${NETALERTX_CONFIG}/app.conf ENV NETALERTX_DB_FILE=${NETALERTX_DB}/app.db ENV PHP_FPM_CONFIG_FILE=/etc/php83/php-fpm.conf ENV PHP_WWW_CONF_FILE=/etc/php83/php-fpm.d/www.conf -ENV SYSTEM_SERVICES=/services +ENV PYTHONPATH=${NETALERTX_SERVER} + #Create netalertx user and group RUN addgroup -g 20211 netalertx && \ - adduser -u 20211 -G netalertx -D -h /app netalertx + adduser -u 20211 -G netalertx -D -h ${NETALERTX_APP} netalertx -RUN apk add --no-cache bash libbsd zip lsblk gettext-envsubst sudo mtr tzdata curl arp-scan iproute2 \ - iproute2-ss nmap nmap-scripts traceroute nbtscan openrc dbus net-tools net-snmp-tools bind-tools awake \ +RUN apk add --no-cache bash mtr libbsd zip lsblk sudo tzdata curl arp-scan iproute2 \ + iproute2-ss nmap nmap-scripts traceroute nbtscan net-tools net-snmp-tools bind-tools awake \ ca-certificates sqlite php83 php83-fpm php83-cgi php83-curl php83-sqlite3 php83-session python3 nginx sudo && \ rm -rf /var/cache/apk/* && \ rm -f /etc/nginx/http.d/default.conf @@ -84,7 +86,7 @@ RUN sh /build/init-nginx.sh && \ sh /build/init-php-fpm.sh && \ sh /build/init-crond.sh && \ sh /build/init-backend.sh && \ - rm -rf /build/* + rm -rf /build # set netalertx to allow sudoers for any command, no password RUN echo "netalertx ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers @@ -100,25 +102,39 @@ RUN addgroup -g 20212 readonly && \ adduser -u 20212 -G readonly -D -h /app readonly # remove netalertx from sudoers -RUN sh -c "sed -i '/netalertx ALL=(ALL) NOPASSWD: ALL/d' /etc/sudoers" -RUN chown -R readonly:readonly ${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} ${SYSTEM_SERVICES} ${NETALERTX_SERVICES} && \ +RUN chown -R readonly:readonly ${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} ${SYSTEM_SERVICES} ${SYSTEM_SERVICES} && \ chmod -R 004 ${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} && \ - chmod 005 ${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} && \ - chmod -R 005 ${SYSTEM_SERVICES} ${NETALERTX_SERVICES} && \ + find ${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} -type d -exec chmod 005 {} + && \ + chmod -R 005 ${SYSTEM_SERVICES} ${SYSTEM_SERVICES}/* && \ chown -R netalertx:netalertx ${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} ${NETALERTX_LOG} && \ - chmod -R 600 ${NETALERTX_CONFIG} ${NETALERTX_DB} {NETALERTX_API} ${NETALERTX_LOG} && \ + chmod -R 600 ${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} ${NETALERTX_LOG} && \ chmod 700 ${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} ${NETALERTX_LOG} ${NETALERTX_PLUGINS_LOG} && \ chown readonly:readonly / && \ chown -R netalertx:netalertx /var/log/nginx /var/lib/nginx /run && \ - echo -ne '#!/bin/bash\nexit 0\n' > /usr/bin/sudo && chmod +x /usr/bin/sudo && \ find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o \ -path /run -prune -o -path /var/log -prune -o -path /tmp -prune -o \ -group 0 -o -user 0 -exec chown readonly:readonly {} + +# +# remove sudo and alpine installers pacakges +RUN apk del sudo && \ + rm -rf /var/cache/apk/* +# remove all users and groups except readonly and netalertx without userdel/groupdel binaries +# RUN awk -F: '($1 != "readonly" && $1 != "netalertx") {print $1}' /etc/passwd | xargs -r -n 1 deluser -r && \ +# awk -F: '($1 != "readonly" && $1 != "netalertx") {print $1}' /etc/group | xargs -r -n 1 delgroup +# Remove all sudoers +RUN rm -Rf /etc/sudoers.d/* /etc/shadow /etc/gshadow /etc/sudoers \ + /lib/apk /lib/firmware /lib/modules-load.d /lib/sysctl.d /mnt /home/ /root \ + /srv /media && \ + echo -ne '#!/bin/bash\nexit 0\n' > /usr/bin/sudo && chmod +x /usr/bin/sudo + + + + USER netalertx HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD /usr/local/bin/healthcheck.sh -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +ENTRYPOINT [ "bash", "/entrypoint.sh" ] diff --git a/install/alpine-docker/app/services/nginx/fastcgi_params b/install/alpine-docker/services/config/nginx/fastcgi_params similarity index 100% rename from install/alpine-docker/app/services/nginx/fastcgi_params rename to install/alpine-docker/services/config/nginx/fastcgi_params diff --git a/install/alpine-docker/app/services/nginx/netalertx.conf b/install/alpine-docker/services/config/nginx/netalertx.conf old mode 100755 new mode 100644 similarity index 100% rename from install/alpine-docker/app/services/nginx/netalertx.conf rename to install/alpine-docker/services/config/nginx/netalertx.conf diff --git a/install/alpine-docker/app/services/nginx/nginx.conf b/install/alpine-docker/services/config/nginx/nginx.conf similarity index 97% rename from install/alpine-docker/app/services/nginx/nginx.conf rename to install/alpine-docker/services/config/nginx/nginx.conf index b51d6ea5..862b1b3a 100644 --- a/install/alpine-docker/app/services/nginx/nginx.conf +++ b/install/alpine-docker/services/config/nginx/nginx.conf @@ -1,5 +1,3 @@ -#user nobody; -user netalertx; # Set number of worker processes automatically based on number of CPU cores. worker_processes auto; @@ -95,5 +93,5 @@ http { # Includes virtual hosts configs. - include /app/services/nginx/netalertx.conf; + include /services/config/nginx/netalertx.conf; } diff --git a/install/alpine-docker/services/healthcheck.sh b/install/alpine-docker/services/healthcheck.sh old mode 100644 new mode 100755 diff --git a/install/alpine-docker/services/start-backend.sh b/install/alpine-docker/services/start-backend.sh old mode 100644 new mode 100755 index ee0e0ba7..79c8dc53 --- a/install/alpine-docker/services/start-backend.sh +++ b/install/alpine-docker/services/start-backend.sh @@ -2,6 +2,6 @@ echo "Starting backend..." cd "${NETALERTX_APP}" || exit # Change user to netalertx -export PYTHONPATH="${NETALERTX_SERVER}" +export PYTHONPATH="${NETALERTX_SERVER}:${NETALERTX_APP}" # Start the backend, teeing stdout and stderr to log files and the container's console python3 -m server > >(tee /app/log/stdout.log) 2> >(tee /app/log/stderr.log >&2) diff --git a/install/alpine-docker/services/start-crond.sh b/install/alpine-docker/services/start-crond.sh old mode 100644 new mode 100755 diff --git a/install/alpine-docker/services/start-nginx.sh b/install/alpine-docker/services/start-nginx.sh old mode 100644 new mode 100755 diff --git a/install/alpine-docker/services/start-php-fpm.sh b/install/alpine-docker/services/start-php-fpm.sh old mode 100644 new mode 100755