Blog ·
Demostrar la propiedad de un nombre de host
Un formulario de monitorización con un campo de host es un generador de tráfico si nadie prueba la propiedad. Dos desafíos, por qué caducan y quién los busca.
Por Provibr
Todo producto que deja a un cliente escribir un nombre de host y luego lo comprueba cada minuto ha construido dos cosas. La primera es monitorización. La segunda es un generador distribuido de peticiones, apuntado a donde al cliente le apetezca, con el nombre de la empresa en el agente de usuario y la dirección de facturación del cliente detrás.
La objeción habitual es que el destino tiene una dirección pública, así que cualquiera podría enviarle tráfico de todos modos. Es cierto y no viene al caso. Una dirección pública no es permiso para medir a alguien, y «cualquiera podría» no es una defensa que sobreviva al primer informe de abuso, sobre todo cuando el tráfico es periódico, sostenido y procede de una plataforma comercial identificable.
Así que un destino que es un nombre de host hay que ganárselo. Este es el diseño en el que nos quedamos, incluidas las partes que son menos evidentes de lo que parecen.
Dos métodos que demuestran cosas distintas
Hay dos maneras prácticas de que alguien demuestre que un nombre es suyo, y conviene dejar claro que no son equivalentes.
Un registro TXT en el DNS demuestra el control de la zona. Quien puede poner un valor ahí decide adónde apunta el nombre, que es la afirmación más fuerte que existe sobre un nombre.
Un fichero en el servidor web demuestra el control de la máquina a la que el nombre resuelve en ese momento. Eso es más débil: en hosting compartido, más gente puede producirlo que editar la zona. También es mucho más alcanzable para un cliente que tiene un servidor pero ningún acceso al proveedor de DNS de su empresa.
Es el mismo par de compromisos que hacen las autoridades de certificación con sus dos tipos de desafío habituales, y de ahí se sigue la misma conclusión: ofrecer los dos, registrar cuál se usó, y no fingir que pesan lo mismo.
La forma del desafío
El registro TXT va bajo su propia etiqueta y no sobre el dominio en sí. Eso no es pulcritud. Un registro en el ápex aterriza junto a los registros de política de correo del cliente, donde cada cadena adicional acerca la respuesta al tamaño a partir del cual los resolutores empiezan a pasarlo mal, y donde la limpieza que otra persona haga de «registros TXT antiguos» lo elimina sin ninguna mala intención. Bajo su propia etiqueta queda solo.
El fichero vive bajo una ruta reservada con el token como nombre de fichero, y el fichero contiene el token y nada más.
El token en sí son treinta y dos caracteres hexadecimales, es decir, ciento veintiocho bits. No es un secreto y no es una clave: va a estar en un DNS público o en un servidor web público. Lo que tiene que ser es imposible de adivinar, porque cualquiera capaz de predecir un token válido puede reclamar un nombre que no le pertenece poniéndolo antes en su propio servidor. El hexadecimal en minúsculas lo mantiene seguro para un registro DNS, seguro dentro de una URL y libre de caracteres que se pueden leer mal cuando un cliente lo copia a mano.
Una regla estructural: exactamente una pieza de código escribe el desafío, y el resultado viaja con la petición hasta quien realiza la comprobación. Si ambos lados conocieran el prefijo de forma independiente, llegaría un día en que el panel mostraría una etiqueta y el comprobador consultaría otra, y el mensaje resultante sería «el registro no está ahí» sobre un registro que sí está. Nada sale más caro de soportar que una respuesta correcta a una pregunta que nadie hizo.
Por qué es el agente quien va a buscarlo
Esta es la decisión de la que cuelga el resto.
La plataforma no resuelve el nombre y no descarga el fichero. Si lo hiciera, nuestra propia infraestructura estaría abriendo conexiones hacia un nombre escrito por un usuario, que es falsificación de peticiones del lado del servidor con un campo de formulario como superficie de ataque. El resultado clásico es una petición a un endpoint de metadatos de la nube desde dentro de nuestra propia red, hecha por nosotros, a petición.
En vez de eso lo hace el propio agente del cliente: el mismo agente que ejecutará después las comprobaciones, situado dentro de la red del propio cliente y conectando solo hacia fuera. Mentir sobre el resultado no aporta nada, porque el premio es el permiso para medir algo que el agente ya alcanzaba. La verificación la realiza la parte que ya tiene el acceso, que es la única disposición en la que desaparece el incentivo de hacer trampa.
Hay una consecuencia que merece decirse en voz alta, porque parece una salvaguarda ausente. Las recomendaciones para este tipo de función suelen decir que hay que bloquear los rangos privados, el bucle local, las direcciones de enlace local y las de metadatos. Esa regla pertenece a las sondas alojadas, es decir, a los puntos de medición que operamos nosotros y que están en nuestra red. Para un agente dentro de la red del propio cliente, las direcciones privadas son el caso normal: su hipervisor, su switch, su almacenamiento. Bloquearlas dejaría sin la única fuente de medición justamente a la situación para la que existe.
Lo que ambas vías comparten es una única función que decide qué direcciones se permiten. Si la verificación y la medición tuvieran cada una su propia lista, llegaría un día en que no coincidirían, y ese día una de las dos es un rodeo alrededor de la otra.
Fallar en cerrado ante respuestas mixtas
Un nombre puede resolver a varias direcciones, y no tienen por qué ser igual de aceptables.
Si un nombre responde con la dirección pública del cliente y también con un endpoint de metadatos, entonces cada ejecución es un nuevo sorteo. Nueve ejecuciones miden la dirección pública y la décima habla con algo completamente distinto. Así que el número de respuestas aceptables no aporta ninguna información: una sola dirección prohibida dentro del conjunto deja todo el nombre inutilizable, y al cliente se le dice cuál era esa dirección, porque una negativa sobre la que no puede actuar es solo un mensaje de error.
Lo mismo vale durante la verificación y durante las comprobaciones ordinarias, que es otra vez la razón de que haya una política de direcciones y no dos.
Detalles que solo se aprenden ejecutándolo
Tres de estos salieron de construir el comprobador; el cuarto es una decisión de diseño que pertenece al mismo conjunto.
Comparar con «contiene», no con igualdad. A un proveedor de DNS se le permite presentar un valor TXT con comillas alrededor, y algunos paneles de control añaden comillas que luego vuelven a quitar en su propia vista. El token es largo y opaco: o está ahí dentro o no está, y exigir una coincidencia exacta solo castiga a los clientes que lo hicieron todo bien.
Enviar el nombre en la cabecera de host y en el nombre de servidor de TLS. La conexión va a una dirección que ya ha pasado la comprobación de la política, pero a un servidor web con varios sitios hay que decirle por cuál se está preguntando. Sin las dos cosas, un cliente correctamente configurado suspende la verificación porque le sirvieron el sitio por defecto de otra persona.
Permitir exactamente una redirección. Un servidor web que empuja todo a HTTPS es normal, y rechazar la redirección haría fallar a media internet. Permitir muchas dejaría que la prueba acabase en un sitio completamente distinto. Un salto, y solo al mismo host.
No exigir HTTPS para el desafío de fichero. La prueba es el token. Un certificado no le añade nada, y exigirlo convierte una comprobación de propiedad en una comprobación de certificado, que es otra pregunta con otros modos de fallo. Es el mismo razonamiento que hay detrás del tipo de desafío por HTTP simple en la emisión de certificados. Conviene notar que este valor por defecto es específico de la verificación: cuando el esquema es justo lo que se está midiendo, adivinarlo produciría una medición verde de algo distinto de lo que el cliente configuró, y ahí lo correcto es negarse.
La prueba caduca, porque los dominios cambian de dueño
Un nombre verificado no debería quedarse verificado para siempre, y la razón no es la paranoia sobre nuestros propios registros.
Los dominios cambian de propietario sin avisar a nadie. Un cliente deja caducar un registro, otra persona lo recoge, y desde ese momento estamos midiendo la máquina de un desconocido cada minuto, con el nombre de nuestro cliente pegado a la planificación. Nadie de esa cadena ha hecho nada malo y el resultado sigue siendo inaceptable.
Noventa días es la validez que elegimos, que es del mismo orden que un certificado de vida corta y por la misma razón: lo bastante corta para que una transferencia se note pronto, lo bastante larga para que los clientes no estén haciendo papeleo cada semana. La reverificación empieza catorce días antes de la caducidad, lo cual es deliberadamente generoso, porque una reverificación fallida suele significar que el agente estaba desconectado o que un resolutor iba lento, y no que la propiedad haya cambiado.
Los intentos están limitados a uno cada seis horas, sin atarse al intervalo de monitorización. Una verificación no es una medición: no dice nada sobre la disponibilidad, no pertenece a una cifra de tiempo activo, y preguntar más a menudo solo genera tráfico contra el DNS del cliente. Seis horas a lo largo de catorce días son más de cincuenta intentos, lo que convierte «caducado» en una señal real en lugar de en mala suerte.
Los estados que salen de esto son pendiente, verificado, caducando, caducado y revocado, y uno de ellos no es una puerta. «Caducando» existe para que la interfaz pueda avisar a alguien; una prueba que expira dentro de diez días es válida hoy, y las comprobaciones siguen ejecutándose. Tratarlo como un estado de puerta aparte le quitaría la monitorización a un cliente un día en el que no cambió nada.
La base de datos impone el emparejamiento en lugar de fiarse del código: una fila tiene o bien un instante de verificación y un instante de caducidad, o bien ninguno de los dos. Una fila verificada sin caducidad es una concesión permanente que nadie eligió, que es exactamente lo que todo este diseño existe para evitar.
Lo que dejaríamos por escrito
- Decidir qué demuestra el desafío, el control de la zona o el control de la máquina, y guardar cuál se usó.
- Poner el desafío bajo una etiqueta propia, nunca en el ápex junto a los registros de correo de alguien.
- Hacer que compruebe la parte que ya tiene el acceso. Si la plataforma descarga un nombre suministrado por el usuario, se ha construido una función de falsificación de peticiones.
- Una sola política de direcciones para verificación y medición. Dos listas acaban siendo dos comportamientos.
- Fallar en cerrado ante respuestas mixtas, y nombrar la dirección infractora en la negativa.
- Dar caducidad a la prueba, y empezar a renovarla mucho antes, porque el fallo del que se protege es silencioso por naturaleza.
Para que quede claro sobre nuestro propio estado: esto es un diseño que existe en código con sus propias pruebas, la monitorización no es algo que se nos pueda comprar hoy, y nada de lo anterior debería leerse como el anuncio de un producto. Es la forma que volveríamos a construir.
Del trabajo de monitorización de Provibr. La cuestión relacionada de medir sin tocar, y cuántos bytes se le permite enviar a una comprobación, está en por qué un escáner debe enviar cero bytes; cómo decide un agente cuál de varios puntos de medición usar está en cómo un agente elige el servidor de borde.