Mi Blog // Archivo digital

Pensamientos, proyectos y notas técnicas

Originalmente, la configuración de mi blog estaba planeada como un proyecto puramente IPv6 a través de WireGuard, ya que todo se ejecuta en un servidor doméstico (por cierto, se pueden obtener direcciones IPv6 gratuitas en route64.org). Para mejorar la accesibilidad, ahora he añadido un proxy IPv4 externo (gracias a @Larvitz).

Sin embargo, surgieron problemas de SSL de inmediato: dado que originalmente tanto el registro A como el AAAA pasaban por el proxy, la validación de Let's Encrypt en mi servidor fallaba.

La solución: El "hack de IPv6"

La solución fue apuntar explícitamente el registro AAAA directamente a la IP de WireGuard de mi servidor, en lugar de dirigirlo también a través del proxy.

  • Dominio: blog.burningboard.org
  • Registro A (Proxy): 194.28.98.217
  • Registro AAAA (Servidor): 2a11:6c7:f05:a8::2 (WireGuard)

Gracias a este registro AAAA directo a mi IP de WireGuard, Let’s Encrypt sigue llegando a mi servidor directamente a través de IPv6 (ya que el registro AAAA tiene prioridad por defecto) y emite el certificado SSL. El tráfico IPv4 es reenviado de forma cifrada por el proxy hacia mí.

La configuración final

Para que la comunicación funcione sin problemas, tuvimos que ajustar los servidores Caddy:

1. En mi servidor (NixOS, blog.nix)

Para que las IPs reales de los visitantes lleguen correctamente y no sean sobrescritas por la IP del proxy, este debe marcarse como de confianza:

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. En el proxy externo (Caddy)

Para que el proxy se comunique correctamente con mi servidor a través de HTTPS, debe enviar el nombre de host (SNI):

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

¡El blog ahora es accesible a través de IPv4 e IPv6, está cifrado de forma segura y mi IP doméstica sigue siendo privada! 🚀

Lo más importante primero: los archivos Markdown habituales siguen siendo la base; simplemente soy un gran fan de esta solución tan sencilla. Pero bajo el capó, han cambiado muchas cosas:

He hecho algunos ajustes en la configuración:

📂 Archivos MD: La estructura del blog sigue siendo sencilla, basada en Markdown.

🌍 Más global que nunca: Mi blog ahora admite traducciones a 43 idiomas. ¡Sí, incluido el klingon! 🖖 (Qapla'!)

El plan inicial era una traducción en tiempo real totalmente automática basada en el reconocimiento de idioma del navegador. Spoiler: solo funcionó a medias. Se nota que la IA es impresionante, pero aún no está exactamente "ahí" donde nos gustaría que estuviera.

La solución: ahora simplemente traduzco cada entrada de antemano a todos los idiomas establecidos, lo cual también es mucho mejor para los motores de búsqueda (SEO). Si el reconocimiento automático falla en algún momento, podéis seleccionar manualmente vuestro idioma preferido a través del icono del globo terráqueo, que se guardará de forma sencilla mediante una cookie.

Las traducciones se realizan ahora con Gemini 3 Flash, lo que ofrece resultados sorprendentemente buenos. Sin embargo, hay que vigilar de cerca a la IA: en la primera ejecución por lotes, también se tradujeron por error las etiquetas (tags), algo que, por supuesto, no estaba planeado.

El código sigue estando disponible (si os interesa, simplemente escribidme un mensaje) 👍 Pero tened en cuenta que el sistema ahora requiere su propia clave API de Gemini 🔑.

He decidido cambiar mi blog de WriteFreely a un desarrollo propio: MD-Blog (donde MD, por supuesto, significa Markdown). El detonante fue una actualización fallida del sistema anterior; sin embargo, al final resultó ser el impulso perfecto para simplificarlo todo radicalmente y obtener el control total sobre el diseño.

El núcleo son archivos Markdown sencillos en la carpeta data/, que se convierten en HTML moderno en tiempo de ejecución. El resultado es ultrarrápido, no requiere base de datos y, gracias a un sistema de diseño propio (que incluye modo oscuro), ahora luce exactamente como me lo imaginaba. Incluso cuenta ahora con un moderno botón para compartir en Mastodon integrado.

Si tienes interés en el código o en esta configuración minimalista, ¡no dudes en contactarme a través de Mastodon!

En realidad, la idea detrás de #Winboat es excelente, pero la implementación parece ser todavía un poco inestable. Desde su instalación a principios de año, el sistema funcionaba, pero hoy el software ha dejado de responder por completo.

De repente, la imagen informó de memoria insuficiente (RAM). Intenté solucionar el problema manualmente, pero lamentablemente esto dejó el sistema definitivamente inutilizable. En lugar de invertir más tiempo en la resolución de problemas, me cambié directamente a la imagen de Windows de Dockurr, que de todos modos constituye la base técnica de Winboat.

Fehlermeldung

1. Preparación

Como utilizo Podman, primero creé los directorios necesarios en mi sistema host. De esta forma, se mantiene la integridad de los datos en caso de que sea necesario recrear el contenedor:

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. El comando de inicio

Nota importante: Sustituye los marcadores de posición en las variables -e USERNAME y -e PASSWORD por tus datos de acceso personales.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

Una vez que el contenedor esté activo, puedes acceder a la instancia de Windows directamente a través de tu navegador:

http://127.0.0.1:8006

Laufender Container

3. Resumen

Solo tuve que ejecutar el comando anterior una vez. En el uso diario, el entorno de Windows ahora se puede controlar cómodamente mediante estos comandos rápidos:

  • Iniciar: podman start windows
  • Detener: podman stop windows (o apagar directamente desde Windows)
  • Comprobar estado: podman ps -a

Enlaces de interés:

He instalado mi propio blog, principalmente para conocer mejor #NixOS. Sorprendentemente, todo el proceso fue bastante sencillo.

WriteFreely es ideal para esto: minimalista, rápido de configurar y sin distracciones. Perfecto para empezar a escribir y aprender algo nuevo por el camino. La configuración es agradablemente clara. Un par de opciones ajustadas, el directorio preparado, un proxy inverso delante y listo.

Así es como se ve mi configuración actual de NixOS para ello:

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # Solución para la generación de claves ActivityPub: la federación requiere openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # Creación automática del directorio de datos con los permisos correctos
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

Eso es básicamente todo. NixOS hace que sea realmente fácil configurar este tipo de servicios de forma limpia y mantenerlos reproducibles.