Linux Debian/Ubuntu para Homelab: Guía Completa 2025

Robot punk usando terminal Linux Debian Ubuntu comandos servidor homelab 2025

Introducción: Linux es el sistema operativo del homelab

Si vas en serio con homelab, Docker, Proxmox, Home Assistant, n8n o cualquier servidor self-hosted, tarde o temprano necesitas dominar Linux. El 90% de las guías técnicas asumen que sabes usar terminal, y sin ese conocimiento estás bloqueado.

Esta guía te lleva de cero a operativo en Debian/Ubuntu: instalación rápida, terminal esencial, gestión de servicios, redes, SSH, troubleshooting y automatización. Todo lo que necesitas para seguir cualquier tutorial avanzado sin perderte.

💡 Por qué esta guía se enfoca en Debian/Ubuntu:

  • Debian: Súper estable, base de Proxmox, usado en servidores de producción
  • Ubuntu Server: LTS con 5 años de soporte, mayor comunidad, más fácil para empezar
  • 70%+ de homelabs usan Debian o Ubuntu
  • apt (gestor de paquetes) es universal en ambos
  • Documentación masiva: Cualquier problema ya está resuelto en Stack Overflow

Olvidamos: RedHat/CentOS (dnf), Arch (pacman), openSUSE (zypper). Son excelentes, pero alargaríamos esta guía a 15,000 palabras.

Instalación rápida: Ubuntu Server 24.04 LTS

Hardware mínimo: 2GB RAM, 25GB disco, CPU 64-bit. Funciona en Raspberry Pi 4, VM Proxmox, VPS, servidor físico.

Pasos esenciales

  1. Descargar ISO: ubuntu.com/download/server (Ubuntu Server 24.04 LTS)
  2. Crear USB booteable: Rufus (Windows), Balena Etcher (multi-plataforma), o dd (Linux)
  3. Bootear desde USB → Installer automático aparece
  4. Configuración clave durante instalación:
    • Language: English (recomendado, mejor documentación) o Español
    • Network: DHCP automático (o configurar IP estática si prefieres)
    • Storage: Use entire disk (simple) o Custom si quieres LVM/RAID
    • Profile: Nombre, usuario, contraseña fuerte, hostname (homelab, servidor, etc.)
    • SSH:Install OpenSSH server (CRÍTICO, permite acceso remoto)
    • Snaps: Opcional (Docker, Nextcloud, etc. – puedes instalar después manualmente)
  5. Reboot → Quitar USB → Login con usuario/password

Primera conexión SSH desde otro PC:

# Desde Windows (PowerShell), Mac o Linux:
ssh usuario@192.168.1.100

# Aceptar fingerprint (primera vez): yes
# Ingresar password
# ¡Ya estás dentro! 🎉
⚡ Si instalas en VM Proxmox o VirtualBox:

Sigue los pasos normales del instalador. Para SSH necesitarás la IP de la VM (ip a dentro de la VM para verla).

Terminal básico: Comandos de supervivencia

Navegación del sistema de archivos

# Ver directorio actual (Print Working Directory)
pwd

# Listar archivos
ls                    # Básico
ls -l                 # Lista detallada (permisos, tamaño, fecha)
ls -lh                # Tamaños legibles (KB, MB, GB)
ls -la                # Incluir archivos ocultos (empiezan con .)
ls -lt                # Ordenar por fecha modificación (más reciente primero)

# Cambiar directorio
cd /home/usuario      # Ir a directorio específico
cd ..                 # Subir un nivel
cd ~                  # Ir a tu home (/home/usuario)
cd -                  # Volver al directorio anterior

# Crear directorio
mkdir proyectos
mkdir -p docker/stacks/media    # Crear directorios padres automáticamente

# Copiar archivos/directorios
cp archivo.txt backup.txt
cp -r directorio/ backup_directorio/    # -r = recursivo (para directorios)

# Mover/renombrar
mv archivo_viejo.txt archivo_nuevo.txt
mv archivo.txt /home/usuario/documentos/

# Eliminar (CUIDADO: no hay papelera de reciclaje)
rm archivo.txt
rm -r directorio/     # Eliminar directorio y contenido
rm -rf directorio/    # Forzar eliminación sin confirmar (PELIGROSO)

# Ver contenido de archivo
cat archivo.txt       # Todo el archivo
less archivo.txt      # Ver con scroll (q para salir)
head archivo.txt      # Primeras 10 líneas
head -n 20 archivo.txt    # Primeras 20 líneas
tail archivo.txt      # Últimas 10 líneas
tail -f /var/log/syslog   # Ver archivo en tiempo real (logs)

Permisos: el concepto MÁS importante de Linux

Todo en Linux tiene permisos: archivos, directorios, scripts. Sin entender esto, te encontrarás con «Permission denied» constantemente.

Ver permisos:

ls -l archivo.sh

# Salida ejemplo:
# -rwxr-xr-x 1 usuario grupo 1234 Oct 10 15:30 archivo.sh
#  ↑↑↑↑↑↑↑↑↑
#  |||||||└─ Otros: r-x (leer, ejecutar)
#  ||||||└── Grupo: r-x (leer, ejecutar)
#  |||||└─── Usuario: rwx (leer, escribir, ejecutar)
#  ||||└──── Número de links
#  |||└───── Propietario (usuario)
#  ||└────── Grupo
#  |└─────── Tamaño (bytes)
#  └──────── - = archivo, d = directorio, l = link

Cambiar permisos con chmod:

# Método numérico (más común):
# r (read) = 4, w (write) = 2, x (execute) = 1
# Usuario - Grupo - Otros

chmod 755 script.sh
# 7 (usuario: rwx = 4+2+1)
# 5 (grupo: r-x = 4+0+1)
# 5 (otros: r-x = 4+0+1)
# Resultado: Usuario puede todo, grupo y otros solo leer/ejecutar

chmod 644 archivo.txt
# Usuario: rw- (6 = 4+2)
# Grupo: r-- (4)
# Otros: r-- (4)
# Archivo de texto normal: solo owner puede modificar

chmod 600 ~/.ssh/id_rsa
# Solo usuario puede leer/escribir (SSH keys privadas DEBEN ser 600)

# Hacer script ejecutable (método rápido):
chmod +x script.sh

# Recursivo (aplicar a todo dentro de directorio):
chmod -R 755 /var/www/html/

Cambiar propietario con chown:

# Cambiar owner
sudo chown usuario archivo.txt

# Cambiar owner y grupo
sudo chown usuario:grupo archivo.txt

# Recursivo
sudo chown -R usuario:grupo /var/www/html/

# Caso común: Docker volúmenes con permisos incorrectos
sudo chown -R 1000:1000 ~/docker/data/nextcloud/
🔑 Regla de oro de permisos:

  • Archivos normales: 644 (rw-r–r–)
  • Scripts ejecutables: 755 (rwxr-xr-x)
  • Directorios: 755 (rwxr-xr-x)
  • SSH keys privadas: 600 (rw——-)
  • Archivos de configuración sensibles: 600

Editar archivos: nano (el más fácil)

# Abrir/crear archivo
nano archivo.txt

# Atajos esenciales (aparecen abajo, ^ = Ctrl):
# Ctrl+O → Guardar (Write Out)
# Enter  → Confirmar nombre archivo
# Ctrl+X → Salir
# Ctrl+K → Cortar línea
# Ctrl+U → Pegar
# Ctrl+W → Buscar
# Ctrl+\ → Buscar y reemplazar

# Editar archivo de sistema (requiere sudo):
sudo nano /etc/hosts

Alternativa: vim (más potente pero curva de aprendizaje):

# Abrir archivo
vim archivo.txt

# Modos:
# - Modo Normal (default): navegación
# - Modo Insert: presionar 'i' para empezar a escribir
# - Modo Command: presionar Esc + ':'

# Comandos básicos:
i          # Entrar modo Insert
Esc        # Volver a modo Normal
:w         # Guardar (write)
:q         # Salir (quit)
:wq        # Guardar y salir
:q!        # Salir sin guardar (forzar)

# Si te quedas atascado en vim: Esc + :q!

Gestión de procesos

# Ver procesos en tiempo real (mejor que top)
htop    # Si no está instalado: sudo apt install htop

# Dentro de htop:
# F3 = Buscar proceso
# F9 = Matar proceso
# F10 = Salir

# Ver todos los procesos
ps aux

# Buscar proceso específico
ps aux | grep nginx

# Matar proceso por PID
kill 1234        # SIGTERM (graceful)
kill -9 1234     # SIGKILL (forzar, usar solo si SIGTERM falla)

# Matar por nombre
pkill nginx
killall nginx

# Ver uso de CPU/RAM de proceso
top -p 1234

Espacio en disco

# Ver espacio en discos montados
df -h

# Ver tamaño de directorios
du -sh /var/log/
du -sh /home/usuario/*

# Top 10 directorios más grandes
du -sh /* | sort -rh | head -10

# Ver inodos (si disk full pero df muestra espacio libre)
df -i

Gestión de paquetes con apt

apt es el gestor de paquetes de Debian/Ubuntu. Instala, actualiza y elimina software.

Comandos esenciales

# Actualizar lista de paquetes disponibles (SIEMPRE primero)
sudo apt update

# Actualizar todos los paquetes instalados
sudo apt upgrade

# Actualizar sistema completo (incluye cambios de dependencias)
sudo apt dist-upgrade

# Instalar paquete
sudo apt install nginx

# Instalar múltiples
sudo apt install docker.io docker-compose curl git htop

# Eliminar paquete
sudo apt remove nginx

# Eliminar paquete + archivos de configuración
sudo apt purge nginx

# Eliminar paquetes huérfanos (ya no necesarios)
sudo apt autoremove

# Buscar paquete
apt search docker

# Ver info de paquete
apt show docker.io

# Ver qué archivos instaló un paquete
dpkg -L nginx

# Ver qué paquete instaló un archivo
dpkg -S /usr/bin/nginx

Repositorios adicionales

A veces necesitas software que no está en repos oficiales.

# Ejemplo: Añadir repo de Docker oficial
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

# Ver repositorios activos
ls /etc/apt/sources.list.d/
cat /etc/apt/sources.list

Servicios con systemd

systemd gestiona servicios (daemons) en Linux moderno. Controla qué corre, cuándo arranca, logs, etc.

Comandos systemctl

# Ver estado de servicio
sudo systemctl status nginx

# Iniciar servicio
sudo systemctl start nginx

# Parar servicio
sudo systemctl stop nginx

# Reiniciar servicio
sudo systemctl restart nginx

# Recargar configuración sin reiniciar (si servicio lo soporta)
sudo systemctl reload nginx

# Habilitar arranque automático (boot)
sudo systemctl enable nginx

# Deshabilitar arranque automático
sudo systemctl disable nginx

# Ver si servicio está habilitado
systemctl is-enabled nginx

# Ver si servicio está corriendo
systemctl is-active nginx

# Listar todos los servicios
systemctl list-units --type=service

# Listar solo servicios corriendo
systemctl list-units --type=service --state=running

# Listar servicios fallidos
systemctl --failed

Logs de servicios (journalctl)

# Ver logs de servicio
sudo journalctl -u nginx

# Últimas 50 líneas
sudo journalctl -u nginx -n 50

# Logs en tiempo real (como tail -f)
sudo journalctl -u nginx -f

# Logs desde arranque actual
sudo journalctl -u nginx -b

# Logs desde fecha específica
sudo journalctl -u nginx --since "2025-10-10 14:00:00"

# Últimas 2 horas
sudo journalctl -u nginx --since "2 hours ago"

# Ver logs de todo el sistema
sudo journalctl

# Limpiar logs antiguos (liberar espacio)
sudo journalctl --vacuum-time=7d    # Mantener solo 7 días
sudo journalctl --vacuum-size=500M  # Mantener máximo 500MB

Crear servicio personalizado

Ejemplo: Script Python que corre como servicio

1. Crear script (/home/usuario/mi_app.py):

#!/usr/bin/env python3
import time
while True:
    print("App corriendo...")
    time.sleep(60)

2. Crear servicio (/etc/systemd/system/mi-app.service):

[Unit]
Description=Mi aplicación Python
After=network.target

[Service]
Type=simple
User=usuario
WorkingDirectory=/home/usuario
ExecStart=/usr/bin/python3 /home/usuario/mi_app.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

3. Activar servicio:

sudo systemctl daemon-reload
sudo systemctl enable mi-app
sudo systemctl start mi-app
sudo systemctl status mi-app

Redes: Configuración y diagnóstico

Ver configuración de red

# Ver interfaces y IPs (comando moderno)
ip a

# Ver solo IPs activas
ip -br a

# Ver tabla de routing
ip route

# Ver gateway por defecto
ip route show default

# Ver conexiones activas
ss -tulpn

# Alternativa antigua (deprecated pero aún funciona):
ifconfig
netstat -tulpn

Configurar IP estática

Ubuntu 20.04+ usa Netplan:

# Editar configuración
sudo nano /etc/netplan/00-installer-config.yaml

# Contenido ejemplo (IP estática):
network:
  version: 2
  ethernets:
    enp0s3:    # Nombre de tu interfaz (verificar con 'ip a')
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 1.1.1.1

# Aplicar cambios
sudo netplan apply

# Si hay error, ver qué falla:
sudo netplan --debug apply

Debian (sin Netplan, usa /etc/network/interfaces):

sudo nano /etc/network/interfaces

# Contenido:
auto enp0s3
iface enp0s3 inet static
  address 192.168.1.100
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-nameservers 8.8.8.8 1.1.1.1

# Reiniciar networking
sudo systemctl restart networking

Diagnóstico de red

# Test conectividad IP
ping 8.8.8.8

# Test DNS
ping google.com

# Ver ruta de paquetes
traceroute google.com

# Test puerto específico
telnet 192.168.1.1 80
# O mejor (si telnet no está instalado):
nc -zv 192.168.1.1 80

# Ver qué proceso usa puerto
sudo ss -tulpn | grep :80
sudo lsof -i :80

# Escanear puertos abiertos en servidor remoto (requiere nmap)
sudo apt install nmap
nmap 192.168.1.100

SSH: Acceso remoto seguro

Configuración básica servidor SSH

# Instalar (si no está)
sudo apt install openssh-server

# Verificar que corre
sudo systemctl status ssh

# Archivo de configuración principal
sudo nano /etc/ssh/sshd_config

# Cambios recomendados:
Port 22                    # Cambiar a otro (ej: 2222) para seguridad
PermitRootLogin no         # No permitir login como root
PasswordAuthentication yes # Después cambiar a 'no' cuando uses keys
PubkeyAuthentication yes   # Permitir login con SSH keys

# Reiniciar SSH después de cambios
sudo systemctl restart ssh

SSH Keys (autenticación sin contraseña)

1. Generar par de keys en tu PC local (no en servidor):

# En tu laptop/desktop (Windows/Mac/Linux)
ssh-keygen -t ed25519 -C "tu_email@example.com"

# Pregunta dónde guardar: Enter (default: ~/.ssh/id_ed25519)
# Passphrase (opcional pero recomendado): ingresar o dejar vacío

# Resultado:
# ~/.ssh/id_ed25519      ← Clave PRIVADA (NUNCA compartir)
# ~/.ssh/id_ed25519.pub  ← Clave PÚBLICA (esta sí se comparte)

2. Copiar clave pública al servidor:

# Método automático (más fácil):
ssh-copy-id usuario@192.168.1.100

# Método manual:
cat ~/.ssh/id_ed25519.pub | ssh usuario@192.168.1.100 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# Desde Windows (PowerShell):
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh usuario@192.168.1.100 "cat >> ~/.ssh/authorized_keys"

3. Probar login sin contraseña:

ssh usuario@192.168.1.100
# Si configuraste passphrase en key, la pregunta. Sino, login directo.

4. Deshabilitar password login (máxima seguridad):

sudo nano /etc/ssh/sshd_config

# Cambiar:
PasswordAuthentication no

sudo systemctl restart ssh

Copiar archivos con SCP y rsync

# SCP (simple copy)
# Local → Remoto
scp archivo.txt usuario@192.168.1.100:/home/usuario/

# Remoto → Local
scp usuario@192.168.1.100:/home/usuario/archivo.txt .

# Directorio completo (recursivo)
scp -r directorio/ usuario@192.168.1.100:/home/usuario/

# rsync (mejor para archivos grandes, resume si falla)
# Local → Remoto
rsync -avz archivo.txt usuario@192.168.1.100:/home/usuario/

# Directorio con progress bar
rsync -avzP directorio/ usuario@192.168.1.100:/home/usuario/directorio/

# Flags:
# -a = archive (preserva permisos, timestamps)
# -v = verbose
# -z = compress
# -P = progress + partial (resume si falla)

Usuarios y grupos

# Crear usuario
sudo adduser nuevo_usuario
# Sigue wizard: password, nombre completo, etc.

# Crear usuario sin wizard (avanzado)
sudo useradd -m -s /bin/bash nuevo_usuario
sudo passwd nuevo_usuario

# Eliminar usuario
sudo deluser usuario
sudo deluser --remove-home usuario    # Eliminar también /home/usuario

# Añadir usuario a grupo
sudo usermod -aG docker usuario
# -aG = append to group (no sobrescribe otros grupos)

# Ver grupos de usuario
groups usuario

# Cambiar password
passwd              # Tu propio password
sudo passwd usuario # Password de otro usuario

# Cambiar a otro usuario
su - usuario
# Volver a tu usuario: exit

# Ejecutar comando como otro usuario
sudo -u usuario comando

# Permitir sudo sin password (CUIDADO, solo para users confiables)
sudo visudo
# Añadir al final:
usuario ALL=(ALL) NOPASSWD:ALL

Firewall con UFW

UFW (Uncomplicated Firewall) simplifica iptables. Esencial para servidores expuestos a internet.

# Instalar (viene preinstalado en Ubuntu)
sudo apt install ufw

# Ver estado
sudo ufw status

# Habilitar firewall (IMPORTANTE: permitir SSH primero o te bloqueas)
sudo ufw allow 22/tcp
sudo ufw enable

# Permitir servicios comunes
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw allow 8123/tcp    # Home Assistant
sudo ufw allow 9090/tcp    # Prometheus

# Permitir rango de puertos
sudo ufw allow 6000:6100/tcp

# Permitir desde IP específica
sudo ufw allow from 192.168.1.0/24

# Permitir SSH solo desde tu red local
sudo ufw allow from 192.168.1.0/24 to any port 22

# Denegar puerto
sudo ufw deny 23/tcp

# Ver reglas numeradas
sudo ufw status numbered

# Eliminar regla por número
sudo ufw delete 3

# Eliminar regla por descripción
sudo ufw delete allow 8080/tcp

# Resetear firewall (eliminar todas las reglas)
sudo ufw reset

# Deshabilitar firewall
sudo ufw disable
⚠️ CUIDADO al habilitar UFW en SSH remoto:

Si habilitas UFW sin permitir puerto SSH primero, te bloquearás y perderás acceso. SIEMPRE ejecutar sudo ufw allow 22/tcp ANTES de sudo ufw enable.

Cron: Tareas programadas

Cron ejecuta comandos automáticamente en horarios específicos. Ideal para backups, limpieza, actualizaciones.

Sintaxis cron

# Formato:
# ┌───────────── minuto (0-59)
# │ ┌───────────── hora (0-23)
# │ │ ┌───────────── día del mes (1-31)
# │ │ │ ┌───────────── mes (1-12)
# │ │ │ │ ┌───────────── día de la semana (0-7, 0 y 7 = domingo)
# │ │ │ │ │
# * * * * * comando_a_ejecutar

# Ejemplos:
30 2 * * *     # Cada día a las 02:30
0 */6 * * *    # Cada 6 horas
0 9 * * 1      # Cada lunes a las 09:00
0 0 1 * *      # Primer día de cada mes a medianoche
*/15 * * * *   # Cada 15 minutos

Gestionar crontab

# Editar crontab de tu usuario
crontab -e
# Primera vez pregunta editor: elige nano (opción 1)

# Ver crontab actual
crontab -l

# Eliminar crontab completo
crontab -r

# Editar crontab de otro usuario (como root)
sudo crontab -u usuario -e

Ejemplos prácticos

# Backup diario de directorio a las 3am
0 3 * * * tar -czf /backups/home-$(date +\%Y\%m\%d).tar.gz /home/usuario/

# Limpiar logs antiguos cada domingo a medianoche
0 0 * * 0 find /var/log/ -name "*.log" -mtime +30 -delete

# Actualizar sistema cada lunes a las 4am
0 4 * * 1 apt update && apt upgrade -y

# Reiniciar servicio cada día a las 5am
0 5 * * * systemctl restart mi-servicio

# Ejecutar script Python cada hora
0 * * * * /usr/bin/python3 /home/usuario/script.py

# Logs de cron (para debugging):
# Añadir redirección al final de comando:
0 3 * * * /home/usuario/backup.sh >> /var/log/mi-backup.log 2>&1
💡 Tips cron:

  • Usa rutas absolutas (/usr/bin/python3 no python3)
  • Cron usa PATH limitado, especifica paths completos
  • Redirige output a log para debugging: comando >> /var/log/cron.log 2>&1
  • Test tu comando manualmente antes de añadir a cron
  • Para tareas complejas, crea script y llámalo desde cron

Scripts Bash básicos

Bash scripts automatizan secuencias de comandos. Esencial para backups, deployments, mantenimiento.

Estructura básica

#!/bin/bash
# Shebang: indica que es script bash

# Variables
NOMBRE="Mundo"
FECHA=$(date +%Y-%m-%d)

# Echo (imprimir)
echo "Hola $NOMBRE"
echo "Hoy es $FECHA"

# Condicionales
if [ -f "/etc/hosts" ]; then
    echo "Archivo existe"
else
    echo "Archivo no existe"
fi

# Loop archivos
for archivo in /var/log/*.log; do
    echo "Procesando $archivo"
done

# Loop numérico
for i in {1..5}; do
    echo "Iteración $i"
done

# While loop
CONTADOR=1
while [ $CONTADOR -le 5 ]; do
    echo "Contador: $CONTADOR"
    CONTADOR=$((CONTADOR + 1))
done

# Funciones
mi_funcion() {
    echo "Argumentos recibidos: $1 $2"
}

mi_funcion "arg1" "arg2"

Ejemplo práctico: Script backup

#!/bin/bash

# Script de backup con rotación de archivos antiguos

BACKUP_DIR="/backups"
SOURCE_DIR="/home/usuario/datos"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.tar.gz"

# Crear directorio de backups si no existe
mkdir -p "$BACKUP_DIR"

# Verificar que source existe
if [ ! -d "$SOURCE_DIR" ]; then
    echo "ERROR: Directorio $SOURCE_DIR no existe"
    exit 1
fi

# Crear backup
echo "Iniciando backup de $SOURCE_DIR..."
tar -czf "$BACKUP_FILE" "$SOURCE_DIR"

if [ $? -eq 0 ]; then
    echo "✅ Backup completado: $BACKUP_FILE"
else
    echo "❌ Error en backup"
    exit 1
fi

# Eliminar backups antiguos (mantener últimos 7)
echo "Limpiando backups antiguos..."
cd "$BACKUP_DIR"
ls -t backup_*.tar.gz | tail -n +8 | xargs -r rm

echo "Backups actuales:"
ls -lh backup_*.tar.gz

echo "✅ Proceso completado"

Hacer ejecutable y usar:

chmod +x backup.sh
./backup.sh

# Añadir a cron (diario a las 3am):
# crontab -e
# 0 3 * * * /home/usuario/backup.sh >> /var/log/backup.log 2>&1

Troubleshooting: Problemas comunes

Problema 1: Sistema no arranca / Kernel panic

Síntomas: Pantalla negra, error «Kernel panic», bootloop.

Causas:

  • Actualización de kernel fallida
  • Disco lleno durante update
  • Archivo /boot corrupto
  • fstab con error (disco no montado)

Soluciones:

  1. Bootear kernel anterior:
    • Reiniciar → En GRUB presionar Shift (o Esc en algunas BIOS)
    • Advanced options → Elegir kernel anterior
    • Una vez dentro: sudo apt remove linux-image-VERSION-PROBLEMATICA
  2. Modo recovery:
    • GRUB → Recovery mode
    • Drop to root shell prompt
    • Montar filesystem: mount -o remount,rw /
    • Reparar: apt --fix-broken install
  3. Verificar fstab:
    • Recovery shell: nano /etc/fstab
    • Comentar (#) líneas de discos que no existen
    • Reboot

Problema 2: Sin red / No ping

Diagnóstico paso a paso:

# 1. Ver si interfaz está UP
ip a
# Buscar: estado UP, inet (IP asignada)

# Si interfaz está DOWN:
sudo ip link set enp0s3 up

# 2. Test gateway
ip route show default
# Copiar IP del gateway (ej: 192.168.1.1)
ping 192.168.1.1

# Si no responde: problema en red local (cable, switch, DHCP)

# 3. Test DNS
ping 8.8.8.8
# Si funciona: problema de DNS
# Solución temporal:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

# 4. Test internet
ping google.com
# Si falla pero 8.8.8.8 funciona: DNS incorrecto

# 5. Reiniciar networking
sudo systemctl restart networking      # Debian
sudo systemctl restart NetworkManager  # Ubuntu Desktop
sudo netplan apply                     # Ubuntu Server

# 6. Verificar firewall
sudo ufw status
# Si está bloqueando, deshabilitar temporalmente:
sudo ufw disable

Problema 3: Disco lleno

Síntomas: Errores «No space left on device», servicios fallan, sistema lento.

Diagnóstico y limpieza:

# 1. Ver uso de disco
df -h
# Identificar partición llena (/, /home, /var)

# 2. Buscar qué consume espacio
sudo du -sh /* | sort -rh | head -10
sudo du -sh /var/* | sort -rh | head -10

# 3. Limpiezas comunes:

# Logs antiguos
sudo journalctl --vacuum-time=7d
sudo find /var/log/ -name "*.log" -mtime +30 -delete

# Paquetes apt cache
sudo apt clean
sudo apt autoremove

# Kernels antiguos
dpkg -l | grep linux-image
sudo apt remove linux-image-VERSION-ANTIGUA

# Archivos temporales
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*

# Docker (si usas)
docker system prune -a --volumes

# Snapshots (si usas Timeshift, etc.)
# Eliminar snapshots antiguos manualmente

# 4. Verificar inodos (a veces disco "lleno" pero df muestra espacio)
df -i
# Si uso de inodos al 100%: muchos archivos pequeños
sudo find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n
# Eliminar directorios con millones de archivos pequeños

Problema 4: Servicio no arranca

Diagnóstico sistemático:

# 1. Ver estado y error
sudo systemctl status nginx

# 2. Ver logs detallados
sudo journalctl -u nginx -n 100 --no-pager

# 3. Verificar configuración (si aplica)
sudo nginx -t    # Test config nginx
# Para otros servicios: ver su documentación

# 4. Verificar permisos de archivos
ls -l /var/log/nginx/
# Si owner incorrecto:
sudo chown -R www-data:www-data /var/log/nginx/

# 5. Verificar puerto no esté en uso
sudo ss -tulpn | grep :80
# Si otro proceso lo usa, matar o cambiar puerto

# 6. Verificar dependencias
# Algunos servicios requieren otros (ej: app → database)
sudo systemctl status postgresql

# 7. Restart forzado
sudo systemctl restart nginx
sudo systemctl daemon-reload  # Si cambiaste .service

# 8. Si nada funciona: reinstalar
sudo apt purge nginx
sudo apt install nginx

Problema 5: Permission denied constante

Causas:

  • Usuario no es owner del archivo/directorio
  • Permisos incorrectos
  • Usuario no está en grupo necesario (ej: docker)
  • SELinux/AppArmor bloqueando (avanzado)

Soluciones:

# Ver permisos y owner
ls -la archivo

# Cambiar owner
sudo chown usuario:usuario archivo
sudo chown -R usuario:usuario directorio/

# Cambiar permisos
chmod 644 archivo      # Usuario: rw, otros: r
chmod 755 directorio/  # Usuario: rwx, otros: rx

# Añadir usuario a grupo (ej: docker)
sudo usermod -aG docker $USER
# IMPORTANTE: logout y login para aplicar cambio de grupo

# Verificar grupos actuales
groups

# Si problema persiste: verificar AppArmor
sudo aa-status
# Deshabilitar perfil problemático (temporal):
sudo aa-complain /usr/bin/programa

Problema 6: SSH no conecta

Diagnóstico:

# 1. Verificar que SSH server corre
sudo systemctl status ssh

# Si no corre:
sudo systemctl start ssh

# 2. Verificar puerto
sudo ss -tulpn | grep :22

# 3. Test desde el propio servidor (localhost)
ssh localhost
# Si funciona: problema de red/firewall
# Si no funciona: problema de SSH config

# 4. Ver logs SSH
sudo journalctl -u ssh -f
# En otra terminal, intenta conectar y observa logs

# 5. Verificar firewall
sudo ufw status
sudo ufw allow 22/tcp

# 6. Test desde cliente con verbose
ssh -vvv usuario@IP
# Muestra debug completo, ver dónde falla

# 7. Verificar sshd_config
sudo nano /etc/ssh/sshd_config
# Verificar:
# Port 22
# PermitRootLogin no
# PubkeyAuthentication yes
# PasswordAuthentication yes

sudo systemctl restart ssh

# 8. Permisos SSH keys (si usas)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys

Mejores prácticas

Seguridad

  • Actualizar regularmente: sudo apt update && sudo apt upgrade semanal
  • Firewall activo: UFW configurado, solo puertos necesarios abiertos
  • SSH con keys: Deshabilitar password authentication
  • fail2ban: Banear IPs con intentos de login fallidos (instalar: sudo apt install fail2ban)
  • No correr servicios como root: Usar usuarios dedicados
  • Permisos mínimos: 644 para archivos, 755 para directorios y scripts
  • Backups automáticos: Cron + script, offsite si es producción

Mantenimiento

  • Monitorizar espacio en disco: Alertas cuando >80%
  • Limpiar logs antiguos: journalctl vacuum, logrotate
  • Eliminar paquetes huérfanos: sudo apt autoremove mensual
  • Verificar servicios críticos: systemctl --failed diario
  • Actualizar Docker images: docker compose pull && docker compose up -d
  • Test de backups: Restaurar periódicamente para verificar que funcionan

Documentación

  • Documentar cambios importantes: Archivo CHANGELOG.md o notas en wiki
  • Comentar scripts: Qué hace, por qué, cuándo se ejecuta
  • Inventario de servicios: Qué corre dónde, puertos, dependencias
  • Passwords en gestor: Vaultwarden, Bitwarden, 1Password (no en scripts plain text)

Recursos y siguiente nivel

Documentación oficial:

Comunidad:

Siguientes pasos:

  1. Práctica constante: Usa Linux como daily driver (WSL2, VM, o bare metal)
  2. Proyectos homelab: Aplica lo aprendido (Docker, Proxmox, Home Assistant)
  3. Scripting avanzado: Automatiza todo (backups, deployments, monitoring)
  4. Networking profundo: iptables, VLANs, VPN (WireGuard, OpenVPN)
  5. Contenedores: Docker mastery, Kubernetes (k3s para homelab)
  6. Infraestructura como código: Ansible, Terraform
  7. Monitorización avanzada: Prometheus, Grafana, Loki

Conclusión

Linux no es difícil, es diferente. Con esta guía dominas lo esencial para:

  • ✅ Instalar y configurar Ubuntu Server/Debian
  • ✅ Navegar terminal sin perderte
  • ✅ Gestionar permisos (el concepto MÁS importante)
  • ✅ Instalar software con apt
  • ✅ Gestionar servicios con systemd
  • ✅ Configurar redes y SSH
  • ✅ Automatizar con cron y bash scripts
  • ✅ Solucionar los 6 problemas más comunes
💪 Ahora puedes seguir CUALQUIER guía técnica:

Docker Compose, Proxmox, Home Assistant, n8n, todo asume estos conocimientos. Ya no te frenan comandos desconocidos. Practica, rompe cosas (en VMs), aprende, repite. En 2 semanas de uso diario dominarás Linux.

¡Bienvenido al mundo Linux! 🐧🚀

Por ziru

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
El Diario IA
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.