lunes, 3 de noviembre de 2025

WEBPROPv2 (XVII). Tareas de manternimiento (II). Clave SSH. Scripts de mantenimiento (copiar ficheros, arrancar servicios etc)

1. Clave ssh

1.1 Creación de una clave ssh para conectarnos al servidor remoto

Primeramente crearemos una carpeta (aunque no esnecesario). Utilizaremsos el tipo ed25519.  

Se le dará el nombre que queramos en este caso "srv01_ssh_key" y opcionalmente se puede añadir un comentario que se añadirá dicho comentario al final en el fichero de la clave pública. El comentario es: "Clave Srv01"


mkdir -p /home/myuser/keys

ssh-keygen -t ed25519 -f /home/myuser/keys/srv01_ssh_key -C "Clave Srv01"

Se creará una clave privada (srv01_ssh_key) y una clave pública (srv01_ssh_key.pub). Hay que tener cuidado de no compartir la clave privada.

Durante el proceso te pide una contraseña, que debes guardar

1.2. Uso de la clave ssh

Cada vez que ejecutemos un comando por ejemplo

ssh -i /home/myuser/keys/srv01_ssh_key usuario@servidor.com

Nos pedirá la contraseña.

Si queremos conservar la contraseña en memoria en cada conexión :

eval "$(ssh-agent -s)"
ssh-add /home/myuser/keys/srv01_ssh_key


1.3. Copiar la clave pública al servidor remoto

Se puede copiar utilizando ssh-copy-id o cat + ssh

# Si se dispone de ssh-copu-id
ssh-copy-id -i /home/myuser/keys/srv01_ssh_key usuario_remoto@IP_REMOTA

#Sinó
cat /home/myuser/keys/srv01_ssh_key | ssh usuario_remoto@IP_REMOTA "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"


1.4. Ejecutar en el servidor remoto

Podemos ejecutar ssh, scp o rsync usando esta clave:

# 1. ssh
ssh -i /home/myuser/keys/srv01_ssh_key usuario_remoto@IP_REMOTA

# 2. scp
scp -i /home/myuser/keys/srv01_ssh_key archivo usuario_remoto@IP_REMOTA:/ruta/

# 3. rsync
rsync -e "ssh -i /home/myuser/keys/srv01_ssh_key" ...

1.5. Configurar ~/.ssh/config con alias y ruta de la clave par acceder al servidor remoto

Así podemos evitar usar la opción -i. Veamos el fichero ~/.ssh/config:

# Read more about SSH config files: https://linux.die.net/man/5/ssh_config

# Servidor GLI i ara té la web de l'Ajuntament
Host srv01
    HostName IP_REMOTA
    User usuario_remoto
    IdentityFile /home/myuser/keys/srv01_ssh_key
    IdentitiesOnly yes
    Port 22

Y ahora ejecutando

ssh IP_REMOTA 

nos pediará la contraseña de la clave privada y entramos


2. Script de borrar (mover) logs y arrancar servicios remotos. Se ejecuta directamente sobre el servidor remoto

Queremos poder ejecutar los comandos mv, systemctl stop y systemctl restart remotamente, cosa que nos pide que lo hagamos con sudo. Para que no nos pida la contraseña de "sudo" ejecutamos:

sudo visudo

y metemos esta línea

usuario_remoto ALL=(ALL) NOPASSWD: /bin/mv, /bin/systemctl stop *, /bin/systemctl restart *


Con esto ya no nos pedirá la contraseña en estos 3 comandos para el usuario en cuestión.

Después de mucho preguntar al chatgpt, me ha dado muchos problemas el intentar parar servicios remotos. Es por ello que he decidido entrar en una sesión remota y ejecutar directamente esta shell que llama a las demas (una para parar los servicios, otra para mover los logs y otra para rearrancar los servicios)

Ahora, aunque lo ejecutemos en el servidor remot directamente no nos pedirá la contraseña de sudo.

2.1 script de llamada a las demás


SERV.00.sh

#!/bin/bash

# 1. Obtenemos la ruta de la carpeta donde está el script
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 2. Lista de scripts a ejecutar
scripts=(
  "SERV01.Pas1.parar_serveis.sh"
  "SERV02.Pas2.copiar_y_borrar_logs.07.sh"
  "SERV03.Pas3.arrancar_serveis.01.sh"
)

# 3. Ejecución de lso scripts
for s in "${scripts[@]}"; do
  path="$DIR/$s"
  if [[ -f "$path" ]]; then
    echo "Ejecutando $s..."
    bash "$path" || { echo "Error en $s"; exit 1; }
  else
    echo "No encontrado: $path"
  fi
done

2.2 script de parada de los servicios


SERV01.Pas1.parar_serveis.sh
 
#!/bin/bash

# ==============================================================================
# CONFIGURACIÓN
# ==============================================================================

# Lista de patrones de búsqueda (expresiones regulares)
PATRONES_BUSQUEDA="(openr|python_)" 

# ==============================================================================
# PROCESO PRINCIPAL
# ==============================================================================

echo "--- Buscando y rearrancando servicios que coincidan con $PATRONES_BUSQUEDA ---"
echo "--------------------------------------------------------------------------"

# 1. Obtener la lista de servicios activos que coinciden con los patrones.
SERVICIOS=$(systemctl list-unit-files --type=service | grep -E "$PATRONES_BUSQUEDA" | awk '{print $1}')

# 2. Iterar sobre la lista de servicios y reiniciarlos.
if [ -z "$SERVICIOS" ]; then
    echo "ℹ️ No se encontraron servicios activos que comiencen por 'openr' o 'python_'."
else
    for SERVICIO in $SERVICIOS; do
        echo "➡️ Parando servicio: $SERVICIO"
        
        # Ejecutar el comando de reinicio. Se usa 'sudo' porque 'systemctl restart'
        # requiere permisos de superusuario para la mayoría de los servicios.
        sudo systemctl stop "$SERVICIO"
        
        # 3. Verificar el estado (opcional, pero recomendado)
        if [ $? -eq 0 ]; then
            echo "   ✅ $SERVICIO parado con éxito."
        else
            echo "   ❌ Fallo al parar $SERVICIO. Verifique los logs (journalctl)."
        fi
    done
fi

echo "--------------------------------------------------------------------------"
echo "--- Proceso completado ---"

2.3 script de traslado de ficheros logs 


SERV02.Pas2.copiar_y_borrar_logs.07.sh
 
#!/bin/bash

#################################
# DEFINICION DE PARAMETROS
# Ruta al fichero de configuración (puedes modificarla)
#################################
# a. Configuración de openresty
FICHERO="/usr/local/openresty/nginx/conf/nginx.conf"

# b. Define your service name pattern (optional)
SERVICES_BEGIN_WITH='^(openr|python_)'

# c. destino de los logs al copiarse
DESTINO="/home/informatica/mylogs"
#========================================
#  Función: copiar_con_fecha
#  Mueve un fichero al destino, añadiendo timestamp antes de la extensión
#========================================



mover_fichero_con_fecha() {
    local fichero="$1"
    #local destino="/home/informatica/mylogs"

    # Verificar si existe el fichero
    if [[ ! -f "$fichero" ]]; then
        echo "❌ No existe el fichero: $fichero"
        return 1
    fi

    # Crear destino si no existe
    mkdir -p "$DESTINO"

    # Obtener nombre base y extensión
    local nombre_base
    nombre_base=$(basename "$fichero")
    local nombre_sin_ext="${nombre_base%.*}"
    local extension="${nombre_base##*.}"

    # Si no tiene extensión
    if [[ "$nombre_sin_ext" == "$nombre_base" ]]; then
        extension=""
    fi

    # Fecha y hora actual
    local timestamp
    timestamp=$(date +"%Y%m%d_%H%M%S")

    # Crear nuevo nombre con timestamp
    local nuevo_nombre
    if [[ -n "$extension" ]]; then
        nuevo_nombre="${nombre_sin_ext}_${timestamp}.${extension}"
    else
        nuevo_nombre="${nombre_sin_ext}_${timestamp}"
    fi

    # Mover el fichero (usar sudo si no hay permisos)
    if [[ -w "$(dirname "$fichero")" ]]; then
        mv "$fichero" "$DESTINO/$nuevo_nombre"
    else
        echo "Using sudo to move $fichero"
        sudo mv "$fichero" "$DESTINO/$nuevo_nombre"
    fi

    echo "✅ Movido a: $DESTINO/$nuevo_nombre"
}



#========================================
#1. Buscamos los logs de openresty
#========================================
# Ruta al fichero de configuración (puedes modificarla)
#FICHERO="/usr/local/openresty/nginx/conf/nginx.conf"

# Verificar si el fichero existe
if [[ ! -f "$FICHERO" ]]; then
    echo "❌ El fichero no existe: $FICHERO"
    exit 1
fi

# Buscar la línea que contiene "error_log /usr/" y extraer la palabra con "/usr/"
all_log_paths=$(grep "error_log /usr/" "$FICHERO" | grep -oE '[^[:space:]]*/usr/[^[:space:];]*')
all_log_paths+=$'\n'"${all_log_paths/error.log/access.log}"

echo "$all_log_paths"

#==================================================================
#2. Añdimos los logs de los servicios que comienzan por "python_"
#==================================================================

# Define your service name pattern (optional)
#SERVICES_BEGIN_WITH='^(openr|python_)'

# Iterate over matching services
for service in $(systemctl list-unit-files --type=service | awk '{print $1}' | grep -E "$SERVICES_BEGIN_WITH"); do
    echo "Service: $service"

    # Extract relevant lines
    current_logs=$(systemctl cat "$service" 2>/dev/null | \
                   grep -E '(StandardOutput|StandardError|SyslogIdentifier)' )

    if [ -n "$current_logs" ]; then
        echo "Current_logs: $current_logs"

		for log_file in $current_logs; do
			# Append only the extracted values (after ":")
			#echo "log_file: $log_file"
			all_log_paths+=$'\n'"${log_file#*:}"
		done	
    fi

    #echo "Journal logs: journalctl -u $service"
    #echo "---"
done

echo "$all_log_paths"

#==================================================================
#3.Movemos los ficheros a la carpeta $DESTINO
#==================================================================
for fichero in $all_log_paths; do if [[ -n "$fichero" && -e "$fichero" ]]; then #if [[ -w "$fichero" ]]; then # rm -f "$fichero" #else # echo "Using sudo to remove $fichero" # sudo rm -f "$fichero" mover_fichero_con_fecha "$fichero" else echo "File not found or variable empty: $fichero" fi done

2.4 script para rearrancar los servicios


SERV03.Pas3.arrancar_serveis.01.sh

#!/bin/bash

# ==============================================================================
# CONFIGURACIÓN
# ==============================================================================

# Lista de patrones de búsqueda (expresiones regulares)
PATRONES_BUSQUEDA="(openr|python_)" 

# ==============================================================================
# PROCESO PRINCIPAL
# ==============================================================================

echo "--- Buscando y rearrancando servicios que coincidan con $PATRONES_BUSQUEDA ---"
echo "--------------------------------------------------------------------------"

# 1. Obtener la lista de servicios activos que coinciden con los patrones.
SERVICIOS=$(systemctl list-unit-files --type=service | grep -E "$PATRONES_BUSQUEDA" | awk '{print $1}')
echo "$SERVICIOS"
# 2. Iterar sobre la lista de servicios y reiniciarlos.
if [ -z "$SERVICIOS" ]; then
    echo "ℹ️ No se encontraron servicios activos que comiencen por 'openr' o 'python_'."
else
    for SERVICIO in $SERVICIOS; do
        echo "➡️ Rearrancando servicio: $SERVICIO"
        
        # Ejecutar el comando de reinicio. Se usa 'sudo' porque 'systemctl restart'
        # requiere permisos de superusuario para la mayoría de los servicios.
        sudo systemctl restart "$SERVICIO"
        
        # 3. Verificar el estado (opcional, pero recomendado)
        if [ $? -eq 0 ]; then
            echo "   ✅ $SERVICIO rearrancado con éxito."
        else
            echo "   ❌ Fallo al rearrancar $SERVICIO. Verifique los logs (journalctl)."
        fi
    done
fi

echo "--------------------------------------------------------------------------"
echo "--- Proceso completado ---"



3. Script que se ejecuta en cliente para copiar los programas al servidor

Hay que tener en cuenta que para poder ejecutar este script tenemos que entrar en sudo visudo y asegurarnos que tiene la línea del usuario para que no pida la contraseña en el comando mv.

CLI00.TOT.Copiar_a_WEBPROP.sh

#!/usr/bin/env bash
# ============================================================
# Copiar TODAS las subcarpetas de un directorio al servidor remoto 192.168.28.16
# EXCEPTO algunas, usando usuario, contraseña e IP (sin clave SSH)
# ============================================================

# Uso:
# ./Copiar_a_WEBPROP.sh /carpeta/local /ruta/remota IP usuario contraseña "carpeta1 carpeta2 ..." [puerto]
# Ejemplo:
# ./copiar_subcarpetas_excluyendo.sh /home/eduard/proyectos /home/juan/backups 192.168.1.100 juan MiPass123 "temp logs node_modules" 22

LOCAL_DIR="/home/ximo/MyPython/versio.02/softprop"
REMOTE_DIR="/home/informatica/eduApps/softprop"
REMOTE_IP="192.XXX.XXX.XXX"
REMOTE_USER="miusuario"
REMOTE_PASS="mipassword"
EXCLUDE_LIST=".pytest_cache .vscode 01_provetes utilitats_varies"    # lista separada por espacios
REMOTE_PORT="${7:-22}"


# Definimos una función para copiar entre carpetas remotas
# ==========================================
# FUNCION PARA COPIAR FICHEROS ENTRE CARPETAS REMOTAS
# ==========================================
copiar_remoto() {
    local origen="$1"
    local destino="$2"

    echo "➡️  Copiando en remoto: $origen$destino"

    # Ejecuta copia remota vía SSH
    #sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" \
    #    "sudo cp -f \"$origen\" \"$destino\" && echo '✅ Copiado: $destino' || echo '❌ Error copiando $origen'"

	sshpass -p "$REMOTE_PASS" ssh -T "$REMOTE_USER@$REMOTE_IP" "sudo cp -f \"$origen\" \"$destino\" && echo '✅ Copiado: $destino' || echo '❌ Error copiando $origen'"
}




# Verifica parámetros
#if [[ -z "$LOCAL_DIR" || -z "$REMOTE_DIR" || -z "$REMOTE_IP" || -z "$REMOTE_USER" || -z "$REMOTE_PASS" ]]; then
#    echo "Uso: $0 /carpeta/local /ruta/remota IP usuario contraseña \"excluir1 excluir2 ...\" [puerto]"
#    exit 1
#fi

# Comprueba dependencias
for cmd in sshpass rsync; do
    if ! command -v $cmd >/dev/null 2>&1; then
        echo "Instalando $cmd..."
        sudo apt update && sudo apt install -y $cmd
    fi
done

# Construye lista de exclusiones para rsync
EXCLUDE_ARGS=()
if [[ -n "$EXCLUDE_LIST" ]]; then
    for folder in $EXCLUDE_LIST; do
        EXCLUDE_ARGS+=(--exclude="$folder/")
    done
fi

echo "🚀 Iniciando copia desde $LOCAL_DIR$REMOTE_USER@$REMOTE_IP:$REMOTE_DIR"
echo "Excluyendo: $EXCLUDE_LIST"
echo "==========================================================="

# Copia todas las subcarpetas excepto las excluidas
sshpass -p "$REMOTE_PASS" rsync -avz --progress \
    -e "ssh -p $REMOTE_PORT -o StrictHostKeyChecking=no" \
    "${EXCLUDE_ARGS[@]}" \
    "$LOCAL_DIR/" "${REMOTE_USER}@${REMOTE_IP}:$REMOTE_DIR"

if [[ $? -eq 0 ]]; then
    echo "✅ Copia completada correctamente."
else
    echo "❌ Error al copiar carpetas."
    exit 2
fi


# Ahora copiamos los ficheros a su lugar:
EXPORTACIO="$REMOTE_DIR/_exportacio"
copiar_remoto "$EXPORTACIO/authentication/xmopenresty.py" \
              "$REMOTE_DIR/authentication/xmopenresty.py"

copiar_remoto "$EXPORTACIO/menus/mnu_main.py" \
              "$REMOTE_DIR/menus/mnu_main.py"

copiar_remoto "$EXPORTACIO/openresty/v04/nginx.conf" \
              "/usr/local/openresty/nginx/conf/nginx.conf"

echo "✅ Todas las copias han finalizado."




No hay comentarios :

Publicar un comentario