Entorno: Linux (Familia RHEL: Fedora) · SSHFS · Autofs · Monitoreo ARP
Nivel: Entusiasta Cacharrero / Nivel de Automatización: “vago pero eficiente”
El problema: IPs que bailan y routers que no ayudan
En la mayoría de nuestras casas, el router del ISP hace lo que quiere: asigna IPs dinámicas y no nos deja tocar el DNS local. Si intentas montar una carpeta remota, lo más probable es que el enlace se rompa en cuanto el router decida darle otra IP a tu servidor.
Esta bitácora documenta una solución pragmática y basada en eventos: 1. Descubrimiento pasivo: Escuchamos al kernel para saber cuándo aparece una MAC específica. 2. Resolución local: Actualizamos /etc/hosts al vuelo cuando el dispositivo se conecta. 3. Montaje bajo demanda: autofs monta la carpeta por SSHFS solo cuando realmente entras en ella.
Paso 1 — Resolución de nombres sin servidor DNS
En lugar de montar un servidor DNS completo (que es un lío), usamos un pequeño script que “escucha” la red y actualiza tu /etc/hosts solo cuando tus cacharros cambian de estado.
1.1 Lo básico
sudo dnf install arp-scan inotify-tools autofs fuse-sshfs
1.2 Configura sudo sin contraseña
Para que el script pueda actualizar /etc/hosts y escanear la red sin pedirte la clave cada 5 minutos, necesitamos darle permisos específicos en /etc/sudoers.d/lan-watch:
sudo visudo /etc/sudoers.d/lan-watch
Añade estas líneas (cambiando tu_usuario por tu nombre de usuario real):
tu_usuario ALL=(ALL) NOPASSWD: /usr/sbin/arp-scan
tu_usuario ALL=(ALL) NOPASSWD: /usr/bin/sed
tu_usuario ALL=(ALL) NOPASSWD: /usr/bin/tee
1.2 El Script “Mágico” — ~/bin/lan-watch.sh
Este script es súper eficiente. No está escaneando todo el rato; se queda esperando a que el kernel le diga: “Oye, este vecino acaba de cambiar de estado”.
#!/bin/bash
PEERS_DIR="$HOME/peers"
MOUNT_BASE="$HOME/peers/homelan"
# Detectamos la interfaz activa automáticamente
IFACE=$(ip route get 8.8.8.8 | grep -Po '(?<=dev )(\S+)')
[ -z "$IFACE" ] && IFACE=$(ip link show | grep -m 1 "state UP" | awk -F': ' '{print $2}')
# Mapa de MAC → Nombre (Pon aquí las MACs de tus máquinas)
declare -A MAC_NAMES=(
["00:11:22:33:44:55"]="servidor-pro"
["66:77:88:99:aa:bb"]="mi-nas"
)
rebuild_hosts() {
BLOCK="# homelan-start\n"
for f in "$PEERS_DIR"/*.txt; do
[ -f "$f" ] || continue
BLOCK+="$(cat $f)\n"
done
BLOCK+="# homelan-end"
sudo sed -i '/# homelan-start/,/# homelan-end/d' /etc/hosts
echo -e "$BLOCK" | sudo tee -a /etc/hosts > /dev/null
}
update_peer() {
local NAME=$1
local IP=$2
local ACTION=$3 # "online" u "offline"
if [ "$ACTION" == "online" ]; then
echo "$IP $NAME.internal $NAME" > "$PEERS_DIR/$NAME.txt"
echo "[$(date)] $NAME está ONLINE: $IP ($IFACE)"
else
if [ -f "$PEERS_DIR/$NAME.txt" ]; then
rm -f "$PEERS_DIR/$NAME.txt"
echo "[$(date)] $NAME está OFFLINE, quitando registro"
# Desmontaje "perezoso" para que no se cuelgue el sistema
if mountpoint -q "$MOUNT_BASE/$NAME" 2>/dev/null; then
sudo umount -l "$MOUNT_BASE/$NAME"
fi
fi
fi
rebuild_hosts
}
# Sincronización inicial al arrancar
SCAN=$(sudo arp-scan -I "$IFACE" --localnet 2>/dev/null)
for MAC in "${!MAC_NAMES[@]}"; do
NAME="${MAC_NAMES[$MAC]}"
IP=$(echo "$SCAN" | grep -i "$MAC" | awk '{print $1}')
[ -n "$IP" ] && update_peer "$NAME" "$IP" "online" || update_peer "$NAME" "" "offline"
done
# Escuchando eventos del kernel en tiempo real
ip monitor neigh dev "$IFACE" | while read -r event; do
IP=$(echo "$event" | awk '{print $1}')
MAC=$(echo "$event" | grep -oi '[0-9a-f:]\{17\}')
STATE=$(echo "$event" | grep -oE "REACHABLE|STALE|FAILED|DELETE")
[ -z "$STATE" ] && continue
NAME=""
[ -n "$MAC" ] && NAME="${MAC_NAMES[${MAC,,}]}"
[ -z "$NAME" ] && NAME=$(basename "$(grep -l "$IP" "$PEERS_DIR"/*.txt 2>/dev/null)" .txt)
[ -z "$NAME" ] && continue
case "$STATE" in
REACHABLE|STALE) update_peer "$NAME" "$IP" "online" ;;
FAILED|DELETE) update_peer "$NAME" "$IP" "offline" ;;
esac
done
1.3 El servicio que lo mantiene vivo
Crea ~/.config/systemd/user/lan-watch.service:
[Unit]
Description=LAN ARP watcher
After=network-online.target
[Service]
ExecStart=%h/bin/lan-watch.sh
Restart=always
[Install]
WantedBy=default.target
Luego dale vida con: systemctl --user enable --now lan-watch.service.
Paso 2 — Configuración de SSH y Autofs
2.1 Generar clave SSH dedicada para el homelab
ssh-keygen -t ed25519 -f ~/.ssh/homelab_key -C "homelab autofs"
2.2 Copiar la clave pública a cada máquina remota
ssh-copy-id -i ~/.ssh/homelab_key -o IdentitiesOnly=yes usuario@host_remoto.internal
2.3 El gran truco: SSH para Root
autofs corre como root, pero nosotros queremos usar nuestras llaves SSH de usuario.
- Autoriza a Root: Root tiene que confiar en la máquina remota. Conéctate una vez a mano usando sudo:
sudo ssh -i /home/tuusuario/.ssh/homelab_keyEsta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo. - Permisos: Asegúrate de que
/etc/fuse.conftenga habilitadouser_allow_other.
2.4 El mapa de Autofs — /etc/auto.homelan
Aquí usamos unos flags específicos para que la conexión no se quede “colgada” si el servidor se apaga.
servidor-pro -fstype=sshfs,port=22,IdentityFile=/home/tuusuario/.ssh/homelab_key,IdentitiesOnly=yes,uid=1000,gid=1000,allow_other,StrictHostKeyChecking=no,reconnect :
StrictHostKeyChecking=no: Para que no falle si la máquina remota cambia de identidad en tus pruebas.reconnect: Intenta reconectar el túnel SSH automáticamente si se cae la conexión de red.uid=1000,gid=1000: Para que tu usuario sea el dueño de los archivos montados.
2.5 El gran truco: SSH para Root
autofs corre como root, pero nosotros queremos usar nuestras llaves SSH de usuario.
- Autoriza a Root: Root tiene que confiar en la máquina remota. Conéctate una vez a mano usando sudo:
bash sudo ssh -i /home/tuusuario/.ssh/homelab_keyEsta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo. - Permisos: Asegúrate de que
/etc/fuse.conftenga habilitadouser_allow_other.
2.6 El mapa de Autofs — /etc/auto.homelan
Aquí usamos unos flags específicos para que la conexión no se quede “colgada” si el servidor se apaga.
servidor-pro -fstype=sshfs,port=22,IdentityFile=/home/tuusuario/.ssh/homelab_key,IdentitiesOnly=yes,uid=1000,gid=1000,allow_other,StrictHostKeyChecking=no,reconnect :Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo. :/home/tuusuario
StrictHostKeyChecking=no: Para que no falle si la máquina remota cambia de identidad en tus pruebas.reconnect: Intenta reconectar el túnel SSH automáticamente si se cae el WiFi.uid=1000,gid=1000: Para que tu usuario sea el dueño de los archivos montados.
Paso 3 — ¿Funciona? (Verificación)
- Resolución: Escribe
getent hosts servidor-pro.internaly debería darte la IP actual. - Visibilidad: Haz un
ls ~/peers/homelan/y deberías ver la carpeta (aunque esté vacía). - Montaje: Entra en ella:
cd ~/peers/homelan/servidor-pro. El montaje SSHFS debería activarse solo.
Tabla de “Primeros Auxilios”:
| Síntoma | Solución rápida |
|---|---|
No such file or directory |
Revisa que haya un : antes del nombre de usuario en el mapa de autofs. |
| Se queda colgado al entrar | Usa umount -l y mira si el servidor sigue vivo. |
Permission denied |
Mira si user_allow_other está descomentado en/etc/fuse.conf. |
Conclusiones de diseño
- Cero estrés: No hay polling, el script no consume nada mientras espera eventos del kernel.
- Limpio: Usamos
.internalque es el estándar oficial para redes privadas (formalmente correcta según RFC 9476 - 2023). - Ordenado: El script limpia los montajes “fantasma” cuando apagas un servidor.
En OpenSAI estaremos atentos a conocer tu experiencia, no dudes en dejar tu comentario ...y si te gustó nuestro contenido: