Ha habido muchas cosas que he estado haciendo este mes desde que arrancó septiembre, así que vamos con una nueva entrega de nichijou sahanji, el té y arroz de cada día, para dejarlo todo bien plasmado.
Así que vamos por orden, día a día, como siempre.
📅 1 de septiembre de 2026
Este mes empezó con algo que vi en el servidor NTP del ZimaBlade que había montado hace poco. Resulta que viendo en el script que tengo para ver quiénes piden la actualización NTP en mi red, salían algunas IP que no eran de la red sino de internet, que no eran más que escaneadores de puertos y salían en la lista solo para asustarme, así que lo arreglé para que ya no mostrara esos escaneos que eran cosas del log del router.
Y la extensión Tako-Dame se llevó la tarde pasando de la v1.55 a la v1.59. Puse la opción de bloquear una URL exacta a mano, plegar las listas, y que al abrir las opciones desde una web esa saliera la primera. De paso arreglé una cosa de fondo: bloquear no podía costar una lectura del storage por cada petición. Ahora se permite por adelantado en vez de esperar a que la extensión lo aprenda sola, y saqué las funciones puras a urls-format.js para probarlas bien.
📅 2 de septiembre de 2026
Este día me hice la gran pregunta: ¿podría hacer un gestor de descargas propio y así no gastarme 20 euros en uno? Así nació tako-downloads, rebautizada luego a たこダウンロード. Un motor de descarga multipunto con reanudación y esquema propio tako://, hecha como app nativa para macOS usando Wails.
Y para cuando se acabó el día ya tenía icono propio, papelera para lo que iba borrando, aviso al terminar cada descarga y un panel que enseña el tiempo que lleva y cuántas conexiones está usando de verdad. Hasta la dejé con una sola instancia abierta, por mucho que le dé al enlace desde el navegador.
📅 3 de septiembre de 2026
Día intenso dándole forma a たこダウンロード. Metí yt-dlp como extractor por debajo, le añadí soporte para descargar emisiones HLS pudiendo elegir la calidad y una caché de una hora. Hasta me traje la extensión de Chrome al propio repositorio para no depender de enlaces externos, y rediseñé la ventana para que tuviera ese aspecto nativo de macOS, con sus tarjetas y su menú contextual.
Y también me pasó que en algunos sitios el vídeo salía mudo porque no declaraban el códec, que los enlaces caducaban mientras la descarga estaba parada —ahora al reanudar se piden de nuevo en vez de morirse— y la más tonta de todas: que una app con ventana en macOS no hereda el PATH de la terminal, así que tuve que enseñarle dónde viven yt-dlp y ffmpeg.
La extensión de Chrome también se llevó lo suyo ese día: además de traérmela al repositorio, aprendió a mandarle a la app la página que tengo abierta y a detectar por su cuenta las emisiones en directo.
📅 4 de septiembre de 2026
Rematando la aplicación. Le puse un icono bonito en la barra de menús, su apartado de “acerca de” con la versión, y opciones para volver a bajar un archivo perdido, editar categorías o renombrarlo antes de guardar. Y una cosa importantísima: hacer que descargue primero en local y solo entregue el archivo en el destino final cuando acaba, pensado para cuando la carpeta de destino está en la red y no quieres saturarla copiando a trocitos.
Y el PATH volvió a dar guerra, pero al revés: ahora era yt-dlp el que no encontraba node. También tuve que sacar las acciones del menú fuera del hilo principal, porque la ventana se quedaba congelada mientras pensaba, bajar el sonido por su lado en los sitios que lo sirven en una lista aparte, y poner arriba del todo lo que acabas de descargar, con la hora a la que se bajó.
📅 5 de septiembre de 2026
Me puse otra vez el traje de cazar latencias porque sospechaba que el script takodns-apply.sh estaba subiendo la latencia a Cloudflare. Al final investigué a fondo y quedó descartado por completo. Resultó que el centro de datos de Cloudflare en el que caes es determinista por tu prefijo de IP y no va dando tumbos como yo me temía. De paso vi en el sing-box que unas peticiones de abema.tv se quedaban colgando para siempre en pending en las herramientas de desarrollo.
Por si alguien se pregunta qué es ese script: es el que le vuelve a poner al router las reglas para que todo lo que se conecte en casa pase por mi DNS del ZimaBlade, quiera o no, y de paso cierra el DNS cifrado, que es por donde algunos aparatos intentan escaparse por su cuenta. Hay que pasarlo a mano cada vez que reinicio el router, porque el firmware de ASUS de serie no ejecuta esas cosas al arrancar.
Y eso sí tenía explicación, que además me hizo gracia porque venía de mí misma: cuando bloqueo un dominio contestando 0.0.0.0, el navegador abre la conexión igual y se queda esperando a alguien que no va a contestar nunca; si la página espera por ese archivo, se retrasa la carga entera. Lo cambié para que la respuesta sea directamente que ese dominio no existe, y así ni lo intenta. Son 227.676 dominios que ahora se bloquean de esta forma.
📅 6 de septiembre de 2026
Día dedicado a sing-box. Hice un comando para encenderlo y apagarlo rápido, y un script que cambia el DNS al arrancar y lo restaura al salir (avisando además si algo apunta mal). También documenté toda la configuración para no perderme luego.
Y hubo una cosa que todavía me hace gracia: tuve que poner el DNS del Mac en 8.8.8.8. Si lo dejaba apuntando directamente al ZimaBlade, la ruta de mi propia red le ganaba a las del túnel y las reglas de DNS del túnel dejaban de aplicarse sin avisar de nada, así que había cosas que se resolvían por su cuenta en vez de por donde debían. Con el 8.8.8.8 sí entran por el camino bueno, y como hace tiempo que tengo el router desviando el DNS de Google hacia el ZimaBlade, al final acaba resolviendo mi servidor de siempre. El script se encarga de ponerlo al arrancar y de devolverlo todo a su sitio al salir.
Y ahí saltó una que no me esperaba: los dominios que casan con una regla de túnel se resolvían por fuera, sin pasar por mi propio DNS, así que mis listas de bloqueo no les llegaban nunca. Lo pillé con la telemetría de Netflix, que desde el móvil funcionaba tan tranquila y estaba mandando datos, mientras que desde el Mac me salía como que ese dominio no existía. Los mandé por el camino directo y ya sí les alcanza el bloqueo. Van tres veces este mes que creo que falla la red y resulta ser mi propio montaje.
Y de eso salió algo grave. Me picó la curiosidad de por qué en el registro de sing-box no paraba de aparecer sony.com, una y otra vez, sin descanso. Tirando de ese hilo resultó que mi Mac estaba haciendo de servidor de DNS abierto a internet por la IP pública de mi WireGuard de casa, y que alguien lo estaba usando para amplificar ataques: mandan una consulta minúscula falsificando la dirección de su víctima, y mi máquina le contestaba a esa pobre con una respuesta miles de veces más grande.
Por eso siempre sony.com, que tiene su gracia: no era el objetivo, era la herramienta. Ese dominio tiene ciento y pico registros de texto, así que la respuesta es enorme y el rebote multiplica de maravilla; les habría valido cualquier otro igual de gordo, a Sony no le estaban haciendo nada. Y el diagnóstico traía trampa, porque al parar sing-box las consultas desaparecían y durante un rato pareció que se las inventaba él.
Lo tranquilizador es lo que no pasó: nadie entró en el Mac, no se filtró nada mío y no había ningún servicio escuchando. Un servidor de DNS abierto solo contesta preguntas, que son información pública. Lo que sí pasó es que mi máquina llevaba quién sabe cuánto participando en ataques contra terceros sin enterarme yo, y encima yendo a más: de unas 35 líneas por segundo a 430. El arreglo acabó siendo una cuestión de orden —la regla que rechaza lo que entra tenía que ir antes de la que atiende el DNS, no después—, más meterla en la plantilla para que no se borrase sola en la siguiente reconstrucción. Lo comprobé desde Tokio: el ping contesta, o sea que la máquina sigue ahí y sigue siendo alcanzable, pero el DNS ya no le abre a nadie de fuera.
Pero lo grave fue el susto que se llevó LugoIlmer en el blog: de repente vio que el script de procesar imágenes que tenemos se comió parte del contenido de un post. Lo probé en un borrador de pruebas y resultó ser cosa de las tablas: el script parte el archivo por los tres guiones para separar la cabecera, y las tablas de Markdown llevan esos mismos guiones en la línea del encabezado, así que cortaba ahí y tiraba por la borda todo lo que venía detrás. Y aparte de eso, aproveché para quitar del menú la opción de pasarlo sobre todos los posts del tirón, que con un fallo así era una bomba.
También hubo tanda en las listas de Unbound contra el rastreo de Abema. Cayeron youboranqs01.com y youborafds01.com (las dos patas de la analítica Youbora), lk.ameba.jp y wr.p-c2-x.abema-tv.com, que es un host súper lento del que sigo sin saber para qué sirve; lo comprobé en el móvil y sin él la posición del vídeo se guarda igual.
📅 7 de septiembre de 2026
Volví al sing-box, esta vez con DMM. El vídeo no puede salir por el VPS de ninguna manera: el servidor que lo sirve devuelve un 404 en cuanto ve una IP de centro de datos, así que tiene que ir por la conexión de casa sí o sí. Probé hasta a mandar la lista por un lado y los trozos de vídeo por otro, y nada. También bloqueé dos dominios de telemetría suyos, moviéndolos antes al grupo directo para que el bloqueo les alcanzara, que es la misma lección de ayer.
Y me pasé un rato peleando con un cambio que no hacía absolutamente nada. Resulta que en mi configuración las reglas escritas como expresión regular se colocan antes que las que van por terminación del dominio, así que la expresión regular gana siempre. Podía mover el dominio de grupo las veces que quisiera, que mientras no moviera también la expresión que lo abarcaba, seguía saliendo por donde a ella le daba la gana.
Y fue el día grande de Tako-Dame: de la v1.60 a la v1.69 del tirón. Primero peleé con los detectores de bloqueadores, que resultó que tenían dos puertas y no una, y de paso le cambié el enfoque: en vez de esconderse del detector, contestarle.
Pero lo más grande fue sacarla de Chrome y llevarla a Safari, con el iPhone como destino. Lo que más me gusta de cómo quedó montado es que el proyecto de Xcode no se lleva una copia de la extensión, sino que apunta a la carpeta de siempre. Así sigo editando donde editaba, compilo, y el teléfono se lleva lo último sin copiar nada a mano. El precio fue que se metía la carpeta entera dentro de la aplicación —las pruebas, la documentación y hasta los propios scripts—, así que hice otro script que la corta y deja pasar solo lo que tiene que ir dentro.
Por el camino, las cosas de Safari: comparte un array entre claves que ni existen, se le colaba un triste .swf que en Chrome no pasaba, y el selector de ficheros de iOS directamente no abre, así que para llevarme el perfil de un sitio a otro el respaldo acabó siendo copiar y pegar texto a lo bruto. También rehíce el popup pensando en el dedo y no en el ratón, y escondí el interruptor de apagar JavaScript por sitio, porque esa pieza en Safari no existe y un botón que no hace nada es peor que no tenerlo: parece que la extensión está rota.
Y lo que me toca de aquí en adelante: reinstalarla en el teléfono cada siete días. Como la firmo con una cuenta gratuita de Apple, la aplicación caduca a la semana y hay que volver a compilarla y pasarla otra vez. Es el peaje por no pagar la cuota anual de desarrollador.
📅 8 de septiembre de 2026
El día que me lié la manta a la cabeza: me hice mi propio CMS. La idea era poder escribir entradas desde cualquier dispositivo, verlas con el tema de verdad mientras las escribo y publicar sin abrir una terminal. Empezó siendo un esqueleto que listaba entradas, autoguardaba y enseñaba la vista en vivo, y acabó el día siendo una aplicación entera.
Por el camino tiré el editor casero a la basura y me pasé a CodeMirror, que fue lo que de verdad desatascó todo: se acabó medir a mano dónde está el cursor. Y con eso vino lo demás: números de línea, la vista previa que sigue al cursor al píxel, soltar fotos para que se conviertan solas y se metan con su texto alternativo, girar y recortar sin salir del editor, asistentes para YouTube, tuits (X), spoilers, colores, enlaces y hasta uno para los globos de texto, con los personajes y los gestos leídos del propio tema.
Lo que más guerra me dio fue el iPhone. Que la barra de atajos se pegue al teclado, que al escribir la vista salte al cursor y no al sitio donde estabas antes de que apareciera el teclado, que al cerrar el teclado no se pierda el sitio, que no quede una franja muerta encima… nada de eso es difícil por separado, pero junto es un rompecabezas.
Y en el blog hice limpieza: toda la documentación a docs/ con el README de índice, unifiqué el script que usamos para Mac y Windows en una sola versión, y el de imágenes ahora crea la carpeta él solo y se queda esperando las fotos.
📅 9 de septiembre de 2026
Segundo día mejorando el CMS, y el más largo. Le puse la regla de oro que me parece lo más importante de todo el proyecto: al guardar una entrada solo se tocan los campos que la pantalla enseña. El resto de la cabecera —about, keywords, etc.— se queda byte a byte como estaba. Lo comprobé contra todas las entradas del blog: reescribir cada campo con su propio valor no cambia ni un carácter de ningún fichero. Con lo fácil que es que un programa te “normalice” la cabecera y te reviente medio blog, eso no era un capricho.
Ese día el editor también aprendió a crear entradas nuevas pidiéndoselas al generador con mi propia plantilla, a publicar haciendo commit de solo esa entrada (con un interruptor para decidir si además se sube y se publica al momento), a seguir el despliegue en el gestor de repositorios y a comprobar que lo que está mirando es mi commit y no otro anterior. Le puse acceso privado para evitar que alguien ajeno pueda entrar, candado al subir fotos para que dos editores no se pisen (normalmente no pasa pero los humanos todo lo pueden www), y que el guardado de uno no borre lo que escribe el otro.
Y publiqué de verdad desde él por primera vez, con una entrada de pruebas que creé, publiqué en la web e hice desaparecer en el mismo día. Ver tu propio commit corriendo en el despliegue y la entrada apareciendo publicada, todo desde el móvil, fue el momento en que aquello dejó de ser un juguete.
También moví el despliegue para que construya desde el SSD, ya que estaba haciéndolo desde un HDD lento.
📅 10 de septiembre de 2026
Día de rematar detalles del CMS, de esos que no se ven pero se notan: que no se pierdan los segundos de la fecha al guardar, que el editor se los comía y eso descolocaba el orden de las entradas publicadas el mismo día; y poder editar los shortcodes que llevan un valor suelto, como los de YouTube, en vez de tener que borrarlos y volver a escribirlos.
📅 12 de septiembre de 2026
Me dio por rehacer entera mi página de inicio, y nació la Startpage V2, que le he puesto de apellido Bento Edition. Sin frameworks: HTML, CSS y JavaScript a pelo, pero con cristal esmerilado, un fondo de malla animado y un brillo que persigue al ratón por los bordes de las tarjetas.
Lo que más uso al final es lo aburrido: el buscador con sugerencias de Google en tiempo real (por JSONP, para esquivar el CORS), el clima de las ciudades que me interesan, y los atajos que se ordenan arrastrando.
Y la tarde se me fue en lo de siempre al ponerle fondos de foto: conseguir que el texto se lea encima de cualquier cosa. Eso y una variable savedFilter que estaba declarada dos veces y paraba en seco la ejecución del app.js entero, que me tuvo un rato mirando una página muerta sin entender nada.
📅 13 de septiembre de 2026
Seguí puliendo la startpage: elegir qué ciudades del clima quieres ver, avisos de lluvia y de calor mirando las doce horas siguientes, y todas ellas pedidas en una sola petición en vez de una por ciudad, y el diseño arreglado para el móvil, que era un desastre entre los 480 y los 768 píxeles.
Pero lo importante del día fue en sing-box, y viene directo del susto del día 6: le puse un cerrojo de DNS por entrada. La primera regla descarta cualquier consulta de DNS que llegue por los túneles, sea cual sea. Es una segunda capa independiente de la de rutas, porque una sola defensa no es una defensa. Lo probé desde nuestro VPS fuera de la red contra el gateway y contra el Mac: cero respuestas, ni A, ni TXT, ni por TCP. Tener un sitio fuera de casa desde el que probar es justo lo que hace falta para saber si alguien llegaría a tocar algo de mi red desde fuera. Y lo metí en la plantilla, para que sobreviva a la siguiente reconstrucción.
📅 14 de septiembre de 2026
Tako-Dame llegó a la v1.70, con un arreglo pequeño: la palabra banner a solas ya no basta para que algo sea candidato a bloqueo, que así estaba tumbando cosas legítimas.
📅 16 de septiembre de 2026
Me monté una API propia para la startpage, que de momento hace una sola cosa: servir los favicons de los atajos desde mi propio dominio en vez de pedírselos a Google. Busca el icono una vez por dominio —mirando primero los iconos que declara la propia página, luego /favicon.ico, y solo como último recurso el servicio de Google, pero pidiéndoselo desde el servidor—, lo guarda en disco y lo renueva a los treinta días.
Como es pública y se dedica a descargar lo que le pidan, le puse el cinturón bien apretado: rechaza direcciones privadas en cada conexión y en cada redirección, solo http y https, nunca SVG (que es un formato que puede llevar código dentro), topes de tamaño y de tiempo, y un límite de cuántos dominios nuevos acepta seguidos. Node sin una sola dependencia.
Y en el blog, tarde de sidebar: una sola columna en los anchos intermedios, el sidebar a dos columnas sin que salga barra de scroll doble, “más del blog” ordenado por fecha de publicación, y la portada emitiendo también la cuarta tarjeta del sidebar apilado. Todo eso es de lo más pesado de ajustar, porque cada post tiene una altura distinta según lo que lleve incrustado.
📅 17 de septiembre de 2026
Volví a Tako-Downloads y la subí de la 0.9.1 a la 0.9.4, con cuatro cosas de las que se notan:
Primero, un criterio mejor para el robo de trabajo: cuando un segmento termina, en vez de ayudar al que tiene más bytes pendientes, ayuda al que va a tardar más en acabar, midiendo la velocidad de cada uno con una media móvil. Y si uno lleva tres segundos sin recibir nada, se considera atascado y va el primero. Probado con una ISO de 8,5 GB: diez segmentos acabaron siendo doce, con pausa y reanudación por medio, y el SHA-256 cuadra con el publicado.
Segundo, los tamaños. Los dividía entre 1024 pero poniendo la etiqueta GB, así que esa misma ISO de 8,47 GB en el Finder salía como 7,9 GB en mi app. Ahora se divide entre 1000 en todas partes.
Tercero, una condición de carrera de las de libro, cazada por el detector que trae Go para esto: Downloaded() y View() leían el tamaño sin el candado mientras otras partes lo escribían, y la interfaz las llama constantemente.
Y cuarto, el más rastrero de todos. Wails firma la aplicación de forma provisional, y macOS la reconoce por la huella del ejecutable, que cambia en cada compilación. Resultado: cada versión nueva perdía el permiso de acceso total al disco, y yt-dlp dejaba de poder leer las cookies del navegador. Ahora, al terminar de compilar, se vuelve a firmar sola con un certificado de desarrollo de verdad.
📅 18 de septiembre de 2026
Este día no me enteré de nada, y esa es justo la historia: el colector del router estuvo veintiuna horas sin recoger nada y no lo supe hasta la mañana siguiente, cuando el resumen diario llegó a Discord con un aviso de que no llegaban líneas desde hacía 1.285 minutos.
El router estaba perfecto: 328 horas encendido, el syslogd mandando lo suyo, los cuatro crones vivos. El muerto era el Windows, con un database is locked en el registro.
Y detrás había tres fallos encadenados. El colector se moría entero ante un solo bloqueo de la base de datos. El enriquecedor, que es el que consulta las IP, solo cerraba la escritura cada 25 consultas, y con la API tardando 30 segundos por IP la dejaba bloqueada muchísimo rato. Pero la raíz de todo era otra cosa: faltaba un índice. La consulta que elige qué IP preguntar recorría las 38.652 filas de la tabla de orígenes de arriba abajo cada vez. Eso llevaba semanas incubándose y solo hacía falta que un día coincidiera con la API lenta.
📅 19 de septiembre de 2026
El día más largo del mes, y con diferencia.
Denunciar a quien escanea, sin denunciar a quien no
Llevo desde agosto guardando el registro del router, y la tentación obvia es mandar esas IP a AbuseIPDB para que otros las bloqueen. El problema es que consultar es privado y reversible, pero reportar es público y permanente: el informe lleva mi nombre, se queda en la ficha de esa IP y si me equivoco he manchado a un tercero.
Y ya me equivoqué una vez a lo grande: en agosto descubrí que el 64% de lo que mi colector llamaba “conexión entrante” eran respuestas QUIC al tráfico de mi propia casa, desviadas por una regla de reenvío de la Switch. Si hubiera estado reportando en automático, habría denunciado a Google por atacarme.
Así que lo hice al revés de como se hace normalmente: primero un simulador que no envía nada, que enseña qué se reportaría y lo contrasta con lo que AbuseIPDB ya sabe. Sobre 30 días y 557.000 eventos, lo interesante no fue lo que quería mandar, sino todo lo que tuve que enseñarle a callarse:
- Paquetes cuyo puerto de origen es el 443 o el 80: 533 IP y 25.065 eventos. Un paquete que sale del 443 de otro no es un escaneo, es el rebote de un ataque contra un tercero con la dirección falsificada. Exactamente la misma forma que el fallo del QUIC. Sin ese filtro habría denunciado a 533 servidores web que no hicieron nada.
- Machacar un solo puerto: alguien mandándome 873 paquetes siempre al mismo puerto no está barriendo nada, es un programa de intercambio de archivos o el resto de un mapeo viejo. Llamar “escaneo de puertos” a eso sería mentir.
- Puertos que yo misma tengo reenviados pero restringidos por origen: el tráfico legítimo cae en la regla de descarte y parece un escaneo.
- Los vecinos de mi propio ISP, que podrían ser gente con el router infectado, pero también infraestructura del proveedor. Denunciar a tu ISP no se arregla borrando el informe.
Y luego la pieza de la que estoy más contenta: los escáneres de investigación. Censys, Shodan, ONYPHE, Shadowserver… escanean internet entero de forma declarada, y varios publican datos de amenazas gratis. El filtro que tenía miraba el nombre del ISP, pero eso solo lo sé si he gastado una consulta en esa IP, y tenía miles sin consultar.
La solución fue el DNS inverso, que es la puerta que ellos mismos dejan abierta: se identifican en el nombre porque les interesa que no los denuncies (aunque hay mucha gente que tira de sistemas automáticos de terceros y se los denuncia igual www). Resolví las 8.485 pendientes desde el VPS en seis minutos —por goteo habrían sido doce días— y aparecieron 1.916 escáneres que el filtro anterior no veía. Infrawatch solita eran 741 IP. Y es autoactualizable: una IP nueva de Censys mañana ya viene etiquetada, sin mantener ninguna lista a mano. De hecho Infrawatch, Internet Census, BufferOver e Internet Albedo no estaban en ninguna de las listas públicas que miré.
Eso sí, el nombre solo no vale: cualquiera con control de su zona inversa puede ponerse scanner.censys.io y librarse. Hay que comprobar que ese nombre resuelva de vuelta a la misma IP. Y ya cazó a uno: www.internet-albedo.net no resolvía de vuelta.
Con todo eso filtrado, mandé el primer informe de verdad. Y al verificar el dominio como webmaster me subieron la cuota a 2.700 consultas al día.
📅 20 de septiembre de 2026
Hoy he seguido con lo de ayer: revisando la segunda tanda de candidatos salieron tres filtros más, y los junté todos en un único sitio donde se decide a quién se denuncia, que los tenía repartidos y eso siempre acaba mal. También hice que la lista negra corrobore ella también, y no se quede todo en la puntuación, y que el colector deje de guardar como “otros” el ruido de crond y dropbear, que llenaba la tabla de nada.