tinc-boot - rede de malha completa sem dor


Automático, seguro, distribuído, com conexões transitivas (ou seja, encaminhando mensagens quando não há acesso direto entre assinantes), sem um único ponto de falha, rede VPN de ponto a ponto, testada pelo tempo, baixo consumo de recursos e malha completa com a capacidade de "perfurar" NAT - é possível?


As respostas corretas são:


  • sim, com dor se você usar tinc.
  • sim, fácil se você usar tinc + tinc-boot

Skip Link Introdutório


Descrição Tinc


Infelizmente, poucas informações foram publicadas sobre o Tinc VPN no Habré, mas ainda há alguns artigos relevantes:



Os artigos em inglês podem ser distinguidos:



A fonte original é melhor considerar a documentação original do Tinc man


Portanto, (uma reimpressão gratuita do site oficial), o Tinc VPN é um serviço (daemon tincd ) que garante o funcionamento de uma rede privada, encapsulando e criptografando o tráfego entre os nós. O código fonte está aberto e disponível sob a licença GPL2. Como a solução clássica (OpenVPN), a rede virtual criada está disponível no nível IP (OSI 3), o que significa que, no caso geral, não é necessário fazer alterações nos aplicativos.


Principais recursos:


  • criptografia, autenticação e compactação de tráfego;
  • solução de malha completa totalmente automática, que inclui a construção de conexões com os nós da rede no modo tudo com todos ou, se isso não for aplicável, o encaminhamento de mensagens entre hosts intermediários;
  • soco NAT;
  • a capacidade de conectar redes isoladas no nível da Ethernet (comutador virtual);
  • suporte a vários sistemas operacionais: Linux, FreeBSD, OS X, Solaris, Windows, etc.

Existem dois ramos do desenvolvimento do tinc: 1.0.x (em quase todos os repositórios) e 1.1 (beta eterno). O artigo usa a versão 1.0.x em qualquer lugar.


O Tinc 1.1x fornece vários novos recursos principais: segurança avançada perfeita, conectividade simplificada do cliente (na verdade, substituindo o tinc-boot ) e um design geralmente mais cuidadoso.

No entanto, no momento, uma versão estável - 1.0.x é indicada e destacada no site oficial; portanto, ao usar todas as vantagens da ramificação 1.1, você deve avaliar todas as vantagens e desvantagens de usar uma versão não final.

Do meu ponto de vista, uma das possibilidades mais fortes é encaminhar mensagens quando a conexão direta não é possível. Ao mesmo tempo, as tabelas de roteamento são criadas automaticamente. Até nós sem um endereço público podem passar o tráfego por si mesmos.



Considere a situação com três servidores (China, Rússia, Cingapura) e três clientes (Rússia, China e Filipinas):


  • servidores têm um endereço público, clientes por trás do NAT;
  • ILV durante a próxima proibição de prováveis ​​proxies O Telegram bloqueou todos os hosters, exceto a China "amiga";
  • a fronteira da rede da China <-> RF é instável e pode cair (devido ao ILV e / ou devido ao censor chinês);
  • as conexões com Cingapura são condicionalmente estáveis ​​(experiência pessoal);
  • Manila (Filipinas) não é uma ameaça para ninguém e, portanto, é permitida para todos (devido à distância de todos e de tudo).

Por exemplo, na troca de tráfego entre Xangai e Moscou, considere os cenários de Tinc (aproximadamente):


  1. Situação nativa: Moscou <-> russia-srv <-> china-srv <-> Xangai
  2. ILV fechou a conexão com a China: Moscou <-> russia-srv <-> Manila <-> Cingapura <-> Xangai
  3. (após 2) em caso de falha do servidor em Cingapura, o tráfego é transferido para o servidor na China e vice-versa.

Sempre que possível, o Tinc tenta estabelecer uma conexão direta entre os dois nós por trás do NAT perfurando.


Uma breve introdução à configuração do tinc


Tinc está posicionado como um serviço fácil de configurar. No entanto, algo deu errado - para criar um novo nó, é minimamente necessário:


  • Descreva a configuração do host (tipo, nome) ( tinc.conf );
  • Descreva o arquivo de configuração (sub-redes atendidas, endereços públicos) ( hosts/ );
  • crie uma chave;
  • crie um script especificando o endereço do nó e os parâmetros relacionados ( tinc-up );
  • é aconselhável criar um script que apague os parâmetros criados depois de parar ( tinc-down ).

Além disso, ao conectar-se a uma rede existente, você deve obter as chaves do host existentes e fornecer as suas próprias.


Ou seja: para o segundo nó



Para o terceiro



Ao usar a sincronização bidirecional (por exemplo, unison ), o número de operações adicionais aumenta para N partes, onde N é o número de nós públicos.


Devemos prestar homenagem aos desenvolvedores do Tinc - para inclusão na rede, basta trocar chaves
com apenas um dos nós (nó de inicialização). Após iniciar o serviço e conectar-se ao participante, o tinc obterá a topologia
rede e poderá trabalhar com todos os assinantes.

No entanto , se o host de inicialização ficar indisponível e o tinc for reiniciado, não haverá como
irá se conectar à rede virtual.

Além disso, as enormes possibilidades de tinc, juntamente com a documentação acadêmica disso (bem descrita, mas com poucos exemplos), fornecem um campo extenso para erros.


Razões para criar tinc-boot


Se generalizarmos os problemas descritos acima e os formularmos como tarefas, obteremos:


  1. é necessária a capacidade de criar um novo site com o mínimo esforço;
    • potencialmente, é necessário possibilitar que o especialista médio (enikey) tenha uma pequena linha para criar um novo nó e conectar-se à rede;
  2. é necessário fornecer distribuição automática de chaves entre todos os nós ativos;
  3. é necessário fornecer um procedimento simplificado de troca de chaves entre o bootnod e o novo cliente.

bootnode - um nó com um endereço público (veja acima);

Devido aos requisitos da reivindicação 2, pode-se argumentar que após a troca de chaves entre o nó de inicialização e o novo nó e após
Ao conectar o nó à rede, a distribuição da nova chave ocorrerá automaticamente.


São essas tarefas que o tinc-boot executa.


O tinc-boot é um aplicativo de código aberto independente, além do tinc , que fornece:


  • criação simples de um novo nó;
  • conexão automática a uma rede existente;
  • definir a maioria dos parâmetros por padrão;
  • distribuição de chaves para nós de mel.

Arquitetura


O arquivo executável tinc-boot consiste em quatro componentes: um servidor de nó de inicialização, um servidor de gerenciamento de distribuição de chaves e comandos de gerenciamento de RPC para ele, além de um módulo de geração de nós.


Módulo de geração de nós


O módulo de geração de nós ( tinc-boot gen ) cria todos os arquivos necessários para que o tinc seja executado com êxito.


Simplificado, seu algoritmo pode ser descrito da seguinte forma:


  1. Defina o nome do host, rede, parâmetros IP, porta, máscara de sub-rede, etc.
  2. Normalize-os (o tinc tem um limite em alguns valores) e crie os que estão faltando
  3. Verifique os parâmetros
  4. Se necessário, instale o tinc-boot no sistema (desativável)
  5. Criar subnet-down tinc-up , tinc-down , subnet-up subnet-down , subnet-down
  6. Crie o tinc.conf configuração tinc.conf
  7. Criar hosts/
  8. Executar geração de chaves
  9. Executar troca de chaves com o nó de inicialização
    1. Criptografe e assine seu próprio arquivo do host com uma chave pública, um vetor de inicialização aleatória (nounce) e nome do host usando xchacha20poly1305, em que a chave de criptografia é o resultado da função sha256 do token
    2. Enviar dados via protocolo HTTP para o nó de inicialização
    3. Decifre a resposta recebida e o cabeçalho do X-Node contém o nome do nó de inicialização usando o nounce original e o mesmo algoritmo
    4. Se for bem-sucedido, salve a chave recebida nos hosts/ e adicione uma entrada ConnectTo ao arquivo de configuração (ou seja, uma recomendação onde se conectar)
    5. Caso contrário, use o seguinte endereço na lista do nó de inicialização e repita da etapa 2
  10. Mostrar recomendações sobre como iniciar um serviço

A conversão via SHA-256 é usada apenas para normalizar a chave para 32 bytes

Para o primeiro nó (ou seja, quando não há nada a especificar como o endereço de inicialização), a etapa 9 é ignorada. Bandeira - --standalone .


Exemplo 1 - criando o primeiro site público


O endereço público é 1.2.3.4


sudo tinc-boot gen --standalone -a 1.2.3.4


  • o sinalizador -a permite especificar endereços disponíveis ao público

Exemplo 1 - adicionando um nó não público à rede


O nó de inicialização será retirado do exemplo acima. O host deve ter o nó de inicialização tinc-boot em execução (descrito posteriormente).


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


  • o sinalizador --token define o token de autorização

Módulo de inicialização


O tinc-boot bootnode gera um servidor HTTP com uma API para troca de chave primária com novos clientes.


Por padrão, a porta 8655 .


Simplificado, o algoritmo pode ser descrito da seguinte maneira:


  1. Aceitar uma solicitação de um cliente
  2. Descriptografe e verifique a solicitação usando xchacha20poly1305, usando o vetor de inicialização passado durante a solicitação e onde a chave de criptografia é o resultado da função sha256 do token
  3. Verificar nome
  4. Salvar arquivo se ainda não houver um arquivo com o mesmo nome
  5. Criptografe e assine seu próprio arquivo e nome de host usando o algoritmo descrito acima
  6. Voltar ao item 1

Juntos, o processo de troca de chaves primárias é o seguinte:



Exemplo 1 - iniciando o nó de download


Supõe-se que a inicialização inicial do nó foi realizada ( tinc-boot gen )


tinc-boot bootnode --token "MY TOKEN"


  • o sinalizador --token define o token de autorização. Deve ser o mesmo para clientes que se conectam ao host.

Exemplo 2 - iniciando o nó de download como um serviço


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


  • o sinalizador --service a criar um serviço systemd (por padrão, neste exemplo, tinc-boot-dnet.service )
  • o sinalizador --token define o token de autorização. Deve ser o mesmo para clientes que se conectam ao host.

Módulo de distribuição de chaves


O módulo de distribuição de chaves ( tinc-boot monitor ) gera um servidor HTTP com uma API para trocar chaves com outros nós dentro da VPN . É fixado no endereço emitido pela rede (a porta padrão é 1655 , não haverá conflitos com várias redes, pois cada rede possui / deve ter seu próprio endereço).


O módulo inicia e funciona completamente automaticamente: você não precisa trabalhar com ele no modo manual.


Este módulo inicia automaticamente quando a rede está tinc-up (no script tinc-down ) e para automaticamente quando pára (no script tinc-down ).


Suporta operações:


  • GET / - fornece seu arquivo de nó
  • POST /rpc/watch?node=<>&subnet=<> - escolhe um arquivo de outro nó, assumindo que exista um serviço semelhante em execução nele. Por padrão, as tentativas atingem o tempo limite de 10 segundos, a cada 30 segundos até o sucesso ou cancelamento.
  • POST /rpc/forget?node=<> - deixa tentativas (se houver) de pegar o arquivo em outro nó
  • POST /rpc/kill - finaliza o serviço

Além disso, a cada minuto (por padrão) e quando um novo arquivo de configuração é recebido, a indexação dos nós salvos é feita para novos nós públicos. Quando nós com o sinalizador Address são detectados, uma entrada é adicionada ao arquivo de configuração tinc.conf para recomendar a conexão ao reiniciar.


Módulo de Distribuição de Chaves (Gerenciamento)


Os comandos para solicitar ( tinc-boot watch ) e cancelar a solicitação ( tinc-boot forget ) do arquivo de configuração de outros nós são executados automaticamente quando um novo nó é detectado (script de subnet-up ) e parado (script de subnet-down ), respectivamente.


No processo de parada do serviço, o script tinc-down é tinc-down no qual o comando tinc-boot kill interrompe o módulo de distribuição de chaves.


Em vez de total


Esse utilitário foi criado sob a influência da dissonância cognitiva entre o gênio dos desenvolvedores de Tinc e a complexidade linear crescente da criação de novos nós.


As principais idéias no processo de desenvolvimento foram:


  • se algo pode ser automatizado, deve ser automatizado;
  • os valores padrão devem cobrir pelo menos 80% de uso (princípio de Pareto);
  • qualquer valor pode ser redefinido usando sinalizadores e variáveis ​​de ambiente;
  • a utilidade deve ajudar, e não causar um desejo de invocar todo o castigo do céu ao criador;
  • o uso de um token de autorização para a inicialização é um risco óbvio; no entanto, na medida do possível, ele foi minimizado devido à criptografia e autenticação totais (mesmo o nome do host no cabeçalho da resposta não pode ser substituído).

Um pouco de cronologia:


  • A primeira vez que usei tinc há mais de 4 anos. Estudou uma quantidade significativa de material. Configure uma rede ideal (na minha opinião)
  • Após meio ano, o tinc foi substituído por zerotier, como uma ferramenta mais conveniente / flexível
  • 2 anos atrás, eu fiz um manual ansible para implantar tinc
  • Um mês depois, meu script foi interrompido na implantação incremental (ou seja, quando é impossível acessar todos os nós da rede, o que significa distribuir chaves)
  • Há duas semanas, escrevi um script bash-script que era o protótipo do tinc-boot
  • 3 dias atrás após a segunda iteração, nasceu a primeira versão (0.0.1 para ser exato) do utilitário
  • Há um dia, reduzi a instalação de um novo nó para uma linha: 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
  • Em breve, será adicionada a possibilidade de uma conexão ainda mais simples à rede (sem sacrificar a segurança)

Durante o desenvolvimento, testei ativamente em servidores e clientes reais (a imagem da descrição do tinc acima foi tirada da vida real). Agora, o sistema funciona perfeitamente e todos os serviços VPN de terceiros agora estão desativados.


O código do aplicativo está escrito no GO e está aberto sob a licença MPL 2.0. Uma licença (tradução livre) permite o uso comercial (se alguém precisar de repente) sem abrir o produto de origem. O único requisito é que as alterações sejam transferidas para o projeto.


Pedidos de piscina são bem-vindos.


Links úteis


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


All Articles