Cuaderno
Notas y comandos
Mi chuleta en abierto: lo que no quiero volver a buscar. 76 notas de 14 temas, con botón para copiar cada comando.
Linux
apt y dpkg: mantener Debian y UbuntuActualizar, limpiar y averiguar a qué paquete pertenece un fichero.
sudo apt update && sudo apt upgrade # actualizar
sudo apt autoremove --purge # quitar lo que ya no hace falta
sudo apt clean # vaciar la caché de .deb descargados
apt list --upgradable # qué hay pendiente
A qué paquete pertenece un comando, y qué ficheros instala un paquete:
dpkg -S $(which nmap)
dpkg -L nmap
apt-cache policy nginx # versión instalada y candidata
Paquetes que ocupan más espacio:
dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -rn | head
#apt #mantenimiento · 14 nov 2026 · Enlace a esta nota
awk: trabajar con columnasSacar columnas, sumar y filtrar en una salida con columnas.
awk '{print $1}' fichero # la primera columna
awk '{print $1, $3}' fichero # columnas 1 y 3
ps aux | awk '{print $2, $11}' # PID y comando
awk -F: '{print $1}' /etc/passwd # separador ":"
Sumar una columna (por ejemplo, bytes):
du -b * | awk '{suma += $1} END {print suma}'
Filtrar por una condición:
ps aux | awk '$3 > 5 {print $11, $3"%"}' # procesos que usan más de 5% de CPU
#awk #texto · 14 nov 2026 · Enlace a esta nota
Buscar un texto dentro de muchos ficherosgrep y find para encontrar dónde está esa línea de configuración.
En todos los ficheros de una carpeta, con número de línea:
grep -rn "texto a buscar" /etc/
Sin distinguir mayúsculas y solo en ficheros .conf:
grep -rni --include="*.conf" "listen" /etc/nginx/
Solo los nombres de los ficheros que lo contienen:
grep -rl "password" .
Buscar ficheros por nombre (insensible a mayúsculas) y por fecha de modificación:
find / -iname "*backup*" 2>/dev/null
find /var/log -type f -mtime -1 # modificados en las últimas 24 h
#grep #find · 14 nov 2026 · Enlace a esta nota
Comprimir y descomprimir: tar, gz y zipLas combinaciones que siempre se olvidan.
tar -czf copia.tar.gz carpeta/ # crear .tar.gz
tar -xzf copia.tar.gz # extraer aquí
tar -xzf copia.tar.gz -C /destino/ # extraer en otra carpeta
tar -tzf copia.tar.gz | head # ver el contenido sin extraer
Con zstd, mucho más rápido para copias grandes:
tar --zstd -cf copia.tar.zst carpeta/
tar --zstd -xf copia.tar.zst
Zip:
zip -r archivo.zip carpeta/
unzip archivo.zip -d destino/
#ficheros · 14 nov 2026 · Enlace a esta nota
Copias con tar: completas e incrementalesUna copia base y luego solo lo que cambia.
Copia completa, guardando un índice de lo copiado:
tar --listed-incremental=indice.snar -czf completa.tar.gz /datos
Las siguientes veces, con el mismo índice, solo guarda lo que ha cambiado:
tar --listed-incremental=indice.snar -czf cambios-$(date +%F).tar.gz /datos
Restaurar: primero la completa, luego las incrementales en orden:
tar --listed-incremental=/dev/null -xzf completa.tar.gz -C /destino
tar --listed-incremental=/dev/null -xzf cambios-2026-11-14.tar.gz -C /destino
#copias #ficheros · 14 nov 2026 · Enlace a esta nota
Cron: programar tareasLa sintaxis de los cinco campos y los errores típicos.
crontab -e # editar las tareas de tu usuario
crontab -l # verlas
Formato: minuto hora día-del-mes mes día-de-la-semana comando
30 8 * * * cada día a las 08:30
*/15 * * * * cada 15 minutos
0 4 * * 1 los lunes a las 04:00
0 9-18 * * 1-5 cada hora de 9 a 18, de lunes a viernes
@reboot al arrancar
Errores típicos:
- Cron no carga tu entorno: usa rutas completas (
/usr/bin/python3, nopython3). - Guarda la salida para saber si falla:
... >> /var/log/mitarea.log 2>&1. %tiene un significado especial en crontab: escápalo como\%.
#cron #automatizacion · 14 nov 2026 · Enlace a esta nota
Disco lleno: qué está ocupando el espacioEncontrar en un minuto las carpetas y ficheros que se comen el disco.
Cuánto espacio queda en cada disco:
df -h
Las carpetas que más ocupan dentro de una ruta, ordenadas (sin salir de ese disco):
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -15
Los ficheros de más de 500 MB de todo el sistema:
sudo find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}' | sort -h
Sospechosos habituales: /var/log (logs sin rotar), /var/lib/docker (imágenes viejas) y la caché de paquetes (sudo apt clean).
Si df dice lleno pero du no encuentra nada, hay un fichero borrado que algún proceso sigue teniendo abierto:
sudo lsof +L1 | head
Reiniciar ese proceso libera el espacio.
#disco · 14 nov 2026 · Enlace a esta nota
find: buscar y actuar sobre ficherosEncontrar por tamaño, fecha o tipo, y hacer algo con lo encontrado.
find /var/log -name "*.log" -mtime +30 # logs de más de 30 días
find . -type f -size +100M # ficheros de más de 100 MB
find . -type d -empty # carpetas vacías
find . -name "*.tmp" -delete # borrar lo encontrado
find . -name "*.sh" -exec chmod +x {} + # hacer ejecutables los .sh
find . -type f -mmin -10 # modificados en los últimos 10 minutos
Combinado con otras órdenes, de forma segura con nombres raros:
find . -name "*.jpg" -print0 | xargs -0 -I{} cp {} /destino/
#find #ficheros · 14 nov 2026 · Enlace a esta nota
journalctl: encontrar la aguja en el pajarFiltrar los logs del sistema por servicio, tiempo y prioridad.
journalctl -u nginx -n 100 --no-pager # últimas 100 de un servicio
journalctl -u nginx -f # en directo
journalctl -u nginx --since "1 hour ago"
journalctl --since "2026-11-14 08:00" --until "2026-11-14 09:00"
journalctl -p err -b # solo errores desde el último arranque
journalctl -k # mensajes del kernel (dmesg)
journalctl --disk-usage # cuánto ocupan los logs
sudo journalctl --vacuum-time=7d # borrar los de más de 7 días
#systemd #logs · 14 nov 2026 · Enlace a esta nota
jq: leer y filtrar JSON en la terminalSacar justo el dato que quieres de la respuesta de una API.
curl -s https://api.ejemplo.com/datos | jq . # todo, con colores y sangría
curl -s ... | jq '.items[0].nombre' # un campo
curl -s ... | jq '.items[] | .nombre' # un campo de cada elemento
curl -s ... | jq '.items | length' # cuántos hay
curl -s ... | jq '.items[] | select(.activo == true)' # filtrar
curl -s ... | jq -r '.items[].email' # -r: sin comillas, una por línea
Convertir un array de objetos a CSV:
jq -r '.items[] | [.nombre, .email] | @csv' datos.json
#jq #json #api · 14 nov 2026 · Enlace a esta nota
Permisos: chmod y chown sin liarseQué significa 755 o 644 y cómo arreglar permisos de una carpeta entera.
Cada cifra es la suma de lectura (4), escritura (2) y ejecución (1), para propietario, grupo y resto:
| Permiso | Uso típico |
|---|---|
| 600 | Claves y secretos: solo el propietario lee y escribe |
| 644 | Ficheros normales |
| 700 | Carpetas privadas |
| 755 | Carpetas y scripts que otros pueden ejecutar |
chmod 600 ~/.ssh/id_ed25519
chown usuario:grupo fichero
sudo chown -R www-data:www-data /var/www/miweb
Arreglar una carpeta entera: carpetas a 755 y ficheros a 644 (sin dar ejecución a todo):
find /ruta -type d -exec chmod 755 {} +
find /ruta -type f -exec chmod 644 {} +
Nunca chmod -R 777: lo arregla todo y lo abre todo. En la sección de herramientas tienes una calculadora de chmod.
#permisos · 14 nov 2026 · Enlace a esta nota
Qué se está comiendo la memoria o la CPULos procesos que más consumen, sin instalar nada.
Memoria total, usada y swap:
free -h
Los 10 procesos que más memoria y CPU usan:
ps aux --sort=-%mem | head -11
ps aux --sort=-%cpu | head -11
Carga del sistema (media de 1, 5 y 15 minutos; se compara con el número de núcleos de nproc):
uptime && nproc
Si la memoria se agotó y el sistema mató algún proceso:
journalctl -k | grep -i "out of memory" | tail
#rendimiento · 14 nov 2026 · Enlace a esta nota
sed: buscar y reemplazar en ficherosCambiar texto en uno o muchos ficheros sin abrirlos.
sed 's/viejo/nuevo/' fichero # muestra el cambio (no lo guarda)
sed -i 's/viejo/nuevo/g' fichero # -i lo guarda; g cambia todas las veces de cada línea
sed -i.bak 's/viejo/nuevo/g' fichero # guarda y deja copia fichero.bak
sed -i 's/viejo/nuevo/g' *.conf # en varios ficheros
Si el texto lleva barras (rutas), usa otro separador:
sed -i 's#/ruta/vieja#/ruta/nueva#g' fichero
Borrar las líneas que contienen algo, o las vacías:
sed -i '/patron/d' fichero
sed -i '/^$/d' fichero
#sed #texto · 14 nov 2026 · Enlace a esta nota
systemd: un temporizador en vez de cronTareas programadas con logs y reintentos, mejor integradas que cron.
Dos ficheros. /etc/systemd/system/tarea.service:
[Unit]
Description=Mi tarea
[Service]
Type=oneshot
ExecStart=/ruta/script.sh
/etc/systemd/system/tarea.timer:
[Unit]
Description=Lanza mi tarea cada día
[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now tarea.timer
systemctl list-timers # cuándo toca cada uno
Persistent=true lanza la tarea al arrancar si el equipo estaba apagado a la hora prevista: eso cron no lo hace.
#systemd #automatizacion · 14 nov 2026 · Enlace a esta nota
tmux: sesiones que sobreviven a la desconexiónPara dejar algo corriendo en un servidor y volver a ello más tarde.
tmux new -s trabajo # nueva sesión llamada "trabajo"
tmux ls # listar sesiones
tmux attach -t trabajo # volver a entrar
Dentro, el prefijo es Ctrl+b y luego:
d soltar la sesión (sigue corriendo al salir)
c ventana nueva · 0-9 cambiar de ventana
% dividir en vertical · " dividir en horizontal
flechas moverse entre paneles · x cerrar el panel
Lo imprescindible: lanzas algo largo por SSH, pulsas Ctrl+b y luego d, cierras el portátil, y al volver tmux attach y sigue ahí.
#tmux #ssh · 14 nov 2026 · Enlace a esta nota
Usuarios, grupos y sudoCrear un usuario, darle sudo y ver quién ha entrado.
sudo adduser daniel
sudo usermod -aG sudo daniel # en Debian/Ubuntu; en RHEL el grupo es wheel
groups daniel
Quién está conectado y los últimos accesos:
who
last -n 20
sudo lastb -n 20 # intentos fallidos
Qué puede hacer un usuario con sudo (lo primero que se mira en una auditoría):
sudo -l -U daniel
#usuarios #seguridad · 14 nov 2026 · Enlace a esta nota
Ver por qué se cae un servicio de systemdUn servicio que se reinicia en bucle no siempre avisa. Esto lo destapa en un minuto.
Estado, último error y cuántas veces se ha reiniciado:
systemctl status mi-servicio --no-pager
systemctl show mi-servicio -p NRestarts -p ActiveEnterTimestamp
Las últimas líneas del registro, solo los errores:
journalctl -u mi-servicio -n 50 --no-pager -p err
Seguirlo en directo mientras lo reinicias en otra terminal:
journalctl -u mi-servicio -f
Un NRestarts de miles es la pista de que lleva días cayendo en bucle sin que nadie se entere. Merece un monitor que avise.
#linux #systemd · 14 nov 2026 · Enlace a esta nota
vim: moverse y salir sin desesperarseLo mínimo para editar un fichero de configuración por SSH.
vim tiene dos modos: normal (para moverse y dar órdenes) e inserción (para escribir). Empiezas en normal.
i empezar a escribir · Esc volver a modo normal
:w guardar · :q salir · :wq guardar y salir · :q! salir sin guardar
/texto buscar (n para el siguiente)
dd borrar la línea · u deshacer · Ctrl+r rehacer
gg ir al principio · G ir al final · :42 ir a la línea 42
Si entraste sin querer y solo quieres salir: Esc, luego :q! y Enter.
#vim #editores · 14 nov 2026 · Enlace a esta nota
Bash
Bucles de Bash que uso a menudoRecorrer ficheros, líneas y rangos sin romperse con espacios.
Por cada fichero (aguanta espacios en los nombres):
for f in *.log; do echo "$f"; done
Por cada línea de un fichero:
while IFS= read -r linea; do echo "$linea"; done < lista.txt
Un rango de IPs, por ejemplo para un ping rápido:
for i in {1..254}; do ping -c1 -W1 192.168.1.$i >/dev/null && echo "192.168.1.$i responde" & done; wait
Reintentar un comando hasta que funcione (máximo 5 veces):
for n in {1..5}; do comando && break; echo "intento $n falló"; sleep $((n*2)); done
#bash · 14 nov 2026 · Enlace a esta nota
Plantilla de script de Bash que no falla en silencioLas tres líneas que evitan la mitad de los sustos.
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# -e: sale al primer error -u: error si usas una variable sin definir -o pipefail: los fallos dentro de una tubería cuentan
log() { echo "[$(date '+%F %T')] $*"; }
trap 'log "ERROR en la línea $LINENO"' ERR
log "Empiezo"
Comprobar un script antes de ejecutarlo:
bash -n script.sh # solo sintaxis
shellcheck script.sh # errores comunes (apt install shellcheck)
#bash #scripts · 14 nov 2026 · Enlace a esta nota
Redirecciones y tuberíasDónde va la salida normal, dónde los errores y cómo juntarlas.
comando > salida.txt # sobrescribe con la salida normal
comando >> salida.txt # añade al final
comando 2> errores.txt # solo los errores
comando > todo.txt 2>&1 # salida y errores juntos
comando 2>/dev/null # descartar errores
comando | tee salida.txt # verlo en pantalla y guardarlo a la vez
Guardar la salida en una variable:
ip=$(hostname -I | awk '{print $1}')
#bash · 14 nov 2026 · Enlace a esta nota
PowerShell
PowerShell: «la ejecución de scripts está deshabilitada»El error de siempre al lanzar un .ps1 y cómo resolverlo sin abrirlo todo.
Ver la política actual:
Get-ExecutionPolicy -List
Permitir tus scripts y los firmados, solo para tu usuario:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Ejecutar un script concreto sin cambiar nada de forma permanente:
powershell -ExecutionPolicy Bypass -File .\script.ps1
Un script descargado de internet queda bloqueado; si te fías de él: Unblock-File .\script.ps1.
#scripts · 14 nov 2026 · Enlace a esta nota
PowerShell: descargar un fichero y comprobar su huellaComprobar que lo que has bajado es exactamente lo que publica el fabricante.
Invoke-WebRequest -Uri "https://ejemplo.com/programa.exe" -OutFile "$env:TEMP\programa.exe"
Get-FileHash "$env:TEMP\programa.exe" -Algorithm SHA256
Compara la huella con la que da la web oficial. Si cambia un solo carácter, el fichero no es el mismo.
Comparar directamente:
(Get-FileHash .\programa.exe -Algorithm SHA256).Hash -eq "HUELLA_OFICIAL".ToUpper()
#seguridad #ficheros · 14 nov 2026 · Enlace a esta nota
PowerShell: ficheros más grandes de una carpetaCuando el disco C: se llena y no sabes por qué.
Los 20 ficheros más grandes a partir de una ruta:
Get-ChildItem C:\Users -Recurse -File -ErrorAction SilentlyContinue |
Sort-Object Length -Descending | Select-Object -First 20 FullName, @{n='MB';e={[math]::Round($_.Length/1MB)}}
Tamaño de cada carpeta de primer nivel:
Get-ChildItem C:\ -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$t = (Get-ChildItem $_.FullName -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum
[pscustomobject]@{ Carpeta = $_.Name; GB = [math]::Round($t/1GB, 2) }
} | Sort-Object GB -Descending
Liberar espacio de Windows Update y archivos temporales: cleanmgr /sageset:1 y luego cleanmgr /sagerun:1.
#disco · 14 nov 2026 · Enlace a esta nota
PowerShell: información del equipo de un vistazoModelo, sistema, memoria, discos y número de serie para un inventario rápido.
Get-ComputerInfo -Property CsName, WindowsProductName, OsVersion, CsManufacturer, CsModel, CsTotalPhysicalMemory
(Get-CimInstance Win32_BIOS).SerialNumber
Get-PhysicalDisk | Select-Object FriendlyName, MediaType, HealthStatus, @{n='GB';e={[math]::Round($_.Size/1GB)}}
Get-Volume | Where-Object DriveLetter | Select-Object DriveLetter, @{n='Libre GB';e={[math]::Round($_.SizeRemaining/1GB,1)}}, @{n='Total GB';e={[math]::Round($_.Size/1GB,1)}}
Programas instalados:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object DisplayName | Select-Object DisplayName, DisplayVersion | Sort-Object DisplayName
#inventario · 14 nov 2026 · Enlace a esta nota
PowerShell: inicios de sesión fallidos y quién entróLos eventos de seguridad que miro primero ante un posible acceso indebido.
Inicios de sesión fallidos (evento 4625) de las últimas 24 horas (como administrador):
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} |
ForEach-Object { [pscustomobject]@{ Hora=$_.TimeCreated; Usuario=$_.Properties[5].Value; IP=$_.Properties[19].Value } } |
Group-Object IP | Sort-Object Count -Descending
Inicios de sesión correctos (4624), cambios de usuarios (4720 creado, 4732 añadido a un grupo) y borrado del registro (1102):
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4720,4732,1102} -MaxEvents 50 | Select-Object TimeCreated, Id, Message
Muchos 4625 desde la misma IP en poco tiempo es un ataque de fuerza bruta.
#seguridad #eventos · 14 nov 2026 · Enlace a esta nota
PowerShell: probar si llego a un servidor y a un puertoTest-NetConnection sustituye a ping, telnet y tracert.
Test-NetConnection 8.8.8.8 # ping
Test-NetConnection servidor.local -Port 443 # ¿está abierto el puerto?
Test-NetConnection google.com -TraceRoute # ruta
Resolve-DnsName danielsanjuan.com # DNS
Resolve-DnsName danielsanjuan.com -Server 1.1.1.1 # preguntando a otro servidor DNS
TcpTestSucceeded : True significa que el puerto responde. Si el ping falla pero el puerto sí responde, es que ese equipo bloquea el ping, no que esté caído.
#redes · 14 nov 2026 · Enlace a esta nota
PowerShell: qué proceso usa un puertoEl equivalente a ss o netstat con el nombre del programa.
Quién escucha en el puerto 3389:
Get-NetTCPConnection -LocalPort 3389 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess, @{n='Proceso';e={(Get-Process -Id $_.OwningProcess).ProcessName}}
Todas las conexiones establecidas hacia fuera, con su programa:
Get-NetTCPConnection -State Established |
Select-Object RemoteAddress, RemotePort, @{n='Proceso';e={(Get-Process -Id $_.OwningProcess).ProcessName}} |
Sort-Object Proceso
Cerrar un proceso por su PID o por su nombre:
Stop-Process -Id 1234 -Force
Stop-Process -Name notepad
#redes #procesos · 14 nov 2026 · Enlace a esta nota
PowerShell: servicios de WindowsVer, arrancar, parar y cambiar el inicio de un servicio.
Get-Service | Where-Object Status -eq Running | Sort-Object DisplayName
Get-Service -Name *update*
Restart-Service -Name Spooler
Set-Service -Name Spooler -StartupType Disabled # Automatic, Manual o Disabled
Servicios automáticos que no están arrancados (suele ser lo que falla):
Get-CimInstance Win32_Service -Filter "StartMode='Auto' AND State<>'Running'" | Select-Object Name, State, ExitCode
#servicios · 14 nov 2026 · Enlace a esta nota
PowerShell: usuarios locales y administradoresQuién tiene permisos de administrador en el equipo.
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet
Get-LocalGroupMember -Group "Administradores" # en Windows en inglés: Administrators
Crear un usuario y deshabilitar otro:
$c = Read-Host -AsSecureString "Contraseña"
New-LocalUser -Name "soporte" -Password $c -FullName "Soporte"
Disable-LocalUser -Name "Invitado"
#usuarios #seguridad · 14 nov 2026 · Enlace a esta nota
Windows
Windows (CMD): los comandos de red de siempreipconfig, netstat y compañía cuando no hay PowerShell a mano.
ipconfig /all :: IP, puerta de enlace, DNS y MAC
ipconfig /flushdns :: vaciar la caché DNS
ipconfig /release && ipconfig /renew
netstat -ano | findstr :443 :: quién usa el puerto 443 (la última columna es el PID)
tasklist /fi "pid eq 1234"
taskkill /pid 1234 /f
tracert 8.8.8.8
nslookup danielsanjuan.com 1.1.1.1
Restablecer la pila de red cuando «no hay internet» sin motivo (pide reiniciar):
netsh winsock reset
netsh int ip reset
#redes #cmd · 14 nov 2026 · Enlace a esta nota
Windows: estado de BitLocker y clave de recuperaciónComprobar si el disco está cifrado y guardar la clave antes de que haga falta.
Como administrador:
manage-bde -status
manage-bde -protectors -get C:
La «Contraseña numérica» es la clave de recuperación de 48 dígitos. Guárdala fuera del equipo: si cambias la placa o falla el TPM, sin ella no hay forma de recuperar los datos.
En PowerShell:
Get-BitLockerVolume | Select-Object MountPoint, VolumeStatus, ProtectionStatus, EncryptionPercentage
#seguridad #cifrado · 14 nov 2026 · Enlace a esta nota
Windows: reparar ficheros del sistemaSFC y DISM, en el orden correcto.
En una consola como administrador:
DISM /Online /Cleanup-Image /RestoreHealth
sfc /scannow
Primero DISM repara la imagen de la que SFC saca los ficheros buenos; después SFC repara el sistema. Si SFC dice que encontró y reparó errores, reinicia.
Comprobar el disco en el siguiente arranque:
chkdsk C: /f /r
#reparacion · 14 nov 2026 · Enlace a esta nota
Windows: ver la contraseña de una wifi guardadaPara cuando necesitas conectar otro dispositivo y no te acuerdas de la clave.
Redes guardadas en el equipo:
netsh wlan show profiles
La contraseña de una de ellas (campo «Contenido de la clave»):
netsh wlan show profile name="NombreDeLaRed" key=clear
Solo funciona con redes que tu equipo ya tiene guardadas, y en tu propio equipo. Por eso conviene que nadie se siente en tu ordenador desbloqueado.
#wifi · 14 nov 2026 · Enlace a esta nota
Redes
Consultar DNS: dig y nslookupVer qué responde de verdad un dominio, sin la caché de tu equipo.
dig danielsanjuan.com +short # A
dig AAAA danielsanjuan.com +short
dig MX danielsanjuan.com +short # correo
dig TXT danielsanjuan.com +short # SPF, verificaciones…
dig danielsanjuan.com @1.1.1.1 +short # preguntando a Cloudflare directamente
dig +trace danielsanjuan.com # toda la cadena, desde los servidores raíz
Sin dig instalado: nslookup -type=MX danielsanjuan.com 8.8.8.8, o por HTTPS:
curl -s -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=danielsanjuan.com&type=A'
#dns · 14 nov 2026 · Enlace a esta nota
curl para depurar una web o una APICabeceras, redirecciones, tiempos y certificados en una línea.
curl -I https://ejemplo.com # solo cabeceras
curl -sL -o /dev/null -w '%{http_code} %{url_effective}\n' https://ejemplo.com # código final tras redirecciones
curl -v https://ejemplo.com 2>&1 | grep -E '^[<>*]' # toda la conversación
curl -s -o /dev/null -w 'DNS %{time_namelookup}s · conexión %{time_connect}s · TLS %{time_appconnect}s · total %{time_total}s\n' https://ejemplo.com
Una petición POST con JSON:
curl -s -X POST https://api.ejemplo.com/v1/cosa -H 'Content-Type: application/json' -d '{"nombre":"prueba"}'
#http #web · 14 nov 2026 · Enlace a esta nota
Dónde se pierde la conexión: mtr y traceroutePara saber si el problema es tu wifi, tu operadora o el servidor.
mtr -rwc 50 8.8.8.8 # 50 paquetes, informe al final
traceroute 8.8.8.8
Cómo leerlo: si las pérdidas empiezan en el salto 1 (tu router) el problema está en casa; si empiezan en los de tu operadora, es la línea. Una pérdida solo en un salto intermedio que no sigue en los siguientes suele ser un router que no contesta a estas pruebas, no un fallo.
#diagnostico · 14 nov 2026 · Enlace a esta nota
Medir la velocidad real entre dos equiposiperf3 separa la velocidad de tu red de la de internet.
En un equipo (servidor):
iperf3 -s
En el otro:
iperf3 -c IP_DEL_SERVIDOR # subida
iperf3 -c IP_DEL_SERVIDOR -R # bajada
iperf3 -c IP_DEL_SERVIDOR -P 4 # 4 conexiones a la vez
Por cable gigabit deberías ver unos 940 Mbit/s. Si por wifi sale muy por debajo de lo que promete el router, mira el canal y la distancia antes de culpar a la operadora.
#rendimiento #wifi · 14 nov 2026 · Enlace a esta nota
Montar una carpeta compartida (SMB) en LinuxMontaje fijo de un NAS o del disco del router, y la diferencia entre soft y hard.
sudo apt install cifs-utils
sudo mkdir -p /mnt/nas
En /etc/fstab (credenciales en un fichero aparte con permisos 600, no en la línea):
//192.168.1.1/Compartida /mnt/nas cifs credentials=/root/.nas,uid=1000,gid=1000,vers=3.0,soft,x-systemd.automount,_netdev 0 0
sudo mount -a && df -h /mnt/nas
soft: si el servidor no responde, la lectura falla con error en vez de quedarse colgada. Los programas no se bloquean, pero pueden ver «I/O error» en cortes breves.hard: espera hasta que vuelva. Nada falla, pero un proceso puede quedarse colgado.- Routers antiguos solo hablan
vers=2.0o incluso1.0. Prueba de mayor a menor.
#linux #redes · 14 nov 2026 · Enlace a esta nota
Probar si un puerto remoto está abiertoSin nmap: con nc, bash o curl.
nc -zv servidor 443 # con netcat
timeout 3 bash -c '</dev/tcp/servidor/443' && echo abierto || echo cerrado # sin instalar nada
curl -sv telnet://servidor:22 --max-time 3 # con curl
UDP (no hay saludo, así que «sin respuesta» no significa cerrado):
nc -zvu servidor 53
#diagnostico · 14 nov 2026 · Enlace a esta nota
Qué proceso está usando un puertoCuando un servicio no arranca porque «el puerto ya está en uso».
sudo ss -ltnp 'sport = :8080'
-l solo escuchando, -t TCP, -n sin resolver nombres, -p el proceso. Para UDP cambia -t por -u.
Si sale docker-proxy, el puerto lo tiene un contenedor:
docker ps --format '{{.Names}}\t{{.Ports}}' | grep 8080
Para saber a qué servicio de systemd pertenece el proceso (con su PID):
cat /proc/<PID>/cgroup | grep -o '[a-z0-9-]*\.service'
#linux #redes · 14 nov 2026 · Enlace a esta nota
Ver IP, rutas y DNS en Linuxip y resolvectl: lo básico para saber cómo sale un equipo a internet.
ip -br a # interfaces e IPs, en una línea cada una
ip r # rutas; la «default» es la puerta de enlace
ip neigh # tabla ARP: equipos vistos en la red local
resolvectl status # qué DNS usa (systemd-resolved)
cat /etc/resolv.conf # si no hay systemd-resolved
IP pública con la que sales a internet:
curl -s https://api.ipify.org; echo
#linux #red · 14 nov 2026 · Enlace a esta nota
SSH
Alias de SSH: ssh pi en vez de ssh -p 2222 daniel@192…El fichero ~/.ssh/config ahorra escribir y errores.
En ~/.ssh/config:
Host pi
HostName 192.168.1.50
User daniel
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host *
ServerAliveInterval 30
Y ya: ssh pi, scp fichero pi:/tmp/, rsync -a carpeta/ pi:copia/. También funciona con VS Code Remote.
#productividad · 14 nov 2026 · Enlace a esta nota
Copiar con rsync sin perder nadaCopias que se pueden repetir y solo pasan lo que cambió.
rsync -avh --progress origen/ destino/ # la barra final de origen importa: copia el contenido
rsync -avh origen/ usuario@servidor:/copias/origen/ # a otro equipo por SSH
rsync -avh --delete origen/ destino/ # espejo: borra en destino lo que ya no está
rsync -avhn --delete origen/ destino/ # -n: prueba sin hacer nada
Siempre -n antes de usar --delete por primera vez.
#copias #ficheros · 14 nov 2026 · Enlace a esta nota
rsync: copias grandes que se reanudanCopiar muchos GB por una red inestable sin empezar de cero cada vez.
rsync -avhP --partial origen/ usuario@servidor:/destino/
-Pjunta--progress(barra) y--partial(guarda lo medio copiado para reanudar).- Si se corta, lanza el mismo comando otra vez: sigue donde iba.
Limitar el ancho de banda para no saturar la línea (en KB/s):
rsync -avhP --bwlimit=2000 origen/ destino/
Excluir carpetas:
rsync -avhP --exclude node_modules --exclude .git origen/ destino/
#copias #red · 14 nov 2026 · Enlace a esta nota
SSH con claves en vez de contraseñaGenerar la clave, copiarla al servidor y desactivar las contraseñas.
ssh-keygen -t ed25519 -C "portatil-daniel"
ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@servidor
ssh usuario@servidor # ya no pide contraseña
Cuando funcione, en el servidor (/etc/ssh/sshd_config):
PasswordAuthentication no
PermitRootLogin no
sudo sshd -t && sudo systemctl reload ssh
No cierres la sesión abierta hasta probar en otra ventana que puedes entrar con la clave.
#seguridad · 14 nov 2026 · Enlace a esta nota
Túneles SSH: llegar a un servicio que no está expuestoVer el panel de un equipo remoto como si estuviera en tu ordenador.
Local: abrir en tu equipo el puerto 8080 de un servidor remoto (por ejemplo, un panel que solo escucha en localhost):
ssh -L 8080:localhost:8080 usuario@servidor
# y abres http://localhost:8080
Saltar a un equipo de la red del servidor:
ssh -L 3389:192.168.1.20:3389 usuario@servidor # escritorio remoto a través del servidor
Proxy SOCKS para navegar como si estuvieras en esa red:
ssh -D 1080 usuario@servidor
-N si no quieres abrir terminal, solo el túnel.
#redes · 14 nov 2026 · Enlace a esta nota
Git
Git: deshacer lo que acabas de hacerEl último commit, un fichero o los cambios sin guardar.
git restore fichero.txt # descartar cambios sin commit de un fichero
git restore --staged fichero.txt # quitarlo del «add» sin perder los cambios
git commit --amend -m "Mensaje bueno" # rehacer el último commit (si aún no lo has subido)
git reset --soft HEAD~1 # deshacer el último commit, conservando los cambios
git revert <commit> # deshacer un commit ya subido, con otro commit que lo anula
Si ya lo subiste y otros lo tienen, usa revert, nunca reset y push --force.
¿Perdiste algo? Git casi nunca borra de verdad:
git reflog
#git · 14 nov 2026 · Enlace a esta nota
Git: ramas sin miedoCrear, cambiar, unir y borrar ramas.
git switch -c web-nueva # crear y cambiar
git switch main # volver
git merge web-nueva # traer los cambios a main
git branch -d web-nueva # borrar la rama ya unida
git push -u origin web-nueva # subirla
git log --oneline --graph --all -20
#git · 14 nov 2026 · Enlace a esta nota
Git: subí una contraseña o un .env al repositorioLo primero no es Git: es cambiar la contraseña.
- Cambia la clave o el token ya. Si el repositorio es público, da por hecho que alguien la tiene: hay robots que leen GitHub en tiempo real.
- Que no se vuelva a subir:
echo ".env" >> .gitignore
git rm --cached .env
git commit -m "Quitar .env del repositorio"
- Borrarlo también del historial (reescribe el historial: avisa a quien tenga el repositorio clonado):
pip install git-filter-repo
git filter-repo --path .env --invert-paths
git push --force --all
#git #seguridad · 14 nov 2026 · Enlace a esta nota
Docker
Docker Compose: lo del día a díaLevantar, actualizar y reconstruir servicios.
docker compose up -d # levantar en segundo plano
docker compose ps
docker compose logs -f servicio
docker compose pull && docker compose up -d # actualizar imágenes
docker compose up -d --build servicio # reconstruir solo uno
docker compose down # parar y quitar (los volúmenes se conservan)
docker compose down -v borra también los volúmenes, es decir, los datos.
#docker · 14 nov 2026 · Enlace a esta nota
Docker ocupa demasiado: qué y cómo liberarCuando /var/lib/docker se come el disco.
Qué ocupa (imágenes, contenedores, volúmenes, caché):
docker system df
Limpiar lo que no se usa, con cuidado:
docker image prune -a # imágenes sin ningún contenedor que las use
docker builder prune # caché de compilación
docker container prune # contenedores parados
Los volúmenes huérfanos (¡miran antes qué son, pueden tener datos!):
docker volume ls -f dangling=true
docker volume prune # borra los huérfanos
docker system prune -a --volumes lo limpia casi todo de golpe: úsalo solo si sabes que no hay datos que conservar.
#docker #disco · 14 nov 2026 · Enlace a esta nota
Docker: ver logs y entrar en un contenedorLo primero cuando un contenedor no funciona.
docker ps -a # todos, también los parados
docker logs --tail 100 -f nombre # últimos logs, siguiendo
docker inspect nombre --format '{{.State.Status}} {{.State.ExitCode}} {{.RestartCount}}'
docker exec -it nombre sh # entrar (bash si la imagen lo tiene)
docker stats --no-stream # CPU y memoria de cada uno
Copiar ficheros entre el equipo y el contenedor:
docker cp nombre:/ruta/fichero ./
docker cp ./fichero nombre:/ruta/
#docker #diagnostico · 14 nov 2026 · Enlace a esta nota
Liberar espacio en Docker sin perder datosQué ocupa espacio y cómo limpiarlo sin llevarse por delante volúmenes ni imágenes que aún se usan.
Qué está ocupando:
docker system df -v | head -40
Contenedores parados, redes sin uso, imágenes huérfanas y caché de compilación (no toca volúmenes):
docker container prune -f
docker image prune -f
docker builder prune -f
Cuidado con docker system prune -a y docker builder prune -a: borran también las imágenes que no usa ningún contenedor en ese momento, aunque las acabes de compilar para otro. Me costó reconstruir una imagen dos veces por eso.
Nunca --volumes sin mirar antes qué hay:
docker volume ls -f dangling=true
#docker #linux · 14 nov 2026 · Enlace a esta nota
Ciberseguridad
Comprobar un certificado TLS y su caducidadCuándo caduca, quién lo emite y para qué dominios vale.
echo | openssl s_client -connect danielsanjuan.com:443 -servername danielsanjuan.com 2>/dev/null | openssl x509 -noout -dates -issuer -subject
Solo los días que quedan:
echo | openssl s_client -connect ejemplo.com:443 -servername ejemplo.com 2>/dev/null | openssl x509 -noout -enddate
Ver todos los dominios que cubre un certificado (campo SAN):
echo | openssl s_client -connect ejemplo.com:443 2>/dev/null | openssl x509 -noout -ext subjectAltName
#web #tls · 14 nov 2026 · Enlace a esta nota
Cortafuegos sencillo con ufwCerrar todo y abrir solo lo justo, sin pelearse con iptables.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 192.168.1.0/24 # confiar en la red de casa
sudo ufw allow 443/tcp # abrir un puerto a todos
sudo ufw limit 22/tcp # SSH con freno a la fuerza bruta
sudo ufw enable
sudo ufw status numbered
Abre el puerto de SSH antes de activar el cortafuegos, o te quedas fuera del servidor. Con Docker, ufw no filtra los puertos que publican los contenedores: eso va aparte.
#servidor #red #defensa · 14 nov 2026 · Enlace a esta nota
Firewall con nftables (lo mínimo)El sustituto moderno de iptables, con una base segura.
Ver las reglas actuales:
sudo nft list ruleset
Una base: denegar entrada por defecto, permitir lo ya establecido, SSH y la red local. En /etc/nftables.conf:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
ip saddr 192.168.1.0/24 accept
tcp dport 22 accept
ip protocol icmp accept
}
}
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables
Abre SSH en las reglas antes de aplicar, o te quedas fuera. Para ufw, ver la nota de ufw.
#firewall #red #defensa · 14 nov 2026 · Enlace a esta nota
Frenar los ataques de fuerza bruta a SSH con fail2banBanea solo las IPs que fallan varias veces al entrar.
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
En /etc/fail2ban/jail.local, dentro de [sshd]:
[sshd]
enabled = true
maxretry = 4
findtime = 10m
bantime = 1h
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd # cuántas IPs lleva baneadas
sudo fail2ban-client set sshd unbanip 1.2.3.4 # si te baneas a ti mismo
Lo primero que pongo en cualquier servidor con SSH abierto. Aun así, mejor claves en vez de contraseñas.
#servidor #ssh #defensa · 14 nov 2026 · Enlace a esta nota
Linux: quién ha entrado y desde dóndeAccesos correctos, fallidos y sesiones activas.
last -n 20 # últimos accesos correctos
sudo lastb -n 20 # intentos fallidos
who # sesiones abiertas ahora
sudo grep "Failed password" /var/log/auth.log | tail
sudo grep "Accepted" /var/log/auth.log | tail # entradas correctas por SSH
Las IPs que más veces han fallado al entrar por SSH:
sudo grep "Failed password" /var/log/auth.log | grep -oE 'from [0-9.]+' | sort | uniq -c | sort -rn | head
#servidor #logs #defensa · 14 nov 2026 · Enlace a esta nota
Nmap, lo que más usoDescubrir equipos, puertos y servicios sin perder tiempo. Solo en redes propias o con permiso.
Qué equipos hay en la red (sin escanear puertos):
sudo nmap -sn 192.168.1.0/24
Los 1000 puertos más comunes, con versión de los servicios:
sudo nmap -sV -T4 192.168.1.10
Todos los puertos TCP, rápido, y luego detalle solo de los abiertos:
sudo nmap -p- --min-rate 2000 -T4 192.168.1.10 -oG - | grep -oP '\d+/open' | cut -d/ -f1 | paste -sd, -
sudo nmap -sC -sV -p 22,80,443 192.168.1.10
UDP, que se olvida siempre (lento, mejor acotado):
sudo nmap -sU --top-ports 50 192.168.1.10
#ciberseguridad #redes · 14 nov 2026 · Enlace a esta nota
openssl: certificados y cifrado desde la terminalGenerar certificados de prueba, ver un certificado y cifrar un fichero.
Certificado autofirmado para pruebas (clave + certificado, un año):
openssl req -x509 -newkey rsa:2048 -nodes -keyout clave.pem -out cert.pem -days 365 -subj "/CN=localhost"
Ver un certificado (fechas, emisor, dominios):
openssl x509 -in cert.pem -noout -text | head -20
Cifrar y descifrar un fichero con contraseña:
openssl enc -aes-256-cbc -pbkdf2 -salt -in secreto.txt -out secreto.enc
openssl enc -d -aes-256-cbc -pbkdf2 -in secreto.enc -out secreto.txt
Generar una contraseña aleatoria rápida:
openssl rand -base64 24
#tls #cifrado · 14 nov 2026 · Enlace a esta nota
Repaso rápido de seguridad de un servidor LinuxLo que miro al heredar un servidor que no he montado yo.
Quién puede usar sudo:
getent group sudo; grep -vE '^#|^$' /etc/sudoers; ls /etc/sudoers.d/
Usuarios que pueden iniciar sesión (tienen shell) y cuáles tienen contraseña:
grep -vE '/(nologin|false)$' /etc/passwd
sudo awk -F: '($2!="*" && $2!="!" && $2!="!!"){print $1}' /etc/shadow
Puertos abiertos al exterior y tareas programadas de todos:
sudo ss -tlnp
for u in $(cut -f1 -d: /etc/passwd); do sudo crontab -l -u $u 2>/dev/null | grep -v '^#' | sed "s/^/$u: /"; done
Ficheros con SUID (una vía habitual de escalada si alguno no debería estarlo):
sudo find / -perm -4000 -type f 2>/dev/null
#servidor #auditoria #defensa · 14 nov 2026 · Enlace a esta nota
Python
Compartir una carpeta por la red en un segundoPara pasar un fichero a otro equipo de la red sin instalar nada.
En la carpeta que quieres compartir:
python3 -m http.server 8000
Desde el otro equipo: http://IP-DEL-EQUIPO:8000. Solo para la red de casa y mientras lo usas; ciérralo con Ctrl+C.
Saber tu IP local:
hostname -I | awk '{print $1}'
#linux #python · 14 nov 2026 · Enlace a esta nota
Ficheros llenos de ceros tras un corte de luzUn programa no arrancaba porque su fichero de estado estaba lleno de bytes nulos. La causa y el arreglo.
Síntoma: después de un apagón, un JSON de estado ocupaba lo mismo de siempre pero era todo \x00, y el programa caía en bucle con JSONDecodeError. Pasa cuando el sistema se apaga mientras se escribe el fichero: el tamaño queda reservado, pero los datos no llegan al disco.
Arreglo: no escribir nunca encima del fichero bueno. Escribir en uno temporal, forzar que llegue al disco y sustituir de golpe:
import json, os
def guardar(ruta, datos):
tmp = ruta + ".tmp"
with open(tmp, "w") as f:
json.dump(datos, f)
f.flush()
os.fsync(f.fileno())
os.replace(tmp, ruta) # atómico: queda el viejo o el nuevo, nunca uno a medias
Y al leer, si está dañado, apartarlo y seguir en vez de romperse:
try:
estado = json.load(open(ruta))
except (ValueError, OSError):
os.rename(ruta, ruta + ".dañado")
estado = {}
Comprobar si un fichero es todo ceros:
python3 -c "b=open('estado.json','rb').read(); print(len(b), b.count(0))"
#linux #python #hallazgo · 14 nov 2026 · Enlace a esta nota
Python de una línea: servidor, JSON y fechasCosas que hago más rápido con python3 -c que buscando una web.
Dar formato a un JSON feo (de una API, por ejemplo):
curl -s https://api.ejemplo.com/datos | python3 -m json.tool
Codificar o descodificar en base64 y en URL:
python3 -c "import base64;print(base64.b64encode(b'texto').decode())"
python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "hola mundo"
La fecha de hace 30 días, para una consulta:
python3 -c "import datetime;print((datetime.date.today()-datetime.timedelta(days=30)))"
#python #trucos · 14 nov 2026 · Enlace a esta nota
Python: entornos virtuales sin ensuciar el sistemaCada proyecto con sus dependencias, sin romper las del sistema.
python3 -m venv .venv
source .venv/bin/activate # en Windows: .venv\Scripts\activate
pip install requests
pip freeze > requirements.txt
deactivate
Recrear el entorno en otro sitio:
python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
En Debian nuevo, instalar paquetes fuera de un venv da «externally-managed-environment»: es a propósito, usa siempre un venv.
#python · 14 nov 2026 · Enlace a esta nota
Python: pedir datos a una API con reintentosEl patrón que uso en todos los bots para que un fallo puntual no lo tire.
import time, requests
def pedir(url, intentos=3, timeout=20):
for n in range(intentos):
try:
r = requests.get(url, timeout=timeout)
r.raise_for_status()
return r.json()
except Exception as e:
print(f"intento {n+1} falló: {e}")
time.sleep(2 ** n) # espera 1, 2, 4 s…
return None
Para una API con clave, va en una cabecera, nunca en la URL ni escrita en el código:
r = requests.get(url, headers={"Authorization": f"Bearer {os.environ['TOKEN']}"}, timeout=20)
#python #api · 14 nov 2026 · Enlace a esta nota
Web y DNS
Certificado HTTPS gratis con Let's EncryptHTTPS en un servidor propio con Nginx y renovación automática.
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d ejemplo.com -d www.ejemplo.com
sudo certbot renew --dry-run # probar la renovación automática
Certbot edita la configuración de Nginx y pone la renovación en un temporizador. Comprobar cuándo renueva:
systemctl list-timers | grep certbot
Si la web está detrás de Cloudflare con proxy (nube naranja), usa el modo DNS en vez del de Nginx.
#web #tls #nginx · 14 nov 2026 · Enlace a esta nota
Correo: SPF, DKIM y DMARC en pocas palabrasLos tres registros que evitan que suplanten tu dominio y que tu correo caiga en spam.
Tres registros TXT en el DNS del dominio:
- SPF: qué servidores pueden enviar en tu nombre.
v=spf1 include:_spf.google.com -all
- DKIM: una firma para que no manipulen tus correos (la clave la da tu proveedor).
- DMARC: qué hacer con el correo que no pasa SPF ni DKIM.
_dmarc TXT "v=DMARC1; p=reject; rua=mailto:dmarc@tudominio.com"
Si tu dominio no envía correo, ciérralo del todo: SPF v=spf1 -all y DMARC p=reject. Así nadie puede falsear correos con tu dominio.
Comprobarlo:
dig TXT tudominio.com +short
dig TXT _dmarc.tudominio.com +short
#dns #correo · 14 nov 2026 · Enlace a esta nota
Dominio propio en GitHub Pages con CloudflareRegistros exactos para el dominio raíz y www, sin tocar el correo ni los subdominios.
En Cloudflare, todos con la nube gris (DNS only), para que GitHub pueda emitir el certificado:
| Tipo | Nombre | Contenido |
|---|---|---|
| A | @ | 185.199.108.153 |
| A | @ | 185.199.109.153 |
| A | @ | 185.199.110.153 |
| A | @ | 185.199.111.153 |
| AAAA | @ | 2606:50c0:8000::153 |
| AAAA | @ | 2606:50c0:8001::153 |
| AAAA | @ | 2606:50c0:8002::153 |
| AAAA | @ | 2606:50c0:8003::153 |
| CNAME | www | usuario.github.io |
Luego, en el repositorio: Settings → Pages → Custom domain, y cuando el certificado esté aprobado, Enforce HTTPS. La dirección usuario.github.io pasa a redirigir sola al dominio.
Comprobar que ya resuelve, sin esperar a la caché local:
curl -s -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=midominio.com&type=A'
#dns #web · 14 nov 2026 · Enlace a esta nota
Proxmox
Proxmox: estado de máquinas, discos y copiasUn vistazo rápido al nodo desde la consola.
qm list # máquinas virtuales y su estado
pct list # contenedores LXC
pvesm status # almacenamientos y espacio libre
qm start 101 / qm stop 101 / qm reboot 101
pvesr status # replicación, si la usas
Uso de disco de las copias y limpieza de las viejas:
du -sh /var/lib/vz/dump/* # copias vzdump
#virtualizacion · 14 nov 2026 · Enlace a esta nota
Proxmox: instantánea antes de tocar una máquinaLa red de seguridad antes de una actualización que puede salir mal.
Desde la consola del nodo (reemplaza 101 por el ID de la máquina):
qm snapshot 101 antes-de-actualizar --description "Kernel 6.x"
qm listsnapshot 101
qm rollback 101 antes-de-actualizar # volver atrás si algo se rompe
qm delsnapshot 101 antes-de-actualizar # borrarla cuando todo va bien
Para contenedores LXC es igual con pct en vez de qm. Un snapshot no sustituye a una copia de seguridad: si falla el disco, se van los dos.
#virtualizacion · 14 nov 2026 · Enlace a esta nota
Raspberry Pi
Raspberry Pi: convertir un script en un servicioQue tu script arranque solo y se reinicie si se cae.
En /etc/systemd/system/mi-bot.service:
[Unit]
Description=Mi bot
After=network-online.target
Wants=network-online.target
[Service]
WorkingDirectory=/home/pi/mi-bot
ExecStart=/home/pi/mi-bot/.venv/bin/python app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now mi-bot
journalctl -u mi-bot -f
Restart=always lo levanta solo si se cae. Para enterarte cuando eso pasa, un monitor tipo Uptime Kuma que avise por Telegram.
#raspberry #systemd · 14 nov 2026 · Enlace a esta nota
Raspberry Pi: temperatura, voltaje y memoriaSi va lenta o se reinicia sola, casi siempre es temperatura o alimentación.
vcgencmd measure_temp # temperatura de la CPU
vcgencmd get_throttled # distinto de 0x0 = problema de alimentación o calor
vcgencmd measure_clock arm # a cuántos MHz va de verdad
get_throttled con el bit 0 a 1 significa bajada de tensión ahora mismo: la fuente o el cable no dan suficiente. Con el bit 16, pasó antes. Una Pi que se reinicia sola en invierno o con un disco USB conectado casi siempre es esto.
Estado de la tarjeta SD y la memoria:
free -h
df -h /
#raspberry #hardware · 14 nov 2026 · Enlace a esta nota
Hallazgos
Generar un audio de prueba con ffmpegPara probar un programa que recibe audios. Y lo que me enseñó sobre la IA.
Un tono de 2 segundos en el formato de las notas de voz de Telegram (ogg/opus):
ffmpeg -f lavfi -i "sine=frequency=440:duration=2" -c:a libopus -b:a 24k tono.ogg
Hallazgo: al pasarle este pitido a una IA para que entendiera la orden, junto con el contexto del usuario, se inventó una frase completa relacionada con ese contexto. La solución fue separar los pasos: primero transcribir sin ningún contexto (y si no hay voz, devolver vacío) y luego interpretar el texto. Con audios, nunca mezcles transcribir e interpretar en la misma petición.
#ffmpeg #hallazgo · 14 nov 2026 · Enlace a esta nota
qBittorrent en un disco de red da «I/O error» y «file too short»Descargas grandes en una carpeta compartida (SMB/CIFS) que se paran con errores raros. La causa es el modo de disco.
Síntomas con la carpeta de descargas en un NAS o en el disco del router por SMB:
file_read error: I/O erroroResource temporarily unavailablefile too short: al archivo le faltan datos que qBittorrent creía tenerHost is downal volver a comprobar el torrent
Causa: qBittorrent 5 con libtorrent 2 usa por defecto archivos mapeados en memoria. Con discos locales va muy bien, con discos de red no.
Arreglo: Opciones → Avanzado → Tipo de E/S de disco: POSIX-compliant, y reiniciar qBittorrent. Por la API:
curl -b cookies.txt --data-urlencode 'json={"disk_io_type":2}' \
http://IP:8080/api/v2/app/setPreferences
Después, forzar la recomprobación del torrent para que sepa qué tiene bien de verdad. Si el disco de red es lento (un router), conviene limitar la velocidad para no saturarlo.
#hallazgo #docker #redes · 14 nov 2026 · Enlace a esta nota
Nada con esa búsqueda.