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.
- 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.
📋 Contenido de esta guía
- Instalación rápida Ubuntu Server
- Terminal básico: Comandos de supervivencia
- Gestión de paquetes con apt
- Servicios con systemd
- Redes: Configuración y diagnóstico
- SSH: Acceso remoto seguro
- Usuarios y grupos
- Firewall con UFW
- Cron: Tareas programadas
- Scripts Bash básicos
- Troubleshooting: Problemas comunes
- Mejores prácticas
- Recursos y siguiente nivel
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
- Descargar ISO: ubuntu.com/download/server (Ubuntu Server 24.04 LTS)
- Crear USB booteable: Rufus (Windows), Balena Etcher (multi-plataforma), o
dd
(Linux) - Bootear desde USB → Installer automático aparece
- 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)
- 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! 🎉
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/
- 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
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
- Usa rutas absolutas (
/usr/bin/python3
nopython3
) - 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:
- 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
- Modo recovery:
- GRUB → Recovery mode
- Drop to root shell prompt
- Montar filesystem:
mount -o remount,rw /
- Reparar:
apt --fix-broken install
- Verificar fstab:
- Recovery shell:
nano /etc/fstab
- Comentar (#) líneas de discos que no existen
- Reboot
- Recovery shell:
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:
- Ubuntu Server docs
- Debian documentation
- ArchWiki (mejor documentación Linux general, aunque sea de Arch)
Comunidad:
- Ask Ubuntu – Stack Exchange específico Ubuntu
- Unix & Linux Stack Exchange
- r/linux4noobs – Reddit para principiantes
- r/homelab – Comunidad homelab con mucho Linux
Siguientes pasos:
- Práctica constante: Usa Linux como daily driver (WSL2, VM, o bare metal)
- Proyectos homelab: Aplica lo aprendido (Docker, Proxmox, Home Assistant)
- Scripting avanzado: Automatiza todo (backups, deployments, monitoring)
- Networking profundo: iptables, VLANs, VPN (WireGuard, OpenVPN)
- Contenedores: Docker mastery, Kubernetes (k3s para homelab)
- Infraestructura como código: Ansible, Terraform
- 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
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! 🐧🚀