"Después del juego es antes del juego"
Sepp Herberger

jueves, 24 de febrero de 2022

NAS sobre DLink DIR 860L-B1 y OpenWRT

Seguimos haciendo cosas con los puntos wifi DLink DIR 860L-B1. Ahora vamos a ver como montar un servidor NAS que tenga al menos los servicios samba y sshfs. Opcionalmente se podrían montar otros servicios adicionales como NFS, RemoteFS, SFTP...

La almacenamiento será sobre disco duro externo de 1TB conectado al puerto USB 3.0 del DLink.

En un principio he intentado hacerlo funcionar con OpenWRT 21.02.1, que ya había utilizado para el montaje del routed client, pero he tenido estos dos problemas:
  • Los paquetes de samba4 ocupan una burrada, no hay espacio en los 16Mb de memoria SD del dispositivo para ellos.
  • En esta versión de OpenWRT no hay samba3. Existe un paquete llamado ksmbd-server que emula samba v3 a nivel de módulo del nucleo. El problema es que en las pruebas que he hecho es inestable y se cae con frecuencia.
Visto lo visto, he vuelto a usar OpenWRT 15.05, que sigue siendo una versión muy estable con buen funcionamiento.

Una vez cargado el sistema y hechas las configuraciones iniciales básicas, veamos como queda. La red pide una IP por DHCP en el puerto "lan" (hemos dado de alta el equipo en el arbol ldap con el nombre "nas" y una IP fija)
# cat /etc/config/network 
config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fdda:86a9:b1ad::/48'

config interface 'lan'
	option ifname 'eth0.1'
	option force_link '1'
	option macaddr '9a:45:4e:fb:75:c1'
	option type 'bridge'
	option proto 'dhcp'
	
config interface 'wan'
	option ifname 'eth0.2'
	option force_link '1'
	option macaddr '9a:45:4e:fb:75:c2'
	option proto 'dhcp'

config interface 'wan6'
	option ifname 'eth0.2'
	option proto 'dhcpv6'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option ports '1 2 3 4 6t'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option ports '0 6t'    
Los interfaces wifi quedan apagados:
# cat /etc/config/wireless 
config wifi-device  radio0
	option type     mac80211
	option channel  36
	option hwmode	11a
	option path	'pci0000:00/0000:00:00.0/0000:01:00.0'
	option htmode	VHT80
	# REMOVE THIS LINE TO ENABLE WIFI:
	option disabled 1

config wifi-iface
	option device   radio0
	option network  lan
	option mode     ap
	option ssid     OpenWrt
	option encryption none

config wifi-device  radio1
	option type     mac80211
	option channel  11
	option hwmode	11g
	option path	'pci0000:00/0000:00:01.0/0000:02:00.0'
	option htmode	HT20
	# REMOVE THIS LINE TO ENABLE WIFI:
	option disabled 1

config wifi-iface
	option device   radio1
	option network  lan
	option mode     ap
	option ssid     OpenWrt
	option encryption none
Creamos un usuario normal para usar luego en samba. En /etc/passwd añadimos el usuario "nas":
# cat /etc/passwd
root:x:0:0:root:/root:/bin/ash
daemon:*:1:1:daemon:/var:/bin/false
ftp:*:55:55:ftp:/home/ftp:/bin/false
network:*:101:101:network:/var:/bin/false
nobody:*:65534:65534:nobody:/var:/bin/false
nas:*:1000:65534:nas:/var:/bin/ash
Y definimos una contraseña para él:
# passwd nas
El montaje del disco externo USB necesita estos paquetes:
# opkg update
# opkg install fdisk block-mount e2fsprogs kmod-fs-ext4 kmod-usb-storage kmod-usb2 kmod-usb3
Formateamos el disco externo (aconsejamos usar formato ext3) y lo pinchamos en el puerto usb. Con:
# fdisk -l
Sacamos un listado de los discos conectados, nuestro disco duro debe aparecer como /dev/sdaX. A continuación creamos el punto de montaje:
# mkdir /disco
# chown nas: /disco
# chmod 777 /disco
Modificamos el fichero "fstab" para que se automonte el disco en el arranque:
# cat /etc/config/fstab 
...
config mount
	option enabled '1'
	option device '/dev/sda1'
	option target '/disco'
Instalamos paquetes para permitir conexiones y transferencia de datos con sshfs, scp y rsync:
# opkg update
# opkg install openssh-sftp-server rsync
Y vamos a la configuración de samba:
# opkg update
# opkg install kmod-usb-storage block-mount samba36-server luci-app-samba
La configuración sería:
# cat /etc/config/samba 
config samba
	option workgroup 'WORKGROUP'
	option homes '1'
	option name 'NAS'
	option description 'NAS'

config sambashare
	option name 'datos'
	option path '/disco'
	option read_only 'no'
	option guest_ok 'no'
	option create_mask '777'
	option dir_mask '777'
   	option users 'nas'
Hay que crear el usuario "nas" en samba, con la contraseña que nos pareza conveniente:
# smbpasswd -a nas
Tras esto reiniciamos y probamos a montar desde una maquina cliente. En una máquina Linux que hará de cliente vamos a probar a montar mediante sshfs:
# sshfs root@nas:/disco /mnt
# mount
....
root@nas:/disco on /mnt type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
# umount /mnt
Vamos a por samba. Samba casi siempre da problemas de permisos con el sistema de ficheros compartido. Para evitarlo, una vez montado el disco duro modificamos de nuevo los permisos de la carpeta (esto se debe a que cuando la partición montada es tipo extX no existe el parametro umask):
# chmod 777 /disco
Y ahora en un cliente Linux probamos a montar usando samba/cifs y creamos un directorio y un fichero para confirmar que todo va bien:
# mount -t cifs //172.19.231.150/datos /mnt -o username=nas,password=xxxx
# mount
....
//172.19.X.Y/datos on /mnt type cifs (rw,relatime,vers=1.0,cache=strict,username=nas,domain=NAS,uid=0,noforceuid,gid=0,noforcegid,addr=172.19.X.Y,unix,posixpaths,serverino,acl,rsize=1048576,wsize=1048576,actimeo=1)
# mkdir /mnt/prueba
# touch /mnt/prueba/test
# umount
Por último, para clientes Windows se realiza el montaje accediendo desde el explorador de archivos a la ruta "\\nas\disco". Pedirá usuario y contraseña y listo...excepto en Windows 10, que da un error derivado de que en dicho sistema se han puesto tiquismiquis con la versión de SMB soportada. Todo el asunto está descrito en este enlace, para que funcione simplemente hay que activar el soporte para SMB 1.0 siguiendo estos pasos:
  • Pulsar Windows Key + R, teclea "optionalfeatures.exe" y pulsa Enter. Sale una ventana muy años 90.
  • Buscar la sección "SMB 1.0/CIFS File Sharing Support" o similar, abrirla.
  • Marcar SMB 1.0/CIFS Client. Desmarcar MB 1.0/CIFS Automatic Removal y SMB 1.0/CIFS Server.
  • Reiniciar y acceder a "\\nas\disco" para verificar que funciona.
Por supuesto, todo esto es un ejemplo sencillo. Nada impide compartir distintas carpetas con distintos permisos de acceso dentro del disco externo, usando recursos samba diferentes. Eso queda al libre albedrío de cada cual.

Al ser un sistema donde el disco va por USB no es lo más rápido del mundo, pero queda ideal para copias de seguridad y tareas que no requieran una velocidad de transferencia excesiva.

Y poco mas se puede probar, simplemente estoy mirando la posibilidad de usar syncthing para mantener el disco NAS sincronizado con otor sistema de ficheros, en plan "copia de seguridad en tiempo real", a ver que tal rinde.

Ya iremos contando. До свидания!

viernes, 18 de febrero de 2022

Multiseat en Windows con Aster

Ya he tratado varias veces el tema del multiseat en este blog. En Linux no hay mayor problema ya que se soporta de forma nativa, sin añadir ningún software adicional, como ya vimos aquí.

En Windows por desgracia esto no es así y, por tanto, hay que usar un sofware comercial. He localizado varios que se han ido quedando por el camino a lo largo de los años, pero uno de ellos permanece y funciona perfectamente para Windows 11 y anteriores: el Aster de Ibik. Evidentemente es un software de pago, valiendo hoy unos 70€ la licencia para hacer un pc bipuesto y permitir trabajar a 2 usuarios simultáneamente, cada uno con su monitor, teclado y ratón. Debemos valorar si esa inversión de 70€ merecen la pena antes de comprar un nuevo PC o no.

Afortunadamente se puede bajar una versión de prueba que permite probarlo y evaluarlo durante un mes antes de tomar una decisión.

Antes de seguir hay que recordar que además de 2 monitores, 2 teclados y 2 ratones, el único PC donde montamos el multiseat debe tener suficiente RAM (8Gb está bien) y dos tarjetas gráficas, normalmente una en placa base y otra en un puerto PCIe. En estos tiempos revueltos donde las tarjetas gráficas cuestan una burrada gracias al burbujón de las criptomonedas y a la escasez de chips, he podido probar con una tarjeta gráfica USB3, que tengo para mis enredos, como esta:
... y puedo confirmar que funciona decentemente. El coste de este adaptador USB3-VGA Hagibis es de unos 15-20 euros.

Descargando la versión de prueba de la aplicación y configurándola según el manual verificamos que funciona. Podemos verlo en ambos puestos de la siguiente foto, cada uno con una sesión de usuario distinta y conectados al mismo PC:
Mostramos la parte trasera y delantera del PC para poder ver el cableado:
En la parte trasera tenemos un teclado y un ratón conectados a los puertos PS/2, un monitor conectado a la tarjeta VGA y el otro monitor conectado a la tarjeta USB3-VGA (la cual está enchufada a un puerto USB 3.0). En la parte delantera tenemos conectado el otro teclado y ratón USB.

La configuración de la aplicación Aster es muy intuitiva (a diferencia de Linux, donde teníamos que meternos con ficheros de configuración editados a mano) usando un interface gráfico y siguiendo el manual que hemos enlazado antes:
Por todo lo demás, he tenido a los usuarios trabajando durante un mes con este sistema, usando el navegador web y la aplicación Autocad 2019 y todo ha ido fluido, si notar ralentizamiento apreciable. Por tanto queda como una opción a considerar cuando queramos dotar o modernizar un aula. Lástima que no haya alternativa gratis como en en Linux....

Out!

martes, 15 de febrero de 2022

Configuración de DLink DIR 860L-B1 como "routed client" para conectar como cliente a una red wifi.

De este tema ya he hablado en anteriores posts:
  1. OpenWRT en DLink DIR 860L-B1: http://2tazasdelinux.blogspot.com/2020/11/instalar-openwrt-en-los-puntos-de.html
  2. Routed client con NAT: http://2tazasdelinux.blogspot.com/2017/03/configuracion-de-openwrt-como-routed.html
  3. Routed client con relayd: http://2tazasdelinux.blogspot.com/2017/04/configuracion-de-openwrt-como-routed.html
Pero ahora voy a documentar como hacerlo funcionar en nuestros famosos y ociosos DLink DIR 860L-B1.

Recapitulemos: un Routed Client es la configuración por defecto de OpenWRT. En ella el router interconecta la red inalámbrica con la red LAN del dispositivo. Como la mayoria de los drivers wifi no permiten hacer un "bridge" si el dispositivo se conecta a la red wifi en modo cliente, cuando queremos interconectar ambas redes tenemos que configurarlo a mano enrutando el tráfico entre uno y otro interfaz. Y como hacer eso es lo que contaremos aquí.

¿Qué utilidad tiene esto?: pues es algo similiar a una "tarjeta wifi" configurada y lista para usar en cualquier momento en un dispositivo que necesite conexión y no nos llegue la red cableada. El DLink se conecta a la red wifi del centro y con el cable de red conectamos a los puertos ethernet hasta 4 dispositivos, de tal manera que esos tienen acceso a la red del centro.

Si por ejemplo tenemos un PC de sobremesa en un area donde no llega red cableada (o llega, pero hay una avería de electrónica de red), simplemente con enchufarlo por un cable de red a un DLink configurado como contamos aqui tendrá acceso a la red del centro de forma inmediata, sin mas aspavientos y sin configurar nada en el PC.

1. Cargar OpenWRT en el DLink.

Aunque en el artículo anterior contamos como instalar OpenWRT y propusimos poner la versión 15.05, ahora he hecho pruebas con versiones posteriores y he visto que la versión 21.02.1 funciona mejor que la 15.05.

Por tanto lo cargamos la imagen como contamos en el articulo anterior, pero ahora usamos OpenWrt 21.02.1 r16325-88151b8303. En cualquier momento podremos encontrar la última imagen en la página oficial de OpenWRT dedicada a nuestro DLink.

Una vez instalado el OpenWRT hay dos alternativas para configurar la interconexión entre la wifi y los puertos ethernet del DLink:
  • Usando IP Masquerading y haciendo NAT.
  • Usando relayd, que crea un "pseudobridge" por software que interconecta el tráfico entre ambas redes.
Veremos cada uno de los casos y sus ventajas e inconvenientes.

2. Usando IP masquerading.

El esquema sería este:


La conexión wifi recibe una IP de nuestra red 172.X.Y.Z y su interfaz ethernet tiene la IP 192.168.1.1. Sobre esa interfaz corre un servidor DHCP que da direcciones a los clientes dentro de ese rango. Ambas redes están interconectadas mediante IP masquerading como se viene haciendo de toda la vida para cualquier subred privada.

Los PC u otros dispositivos conectados a los puertos ethernet, con direccionamiento 192.168.1.X, son enrutados a través de la conexión wifi hacia la red del centro.

Para lograr esto hay que realizar la siguiente configuración en los ficheros de OpenWRT:

Primero la configuración de red:
# cat /etc/config/network
config interface 'loopback'
    option device 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config globals 'globals'
    option packet_steering '1'
    option ula_prefix 'fdd3:89a2:bcfc::/48'

config device
    option name 'br-lan'
    option type 'bridge'
    list ports 'lan1'
    list ports 'lan2'
    list ports 'lan3'
    list ports 'lan4'

config device
    option name 'lan1'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan2'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan3'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan4'
    option macaddr '90:8d:78:59:c9:5c'

config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option ipaddr '192.168.1.1'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option force_link '1'
    option ip6assign '60'

config device
    option name 'wan'
    option macaddr '90:8d:78:59:c9:5f'

config interface 'wan'
    option device 'wan'
    option proto 'dhcp'

config interface 'wan6'
    option device 'wan'
    option proto 'dhcpv6'

config interface 'wwan'
    option proto 'dhcp'
Como vemos hay 3 interfaces
  • lan: correspondiente al bridge que une los 4 puertos LAN ethernet del router, con IP 192.168.1.1
  • wan: correspondiente al puerto wan del router (el amarillo), que no usamos para nada.
  • wwan: correspondiente a la conexión wifi, que se configura por dhcp.
Ahora la configuración de la wifi:
# cat /etc/config/wireless

config wifi-device 'radio0' #Esde dispostivo es de la red de 5Ghz, no la uso, lo dejo desactivado.
    option type 'mac80211'
    option channel '36'
    option hwmode '11a'
    option path '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
    option htmode 'VHT80'
    option disabled '1'

config wifi-device 'radio1'
    option type 'mac80211'
    option channel '11'
    option hwmode '11g'
    option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
    option cell_density '0'

config wifi-iface 'wifinet0'
    option device 'radio1'
    option mode 'sta'
    option network 'wwan'
    option ssid 'SSID_RED_EDUCATIVA'
    option encryption 'psk2'
    option key 'PASSWD_RED_EDUCATIVA'
Conectamos el interface de red wwan/radio1 indicando la contraseña y clave de la red educativa. Esto lo adaptarás según la wifi que quieras usar de tu centro. El DLink se conecta, autentica y recibe una IP por DHCP. Para facilitar la gestión recomiendo que la tarjeta wifi tenga configurada una IP fija en el servidor DHCP del centro.

Ahora vamos a ver el servidor DHCP:
#cat /etc/config/dhcp
config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option filterwin2k '0'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option nonegcache '0'
    option authoritative '1'
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
    option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
    option nonwildcard '1'
    option localservice '1'
    option ednspacket_max '1232'

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
    option dhcpv4 'server'
    option dhcpv6 'server'
    option ra 'server'
    option ra_slaac '1'
    option ignore '0'
    list ra_flags 'managed-config'
    list ra_flags 'other-config'

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

config odhcpd 'odhcpd'
    option maindhcp '0'
    option leasefile '/tmp/hosts/odhcpd'
    option leasetrigger '/usr/sbin/odhcpd-update'
    option loglevel '4'
Simplemente se define un servidor dhcp sobre el interface lan (el que da conexión cableada por los 4 puertos ethernet), que repartirá direcciones en el rango 192.168.1.100 a 192.168.1.150.

Ahora vemos la configuracion del firewall:
# cat /etc/config/firewall

config defaults
    option syn_flood '1'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'

config zone
    option name 'lan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'
    list network 'lan'

config zone
    option name 'wwan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'
    option masq '1'
    list network 'wwan'

config zone
    option name 'wan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'
    option mtu_fix '1'
    list network 'wan'
    list network 'wan6'

config forwarding
    option src 'lan'
    option dest 'wwan'

config rule
    option name 'Allow-DHCP-Renew'
    option src 'wan'
    option proto 'udp'
    option dest_port '68'
    option target 'ACCEPT'
    option family 'ipv4'
....
.... esta parte queda sin tocar....
....

....
config include
    option path '/etc/firewall.user'
Basicamente se permite el forwarding entre lan y wwan, activando el masquerading en wwan. De esta manera el tráfico se enrutará entre ambos interfaces y redes.

3. Usando relayd.

En esta solución también la conexión wifi recibe una IP de nuestra red 172.X.Y.Z y su interfaz ethernet tiene la IP 192.168.1.1. Pero aquí acaban las similitudes con NAT. El servicio DHCP lo da el servidor del centro, por lo que las IP que reciben los clientes son de dicha red, del tipo 172.X.Y.W. Ambas redes están interconectadas mediante un demonio relayd que pasa el tráfico entre ellas por software (por eso a esta solución se le llama "pseudobridge").

Los PC u otros dispositivos conectados a los puertos ethernet tienen direccionamiento 172.X.Y.W, y gracias al relayd están lógicamente en la red del centro pudiendo ser alcanzados por ping u otro tipo de conexión. Por ejemplo, si conectamos una impresora por cable de red al DLink se podrá acceder a su IP para imprimir desde cualquier punto del centro.

Para lograr esto hay que realizar la configuración que datallaremos a continuación.

Instalar y activar el servicio relayd:
# opkg update
# opkg install relayd
# /etc/init.d/relayd enable
# /etc/init.d/relayd restart
La configuración de red:
# cat /etc/config/network

config interface 'loopback'
    option device 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config globals 'globals'
    option packet_steering '1'
    option ula_prefix 'fdd3:89a2:bcfc::/48'

config device
    option name 'br-lan'
    option type 'bridge'
    list ports 'lan1'
    list ports 'lan2'
    list ports 'lan3'
    list ports 'lan4'

config device
    option name 'lan1'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan2'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan3'
    option macaddr '90:8d:78:59:c9:5c'

config device
    option name 'lan4'
    option macaddr '90:8d:78:59:c9:5c'

config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option ipaddr '192.168.1.1'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option force_link '1'
    option ip6assign '60'

config device
    option name 'wan'
    option macaddr '90:8d:78:59:c9:5f'

config interface 'wan'
    option device 'wan'
    option proto 'dhcp'

config interface 'wan6'
    option device 'wan'
    option proto 'dhcpv6'

config interface 'wwan'
    option proto 'dhcp'

config 'interface' 'stabridge'
    option 'proto'      'relay'
    option 'network'    'lan wwan'
En este sistema hay también 3 interfaces:
  • lan: correspondiente al bridge que une los 4 puertos LAN ethernet del router, con IP 192.168.1.1
  • wan: correspondiente al puerto wan del router (el amarillo), que no usamos para nada.
  • wwan: correspondiente a la conexión wifi, que se configura por dhcp.
Adicionalmente interconectamos los interfaces lan y wwan mediante el demonio relayd.

Ahora la configuración de la wifi, que es totalmente igual a la del caso anterior:
# cat /etc/config/wireless

config wifi-device 'radio0' #Esde dispostivo es de la red de 5Ghz, no la uso, lo dejo desactivado.
    option type 'mac80211'
    option channel '36'
    option hwmode '11a'
    option path '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
    option htmode 'VHT80'
    option disabled '1'

config wifi-device 'radio1'
    option type 'mac80211'
    option channel '11'
    option hwmode '11g'
    option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
    option cell_density '0'

config wifi-iface 'wifinet0'
    option device 'radio1'
    option mode 'sta'
    option network 'wwan'
    option ssid 'SSID_RED_EDUCATIVA'
    option encryption 'psk2'
    option key 'PASSWD_RED_EDUCATIVA'
Conectamos el interface de red wwan/radio1 indicando la contraseña y clave de la red educativa. Esto lo adaptarás según la wifi que quieras usar de tu centro. El DLink se conecta, autentica y recibe una IP por DHCP. Para facilitar la gestión recomiendo que la tarjeta wifi tenga configurada una IP fija en el servidor DHCP del centro.

Ahora vamos a ver el servidor DHCP:
#cat /etc/config/dhcp
config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option filterwin2k '0'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option nonegcache '0'
    option authoritative '1'
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
    option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
    option nonwildcard '1'
    option localservice '1'
    option ednspacket_max '1232'

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
    option dhcpv4 'server'
    option dhcpv6 'server'
    option ra 'server'
    option ra_slaac '1'
    option ignore '1'
    list ra_flags 'managed-config'
    list ra_flags 'other-config'

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

config odhcpd 'odhcpd'
    option maindhcp '0'
    option leasefile '/tmp/hosts/odhcpd'
    option leasetrigger '/usr/sbin/odhcpd-update'
    option loglevel '4'
El servidor DHCP local está desactivado tanto en el interface wan como en el lan. Las direcciones IP para los puestos que se conecten por la red cableada llegarán desde el servidor DHCP del centro.

Ahora vemos la configuracion del firewall:
# cat /etc/config/firewall
config defaults
	option syn_flood '1'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'

config zone
    option name 'lan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'
    list network 'lan'
    list network 'wwan'
....
.... esta parte queda sin tocar....
....
config include
    option path '/etc/firewall.user'
Simplemente permitimos todo tráfico (INPUT/OUTPUT/FORWARD) entre lan y wwan. El resto permanece igual.

4. Consideraciones finales.

Varias cosas importantes a tener en cuenta:
  • Usando NAT/Masquerading: hay que recordar que los equipos conectados por cable al DLink están en una red privada, con direccionamiento 192.168.1.X, por lo que aunque ellos tendrán acceso hacia todo el mundo, desde la red del centro no se podrá acceder a ellos.
  • Relayd: en este caso los equipos si están en la red del centro, con IP 172.X.Y.Z y se puede interactuar (ping, ssh, imprimir, etc) con ellos. Pero hemos tenido un problema grave al empezar a trabajar: en nuestro DLink, usando relayd, las respuestas DHCP no llegan. El puesto conectado al interface lan pide una IP, la petición llega al servidor DHCP del centro, se manda un paquete con la IP y al llegar al demonio relayd se pierde. Es un problema documentado en algunos router con OpenWRT y no está solucionado. En el siguiente punto vemos como hacer que funcione todo a pesar de este problema.
  • Relayd: como acabamos de decir, en nuestro DLink los paquetes DHCP llegados de fuera se pierden. Por ello, para que los equipos conectados al DLink mediante red cableada tengan red debemos configurarles la IP, puerta de enlace y DNS de forma estática a mano. Con este trámite todo funciona perfectamente.
  • Velocidad: no olvidemos que todo está conectado a través de un enlace wifi "G" que sería el cuello de botella. En las pruebas realizadas la descarga está entre 5-10MB/s. Esto hace que trabajar con un home montado mediante NFS sea muy lento, por lo que se aconseja (como ya hacemos con los portátiles de nuestros centros) trabajar con usuarios con home local.
  • Si probamos ambos métodos, NAT y relayd, se aconseja resetear la configuración del OpenWRT para empezar desde un sistema limpio cada prueba. Esto se hace con:
    # firstboot
    # reboot -f
    
Y con esto acabamos este nuevo montaje OpenWRT. Conforme vaya probando otras soluciones las iré poniendo aquí, tengo pensado probar a montar algo como un servidor NAS aprovechando el puerto USB 3, por ejemplo.

Out!

lunes, 14 de febrero de 2022

Documentación FCT en formato Google Doc

En los centros que tienen Ciclos Formativos los tutores tienen que rellenar todos los años una extensa documentación que está disponible en formato ODT, DOC y PDF. Estos documentos están diseñados de una manera que deja bastante que desear en cuanto a usabilidad y portabilidad, con algunos detalles bastante irritantes. Todos los cursos hay problemas con estas plantillas a la hora de abrirlas entre distintos sistemas operativos y programas ofimáticos.



Para intentar evitar estas dificultades hemos hecho una version Google Doc de todos estos documentos que puede ser rellenada en de forma online usando el navegador. Este es el enlace a la carpeta compartida donde están los documentos: pulsa aquí. Se supone que esto los hace mas portables y reutilzables.

La carpeta de Google Drive compartida es de solo lectura, por lo que cada cual tendrá que hacer una copia de los documentos en su drive local para trabajar con ellos. A ver si ya nos quitamos este quebradero de cabeza de una vez.

domingo, 13 de febrero de 2022

Desactivar encendido repentino en Windows 10

Gran misterio de los que te asaltan a traición por los pasillos: "¿qué le has hecho a los ordenadores que se encienden solos cuando pasas al lado de ellos?". Sucedía en un aula de ciclos formativos con Windows 10. Investigando en este interesante mensaje sobre encendidos intempestivos veo que la única causa posible es que están configurados por defecto para salir de hibernación/suspensión ante eventos de teclado y/o ratón. En una consola de administrador, con el comando:
powercfg -devicequery wake_armed
Nos lista los dispositivos que están "armados" para despertar el equipo ante un estímulo externo. Supongamos que en ese listado aparecen teclado y/o ratón con las denominaciones "Teclado PS/2 estándar" y "Mouse compatible con HID". Con los comandos:
powercfg -devicedisablewake "Teclado PS/2 estándar"
powercfg -devicedisablewake "Mouse compatible con HID"
Desactivamos estos encendidos repentinos de forma permanente y el problema deja de suceder. El inconveniente es que si cambiamos el teclado y el ratón y pasan a llamarse de otra manera puede que vuelva a presentarse el problema.

¿Y por qué al pasar al lado del PC se producía un encendido causado por el ratón? Pues la única explicación que encuentro es que pasaban al trote y hacían vibrar el suelo, la mesa y el ratón.

martes, 26 de octubre de 2021

Extraer los nombres de los interfaces de red levantados y con enlace activo.

Si queremos sacar la lista de interfaces de red que hay levantadas y con señal (LINK STATE UP) en el cable en un PC con Linux, podemos hacerlo con esta secuencia de comandos:
interfaces_up=$(ip link show | grep "state UP" | cut -d" " -f2 |  grep -v "lo:" | tr -d ":" | tr "\n" " ")
echo $interfaces_up
Todo queda en una única línea para que, por ejemplo, podamos iterar por ellas mediante un comando for.

Libros Santillana y Flash. Actualización 2021.

Ya tratamos el tema de los libros digitales Santillana en 2017 y 2018. En 2019 y 2020 Santillana no perpetró ninguna nueva versión, pero este año no ha podido evitar brindarnos una nueva edición de sus libros de Francés. Vemos que sigue apostando por la novedosa tecnología de Flash, aunque afortunadamente ya no incluye los audios en cintas de cassette.

Tenemos los libros de Parachute 1, 2, 3 y 4 para eso y C'est à dire para Bachillerato, distribuidos cada uno en un fichero .zip. Tras descomprimirlos vemos su contenido:
drwxrwsrwx 3 user user     4096 ene 16  2020 app.app
-rwxrwxrwx 1 user user   303687 jun  1 16:45 browser.swf
drwxrwsrwx 4 user user    53248 ago 10  2020 contenido
drwxrwsrwx 2 user user    36864 ago 10  2020 curso
-rwxrwxrwx 1 user user     1214 jun  1 16:45 exeBrowser.htm
-rwxrwxrwx 1 user user 11487542 jun  1 16:45 exeLinux
-rwxrwxrwx 1 user user       98 jun  1 16:56 exeMac
-rwxrwxrwx 1 user user  5547573 jun  1 16:45 exeWin.exe
-rwxrwxrwx 1 user user     1598 jun  1 16:45 lisez-moi.txt
drwxrwsrwx 3 user user     4096 ene 16  2020 macsc.app
drwxrwsrwx 2 user user     4096 ago 10  2020 modulos
drwxrwsrwx 2 user user     4096 ago 10  2020 recursos
-rw-rw-r-- 1 user user   328028 oct 19 09:41 strace.log
Me llama la atención que en 2018 habían quitado la versión web/flash (exeBrowser.htm) dejando solo las versiones basadas en un ejecutable (Linux, Windows y OSX), pero al parecer de nuevo la han recuperado.

Como nosotros tenemos sistemas Linux hay varias opciones para ejecutar este software:
  1. Lanzando el ejecutable de Linux exeLinux directamente con un fichero .destkop como éste:
    # cat Parachute1.desktop
    #!/usr/bin/env xdg-open
    [Desktop Entry]
    Name=Parachute 1 - 2021
    Version=4.1.0.0
    Type=Application
    Terminal=true
    StartupNotify=true
    Exec=/home/ruta/PARACHUTE1/exeLinux
    Categories=Education
    Icon=/home/ruta/PARACHUTE1/recursos/intro01.jpg
    Path=/home/ruta/PARACHUTE1
    
    Para que funcione la versión de Linux hay que instalar con apt-get varias librerias de i386, como ya contamos aquí y ni aun así funciona siempre. Por ejemplo, en ciertos PC con tarjeta nVidia y driver nouveau me he encontrado con que fallan al ejecutarse, mostrando este mensaje y abortando:
    libpng warning : Application jmp_buf size changed 
    Violacion de segmento
    
    No he encontrado manera de hacerlo funcionar. Otro problema que tiene el exeLinux es que no puede mostrar los vídeos, teniendo que abrirlos aparte como ya indicamos aquí. Seguramente es un problema derivado del Flash embebido en el ejecutable.

    Adicionalmente, si mostramos los vídeos aparte no se verán los subtítulos, ya que vienen en un formato particular. Como si no hubiera formatos de subtítulos previos, Santillana ha decidido brindar al mundo su propio formato.
  2. Lanzando el ejecutable de Windows exeWin.exe mediante wine, con un .destkop como este:
    # cat Parachute1.desktop
    #!/usr/bin/env xdg-open
    [Desktop Entry]
    Name=Parachute 1 - 2021
    Version=4.1.0.0
    Type=Application
    Terminal=true
    StartupNotify=true
    Exec=wine /home/ruta/PARACHUTE1/exeWin.exe
    Categories=Education
    Icon=/home/ruta/PARACHUTE1/recursos/intro01.jpg
    Path=/home/ruta/PARACHUTE1
    
    En este caso el programa se abre bien a pantalla completa en todas las máquinas que he probado, pero al ir mediante wine es sensiblemente mas lento e inestable.

    El exeWin.exe muestra el mismo problema que el caso anterior a la hora de mostrar los vídeos.

  3. Lanzando el exeBrowser.htm, mediante un navegador que sopoorte Flash. Gracias a mis compañeros de otros centro supe que el navegador palemoon sigue dando soporte a la última versión de Flash que se liberó. Usaríamos este fichero .desktop:
    # cat Parachute1.desktop
    #!/usr/bin/env xdg-open
    [Desktop Entry]
    Name=Parachute 1 - 2021
    Version=4.1.0.0
    Type=Application
    Terminal=true
    StartupNotify=true
    Exec=palemoon /home/ruta/PARACHUTE1/exeBrowser.htm
    Categories=Education
    Icon=/home/ruta/PARACHUTE1/recursos/intro01.jpg
    Path=/home/ruta/PARACHUTE1
    
    De esta manera se abre bien, dentro de una ventana de navegador web y se reproducen los vídeos (y subtitulos) sin mayor problema. Es una pena que por necedad de Santillana tengamos que andar trabajando con navegadores antiguos, pero es lo que hay.

    Para que se abra el .htm desde el navegador hay que dar permisos para que Flash pueda abrir la ruta (en nuestro ejemplo /home/ruta/PARACHUTE1) tal como contamos en esta entrada. Podéis ver allí con detalle como hacerlo.

    El palemoon lo he descargado desde este enlace. El fichero palemoon_29.4.1-1.gtk2_amd64.deb se instala directamente en nuestro Ubuntu 18.04 mediante tarea puppet sin mayor problema.
Bueno, dentro de dos o tres años nos vemos de nuevo con un Ubuntu actualizado y un Santillana todavía con Flash. Eso si que es resistencia al cambio.

lunes, 5 de julio de 2021

Inconsistencia en el repositorio local de paquetes "reprepro"

Ya comenté que tengo un repositorio local de paquetes construido con reprepro, que me viene muy bien para instalar paquetes de Ubuntu que no vienen en los repositorios oficiales y que habria que descargar e instalar de forma manual en cada máquina. Tambien ofrece muy buena integración con pkgsync, que lleva mal el usar paquetes ajenos a los repositorios.

Hace poco estaba quitando un paquete del repositorio y a mitad de proceso he tenido un problema de dificultades (como dijo el ministro) y se ha cerrado la conexión. El paquete ha quedado medio quitado, medio no, ya que al parecer la desinstalación no es un proceso transaccional. De esta manera, si hacia:
# cd /var/www/repositorio/centro 
# reprepro list bionic
El paquete no aparecía en el repositorio, pero si en los clientes hacía:
# apt-cache search paquete-problematico
Si que aparecía y podía instalarlo. Por otro lado, si intentaba eliminar el paquete:
# reprepro remove bionic paquete-problematico
Not removed as not found: ...
Exporting indices...
Me decía que no estaba, pero si intentaba añadirlo de nuevo:
# reprepro --ask-passphrase includedeb bionic paquete-problematico-vX.Y.Z.deb 
Within references.db subtable references at put: BDB0067 DB_KEYEXIST: Key/data pair already exists
Me decía que no podía añadirlo ya que el registro estaba duplicado. Reprepro utiliza internamente una base de datos en formato Berkeley DB que carece de herramientas sencillas para manejarla. ¿Cómo salir del atolladero y librarnos de este paquete de Schörindger?

Reprepro tiene poca documentación y soporte. Tras buscar en Google y encontrar gente con el mismo problema sin solución, he ido a leer la página de manual (lo último que se lee antes de que se explote todo) y he dado con los comandos:
# reprepro rereference
Con este comando anterior se reconcilian las bases de datos. Después de ejecutarlo podemos reinstalar y luego quitar el paquete normalmente, quedándolo fuera del repositorio. Con:
# reprepro clearvanished 
Eliminamos el fichero .deb de la ruta donde está, ya que por defecto se quedan allí aunque ya no estén indexados. Con esto queda la tarea completada.


Los taikonautas chinos acaban de hacer el primer paseo espacial desde su flamante estación.



Recordemos que esa estación la ha construido China con sus propios medios, ya que tenían vetada por USA la entrada a la Estación Espacial Internacional. Ante este panorama, la Republica Popular de China ha optado constuirse su propia estación espacial, con casinos... y furcias.


miércoles, 30 de junio de 2021

Puesta a punto de portátiles de alumnos al final de curso

Cuando se nos van los niños nos toca hacer una limpieza y actualización de los portátiles para quedarlo todo listo de cara al curso venidero. Voy a repasar las actuaciones que realizo para dejarlo todo en orden. Primero verifico en cada portátil que los paquetes están bien y actualizo todo:
# dpkg --configure -a
# apt-get update
# apt-get upgrade
# puppet agent -tv
Luego lanzo un script para limpiar los perfiles de los usuarios, borrar todas las conexiones wifi creadas excepto "educarex" y restaurar el background por defecto en el lightdm (en el caso de que la tengamos personalizada según conté en esta entrada antigua)
# cat limpiar-usuarios-y-wifi.sh
#!/bin/bash

#Limpia credenciales cacheadas
sss_cache -E
rm -rf /var/lib/sss/db/cache_LDAP.ldb

#Limpia conexiones wifi antiguas, excepto educarex
if [ -e /etc/NetworkManager/system-connections/educarex ]
then
    cp /etc/NetworkManager/system-connections/educarex /tmp/educarex
    rm /etc/NetworkManager/system-connections/*
    cp /tmp/educarex /etc/NetworkManager/system-connections/
else
    rm /etc/NetworkManager/system-connections/*
fi

#Limpia homes antiguos
rm -rf /home/alumnos/*

#Pone background por defecto. 
cp -f  /usr/share/xfce4/backdrops/linexEDU_2018_4_bak.png /usr/share/xfce4/backdrops/linexEDU_2018_4.png
Hacer esto en todos los portátiles uno a uno es un poco latoso. Para evitar esta tarea repetitva lo que hago es encenderlos por grupos, dejando que se conecten a la red wifi del centro de forma automática. Luego hago un nmap para localizar estos equipos y mostrar sus IP y nombres:
# cat escanear-educarex-nombres 
#!/bin/bash

red="10.192.x.0" # Cambiar x por la subred de tu centro.
password="contraseña de root de portatiles" 

machines=$(nmap -p 22 ${red}/24 | cut -d" " -f5 | grep 10)
for maquina in $machines
do
   name=$(sshpass -p${password} ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@$maquina 'echo $HOSTNAME' 2> /dev/null)
   echo "$maquina ->  $name"
done
echo ""
Esto genera una salida como:
# ./escanear-educarex-nombres 
10.192.x.1 ->  
10.192.x.75 ->  
10.192.x.102 -> porthp-o12  
10.192.x.143 -> porthp-o11
....
10.192.x.153 ->  
10.192.x.154 ->  porthp-o25
...
En este listado anterior sacamos las IP de todos los dispositivos conectados a la red "educarex" que tienen el puerto 22 (ssh) abierto. Si son portátiles inicia sesión en ellos y muestra su nombre, lo cual nos permite identificar los equipos de forma fehaciente. Una vez tenemos este listado de IPs podemos hacer una conexión multiple hacia ellas con tmux-cssh:
# tmux-cssh -u root 10.192.x.102 10.192.x.143 ... 10.192.x.154 ...
Esto abre en paralelo un porrón de conexiones ssh que nos permiten trabajar con todos los portátiles a la vez, escribiendo comandos que se lanzan de forma simultánea en todos ellos. De esta manera puedo operar con 30, 50.. portátiles sin problema, avanzando rápidamente.

Otra cosa que me gusta hacer es verificar el estado de salud de la batería de los portátiles. Cuando los enciendo me cuido de que estén completamente cargados al máximo y una vez actualizados y limpios lanzo el siguiente comando usando la consola tmux-cssh:
# while true
do
   uptime                                                                              
   upower -i /org/freedesktop/UPower/devices/battery_BAT0  | grep percen 
   sleep 10
done  
Con esto lanzo simultaneamente un bucle infinito que muestra el tiempo de encendido y bateria restante, actualizándose cada 10 segundos. De esta manera, tras un rato podemos chequear como baja la batería en cada uno de los portátiles y hacernos una idea de su salud.

Una vez hecho esto ya podemos retornar los portátiles al armario y dejarlos ya listos para ser usados el próximo curso.

Alucinante video de la Zhurong en Marte. La primera vez que vemos un vídeo y oímos un rover movíendose por la superfice de Marte, con el aterrizador de fondo. Los camaradas chinos han vuelto a lucirse:



Habrá que celebrarlo como se merece:

martes, 18 de mayo de 2021

Zabbix (I): template para impresoras Brother láser color

Bueno, pues por fin me he metido en el apasionante mundo de Zabbix. Con ayuda de mis compañeros he ido montando el sistema, los clientes y los templates para cada tipo de dispositivo que se puede encontrar en mi red. Es todo un universo nuevo, pero merece la pena sobradamente.

Una de las cosas que más me interesa monitorizar son las impresoras, tanto para llevar un control histórico del gasto como para recibir avisos de que queda poca tinta/tóner e ir encargando con repuestos tiempo. Para las impresoras HP y Epson que tenemos en los centros ya hay templates de monitorización que han compartido los compañeros, pero tengo por mi parte varias impresoras Brother láser color (DCP-9020CDW, HL-4140CN y alguna más) para las cuales el número de templates que se encuentran es bastante escaso. En la página de templates oficial de Zabbix aparecen apenas 3 plantillas, todas para láser monocromo, que se pueden importar (algunas con errores que hay que corregir editando a mano XML, pues son un poco antiguas), pero no nos dan toda la información que queremos sobre las impresoras láser en color.

Me ha tocado investigar un poco para crear una plantilla mezcla de las 3 existentes más items nuevos para obtener los datos que faltaban. Esta es la parte divertida de nuestro trabajo, no todo iba a ser azotar usuarios. No ha sido todo nuevo, puesto que las impresoras son interrogadas usando el protocolo SNMP y ya tenía experiencia al haberlo utilizado hace bastante tiempo para otra entrada del blog.

AVISO: tochazo inside.

1. Uso de snmpwalk para interrogar impresoras.

Para preguntar sobre toda la información que comparte de forma pública una impresora usamos el comando:
# snmpwalk -v 2c -c public 172.a.b.c
iso.3.6.1.2.1.1.1.0 = STRING: "Brother NC-8500h, Firmware Ver.1.15  (15.10.15),MID 8CE-403,FID 2"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.2435.2.3.9.1
iso.3.6.1.2.1.1.3.0 = Timeticks: (9993270) 1 day, 3:45:32.70
iso.3.6.1.2.1.1.4.0 = STRING: "contacto@gmail.es"
iso.3.6.1.2.1.1.5.0 = STRING: "BN_SALAPROFESORES"
iso.3.6.1.2.1.1.6.0 = STRING: "Sala de Profesores"
iso.3.6.1.2.1.1.7.0 = INTEGER: 72
iso.3.6.1.2.1.1.8.0 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.2.1 = OID: iso.3.6.1.6.3.1
iso.3.6.1.2.1.1.9.1.2.2 = OID: iso.3.6.1.6.3.10.3.1.1
iso.3.6.1.2.1.1.9.1.2.3 = OID: iso.3.6.1.6.3.11.3.1.1
iso.3.6.1.2.1.1.9.1.2.4 = OID: iso.3.6.1.6.3.15.2.1.1
iso.3.6.1.2.1.1.9.1.2.5 = OID: iso.3.6.1.6.3.16.2.1.1
iso.3.6.1.2.1.1.9.1.3.1 = STRING: "The MIB Module from SNMPv2 entities"
iso.3.6.1.2.1.1.9.1.3.2 = STRING: "SNMP Management Architecture MIB"
iso.3.6.1.2.1.1.9.1.3.3 = STRING: "Message Processing and Dispatching MIB"
iso.3.6.1.2.1.1.9.1.3.4 = STRING: "USM User MIB"
iso.3.6.1.2.1.1.9.1.3.5 = STRING: "VACM MIB"
.......................
.......................
.......................
La lista es bastante grande y normalmente ahí hay información de sobra sobre el estado de nuestra impresora. Cada rama o nodo tiene un significado más o menos estándar (aunque recordemos el axioma que dice "lo bueno de los estándares es que hay varios donde elegir"). Por ejemplo, de la lista anterior el OID iso.3.6.1.2.1.1.6 se describe como:

Literalmente: "The physical location of this node (e.g., 'telephone closet, 3rd floor'). If the location is unknown, the value is the zero-length string", es decir, la ubicación física de la impresora tal como está definida en su configuración. El valor de este campo se obtiene con:
# snmpwalk -v 2c -c public 172.a.b.c iso.3.6.1.2.1.1.6
iso.3.6.1.2.1.1.6.0 = STRING: "Sala de Profesores"
La información sobre el contenido cada OID (object identifier o Identificador de Objeto, que se define como una secuencia de números que se asignan jerárquicamente y que permite identificar objetos en la red, siendo usados con gran cantidad de protocolos) estándar se puede consultar en varios sitios de internet:
2. Problemática con las impresoras Brother.

Hasta aqui todo sería estupendo si todas las impresoras respetasen los OID estándar. Con las HP y las Epson no hay problema, pero mis Brother son rebeldes. La mayoría de los OID (ubicación, status, páginas impresas, número de serie, etc) se ajustan al estándar definido y vale el mismo template que para cualquier otra impresora, pero aquellos que deben decirme el nivel de tóner restante mienten o son inexactos.

El estado de los consumibles se encuentra en la rama iso.3.6.1.2.1.43.11, prtMarkerSupplies. Vamos a husmear dentro (añado comentarios explicando el significado de las ramas):
# snmpwalk -v 2c -c public 172.19.231.51 iso.3.6.1.2.1.43.11                       
iso.3.6.1.2.1.43.11.1.1.2.1.1 = INTEGER: 1   --- prtMarkerSuppliesMarkerIndex(2)
iso.3.6.1.2.1.43.11.1.1.2.1.2 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.3 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.4 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.5 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.6 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.7 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.8 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.9 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.2.1.10 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.3.1.1 = INTEGER: 1   --- prtMarkerSuppliesColorantIndex(3)
iso.3.6.1.2.1.43.11.1.1.3.1.2 = INTEGER: 2
iso.3.6.1.2.1.43.11.1.1.3.1.3 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.3.1.4 = INTEGER: 4
iso.3.6.1.2.1.43.11.1.1.3.1.5 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.3.1.6 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.3.1.7 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.3.1.8 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.3.1.9 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.3.1.10 = INTEGER: 0
iso.3.6.1.2.1.43.11.1.1.4.1.1 = INTEGER: 3   --- prtMarkerSuppliesClass(4)
iso.3.6.1.2.1.43.11.1.1.4.1.2 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.3 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.4 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.5 = INTEGER: 4
iso.3.6.1.2.1.43.11.1.1.4.1.6 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.7 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.8 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.9 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.4.1.10 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.5.1.1 = INTEGER: 3  --- prtMarkerSuppliesType(5) : tipo de consumible
iso.3.6.1.2.1.43.11.1.1.5.1.2 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.5.1.3 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.5.1.4 = INTEGER: 3
iso.3.6.1.2.1.43.11.1.1.5.1.5 = INTEGER: 4
iso.3.6.1.2.1.43.11.1.1.5.1.6 = INTEGER: 1
iso.3.6.1.2.1.43.11.1.1.5.1.7 = INTEGER: 9
iso.3.6.1.2.1.43.11.1.1.5.1.8 = INTEGER: 9
iso.3.6.1.2.1.43.11.1.1.5.1.9 = INTEGER: 9
iso.3.6.1.2.1.43.11.1.1.5.1.10 = INTEGER: 9
iso.3.6.1.2.1.43.11.1.1.6.1.1 = STRING: "Black Toner Cartridge"  --- prtMarkerSuppliesDescription(6) : descripción del consumible. 
iso.3.6.1.2.1.43.11.1.1.6.1.2 = STRING: "Cyan Toner Cartridge"
iso.3.6.1.2.1.43.11.1.1.6.1.3 = STRING: "Magenta Toner Cartridge"
iso.3.6.1.2.1.43.11.1.1.6.1.4 = STRING: "Yellow Toner Cartridge"
iso.3.6.1.2.1.43.11.1.1.6.1.5 = STRING: "Waste Toner Box"
iso.3.6.1.2.1.43.11.1.1.6.1.6 = STRING: "Belt Unit"
iso.3.6.1.2.1.43.11.1.1.6.1.7 = STRING: "Black Drum Unit"
iso.3.6.1.2.1.43.11.1.1.6.1.8 = STRING: "Cyan Drum Unit"
iso.3.6.1.2.1.43.11.1.1.6.1.9 = STRING: "Magenta Drum Unit"
iso.3.6.1.2.1.43.11.1.1.6.1.10 = STRING: "Yellow Drum Unit"
iso.3.6.1.2.1.43.11.1.1.7.1.1 = INTEGER: 13 --- prtMarkerSuppliesSupplyUnit(7) : unidad de medida del consumible.
iso.3.6.1.2.1.43.11.1.1.7.1.2 = INTEGER: 13
iso.3.6.1.2.1.43.11.1.1.7.1.3 = INTEGER: 13
iso.3.6.1.2.1.43.11.1.1.7.1.4 = INTEGER: 13
iso.3.6.1.2.1.43.11.1.1.7.1.5 = INTEGER: 13
iso.3.6.1.2.1.43.11.1.1.7.1.6 = INTEGER: 7
iso.3.6.1.2.1.43.11.1.1.7.1.7 = INTEGER: 7
iso.3.6.1.2.1.43.11.1.1.7.1.8 = INTEGER: 7
iso.3.6.1.2.1.43.11.1.1.7.1.9 = INTEGER: 7
iso.3.6.1.2.1.43.11.1.1.7.1.10 = INTEGER: 7
iso.3.6.1.2.1.43.11.1.1.8.1.1 = INTEGER: -2  --- prtMarkerSuppliesMaxCapacity(8) : máxima capacidad del consumible.
iso.3.6.1.2.1.43.11.1.1.8.1.2 = INTEGER: -2
iso.3.6.1.2.1.43.11.1.1.8.1.3 = INTEGER: -2
iso.3.6.1.2.1.43.11.1.1.8.1.4 = INTEGER: -2
iso.3.6.1.2.1.43.11.1.1.8.1.5 = INTEGER: -2
iso.3.6.1.2.1.43.11.1.1.8.1.6 = INTEGER: 50000
iso.3.6.1.2.1.43.11.1.1.8.1.7 = INTEGER: 15000
iso.3.6.1.2.1.43.11.1.1.8.1.8 = INTEGER: 15000
iso.3.6.1.2.1.43.11.1.1.8.1.9 = INTEGER: 15000
iso.3.6.1.2.1.43.11.1.1.8.1.10 = INTEGER: 15000
iso.3.6.1.2.1.43.11.1.1.9.1.1 = INTEGER: -3  --- prtMarkerSuppliesLevel(9) : nivel actual del consumible.
iso.3.6.1.2.1.43.11.1.1.9.1.2 = INTEGER: -3
iso.3.6.1.2.1.43.11.1.1.9.1.3 = INTEGER: -3
iso.3.6.1.2.1.43.11.1.1.9.1.4 = INTEGER: -3
iso.3.6.1.2.1.43.11.1.1.9.1.5 = INTEGER: -3
iso.3.6.1.2.1.43.11.1.1.9.1.6 = INTEGER: 48217
iso.3.6.1.2.1.43.11.1.1.9.1.7 = INTEGER: 4556
iso.3.6.1.2.1.43.11.1.1.9.1.8 = INTEGER: 4556
iso.3.6.1.2.1.43.11.1.1.9.1.9 = INTEGER: 4556
iso.3.6.1.2.1.43.11.1.1.9.1.10 = INTEGER: 4556
Detallo las ramas que más nos interesan:
  • prtMarkerSuppliesType, nodo iso.3.6.1.2.1.43.11.1.1.5: tipos de consumible. Por ejemplo, el valor 3 equivale a "tóner".
  • prtMarkerSuppliesDescription, nodo iso.3.6.1.2.1.43.11.1.1.6: descripción del consumible. Por ejemplo "Magenta Toner Cartridge".
  • prtMarkerSuppliesSupplyUnit, nodo iso.3.6.1.2.1.43.11.1.1.7: unidades de medida del consumible. Por ejemplo, el valor 13 equivale a "decígramos".
  • prtMarkerSuppliesMaxCapacity, nodo iso.3.6.1.2.1.43.11.1.1.8: valor máximo de capacidad del consumible: puede ser la cantidad de tóner o tinta que cabe en el cartucho, o el número máximo de páginas que tiene de vida útil un tambor/cinta de arrastre.
  • prtMarkerSuppliesLevel, nodo iso.3.6.1.2.1.43.11.1.1.9: nivel actual del consumible: puede ser la cantidad de tóner o tinta que resta en el cartucho (un %, un número estimado de páginas, etc), o el número de páginas que le quedan por imprimir a un tambor/cinta de arrastre.

Con estos indicadores se puede controlar cuanto consumible queda... en teoría. En el caso de las impresoras Brother el contenido de las ramas prtMarkerSuppliesMaxCapacity y prtMarkerSuppliesLevel no dan datos reales sobre los niveles de tóner, aunque si del estado de otros consumibles: almacén de tóner, cinta de arrastre y tambores. En ellas prtMarkerSuppliesMaxCapacity siempre tiene el valor -2 y prtMarkerSuppliesLevel lo he visto con únicamente dos valores distintos: -3 (hay toner) y 0 (no hay tóner), lo cual es muy poco informativo. En Internet se habla de otros posibles valores asociados a varios estados ("full", "almost empty", "empty" or "absent) pero en mis pruebas esos valores nunca han aparecido.

Cusiosamente, casi todos los otros parámetros estándar de impresoras si que están implementados para las Brother. Por ejemplo, hrPrinterStatus con los valores de estado de la impresora: other(1), unknown(2), idle(3), printing(4), warmup(5).

Buscando una solución encontré un parámetro llamado prtAlertcode en la rama iso.3.6.1.2.1.43.18.1.1.7 que nos devuelve un código de alerta si pasa algo en la impresora. Como se ve en el enlace anterior hay un buen número de códigos, incluido el 1104 que significa markerTonerAlmostEmpty: queda poco tóner. No nos dice el color, pero puede servir para alertar si no nos queda más remedio.

Evidentemente, con esta información es imposible poder monitorizar con detalle el nivel de los consumibles y planificar su adquisión. Pero esto no puede quedar aquí: si vamos al interface web o el panel de la impresora Brother vemos que si que conocen y muestran esos niveles. Es obvio que tiene que haber alguna manera de interrogar a la impresora para obtenerlos.

3. Buscando e interpretando los OID privados.

Mirando con mas detalle me encontré que hay ciertas ramas "ocultas" o privadas que dependen del fabricante del dispositivo y que no salen haciendo un snmpwalk normal. El nodo sysObjectID, con OID iso.3.6.1.2.1.1.2 contiene "The vendor's authoritative identification of the network management subsystem contained in the entity". En caso de las Brother su contenido es:
# snmpwalk -v 2c -c public 172.a.b.c 1.3.6.1.2.1.1.2
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.2435.2.3.9.1
Es decir, ese nodo contiene una referencia a otra rama, que en el caso de la Brother es iso.3.6.1.4.1.2435. Esta es una rama oculta, que si consultamos directamente con:
# snmpwalk -v 2c -c public 172.a.b.c 1.3.6.1.4.1.2435
.....
.....
.....
Muestra mas de 5000 nodos con mucha información privada de la impresora Brother. El código 2435 corresponde a Brother, pero como se puede ver en este enlace hay códigos para todo tipo de fabricantes, asignados por IANA. Cada uno tendrá su rama privada colgando de ahí.

En https://oidref.com/ podemos perdernos husmeando dentro de esa rama. Yo he ido al grano, buscando valores que me interesaban para su monitorización con Zabbix, por ejemplo el nodo brBackLightColor, que tiene 4 posibles valores: 0:Off/1:Green/2:Orange/3:Red. Básicamente sirven para indicarnos el color que muestra led del panel de la impresora, 0 o 1 significa que bien, y 2 o 3 que hay problemas. Los templates de Zabbix que encontré para impresoras Brother monocromo usaban brBackLightColor en conjunción con prtAlertCode (visto anteriormente) para avisar de forma rudimentaria de que quedaba poca tinta.

Otra rama que me ha venido bien es brPrintPages, iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.52.1.3, que muestra desglosadas las páginas impresas en B/N y en color.

Pero no olvidemos que la meta es saber los niveles de los 4 tóneres de color. No hallaba información alguna hasta que encontré pistas en este enlace, y sobre todo en este otro, donde se muestra un programa que lee los niveles reales de tóner de una Brother color. Los datos se leen por SNMP mediante este conjunto de scripts en Python. Indagando en el código veo que los niveles de tinta se sacan de la rama iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0, llamada brInfoMaintenance. ¿Qué hay allí?:
# snmpwalk -v 2c -c public 172.a.b.c iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8
iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0 = Hex-STRING: 76 01 04 00 00 00 01 77 01 04 00 00 00 01 78 01 
04 00 00 00 01 7F 01 04 00 00 00 01 68 01 04 00 
00 00 01 55 01 04 00 00 00 01 31 01 04 00 00 00 
01 32 01 04 00 00 00 02 33 01 04 00 00 00 01 34 
01 04 00 00 00 01 70 01 04 00 00 01 F4 82 01 04 
00 00 00 0A 71 01 04 00 00 22 60 83 01 04 00 00 
00 5A 72 01 04 00 00 19 64 84 01 04 00 00 00 46 
6F 01 04 00 00 25 1C 81 01 04 00 00 00 64 79 01 
04 00 00 0C 1C 7A 01 04 00 00 0C 1C 7B 01 04 00 
00 0C 1C 80 01 04 00 00 0C 1C 69 01 04 00 00 25 
E4 73 01 04 00 00 28 FA 74 01 04 00 00 28 FA 75 
01 04 00 00 28 FA 7E 01 04 00 00 28 FA 54 01 04 
00 00 00 01 35 01 04 00 00 00 01 6A 01 04 00 00 
21 34 6D 01 04 00 00 26 AC FF 
Mmmm, esto es una retahíla hexadecimal incomprensible...

4. Extrayendo información de brInfoMaintenance

Bueno, pues ahi dentro está la información. Y alguien ha hecho ingeniería inversa para extraerla. Tras leer dicha página comprendo que, para las impresoras que tengo, la información se organiza en septetos de bytes, asi que formateo la salida del comando para que salga en grupos de 7 valores::
# snmpwalk -v 2c -c public 172.a.b.c iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0 | tr -d "\n" | cut -c54- |  fold -w 21
76 01 04 00 00 00 01 
77 01 04 00 00 00 01 
78 01 04 00 00 00 01 
7F 01 04 00 00 00 01 
68 01 04 00 00 00 01 
55 01 04 00 00 00 01 
31 01 04 00 00 00 01 
32 01 04 00 00 00 02 
33 01 04 00 00 00 01 
34 01 04 00 00 00 01 
70 01 04 00 00 01 F4 
82 01 04 00 00 00 0A 
71 01 04 00 00 22 60 
83 01 04 00 00 00 5A 
72 01 04 00 00 19 64 
84 01 04 00 00 00 46 
6F 01 04 00 00 25 1C 
81 01 04 00 00 00 64 
79 01 04 00 00 0C 1C 
7A 01 04 00 00 0C 1C 
7B 01 04 00 00 0C 1C 
80 01 04 00 00 0C 1C 
69 01 04 00 00 25 E4 
73 01 04 00 00 28 FA 
74 01 04 00 00 28 FA 
75 01 04 00 00 28 FA 
7E 01 04 00 00 28 FA 
54 01 04 00 00 00 01 
35 01 04 00 00 00 01 
6A 01 04 00 00 21 34 
6D 01 04 00 00 26 AC 
FF 
Así formateado, verifico que el significado del primer byte se describe en esta tabla:
"11": VAL_DRUM_COUNT
"31": VAL_BLACK_TONER_STATUS
"32": VAL_CYAN_TONER_STATUS
"33": VAL_MAGENTA_TONER_STATUS
"34": VAL_YELLOW_TONER_STATUS
"41": VAL_DRUM_REMAIN
"63": VAL_DRUM_STATUS
"69": VAL_BELT_REMAIN
"6a": VAL_FUSER_REMAIN
"6b": VAL_LASER_REMAIN
"6c": VAL_PF_MP_REMAIN
"6d": VAL_PF_1_REMAIN
"6f": VAL_BLACK_TONER_REMAIN
"70": VAL_CYAN_TONER_REMAIN
"71": VAL_MAGENTA_TONER_REMAIN
"72": VAL_YELLOW_TONER_REMAIN
"73": VAL_CYAN_DRUM_COUNT
"74": VAL_MAGENTA_DRUM_COUNT
"75": VAL_YELLOW_DRUM_COUNT
"7e": VAL_BLACK_DRUM_COUNT
"79": VAL_CYAN_DRUM_REMAIN
"7a": VAL_MAGENTA_DRUM_REMAIN
"7b": VAL_YELLOW_DRUM_REMAIN
"80": VAL_BLACK_DRUM_REMAIN
"81": VAL_BLACK_TONER
"82": VAL_CYAN_TONER
"83": VAL_MAGENTA_TONER
"84": VAL_YELLOW_TONER
"a1": VAL_BLACK_TONER_REMAIN
"a2": VAL_CYAN_TONER_REMAIN
"a3": VAL_MAGENTA_TONER_REMAIN
"a4": VAL_YELLOW_TONER_REMAIN
A continuación vienen los valores fijos "01 04" y los cuatro últimos bytes son el valor del parámetro, por ejemplo:
71 01 04 00 00 23 F0
El "71" es VAL_MAGENTA_TONER_REMAIN, tóner restante magenta. El "01 04" lo ignoramos. Y el "00 00 23 F0" es el número hexadecimal 0x23F0, que en decimal es 9200. Ese 9200 se debe dividir por 100 y nos da el porcentaje de toner magenta restante: 9200/100=92% de tóner. ¡Ahí está la información!. Por tanto, en:
"6f": VAL_BLACK_TONER_REMAIN
"70": VAL_CYAN_TONER_REMAIN
"71": VAL_MAGENTA_TONER_REMAIN
"72": VAL_YELLOW_TONER_REMAIN
Podremos sacar el % de cada cartucho de tóner. Puñeteramente endiablado lo ha puesto Brother. Menos mal que un esforzado hacker de los buenos lo ha decodificado, Gloria y Honor para él.

5. El template Zabbix final.

Bueno, pues el template debe extraer el churro hexadecimal de iso.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0, buscar los códigos 6F, 70, 71 y 72 para cada cartucho de tóner y extraer el nivel en cada uno.

La manera mas sencilla que he encontrado es crear un item que lee la secuencia hexadecimal completa por SNMP y luego hace un preprocessing con Javascript (me encanta ese lenguaje) que busca el código identificador del cartucho en cuestión, extrae los dos bytes con el valor, los convierte de hexadecimal a decimal y lo divide por 100 para obtener el valor que será el mostrado por el item. El código para el tóner Cyan sería:
var pos = value.indexOf("70 01 04 00 00");
var res=0;
if (pos >=0 ) { 
   res=value.substring(pos+15, pos+20);
   res=parseInt(res.replace(" ", ""),16)/100;
};
return res;
El ítem completo sería:
<item>
      <name>Brother Info Maintenance Cyan</name>
      <type>SNMP_AGENT</type>
      <snmp_oid>1.3.6.1.4.1.2435.2.3.9.4.2.1.5.5.8.0</snmp_oid>
      <key>brInfoMaintenanceCyan</key>
      <delay>15m</delay>
      <units>%</units>
      <applications>
        <application>
          <name>Supplies</name>
        </application>
      </applications>
      <preprocessing>
        <step>
          <type>JAVASCRIPT</type>
          <params>
            var pos = value.indexOf("70 01 04 00 00");
            var res=0;
            if (pos >=0 ) { 
                res=value.substring(pos+15, pos+20);
                res=parseInt(res.replace(" ", ""),16)/100;
            };
            return res;
          </params>
        </step>
      </preprocessing>
      <triggers>
        <trigger>
          <expression>{last()}<=10</expression>
          <name>Cyan Ink Low  at {HOST.NAME}</name>
          <priority>AVERAGE</priority>
          <manual_close>YES</manual_close>
        </trigger>
      </triggers>
</item>
Como se puede ver añadimos un trigger que avisa cuando el tóner está por debajo del 10%. El resto de colores se haría con el mismo método.

Finalmente, incluyo enlace Template_Brother_Laser_Printers.xml con el template Zabbix final para impresoras Brother Láser Color, en formato XML listo para ser importado y leer bien todos los niveles de tóner, junto con varios valores más adicionales que me ha parecido interesante mantener o añadir. Algo me dice que este será el template Zabbix mas enrevasado que nunca escribiré.



Estamos que no paramos con Marte. Los camaradas de la República Popular de China ha aterrizado con la discreción que le caracteriza su rover Zhurong. Parece ser que para la civilización China a la primera va la vencida. Todavía no hay imágenes directas, pero esto nos sirve como adelanto:


Esperamos ansiosos las imágenes del rover trabajando.