tinc-boot - red de malla completa sin dolor


Automático, seguro, distribuido, con conexiones transitivas (es decir, reenvío de mensajes cuando no hay acceso directo entre suscriptores), sin un solo punto de falla, red VPN de malla completa, probada por el tiempo, de bajo consumo de recursos y con la capacidad de "perforar" NAT: ¿es posible?


Las respuestas correctas son:


  • sí, con dolor si usa tinc.
  • sí, fácil si usas tinc + tinc-boot

Saltar enlace introductorio


Descripción de Tinc


Desafortunadamente, se publicó un poco de información sobre Tinc VPN en Habré, pero todavía se pueden encontrar algunos artículos relevantes:



De los artículos en inglés se pueden distinguir:



La fuente original es mejor considerar la documentación original de Tinc man


Entonces (una reimpresión gratuita desde el sitio oficial), Tinc VPN es un servicio ( tincd daemon) que garantiza el funcionamiento de una red privada al tunelizar y encriptar el tráfico entre nodos. El código fuente está abierto y disponible bajo la licencia GPL2. Al igual que la solución clásica (OpenVPN), la red virtual creada está disponible a nivel de IP (OSI 3), lo que significa que, en el caso general, no es necesario realizar cambios en las aplicaciones.


Características clave


  • cifrado, autenticación y compresión del tráfico;
  • solución totalmente automática de malla completa, que incluye la creación de conexiones a nodos de red en un modo todo junto o, si esto no es aplicable, reenviar mensajes entre hosts intermedios;
  • golpe NAT;
  • la capacidad de conectar redes aisladas a nivel de ethernet (conmutador virtual);
  • Soporte de múltiples sistemas operativos: Linux, FreeBSD, OS X, Solaris, Windows, etc.

Hay dos ramas de desarrollo de tinc: 1.0.x (en casi todos los repositorios) y 1.1 (beta eterna). El artículo usa la versión 1.0.x en todas partes.


Tinc 1.1x ofrece varias características clave nuevas: seguridad de avance perfecta, conectividad de cliente simplificada (en realidad reemplaza a tinc-boot ) y un diseño generalmente más atento.

Sin embargo, en este momento, una versión estable - 1.0.x se indica y destaca en el sitio web oficial, por lo que al usar todas las ventajas de la rama 1.1, debe evaluar todas las ventajas y desventajas de usar una versión no final.

Desde mi punto de vista, una de las posibilidades más fuertes es reenviar mensajes cuando no es posible la conexión directa. Al mismo tiempo, las tablas de enrutamiento se crean automáticamente. Incluso los nodos sin una dirección pública pueden pasar el tráfico a través de ellos mismos.



Considere la situación con tres servidores (China, Rusia, Singapur) y tres clientes (Rusia, China y Filipinas):


  • los servidores tienen una dirección pública, clientes detrás de NAT;
  • ILV durante la próxima prohibición de probables representantes El Telegram bloqueó a todos los anfitriones, excepto a la "amiga" China;
  • la frontera de la red de China <-> RF es inestable y puede caer (debido a ILV y / o al censor chino);
  • las conexiones a Singapur son condicionalmente estables (experiencia personal);
  • Manila (Filipinas) no es una amenaza para nadie y, por lo tanto, está permitido para todos (debido a la distancia de todos y de todo).

Por ejemplo, el intercambio de tráfico entre Shanghai y Moscú, considere los escenarios de Tinc (aproximadamente):


  1. Situación nativa: Moscú <-> rusia-srv <-> china-srv <-> Shanghai
  2. ILV cerró la conexión a China: Moscú <-> rusia-srv <-> Manila <-> Singapur <-> Shanghai
  3. (después de 2) en caso de falla del servidor en Singapur, el tráfico se transfiere al servidor en China y viceversa.

Siempre que sea posible, Tinc intenta establecer una conexión directa entre los dos nodos detrás de NAT mediante puñetazos.


Una breve introducción a la configuración de tinc


Tinc se posiciona como un servicio fácil de configurar. Sin embargo, algo salió mal: para crear un nuevo nodo, es mínimamente necesario:


  • Describa la configuración del host (tipo, nombre) ( tinc.conf );
  • Describa el archivo de configuración (subredes servidas, direcciones públicas) ( hosts/ );
  • crear una clave;
  • crear un script que especifique la dirección del nodo y los parámetros relacionados ( tinc-up );
  • Es recomendable crear un script que borre los parámetros creados después de detenerse ( tinc-down ).

Además de esto, cuando se conecta a una red existente, debe obtener las claves de host existentes y proporcionar las suyas propias.


Es decir: para el segundo nodo



Para el tercero



Cuando se usa la sincronización bidireccional (por ejemplo, unison ), el número de operaciones adicionales aumenta a N piezas, donde N es el número de nodos públicos.


Debemos rendir homenaje a los desarrolladores de Tinc: para su inclusión en la red, solo intercambie claves
con solo uno de los nodos (bootnode). Después de iniciar el servicio y conectarse con el participante, tinc obtendrá la topología
red y podrá trabajar con todos los suscriptores.

Sin embargo , si el host de arranque no está disponible y tinc se ha reiniciado, entonces no hay forma
se conectará a la red virtual.

Además, las enormes posibilidades de tinc, junto con la documentación académica de esto (bien descrita, pero con pocos ejemplos), proporcionan un campo extenso para los errores.


Razones para crear tinc-boot


Si generalizamos los problemas descritos anteriormente y los formulamos como tareas, entonces obtenemos:


  1. se necesita la capacidad de crear un nuevo sitio con un mínimo esfuerzo;
    • potencialmente, es necesario hacer posible darle al especialista promedio (enikey) una pequeña línea para crear un nuevo nodo y conectarse a la red;
  2. es necesario proporcionar una distribución automática de claves entre todos los nodos activos;
  3. es necesario proporcionar un procedimiento simplificado de intercambio de claves entre el bootnod y el nuevo cliente.

bootnode: un nodo con una dirección pública (ver arriba);

Debido a los requisitos de la reivindicación 2, se puede argumentar que después del intercambio de claves entre el nodo de arranque y el nuevo nodo, y después
conectando el nodo a la red, la distribución de la nueva clave se realizará automáticamente.


Son estas tareas las que realiza tinc-boot .


tinc-boot es una aplicación de código abierto independiente, aparte de tinc , que proporciona:


  • creación simple de un nuevo nodo;
  • conexión automática a una red existente;
  • establecer la mayoría de los parámetros por defecto;
  • distribución clave a los nodos de miel.

Arquitectura


El archivo ejecutable tinc-boot consta de cuatro componentes: un servidor bootnode, un servidor de administración de distribución de claves y comandos de administración RPC para él, así como un módulo de generación de nodos.


Módulo de generación de nodos


El módulo de generación de nodos ( tinc-boot gen ) crea todos los archivos necesarios para que tinc se ejecute correctamente.


Simplificado, su algoritmo se puede describir de la siguiente manera:


  1. Defina el nombre de host, la red, los parámetros de IP, el puerto, la máscara de subred, etc.
  2. Normalícelos (tinc tiene un límite en algunos valores) y cree los que faltan
  3. Verificar parámetros
  4. Si es necesario, instale tinc-boot en el sistema (desactivable)
  5. Crear tinc-up , tinc-down subnet-up , subnet-up , tinc-down subnet-up
  6. Crear tinc.conf configuración tinc.conf
  7. Crear hosts/
  8. Realizar generación de claves
  9. Realizar intercambio de claves con bootnode
    1. Cifre y firme su propio archivo de host con una clave pública, un vector de inicialización aleatorio (nombre) y un nombre de host utilizando xchacha20poly1305, donde la clave de cifrado es el resultado de la función sha256 del token
    2. Enviar datos a través del protocolo HTTP al bootnode
    3. Descifre la respuesta recibida y el encabezado del X-Node contiene el nombre del nodo de arranque utilizando el nombre original y el mismo algoritmo
    4. Si tiene éxito, guarde la clave recibida en hosts/ y agregue una entrada ConnectTo al archivo de configuración (es decir, una recomendación de dónde conectarse)
    5. De lo contrario, use la siguiente dirección en la lista del nodo de arranque y repita desde el paso 2
  10. Mostrar recomendaciones para iniciar un servicio

La conversión a través de SHA-256 se usa solo para normalizar la clave a 32 bytes

Para el primer nodo (es decir, cuando no hay nada que especificar como dirección de arranque), se omite el paso 9. Bandera - --standalone .


Ejemplo 1: crear el primer sitio público


La dirección pública es 1.2.3.4


sudo tinc-boot gen --standalone -a 1.2.3.4


  • la bandera -a permite especificar direcciones disponibles públicamente

Ejemplo 1: agregar un nodo no público a la red


El nodo de arranque se tomará del ejemplo anterior. El host debe tener tno-boot bootnode ejecutándose (descrito más adelante).


sudo tinc-boot gen --token "MY TOKEN" http://1.2.3.4:8655


  • la bandera --token establece el token de autorización

Módulo Bootstrap


El tinc-boot bootnode genera un servidor HTTP con una API para el intercambio de claves primarias con nuevos clientes.


Por defecto, 8655 puerto 8655 .


Simplificado, el algoritmo se puede describir de la siguiente manera:


  1. Aceptar una solicitud de un cliente
  2. Descifre y verifique la solicitud usando xchacha20poly1305, usando el vector de inicialización pasado durante la solicitud y donde la clave de cifrado es el resultado de la función sha256 del token
  3. Comprobar nombre
  4. Guarde el archivo si todavía no hay un archivo con el mismo nombre
  5. Cifre y firme su propio archivo y nombre de host utilizando el algoritmo descrito anteriormente
  6. Regresar al ítem 1

Juntos, el proceso principal de intercambio de claves es el siguiente:



Ejemplo 1: inicio del nodo de descarga


Se supone que se realizó la inicialización inicial del nodo ( tinc-boot gen )


tinc-boot bootnode --token "MY TOKEN"


  • la bandera --token establece el token de autorización. Debería ser lo mismo para los clientes que se conectan al host.

Ejemplo 2: inicio del nodo de descarga como servicio


tinc-boot bootnode --service --token "MY TOKEN"


  • el --service que cree un servicio systemd (de manera predeterminada, en este ejemplo, tinc-boot-dnet.service )
  • la bandera --token establece el token de autorización. Debería ser lo mismo para los clientes que se conectan al host.

Módulo de distribución de llaves


El módulo de distribución de claves ( tinc-boot monitor ) genera un servidor HTTP con una API para intercambiar claves con otros nodos dentro de la VPN . Se fija a la dirección emitida por la red (el puerto predeterminado es 1655 , no habrá conflictos con varias redes, ya que cada red tiene / debe tener su propia dirección).


El módulo se inicia y funciona de forma completamente automática: no necesita trabajar con él en modo manual.


Este módulo se inicia automáticamente cuando la red está activa (en la secuencia tinc-up comandos tinc-up ) y se detiene automáticamente cuando se detiene (en la secuencia de comandos tinc-down ).


Soporta operaciones:


  • GET / - dale tu archivo de nodo
  • POST /rpc/watch?node=<>&subnet=<> : recoge un archivo de otro nodo, suponiendo que se esté ejecutando un servicio similar. Por defecto, los intentos tienen un tiempo de espera de 10 segundos, cada 30 segundos hasta el éxito o la cancelación.
  • POST /rpc/forget?node=<> - deja intentos (si los hay) de recoger el archivo de otro nodo
  • POST /rpc/kill : finaliza el servicio

Además, cada minuto (de forma predeterminada) y cuando se recibe un nuevo archivo de configuración, se realiza la indexación de los nodos guardados para los nuevos nodos públicos. Cuando se detectan nodos con el indicador de Address , se agrega una entrada al archivo de configuración tinc.conf para recomendar la conexión al reiniciar.


Módulo de distribución de claves (gestión)


Los comandos para solicitar ( tinc-boot watch ) y cancelar la solicitud ( tinc-boot forget ) del archivo de configuración desde otros nodos se ejecutan automáticamente cuando se detecta un nuevo nodo (secuencia subnet-up comandos de subnet-up ) y se detiene (secuencia de comandos de subnet-down ), respectivamente.


En el proceso de detener el servicio, se tinc-down script tinc-down en el que el comando tinc-boot kill detiene el módulo de distribución de claves.


En lugar de total


Esta utilidad se creó bajo la influencia de la disonancia cognitiva entre el genio de los desarrolladores de Tinc y la creciente complejidad lineal de configurar nuevos nodos.


Las ideas principales en el proceso de desarrollo fueron:


  • si algo puede automatizarse, debe automatizarse;
  • los valores predeterminados deben cubrir al menos el 80% de uso (principio de Pareto);
  • cualquier valor puede ser redefinido usando tanto banderas como variables de entorno;
  • la utilidad debería ayudar, y no causar un deseo de invocar todo el castigo del cielo sobre el creador;
  • el uso de un token de autorización para la inicialización inicial es un riesgo obvio, sin embargo, en la medida de lo posible, se minimizó debido a la criptografía total y la autenticación (incluso el nombre del nodo en el encabezado de la respuesta no se puede reemplazar).

Un poco de cronología:


  • La primera vez que usé tinc hace más de 4 años. Estudió una cantidad significativa de material. Establecer una red ideal (en mi opinión)
  • Después de medio año, tinc fue reemplazado a favor de zerotier, como una herramienta más conveniente / flexible
  • Hace 2 años, hice un libro de jugadas ansible para implementar tinc
  • Un mes después, mi script se descompuso en una implementación incremental (es decir, cuando es imposible acceder a todos los nodos de la red, lo que significa distribuir claves)
  • Hace dos semanas, escribí un script de bash-script que era el prototipo de tinc-boot
  • Hace 3 días después de la segunda iteración, nació la primera versión (0.0.1 para ser exactos) de la utilidad
  • Hace 1 día, reduje la instalación de un nuevo nodo a una línea: curl -L https://github.com/reddec/tinc-boot/releases/latest/download/tinc-boot_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin/ tinc-boot curl -L https://github.com/reddec/tinc-boot/releases/latest/download/tinc-boot_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin/ tinc-boot
  • Pronto, se agregará la posibilidad de una conexión aún más simple a la red (sin sacrificar la seguridad)

Durante el desarrollo, probé activamente en servidores y clientes reales (la imagen de la descripción de tinc anterior está tomada de la vida real). Ahora el sistema funciona a la perfección y todos los servicios de VPN de terceros ahora están deshabilitados.


El código de la aplicación está escrito en GO y está abierto bajo la licencia MPL 2.0. Una licencia (traducción gratuita) permite el uso comercial (si alguien lo necesita repentinamente) sin abrir el producto fuente. El único requisito es que los cambios deben transferirse al proyecto.


Las solicitudes de piscina son bienvenidas.


Enlaces utiles


Source: https://habr.com/ru/post/468213/


All Articles