Configurando o roteamento dinâmico (em particular o BGP) sobre o túnel OpenVPN no Linux (e provavelmente * BSD)

Por que e sobre o que é este artigo?


Se você pesquisar no tópico "openvpn bgp", poderá encontrar vários artigos interessantes e úteis de um ponto de vista prático (por exemplo, uma ou duas vezes ). Mas começando a resolver o problema no título, por muitas razões, eu nem me preocupei em pesquisá-lo no Google. A ideia surgiu de alguma forma por si só durante um longo trabalho com o OpenVPN em geral (no âmbito de tarefas bastante típicas, com um conjunto fixo de redes nos dois lados), trabalhando com a implementação do OpenVPN no sistema MikroTik RouterOS e encaixando os sistemas Linux e RouterOS entre si. Na verdade, no processo de descobrir as razões para escrever nossa própria implementação do OpenVPN no RouterOS, surgiu o “insight” sobre como esse problema pode ser resolvido dentro da estrutura da edição OpenVPN, com equipe completa. Depois, houve uma pequena verificação experimental, que mostrou a capacidade total de trabalho da idéia e o lançamento desta solução na operação "industrial".


Tendo em mente que esta situação é bastante típica para diferentes aplicações, e a solução descrita abaixo ainda não foi apresentada, decidi compartilhar a idéia com a comunidade.



A essência do problema ("quem é o culpado?")


Qual é a diferença entre a versão regular do OpenVPN e a que é implementada no RouterOS? Provavelmente existem algumas diferenças, mas neste artigo consideraremos apenas uma coisa: o OpenVPN comum em outros sistemas que não o RouterOS (e possivelmente outros) é uma combinação que contém a parte de transporte (ou seja, a própria transmissão de pacotes, também é encaminhada, é também um plano de dados) ) e roteamento (ou seja, troca de informações sobre rotas, roteamento, também é um plano de controle) e, no RouterOS, o serviço OpenVPN é responsável apenas pela parte de transporte , e o roteamento é tratado por um processo de sistema diferente, que permite, por um lado, não duplicar a funcionalidade do roteamento sob O sistema (além disso, não mantém várias tabelas de rotas idênticas em serviços diferentes e as sincroniza constantemente) e, por outro lado, permite a transferência transparente de tabelas de rotas sobre esses veículos e altera as tabelas de rotas de ambos os lados em tempo real.


Além disso, a implementação regular do OpenVPN tem mais uma desvantagem: a transferência de rotas ocorre apenas em uma direção (do servidor para o cliente) e apenas no momento de estabelecer uma sessão (ou seja, elevar o túnel). Não há uma maneira regular de adicionar uma rota à tabela de rotas OpenVPN interna em movimento durante a operação do túnel, bem como transferir rotas de um lado para o outro. Além disso, nem mesmo é possível obter a própria tabela de rotas.


Solução para o problema ("O que fazer")


Analisando meus scripts que automatizam a atribuição de rotas a diferentes clientes, notei que o OpenVPN tem duas opções diferentes que especificam rotas:


  • i route - define as rotas dentro da tabela de roteamento do processo OpenVPN.
  • route - define as rotas que o processo OpenVPN passa para a tabela de rotas do sistema (ou seja, adiciona rotas à tabela através de sua interface de túnel quando conectado e as exclui quando desconectadas).

Surgiu a pergunta óbvia: o que acontecerá se i route adicionar a rota 0.0.0.0/0 em ambos os lados usando a i route e depois adicionar ou remover as rotas necessárias (incluindo aquelas que aparecem ou desaparecem dinamicamente) na própria interface do túnel, por exemplo, com um serviço de roteamento ( roteado, zebra / quagga, pássaro, etc.)?


O experimento mostrou que esse esquema realmente funciona com um pequeno inconveniente de restrição: apenas um cliente pode ser conectado a um túnel do servidor. O resto do circuito acabou sendo totalmente operacional.


O esquema opera no modo TLS sobre TCP, ou seja, para configuração, você deve primeiro gerar chaves e certificados SSL.


Abaixo, dou um exemplo de configuração do OpenVPN para o servidor e o lado do cliente.


Configuração do lado do servidor (uma para cada cliente).


Arquivo server_dyn_rt.conf (lado do servidor)


 daemon compress ping-timer-rem persist-tun persist-key tls-server proto tcp-server topology net30 mode server script-security 3 keepalive 15 45 tun-mtu 1500 remote-cert-tls client verify-x509-name <CLIENT_DISTINGUISHED_NAME> name auth <TLS_AUTH_ALGORITHM> cipher <CIPHER_ALGORITHM> local <SERVER_PUBLIC_IP> lport <SERVER_PUBLIC_PORT> dev-type tun dev <TUNNEL_INTERFACE_NAME> ifconfig <TUNNEL_SERVER_SIDE_IP> <TUNNEL_CLIENT_SIDE_IP> client-connect client_connect.sh push "route-gateway <TUNNEL_SERVER_SIDE_IP>" push "topology net30" push&nbsp"persist-tun" push&nbsp"persist-key" <dh> ... Diffie-Hellman data <</dh> <ca> ... Certificate Authority certificate data </ca> <cert> ... Server certificate data </cert> <key> ... Server Private Key data </key> 

Arquivo client_connect.sh (lado do servidor)


 #!/bin/sh echo 'ifconfig-push TUNNEL_CLIENT_SIDE_IP TUNNEL_SERVER_SIDE_IP' >> ${1} echo 'push "iroute 0.0.0.0 0.0.0.0"' >> ${1} echo 'iroute 0.0.0.0 0.0.0.0' >> ${1} exit 0 

Arquivo client_dyn_rt.conf (lado do cliente)


 daemon compress tls-client auth <TLS_AUTH_ALGORITHM> cipher <CIPHER_ALGORITHM> client dev-type tun dev <TUNNEL_INTERFACE_NAME> script-security 3 remote-cert-tls server verify-x509-name <SERVER_DISTINGUISHED_NAME> name remote <SERVER_PUBLIC_IP> <SERVER_PUBLIC_PORT> tcp <ca> ... Certificate Authority certificate data </ca> <cert> ... Client certificate data </cert> <key> ... Client Private Key data </key> 

Não cito as configurações de pacotes e protocolos de roteamento, seja por causa da variedade de pacotes ou por causa da variedade de configurações em si (na verdade, como fonte de exemplos de configuração, você pode usar o segundo dos artigos, links para os quais são fornecidos no início do artigo). Eu só quero observar que a configuração acima permite que você use BGP em particular (que eu pessoalmente gosto tanto por sua “controlabilidade” quanto pela capacidade de transmitir rotas de vários protocolos dentro da mesma sessão). No caso do BGP, o endereço <TUNNEL_CLIENT_SIDE_IP> deve ser usado como o endereço do vizinho no lado "servidor" e o endereço <TUNNEL_SERVER_SIDE_IP> ou os endereços "internos" das respectivas partes devem ser usados ​​no lado do cliente, mas você precisa adicionar as rotas correspondentes à configuração servidor e / ou cliente.



Prós e contras da solução acima


Contras:

  1. Deve haver exatamente um cliente por servidor, portanto, para vários clientes, você precisará manter vários processos OpenVPN ativos. Como resultado - alguma memória está cheia e tudo mais.
  2. Você não pode usar o modo de chave pré-compartilhada no OpenVPN, pois nesse modo é proibida a transferência dinâmica de parâmetros do servidor para o cliente (push / pull). Por isso, é necessária uma configuração mais complexa, incluindo a geração de um conjunto de chaves e certificados, bem como um script para gerar um pedaço de configuração do cliente no servidor (que, no entanto, pode ser substituído por um diretório de arquivos estáticos, substituindo a opção client-connect /path/to/script opção client-connect /path/to/script client-connect-dir /path/to/config/dir , o que aumenta o nível de segurança do lado do servidor.

Prós:

  1. Diferentemente de protocolos como o GRE / IPIP, os túneis OpenVPN podem ter uma MTU de 1500 bytes (porque o processo OpenVPN oculta toda a fragmentação / desfragmentação "oculta", enviando pacotes completos para a interface do túnel). Isso facilita a configuração de todos os tipos de túneis secundários no túnel OpenVPN.
  2. O túnel OpenVPN suporta simultaneamente a transmissão de IPv4 e IPv6, o que reduz o número de túneis entre pares de nós, o custo de sua configuração e administração, além de transmitir rotas IPv6 na mesma sessão BGP que as rotas IPv4.
  3. Todas as vantagens do protocolo OpenVPN, como a facilidade de configuração de equipamentos de rede intermediários (ou a completa falta de necessidade), a capacidade de mascarar o tráfego sob HTTPS, a presença de uma implementação para a maioria das plataformas, etc.

Espero que alguém ache o guia acima útil.

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


All Articles