Cómo emular NAT loopback con dnsmasq

Aunque el título de la entrada queda muy técnico, el problema es bastante sencillo: tenemos un bonito dominio midominio.com que nos hemos agenciado para acceder desde el mundo exterior a nuestras cosas, pero desde dentro de nuestra red interna los enlaces midominio.com no funcionan. Nos sale la interfaz de administración del router, o falla directamente. Y no es sólo desde los PCs de la LAN, es que desde cualquier móvil o similar que se haya conectado a la wifi pasa lo mismo.

¿Por qué pasa esto? ¿Por qué hasta ahora me iba bien y desde que he cambiado de proveedor de internet ya no? Pues porque el que estas cosas funcionen depende de si nuestro router soporta una cosa llamada NAT loopback. Para explicar qué es esto, hay que ver un poco en detalle cómo funciona una conexión cuando accedemos desde fuera de nuestra red (en un caso doméstico típico):

  1. Nos conectamos a midominio.com
  2. El servidor DNS de allá donde estemos resuelva que midominio.com se corresponde con la IP 1.2.3.4
  3. Desde la IP que sea que tengamos allá donde estemos, nos conectamos a 1.2.3.4.
  4. Nuestro router se da cuenta de que esa conexión a la IP 1.2.3.4 la tiene que redirigir a la IP interna 192.168.0.x
  5. Todo funciona fantabulosamente

Si hacemos esto mismo desde dentro de la red, la cosa es diferente:

  1. Nos conectamos a midominio.com
  2. Nuestro servidor DNS lo traduce igualmente a la IP 1.2.3.4
  3. Nos conectamos allí, pero como nuestra máquina está en nuestra red, sale al exterior como la IP 1.2.3.4
  4. Al hacer una conexión desde una IP a sí misma, pasan cosas terribles.

Ojo, que no es que no tenga que funcionar la cosa. A partir de este momento, lo que pasa es que depende de si nuestro router soporta NAT loopback. Si es así, lo que pasa es que el router es tan inteligente que se da cuenta que, por mucho que hayamos accedido a través de midominio.com y tal dando una vuelta, en el fondo donde queremos conectar es a una IP interna de la LAN. Por tanto calcula cuál es, y redirige el tráfico correspondientemente. Si, por el contrario, el router no soporta NAT loopback, pues es probable que la conexión falle.

Si nos encontramos en este último caso, por ejemplo porque hemos cambiado de proveedor de internet y nos han puesto un router que es una mierda pinchada en un palo con prestaciones algo reducidas, no todo está perdido, y hay varias soluciones.

La facilonga e incompleta: Editar el fichero hosts

Básicamente se trata de ir a cada máquina, editar el fichero /etc/hosts, y añadir a pelo nuestro dominio para que lo resuelva siempre hacia la IP interna que nos interese. Es fácil, rápido y en 5 minutos tenemos el problema resuelto. Pero tiene dos grandes problemas:

  • Hay que toquitear todos y cada uno de los dispositivos de nuestra red, que es un poco rollo
  • Hay cacharros que no se dejan tocar el fichero hosts. Por ejemplo, para tocar el hosts de un dispositivo Android tiene que estar rooteado, que en muchos casos no es plan.
  • Para los PCs que siempre van a estar ahí va bien, pero, ¿qué pasa con los móviles, tablets y compañía, que hoy se conectan dentro de la LAN pero mañana los saco de casa y están fuera? Si pongo una entrada a piñón en el hosts sólo resolverán bien en la LAN, y si no la pongo sólo funcionará bien fuera de ella.

Vamos, que pintaba bien pero esto es un bluf. Hay que currárselo un poco más.

La trabajosa pero buena: dnsmasq

La mejor opción y más sostenible es aprovechar algún equipo que tengamos encendido siempre en la LAN, y montar ahí un mini servidor de DNS. La verdad es que montar un servidor DNS de verdad es un tostón, pero hay cosas como dnsmasq que son mucho más sencillas. En realidad, ponerlo en marcha es tan fácil como instalar el paquete:

sudo apt-get install dnsmasq

Sólo haciendo esto ya tendremos dnsmasq instalado y funcionando sobre la IP local (127.0.0.1), reenviando las peticiones DNS a los servidores DNS que tengamos configurados en el sistema, y haciendo además de caché DNS, que nunca viene mal. Ahora completamos el tema simplemente editando el /etc/dnsmasq.conf, y añadiendo al final un par de líneas tipo:

address=/midominio.com/192.168.1.17

Aquí le he dicho que para midominio.com lo resuelva con la IP que le he dado. Para todo lo demás, que lo propague al resto de DNSs. Un truqui que me ha costado encontrar como se hacía: si queremos que resuelva a IPs internas todos los subdominios menos alguno, se puede hacer así:

address=/midominio.com/192.168.1.17 server=/otraip.midominio.com/#

Y listos. Así enviará a la IP interna todas las peticiones de midominio.com, excepto las de otraip.midominio.com, que simplemente las propagará a los DNSs “normales”.

Para que esto funcione en toda la LAN, hay que decirles de alguna manera a los dispositivos que usen como servidor DNS no los DNSs típicos de la operadora, sino la máquina en la que está instalado dnsmasq. Pero tampoco hay que hacerlo a piñón de uno en uno, lo más limpio es entrar a la interfaz de administración de nuestro router, y en las opciones de DHCP le decimos que asigne como servidor DNS primario la IP de nuestro servidor con dnsmasq. Como secundarios dejamos los que hay por si las moscas un día está el servidor caído, y a partir de aquí a cualquier cacharro que se conecte a nuestra Wifi u obtenga IP por DHCP se le asignará como DNS primario nuestro servidor, con lo que en la práctica es como si tuviéramos NAT loopback.

Fuente original: https://nosoyvagosoyeficiente.wordpress.com/2018/06/21/emular-nat-loopback-con-dnsmasq/