| Server IP : 146.190.157.162 / Your IP : 216.73.217.6 Web Server : Apache System : Linux ubuntu-s-2vcpu-4gb-amd-sfo3-01-KIT-DIGITAL 6.5.0-44-generic #44-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 7 15:10:09 UTC 2024 x86_64 User : businessweek ( 639) PHP Version : 8.2.10-2ubuntu2.2 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_signal,pcntl_signal_dispatch,pcntl_getpriority,pcntl_setpriority,dl,putenv,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/ |
Upload File : |
#!/bin/bash
# =============================================================
# secure_all_sites.sh
# Verifica y corrige permisos en todos los sitios WordPress
# bajo /var/www/html/ — ignora los que no son WP
# Solo actúa si detecta algo fuera de lugar
# =============================================================
SITE_BASE="/var/www/html"
LOG_FILE="/var/www/html/wordpress-manager-v2/logs/secure_all_sites.log"
BAD_PLUGINS_REGEX="asazysac|javax-|u-short|urshort"
mkdir -p "$(dirname "$LOG_FILE")"
exec > >(tee -a "$LOG_FILE") 2>&1
echo "=============================================="
echo " secure_all_sites.sh"
echo " Inicio: $(date)"
echo " Base: $SITE_BASE"
echo "=============================================="
echo ""
COUNT_FIXED=0
COUNT_OK=0
COUNT_SKIPPED=0
# -------------------------------------------------------------
# Helpers
# -------------------------------------------------------------
is_immutable() {
lsattr "$1" 2>/dev/null | cut -c5 | grep -q 'i'
}
# -------------------------------------------------------------
# Función: verifica si el sitio necesita corrección
# Imprime los problemas encontrados y devuelve 1 si hay alguno
# -------------------------------------------------------------
needs_fix() {
local SITE="$1"
local PROJECT="$2"
local ISSUES=0
# Owner general del sitio
local OWNER
OWNER=$(stat -c '%U:%G' "$SITE" 2>/dev/null)
if [ "$OWNER" != "$PROJECT:$PROJECT" ]; then
echo " [!] Owner incorrecto en raíz ($OWNER)"
ISSUES=1
fi
# Archivos con owner incorrecto (fuera de uploads)
local BAD_OWNER_COUNT
BAD_OWNER_COUNT=$(find "$SITE" ! -user "$PROJECT" 2>/dev/null | grep -v "wp-content/uploads" | wc -l)
if [ "$BAD_OWNER_COUNT" -gt 0 ]; then
echo " [!] $BAD_OWNER_COUNT archivos/dirs con owner incorrecto"
ISSUES=1
fi
# Directorios que no son 755 (fuera de uploads)
local BAD_DIRS
BAD_DIRS=$(find "$SITE" -type d ! -perm 755 2>/dev/null | grep -v "wp-content/uploads" | wc -l)
if [ "$BAD_DIRS" -gt 0 ]; then
echo " [!] $BAD_DIRS directorios sin permiso 755"
ISSUES=1
fi
# Archivos que no son 644 (fuera de uploads)
local BAD_FILES
BAD_FILES=$(find "$SITE" -type f ! -perm 644 2>/dev/null | grep -v "wp-content/uploads" | wc -l)
if [ "$BAD_FILES" -gt 0 ]; then
echo " [!] $BAD_FILES archivos sin permiso 644"
ISSUES=1
fi
# Uploads: group www-data y permisos 775
if [ -d "$SITE/wp-content/uploads" ]; then
local UPLOADS_GROUP
UPLOADS_GROUP=$(stat -c '%G' "$SITE/wp-content/uploads" 2>/dev/null)
if [ "$UPLOADS_GROUP" != "www-data" ]; then
echo " [!] uploads/ group incorrecto ($UPLOADS_GROUP)"
ISSUES=1
fi
local BAD_UPLOADS
BAD_UPLOADS=$(find "$SITE/wp-content/uploads" -type d ! -perm 775 2>/dev/null | wc -l)
if [ "$BAD_UPLOADS" -gt 0 ]; then
echo " [!] uploads/ dirs sin permiso 775"
ISSUES=1
fi
fi
# uploads/.htaccess existe e inmutable
if [ ! -f "$SITE/wp-content/uploads/.htaccess" ]; then
echo " [!] uploads/.htaccess no existe"
ISSUES=1
elif ! is_immutable "$SITE/wp-content/uploads/.htaccess"; then
echo " [!] uploads/.htaccess no es inmutable"
ISSUES=1
fi
# wp-content/.htaccess existe e inmutable
if [ ! -f "$SITE/wp-content/.htaccess" ]; then
echo " [!] wp-content/.htaccess no existe"
ISSUES=1
elif ! is_immutable "$SITE/wp-content/.htaccess"; then
echo " [!] wp-content/.htaccess no es inmutable"
ISSUES=1
fi
# Archivos críticos inmutables
for CRITICAL in "index.php" ".htaccess" "wp-config.php"; do
if [ -f "$SITE/$CRITICAL" ] && ! is_immutable "$SITE/$CRITICAL"; then
echo " [!] $CRITICAL no es inmutable"
ISSUES=1
fi
done
# Plugins sospechosos
if [ -d "$SITE/wp-content/plugins" ]; then
local BAD_PLUGINS
BAD_PLUGINS=$(find "$SITE/wp-content/plugins" -maxdepth 1 \
-regextype posix-extended \
-regex ".*($BAD_PLUGINS_REGEX).*" 2>/dev/null)
if [ -n "$BAD_PLUGINS" ]; then
echo " [!] Plugins sospechosos: $BAD_PLUGINS"
ISSUES=1
fi
fi
return $ISSUES
}
# -------------------------------------------------------------
# Función: aplica el cierre de permisos completo
# -------------------------------------------------------------
secure_site() {
local SITE="$1"
local PROJECT="$2"
chattr -i "$SITE/index.php" "$SITE/.htaccess" "$SITE/wp-config.php" 2>/dev/null
chattr -i "$SITE/wp-content/uploads/.htaccess" 2>/dev/null
chattr -i "$SITE/wp-content/.htaccess" 2>/dev/null
chattr -R -i "$SITE/wp-admin" "$SITE/wp-includes" 2>/dev/null
chattr -i "$SITE"/*.php 2>/dev/null
if [ -d "$SITE/wp-content/plugins" ]; then
find "$SITE/wp-content/plugins" -maxdepth 1 \
-regextype posix-extended \
-regex ".*($BAD_PLUGINS_REGEX).*" \
-exec rm -rf {} + 2>/dev/null
fi
chown -R "$PROJECT":"$PROJECT" "$SITE"
find "$SITE" -type d -exec chmod 755 {} \;
find "$SITE" -type f -exec chmod 644 {} \;
mkdir -p "$SITE/wp-content/uploads"
chgrp -R www-data "$SITE/wp-content/uploads"
chmod -R 775 "$SITE/wp-content/uploads"
printf '<Files *.php>\n deny from all\n</Files>\n' > "$SITE/wp-content/uploads/.htaccess"
chown "$PROJECT":www-data "$SITE/wp-content/uploads/.htaccess"
chmod 644 "$SITE/wp-content/uploads/.htaccess"
chattr +i "$SITE/wp-content/uploads/.htaccess"
printf '<Files *.php>\n deny from all\n</Files>\n' > "$SITE/wp-content/.htaccess"
chown "$PROJECT":"$PROJECT" "$SITE/wp-content/.htaccess"
chmod 644 "$SITE/wp-content/.htaccess"
chattr +i "$SITE/wp-content/.htaccess"
echo '<?php define("WP_USE_THEMES", true); require __DIR__ . "/wp-blog-header.php";' > "$SITE/index.php"
chattr +i "$SITE/index.php"
chattr +i "$SITE/.htaccess" 2>/dev/null
chattr +i "$SITE/wp-config.php"
chattr -R +i "$SITE/wp-admin"
chattr -R +i "$SITE/wp-includes"
chattr +i "$SITE"/*.php 2>/dev/null
}
# -------------------------------------------------------------
# Bucle principal
# -------------------------------------------------------------
for SITE in "$SITE_BASE"/*/; do
PROJECT=$(basename "$SITE")
if [ ! -d "$SITE" ]; then
continue
fi
if [ ! -f "$SITE/wp-config.php" ]; then
echo "[–] IGNORADO → $PROJECT (no es WordPress)"
COUNT_SKIPPED=$((COUNT_SKIPPED + 1))
continue
fi
# Verificar si necesita corrección
FIX_OUTPUT=$(needs_fix "$SITE" "$PROJECT" 2>&1)
if [ $? -ne 0 ]; then
echo "[!] CORRIGIENDO → $PROJECT"
echo "$FIX_OUTPUT"
secure_site "$SITE" "$PROJECT"
echo "[✔] COMPLETADO → $PROJECT"
COUNT_FIXED=$((COUNT_FIXED + 1))
else
echo "[✓] OK → $PROJECT (permisos correctos)"
COUNT_OK=$((COUNT_OK + 1))
fi
done
echo ""
echo "=============================================="
echo " Fin: $(date)"
echo " Resumen:"
echo " ✔ Sitios corregidos : $COUNT_FIXED"
echo " ✓ Sitios ya seguros : $COUNT_OK"
echo " – Sitios ignorados : $COUNT_SKIPPED"
echo "=============================================="