En otra de mis aventuras con el Mini PC que convertí en servidor, he encontrado una situación interesante con respecto a su uso desde fuera de la red doméstica. Al principio, solo utilizaba los servicios que instalaba de forma local, pero conforme pasaba el tiempo, me encontraba con cosas algo difíciles de realizar desde mi trabajo. Por ejemplo, pensé en permitir solo el acceso local a los servicios que corrían en el Mini PC, pero el tiempo y algunas situaciones me hicieron pensar en alojar la instancia de gitLab que uso para desarrollos en MCV Software en dicho servidor. Ese GitLab es prácticamente una instancia de un solo usuario, ya que la gran mayoría de proyectos que se encuentran abiertos ahí también están en nuestra organización en GitHub. A una semana de haber terminado la implementación inicial, simplemente puedo decir que ha estado funcionando de forma excelente. Eso sí, nunca hay que olvidarse de hacer copias de seguridad, pero eso siempre es recomendación, sin importar dónde se aloje el servidor.
Uno de los principales inconvenientes en el servidor que tengo en casa es que el proveedor de internet, que es Izzi, asigna direcciones IPV4 bajo un esquema CG-NAT. Esto significa que una sola dirección IPV4, que son las más utilizadas hasta este momento, y las que ya se han terminado, según noticias, se reparte entre muchas conexiones residenciales. Ciertamente es imposible decir el número de usuarios que comparten una misma dirección IP. Esto es especialmente difícil para usuarios que requieren tener puertos abiertos en un Router, como aquellos que juegan en consolas, utilizan cámaras Wifi o algunos otros dispositivos del denominado internet de las cosas. Simplemente no puedes abrir puertos en el router, porque el proveedor no tiene manera de saber si el puerto que tú necesitas estará siendo requerido más adelante por otro de tus vecinos de dirección IP. Entonces, para evitarse ese tipo de situaciones, prefieren compartir varios cientos de clientes con una sola dirección, e impedirles el acceso a puertos abiertos, configuración de modos tipo puente en el router, y otras cosas que me hubieran venido muy bien en esta aventura.
Pero aquí hay una cosa. Si CG-NAT impide que la gente juegue, ¿cómo es que Izzi puede vender algo? La respuesta está en IPV6.
Al terminarse las direcciones IPV4, se comenzaron a distribuir direcciones IPV6, que tiene muchos más espacios para asignar dispositivos y se estima que toda la humanidad, con sus incontables dispositivos, jamás agotará el espacio de direcciones, como sí pasó con IPV4. Actualmente, el estándar IPV6 está siendo lentamente adoptado por proveedores y servicios, que ven que implementar este nuevo protocolo es más barato (los bloques de direcciones, que controlan qué proveedor puede asignar cada dirección, son notablemente más baratos y ofrecen más direcciones disponibles). Esto a su vez, causa que proveedores en México estén implementando sistemas con CG-NAT para los sitios que aún no soporten IPV6, pero al mismo tiempo asignen una dirección IPV6 completamente usable para cualquier dispositivo que así lo requiera. Este ha sido mi caso, y mi sorpresa mayúscula al comprobar que puedo conectarme a mi pequeño servidor casero desde cualquier lugar que tenga una dirección IPV6 válida. Para hacerlo fue necesario configurar un par de aspectos en el Router de Izzi, principalmente para permitir el tráfico proveniente de direcciones IPV6 hacia dentro de la red local, pero una vez hecho eso, fue un éxito inmediato.
Ahora bien, para darle un nombre a nuestra dirección IPV6, que normalmente puede cambiar cada cierto tiempo (aunque, hay qué decir que en el tiempo que la he tenido configurada, no he visto un solo cambio, incluso después de reinicios de router), he decidido utilizar los servicios de Cloudflare como un DNS dinámico. Ah, Cloudflare, ese servicio que funciona normalmente muy bien, pero que cuando cae, hace que medio internet se vaya con él. Cada vez me gusta más, a decir verdad, y hoy no va a ser la excepción, ya que he encontrado un contenedor Docker que permite establecer la configuración para un DNS dinámico. De ese modo, siempre tendré un subdominio que apunta hacia mi dirección IPV6, sin importar si esta dirección cambia en algún momento. Siempre que el contenedor esté activo, la dirección se mantendrá actualizada.
Requisitos
Lo primero que se debe tener en cuenta, naturalmente, es que al tratarse de un contenedor Docker, se necesitan instalados docker y docker compose en el equipo host. Para eso, se puede remitir a la documentación de instalación de Docker, para diversos sistemas operativos. En mi caso, el host es un Debian 11, aunque la configuración no debería ser diferente para otros tipos de host. También es evidente que necesitarás un dominio apuntado ya a los servidores DNS de Cloudflare, para que pueda crear los subdominios necesarios.
obteniendo datos de Cloudflare
Ya que el contenedor necesita escribir y leer información de los sistemas de Cloudflare, necesitaremos dos datos importantes: el ID de zona, que nos permite identificar cada dominio en Cloudflare, y un token de API, que permite realizar acciones a nombre del usuario que posee la zona DNS.
Creando token de API
- Accede a la sección de Tokens de API dentro de tu perfil de Cloudflare, y selecciona el botón llamado “create token”.
- La primer pantalla nos permite seleccionar una plantilla de permisos. Esto es útil ya que se configuran los permisos que se utilizan para la mayoría de los casos. La plantilla que nos interesa es la primera, llamada “Edit Zone DNS”. Para usarla, simplemente pulsa sobre la columna de la derecha, en el botón llamado “use template”.
- Una vez seleccionada la plantilla, hay que configurar algunos permisos relacionados con esta. Por defecto, el tipo de permiso que se le da a la plantilla es de edición, lo que se debe dejar así. En el apartado “Zone Resources”, se permite decidir si el Token tiene permiso para modificar todas las zonas o una zona específica. Esto se configura en el campo llamado “Specific zone”, que se puede manipular como un cuadro combinado, con la salvedad que para seleccionar una opción se debe presionar Intro. Si se ha elegido permitir solo trabajar sobre una zona específica, se debe seleccionar la zona en el siguiente apartado, llamado “Select”. El resto de opciones deberían permanecer como están configuradas por defecto, así que lo que sigue es presionar el botón llamado “Continue to summary”.
- Una vez en el resumen del token, simplemente presiona el botón “Create token” para terminar con el proceso. Cloudflare debería mostrar un token que permitirá acceder a su API. Copia ese código y guárdalo para usarlo más adelante.
Obteniendo el ID de zona
Copiar el ID de zona es de lo más sencillo. Simplemente hay qué acceder al sitio para el que deseas crear subdominios, esto en la página de Perfil de Cloudflare, y buscar un encabezado que se titula como “Zone ID”. Debajo de este, está nuestro ID de zona. Al igual que con el token de API, copia este valor y guárdalo para más adelante.
Configurando el contenedor
- Crea un directorio para poder guardar la configuración del contenedor, y el archivo para docker-compose:
mkdir cloudflare-ddns
- Crea un fichero llamado config.json, con opciones parecidas a las siguientes. Para ver la configuración de referencia, puedes consultarla directamente en el repositorio:
{
"cloudflare": [
{
"authentication": {
"api_token": "V_XXXXXXXX",
"api_key": {
"api_key": "",
"account_email": ""
}
},
"zone_id": "XXXXXXXXXX",
"subdomains": [
{
"name": "subdominio",
"proxied": false
},
{
"name": "otro_subdominio",
"proxied": true
}
]
}
],
"a": false,
"aaaa": true,
"purgeUnknownRecords": false,
"ttl": 300
}
- Reemplaza los valores para api_token y zone_id con los que has copiado previamente en las fases anteriores.
- Presta atención que al momento de crear los subdominios, no es necesario que coloques el dominio completo en el apartado “name”. Es decir, si tu dominio es example.com, y necesitas hacer un subdominio llamado prueba.example.com, solamente se coloca la palabra prueba en el nombre de subdominio.
- el parámetro proxied indica si Cloudflare debería redirigir mediante su sistema proxy el subdominio o no. Ponerlo a true hace que solo se pueda usar el puerto 443, por lo que si tienes software corriendo en otros puertos tal vez sea mejor no poner proxied a true.
- Los parámetros “a” y “aaa” controlan si se deben crear registros para la dirección IPV4 (a) y para IPV6 (aaa). En mi caso, como mi IPV4 está detrás de un NAT, lo he desactivado.
- “purgeUnknownRecords” borra los registros que no estén configurados en este archivo.
- ttl controla cuanto tiempo en segundos pasará antes de que el contenedor actualice la dirección IP. Las direcciones se actualizan solamente al cambiar, así que los 5 minutos que se configuran por defecto parecen una buena idea.
- Crea un fichero docker-compose.yml, con lo siguiente:
version: "3.7"
services:
cloudflare-ddns:
image: timothyjmiller/cloudflare-ddns:latest
container_name: cloudflare-ddns
security_opt:
- no-new-privileges:true
network_mode: "host"
environment:
- PUID=1000
- PGID=1000
volumes:
- ./config.json:/config.json
restart: unless-stopped
- Para comenzar a correr el contenedor, simplemente ejecuta el comando correspondiente:
sudo docker compose up -d
- Luego de descargar y poner en marcha el servicio, puedes revisar sus logs para verificar que ya está actualizando los registros DNS con el siguiente comando:
sudo docker compose logs --tail 20
conclusión
Si todo ha salido como se espera, los logs del comando deberían indicar que se están actualizando las direcciones IP cada x número de segundos, donde X es el número especificado como ttl. También debería ser posible hacer ping hacia el subdominio, y ver que el servicio responde correctamente. Si algo de esto no funciona, puedes comenzar diagnosticando los puertos en el router, el estado del firewall y tratar de acceder directamente a la dirección (sin usar el subdominio) para identificar por dónde puede estar el problema.