#!/usr/bin/env bash # # JbTecWiz Support Centre -- generated fix script # # Fault : nginx 502 Bad Gateway # Fix : Fix the socket permissions # Source: https://jbtecwiz.com/support/lnx-web-502 # # Run as : Root shell # Expect : 20 minutes # Risk : medium # Reversible : yes # # WHEN THIS IS THE RIGHT FIX # The log says permission denied on a socket path. # # HOW TO UNDO IT # Restore the previous pool configuration from a backup copy. # # Walks the fix one step at a time and asks before each. Steps with no # command are yours to do -- it prints those and waits. DRYRUN=1 prints # without executing; UNATTENDED=1 does not ask. # # -------------------------------------------------------------------- # NO WARRANTY - USE AT YOUR OWN RISK # # This script is provided by JbTecWiz as-is and with no warranty of any # kind, express or implied. You run it entirely at your own risk. # # JbTecWiz accepts no liability for any loss or damage arising from its # use, including but not limited to data loss, downtime, or configuration # changes that turn out to be wrong for your system. # # You are responsible for reading this script before running it, for # satisfying yourself that it suits the machine in front of you, and for # having a working backup first. Some steps cannot be undone. # -------------------------------------------------------------------- set -uo pipefail DRYRUN="${DRYRUN:-0}" UNATTENDED="${UNATTENDED:-0}" failed=0 if [ "$(id -u)" -ne 0 ]; then echo " This fix is documented as needing root. Re-run with sudo." >&2 exit 3 fi rule() { printf "\n%s\n" "$(printf '-%.0s' $(seq 1 70))"; if [ $# -gt 0 ]; then echo "$1"; fi; } prose() { echo "$1" | fold -s -w 74 | sed "s/^/ /"; } # Returns 0 when the caller should run the command, 1 when it should not. # A manual step always returns 1 -- there is nothing for the caller to run. step() { # step [command lines...] local n="$1" dotext="$2" why="$3" mode="$4"; shift 4 rule " Step $n of 4" prose "$dotext" if [ -n "$why" ]; then echo; prose "$why"; fi if [ "$mode" = "manual" ]; then echo; echo " -> Do this yourself, then press Enter to carry on." if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r _; fi return 1 fi echo; printf " %s\n" "$@"; echo if [ "$DRYRUN" = "1" ]; then echo " (dry run -- not executed)"; return 1; fi if [ "$UNATTENDED" = "0" ]; then read -r -p " Run this step? [Y]es / [S]kip / [Q]uit " a case "$a" in [Qq]*) echo " Stopped at your request."; exit 0 ;; [Ss]*) echo " Skipped."; return 1 ;; esac fi return 0 } rule echo " nginx 502 Bad Gateway" echo " Fix the socket permissions" echo echo " Risk: medium Reversible 20 minutes" echo prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' rule echo if [ "$UNATTENDED" = "0" ] && [ "$DRYRUN" = "0" ]; then read -r -p " Ready? [y/N] " go case "$go" in [Yy]*) ;; *) echo " Nothing was changed."; exit 0;; esac fi if step 1 'Look at the socket and who owns it.' '' cmd 'ls -l /run/php/php8.2-fpm.sock' 'id www-data' 'ps -o user= -C nginx | sort -u'; then ls -l /run/php/php8.2-fpm.sock id www-data ps -o user= -C nginx | sort -u if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 1 failed. The rest of the fix may depend on it." >&2 fi fi if step 2 'Set the pool'\''s socket ownership to the user nginx runs as.' 'The socket is created by php-fpm with the ownership in its pool configuration. Changing the permissions by hand works until the next restart recreates it, which is why this fault appears to come back on its own.' cmd 'sudo sed -i '\''s/^;*listen.owner.*/listen.owner = www-data/; s/^;*listen.group.*/listen.group = www-data/; s/^;*listen.mode.*/listen.mode = 0660/'\'' /etc/php/8.2/fpm/pool.d/www.conf' 'sudo systemctl restart php8.2-fpm'; then sudo sed -i 's/^;*listen.owner.*/listen.owner = www-data/; s/^;*listen.group.*/listen.group = www-data/; s/^;*listen.mode.*/listen.mode = 0660/' /etc/php/8.2/fpm/pool.d/www.conf sudo systemctl restart php8.2-fpm if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 2 failed. The rest of the fix may depend on it." >&2 fi fi if step 3 'On a system with SELinux, check for a denial before assuming it is Unix permissions.' '' cmd 'sudo ausearch -m avc -ts recent | grep -i nginx | tail -20' 'sudo setsebool -P httpd_can_network_connect 1'; then sudo ausearch -m avc -ts recent | grep -i nginx | tail -20 sudo setsebool -P httpd_can_network_connect 1 if [ $? -ne 0 ]; then failed=$((failed+1)) echo " Step 3 failed. The rest of the fix may depend on it." >&2 fi fi step 4 'Check the directory permissions too -- nginx needs execute on every directory in the socket'\''s path.' '' manual || true rule " Confirm it worked" prose 'The socket is readable by the nginx user and requests succeed.' if [ "$DRYRUN" = "0" ]; then sudo -u www-data test -w /run/php/php8.2-fpm.sock && echo writable fi rule if [ "$failed" -gt 0 ]; then echo " Finished with $failed failed step(s)." echo " Read the full write-up at https://jbtecwiz.com/support/lnx-web-502" else echo " Finished." fi echo prose 'To undo: Restore the previous pool configuration from a backup copy.' rule