Mejorando un router openWRT para conseguir mayor control sobre mi red doméstica.

portico.home es el nombre del router que tiene la siguiente configuración:

system type             : Atheros AR7242 rev 1
 machine                 : Buffalo WZR-HP-G300NH2
 processor               : 0
 cpu model               : MIPS 24Kc V7.4
 BogoMIPS                : 265.42
 wait instruction        : yes
 microsecond timers      : yes
 tlb_entries             : 16
 extra interrupt vector  : yes
 hardware watchpoint     : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
 isa                     : mips1 mips2 mips32r1 mips32r2
 ASEs implemented        : mips16
 Options implemented     : tlb 4kex 4k_cache prefetch mcheck ejtag llsc dc_aliases perf_cntr_intr_bit nan_legacy nan_2008 perf
 shadow register sets    : 1
 kscratch registers      : 0
 package                 : 0
 core                    : 0
 VCED exceptions         : not available
 VCEI exceptions         : not available

Y ahora mismo funciona con la siguiente versión de openWRT:

root@portico:/etc# cat /etc/openwrt_release 
 DISTRIB_ID='OpenWrt'
 DISTRIB_RELEASE='19.07.6'
 DISTRIB_REVISION='r11278-8055e38794'
 DISTRIB_TARGET='ar71xx/generic'
 DISTRIB_ARCH='mips_24kc'
 DISTRIB_DESCRIPTION='OpenWrt 19.07.6 r11278-8055e38794'
 DISTRIB_TAINTS=''

Aunque ya lo estaba empleando como punto de acceso a Internet inalámbrico y alámbrico quería sacarle algo más de partido. Para empezar un servidor de nombres que no fuese dnsmasq porque está más o menos bien pero yo quería que existiese uno secundario, además de actualización automática de la zona, y eso sé conseguirlo con bind9.

Así que he llegado a estar cinco horas en varias tandas para conseguir que:

  • dnsmasq sólo sea un servidor DHCP con asignación de IP por dirección MAC
  • bind9 se utilice como servidor de zona principal

Aún me falta que se actualicen los nombres de aquellas máquinas que no tengan una IP determinada. No es difícil pero algo tendré que escribir porque hay que extraer la información del registro del sistema o de la tabla de asignaciones de IP.

Una vez que he conseguido también que envíe los parámetros correctos vía DHCP (pasarela, servidores DNS,…) y que él mismo utilice su propio servidor para resolver me quedaba la parte de salvaguardar todos estos cambios.

La máquina es tan pequeña en recursos que instalar algo como git o similar era absurdo. En su lugar he consultado varias fuentes y escrito un pequeño programa que realiza la copia y me envía por correo un registro de lo sucedido. He predispuesto que se ejecute todas las semanas (a menos que se lance a mano) porque a menos que haya cambios muy significativos no tiene sentido mayor frecuencia.

Cómo realizar copias

El proceso de realizar copias de seguridad fuera de esa máquina consiste en varios pasos:

  1. Crear una cuenta SSH en la máquina que albergará los datos
  2. Crear una clave SSH para el usuario root en el router y pasarla a la cuenta remota como autorizada.
  3. Asegurarnos de que se salva todo lo necesario en el archivo /etc/sysupgrade.conf
  4. Crear el script para realizar copias
  5. Instalar y configurar un programa para envío de correo (msmtp)
  6. Añadir el envío de correo al script de copias
  7. Programar su ejecución tras haberlo probado varias docenas de veces.

En este caso no estoy realizando copias completas de la memoria del router. Eso es un proceso que dejo para más tarde y ahora voy a añadir detalles concretos a los pasos anteriores.

Crear clave SSH en el router

Se utiliza el programa dropbearkey para crear la clave y luego se le pide que imprima la huella y la clave pública. Para obtener sólo ese archivo es necesario filtrar la salida y guardarla.

root@portico:~# dropbearkey -t rsa -f id_rsa 
root@portico:~# dropbearkey -y -f id_rsa | grep "^ssh-rsa " > id_rsa.pub

Envío de correo

Se instala el paquete msmtp y se configura en el archivo /etc/msmtprc indicándole:

# Cuenta predeterminada
account default

# Dónde enviar el correo y cómo
host taquiones.net
port 25
tls_starttls on

# Construír dirección del remitente SMTP
from %U@portico.home

# Activar registro de sucesos
syslog LOG_MAIL

El envío es de lo más espartano. Se le indica a dónde va y se le deben suministrar todas las cabeceras necesarias.

Copias de seguridad

Las copias se realizan con un script como el siguiente:

#!/bin/sh

VERSION=0.1
BACKUP_FILE="/tmp/backup-$(cat /proc/sys/kernel/hostname)-$(date +%F).tgz"
TMP=/tmp/backup-$$.log

(
     # Lista de paquetes instalados
     opkg list-installed > /etc/config/installed.packages
      # Crear copia  
sysupgrade -v --create-backup $BACKUP_FILE 
# Enviar copia a servidor  
echo "Enviando copia a backup.home ..."  
scp $BACKUP_FILE ocs@backup.home:domus/portico.home/ 
# Borrar copia  echo "Borrando copia $BACKUP_FILE" 
rm -f $BACKUP_FILE
) > $TMP

(
  echo -e "Subject: [BACKUP portico.home] $(date +%F)\n\n" 
  cat $TMP
) | msmtp root@taquiones.net

rm -f $TMP

El script emplea un mecanismo del propio sistema operativo llamado sysupgrade que crea la copia teniendo en cuenta todo lo que ha cambiado en la configuración y todo lo que se le indica que salve siempre, y uno previo que guarda la lista de paquetes instalados por si es necesario recuperar de golpe la instalación.

El resultado del envío es sencillo dada la capacidad del router:

Saving config files…
 etc/bind/bind.keys
 etc/bind/db.0
 etc/bind/db.127
 etc/bind/db.192.168.100
 etc/bind/db.255
 etc/bind/db.home
 etc/bind/db.local
 etc/bind/db.root
 etc/bind/named.conf
 etc/config/adblock
 etc/config/ddns
 etc/config/ddns-opkg
 etc/config/dhcp
 etc/config/dhcp-opkg
 etc/config/dhcp.orig
 etc/config/dropbear
 etc/config/firewall
 etc/config/fstab
 etc/config/installed.packages
 etc/config/luci
 etc/config/luci-opkg
 etc/config/network
 etc/config/openvpn
 etc/config/openvpn_recipes
 etc/config/rpcd
 etc/config/simple-adblock
 etc/config/snort
 etc/config/system
 etc/config/ubootenv
 etc/config/ucitrack
 etc/config/ucitrack-opkg
 etc/config/uhttpd
 etc/config/wireless
 etc/crontabs/cron.update
 etc/crontabs/root
 etc/dropbear/authorized_keys
 etc/dropbear/dropbear_rsa_host_key
 etc/ethers
 etc/group
 etc/hosts
 etc/inittab
 etc/luci-uploads/.placeholder
 etc/msmtprc
 etc/opkg/keys/0b26f36ae0f4106d
 etc/opkg/keys/1035ac73cc4e59e3
 etc/opkg/keys/5151f69420c3f508
 etc/opkg/keys/72a57f2191b211e0
 etc/opkg/keys/792d9d9b39f180dc
 etc/opkg/keys/9ef4694208102c43
 etc/opkg/keys/b26f36ae0f4106d
 etc/opkg/keys/b2d571e0880ff617
 etc/opkg/keys/b5043e70f9a75cde
 etc/opkg/keys/c10b9afab19ee428
 etc/opkg/keys/dace9d4df16896bf
 etc/opkg/keys/dd6de0d06bbd3d85
 etc/opkg/keys/f94b9dd6febac963
 etc/passwd
 etc/profile
 etc/rc.local
 etc/resolv.conf
 etc/shadow
 etc/shells
 etc/sysctl.conf
 etc/sysupgrade.conf
 root/.ssh/id_dropbear
 root/.ssh/id_dropbear.pub
 root/.ssh/known_hosts
 usr/local/bin/backup.sh
 Enviando copia a backup.home …
 Borrando copia /tmp/backup-portico-2021-01-26.tgz

Referencias