IPSec Todo-Poderoso

Boa tarde amigos. Não é segredo que muitos de nós temos pelo menos uma vez, mas tivemos que lidar com a necessidade de configurar uma VPN. Sendo um leitor ativo da Habr, notei que, apesar da abundância de artigos sobre o IPSec, para muitos ainda parece ser algo complicado e sobrecarregado. Neste artigo, tentarei dissipar esses mitos usando minha própria configuração totalmente funcional como exemplo. Em quatro exemplos, analisaremos completamente a configuração da solução Linux (Strongswan) mais popular, de um túnel simples com autenticação lateral com chaves PSK a uma conexão host a host com autenticação de ambos os lados com base em certificados de Let's Encrypt. Interessante? Bem-vindo ao gato!

fundo


Inicialmente, a VPN foi planejada apenas para a organização do canal entre o mini-roteador dos pais e o servidor "de cabeceira" doméstico, que atua simultaneamente como roteador.

Após um curto período de tempo, o Keenetic foi adicionado a esta empresa a partir de dois dispositivos.
Mas, uma vez iniciado, acabou sendo difícil parar, e logo telefones e laptops apareceram no diagrama, que queriam se esconder do olho publicitário que tudo vê do MT_Free e de outras redes WiFi não criptografadas.

Então, o amado ILV finalmente fortaleceu o Banhammer, por quem se apaixonou por balançar publicamente em todas as direções e, a fim de neutralizar sua preocupação por meros mortais, ele teve que apoiar o setor de TI estrangeiro para adquirir VPS no exterior.
Além disso, um certo cidadão que se parece com Shapoklyak, circulando por toda parte com sua bolsa no Pacote, e provavelmente acreditando que “Quem ajuda as pessoas, está perdendo tempo. Você não pode se tornar famoso por boas ações - eu queria espiar secretamente o tráfego de outra pessoa e levá-lo a lápis. Também teremos que nos defender contra esse amor não solicitado e VPN, neste caso, exatamente o que o médico ordenou.

Para resumir um breve resumo. Era necessário encontrar uma solução que idealmente pudesse fechar várias tarefas ao mesmo tempo:

  • Interconexão entre roteadores Linux
  • Construa um túnel entre o Linux e o Keenetic Household
  • Conceda acesso a recursos domésticos e à Internet a dispositivos vestíveis (telefones, laptops) de redes não confiáveis
  • Crie um túnel criptografado com segurança para o VPS remoto

Não se esqueça do maravilhoso princípio KISS - Keep It Simple, Stupid. Quanto menos componentes estiverem envolvidos e mais fácil é configurar cada um deles - mais confiável.

Visão geral das soluções existentes


Resumir brevemente o que é agora:

PPTP

Avô Lenin de todos os protocolos. Morreu, "deteriorado em mofo e mel de tília".

L2TP

Alguém além de um provedor usa isso?

O

projeto Wireguard está em desenvolvimento. Ativamente serrado. É fácil criar um túnel entre dois pares com um IP estático. Em outros casos, muletas, bicicletas com rodas quadradas e uma fita elétrica azul estão sempre prontas para ajudar, mas esse não é o nosso caminho. Profissionais do

OpenVPN

:

  • Suporte para múltiplas plataformas - Windows, Linux, OpenWRT e seus derivados, Android
  • Forte criptografia e suporte a certificados.
  • Flexibilidade de personalização.

E contras:

  • Trabalhe inteiramente no espaço do usuário.
  • Suporte limitado de roteadores domésticos - krenenko-kosenko no Mikrotik (sem prejudicar as outras vantagens das glândulas) e normal no OpenWRT.
  • Dificuldades na configuração de clientes móveis: você precisa baixar ou criar seu próprio instalador, copiar configurações em algum lugar.
  • Se houver vários túneis, as danças aguardam com a edição das unidades do sistema no servidor.

OpenConnect (implementação de código aberto do protocolo Cisco Anyconnect)
Uma solução muito interessante sobre a qual, infelizmente, é um pouco de informação.

Prós:

  • O suporte relativamente amplo para várias plataformas - Windows, Android, Mac baseado no aplicativo nativo Cisco Anyconnect da loja - é uma opção ideal para fornecer acesso à rede interna de dispositivos vestíveis.
  • Criptografia forte, suporte a certificado, conectividade 2FA
  • O protocolo em si é totalmente baseado em TLS (ao contrário do OpenVPN, que é facilmente detectado na porta 443). Além do TLS, o DTLS também é suportado - durante a sessão estabelecida, o cliente pode mudar para a transmissão de dados via UDP e vice-versa.
  • Excelente coexistência em uma porta de uma VPN e um servidor Web completo usando sniproxy.
  • Fácil configuração do servidor e dos clientes.

Aqui, também, não foram sem contras:

  • Trabalhe inteiramente no espaço do usuário.
  • TCP em cima do TCP é uma má idéia.
  • Não há suporte de equipamentos de nível cliente.
  • A complexidade de instalar túneis entre dois Linux: teoricamente possível, praticamente - é melhor gastar tempo com algo mais útil.
  • Se houver vários túneis, as danças com várias configurações e unidades de edição do sistema estarão aguardando.

Parece um beco sem saída, mas depois de olhar mais de perto e passar um tempo estudando, percebi que o IPSec baseado no IKEv2 é capaz de substituir todo o resto. Prós

IKEv2 IPSEC

:

  • Com o advento do IKEv2, o próprio protocolo tornou-se mais fácil de configurar, em comparação com a versão anterior, mas com o custo de perder a compatibilidade com versões anteriores.
  • Graças à padronização, o trabalho é fornecido em qualquer lugar e em qualquer lugar - a lista pode ser mantida indefinidamente. Linux, Mikrotik (nas últimas versões do RouterOS), OpenWRT, Android, iPhone. O Windows também possui suporte nativo a partir do Windows 7.
  • Alta velocidade: tráfego processando completamente no espaço do kernel. A parte do espaço do usuário é necessária apenas para definir parâmetros de conexão e monitorar a integridade do canal.
  • A capacidade de usar vários métodos de autenticação: usando PSK e certificados e em qualquer combinação.
  • Vários modos de operação: túnel e transporte. Como eles diferem pode ser lido, inclusive em Habré.
  • Configurações pouco exigentes para nós intermediários: se na primeira versão do IKE houve problemas causados ​​pelo NAT, o IKEv2 possui mecanismos internos para superar a NAT e a fragmentação nativa das mensagens IKE, o que permite estabelecer uma conexão nos canais com uma curva MTU. Olhando para o futuro, direi que, na prática, nunca encontrei uma rede WiFi, onde quer que um cliente possa estabelecer uma conexão.

Contras, no entanto, também têm:

  • Você precisa gastar algum tempo estudando e entendendo como funciona.
  • Um recurso que pode confundir um novato: o IPSec, diferentemente das soluções VPN convencionais, não cria interfaces de rede. Somente políticas de processamento de tráfego são definidas, tudo o mais é resolvido por meio de firewall.

Antes de prosseguir com a configuração, assumimos que o leitor já esteja um pouco familiarizado com os conceitos e termos básicos. Para ajudar um iniciante, você pode recomendar um artigo da Wikipedia e do próprio Habr, no qual já existem artigos bastante interessantes e úteis sobre esse tópico.

Introdução à configuração


Tendo decidido sobre a decisão, prosseguimos para a configuração. O diagrama de rede no meu caso tem o seguinte formato (removido sob o spoiler)

Diagrama de rede

ipsecgw.example.com é o servidor doméstico que é o centro da rede. IP externo 1.1.1.1. Uma rede interna 10.0.0.0/23 e outro endereço 10.255.255.1/30 para definir uma sessão BGP privada com VPS;
mama é um roteador Linux baseado em um nettop pequeno e silencioso instalado pelos pais. O ISP emite um endereço IP dinâmico. Rede interna 10.0.3.0/24;
keenetic - roteador Keenetic com o IPSec instalado. O ISP emite um endereço IP dinâmico. Rede interna 10.0.4.0/24;
guerreiros da estrada - dispositivos portáteis que se conectam a partir de redes não confiáveis. Os endereços são emitidos aos clientes dinamicamente quando conectados a partir do pool interno (10.1.1.0/24);
rkn.exemplo.com- VPS fora da jurisdição de um ILV respeitado. IP externo - 5.5.5.5, endereço interno 10.255.255.2/30 para definir uma sessão BGP privada.

Primeiro passo. Do simples ao complexo: túneis usando chaves pré-compartilhadas (PSK)


Nas duas caixas Linux, instalamos os pacotes necessários:

sudo yum install strongswan

Nos dois hosts, abra as portas 500 / udp, 4500 / udp e permita a passagem do protocolo ESP.
Edite o arquivo /etc/strongswan/ipsec.secrects (no lado do host ipsecgw.example.com) e adicione a seguinte linha:

mama@router.home.local: PSK "Very strong PSK"

No segundo lado, da mesma forma:

root@root.mama.local: PSK "Very strong PSK"

Nesse caso, o ID é um endereço de email fictício. Mais informações podem ser encontradas no wiki oficial .

Segredos salvos, seguindo em frente.

No host ipsecgw.example.com, edite o arquivo /etc/strongswan/ipsec.conf:

config setup //   charon
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0" //  
conn %default //    
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2 //      - IKEv2
    dpdaction = hold
    dpddelay = 5s // 5   DPD (Dead Peer Detection)   
    mobike = yes // Mobile IKE -     IP    
conn mama //  
    left = %defaultroute //Left -  .  %defaultroute       IKE- ,    default route
    right = %any //     IP-
    authby = psk //   -   
    leftid = mama@router.home.local // ID,   ipsec.secrets
    rightid = root@router.mama.local //ID  
    leftsubnet = 10.0.0.0/23,10.1.1.0/24 
    rightsubnet = 10.0.3.0/24
    type = tunnel 
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519! 
    auto = add //  charon        

Da mesma forma, editamos no ponto remoto /etc/strongswan/ipsec.conf:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn mama
    left = %defaultroute
    right = ipsecgw.example.com
    authby = psk
    leftid = root@router.mama.local
    rightid = mama@router.home.local
    leftsubnet = 10.0.3.0/24
    rightsubnet = 10.0.0.0/23,10.1.1.0/24
    type = tunnel
    ike = aes128gcm16-sha384-x25519!
    esp = aes128gcm16-sha384-x25519!
    auto = route

Se você comparar as configurações, poderá ver que elas são quase espelhadas, apenas as definições de pares são trocadas.

A diretiva auto = route faz com que charon configure uma interceptação para o tráfego que cai nas diretivas left / rightsubnet (seletores de tráfego). A coordenação dos parâmetros do túnel e a troca de chaves serão iniciadas imediatamente após o aparecimento do tráfego que cai sob as condições especificadas.

No servidor ipsecgw.example.com nas configurações de firewall, proibimos o mascaramento para uma rede 10.0.3.0/24. Permita o encaminhamento de pacotes entre 10.0.0.0/23 e 10.0.3.0/24 e vice-versa. No host remoto, realizamos configurações semelhantes, desativando o mascaramento da rede 10.0.0.0/23 e configurando o encaminhamento.

Reiniciamos o strongswan nos dois servidores e tentamos executar ping no nó central:

sudo systemctl restart strongswan
ping 10.0.0.1


Verifique se tudo funciona:
sudo strongswan status
Security Associations (1 up, 0 connecting):
        mama[53]: ESTABLISHED 84 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{141}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c4eb45fe_i ca5ec6ca_o
        mama{141}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


Também será útil garantir que o parâmetro make_before_break esteja definido como yes no arquivo /etc/strongswan/strongswan.d/charon.conf em todos os pares. Nesse caso, o daemon charon que atende ao protocolo IKEv2 não excluirá a associação de segurança atual durante o procedimento de alteração de chave, mas criará um novo primeiro.

Passo dois O aparecimento de Keenetic


Uma surpresa agradável foi a VPN IPSec embutida no firmware oficial do Keenetic. Para ativá-lo, basta acessar as Configurações do componente KeeneticOS e adicionar o pacote VPN IPSec .

Preparamos as configurações no nó central, para isso:

Edite o /etc/strongswan/ipsec.secrects e adicione o PSK para o novo par:

keenetic@router.home.local: PSK "Keenetic+PSK"

Edite /etc/strongswan/ipsec.conf e adicione outra conexão ao final:

conn keenetic
    left = %defaultroute
    right = %any
    authby = psk
    leftid = keenetic@router.home.local
    rightid = root@router.keenetic.local
    leftsubnet = 10.0.0.0/23
    rightsubnet = 10.0.4.0/24
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add

No lado do Keenetic, a configuração é feita na WebUI ao longo do caminho: Internet -> Conexões ->
Outras conexões
. É bem simples
(3 fotos)






Se você planeja direcionar volumes significativos de tráfego através do túnel, pode tentar ativar a aceleração de hardware, suportada por muitos modelos. Ativado pelo comando de hardware do mecanismo de criptografia na CLI. Para desabilitar e processar processos de criptografia e hash usando instruções gerais da CPU - software de mecanismo de criptografia

Depois de salvar as configurações, restauramos a troca forte e deixamos o Keenetic pensar por meio minuto. Então, no terminal, vemos uma conexão bem-sucedida:

Tudo está funcionando:
sudo strongswan status
Security Associations (2 up, 0 connecting):
    keenetic[57]: ESTABLISHED 39 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{146}:  INSTALLED, TUNNEL, reqid 29, ESP SPIs: ca8f556e_i ca11848a_o
    keenetic{146}:   10.0.0.0/23 === 10.0.4.0/24
        mama[53]: ESTABLISHED 2 hours ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{145}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c5dc78db_i c7baafd2_o
        mama{145}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


Passo três Protegendo dispositivos móveis


Depois de ler vários manuais e vários artigos, foi decidido parar com um certificado gratuito do Let's Encrypt para autenticar o servidor e a autorização clássica por login e senha dos clientes. Assim, eliminamos a necessidade de manter nossa própria infraestrutura de PKI, monitorar a expiração de chaves e realizar gestos desnecessários com dispositivos móveis instalando certificados autoassinados na lista confiável.

Instale os pacotes ausentes:

sudo yum install epel-release
sudo yum install certbot

Obtemos o certificado independente (não esqueça de abrir 80 / tcp nas configurações do iptables primeiro):

sudo certbot certonly --standalone -d ipsecgw.example.com

Após o certbot concluir seu trabalho, devemos ensinar a Strongswan a ver nosso certificado:

  • no diretório /etc/strongswan/ipsec.d/cacerts, crie 2 links simbólicos: um para o armazenamento raiz de certificados confiáveis ​​em / etc / pki / tls / certs; e um segundo com o nome ca.pem apontando para /etc/letsencrypt/live/ipsecgw.example.com/chain.pem
  • Também são criados dois links simbólicos no diretório /etc/strongswan/ipsec.d/certs: o primeiro, com o nome certificate.pem, refere-se ao arquivo /etc/letsencrypt/live/ipsecgw.example.com/cert.pem. E o segundo, chamado fullchain.pem, com link para /etc/letsencrypt/live/ipsecgw.example.com/fullchain.pem
  • No diretório /etc/strongswan/ipsec.d/private, coloque o link simbólico key.pem apontando para a chave privada gerada pelo certbot e ao longo do caminho /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem

Adicione autenticação via RSA ao ipsec.secrets e um monte de logins / senhas para novos usuários:

ipsecgw.example.com     : RSA key.pem
username phone          : EAP "Q1rkz*qt"
username notebook       : EAP "Zr!s1LBz"

Reiniciamos o Strongswan e, ao chamar listadores de sudo strongswan, devemos ver as informações do certificado:

List of X.509 End Entity Certificates

  subject:  "CN=ipsecgw.example.com"
  issuer:   "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3"
  validity:  not before May 23 19:36:52 2020, ok
             not after  Aug 21 19:36:52 2020, ok (expires in 87 days)
  serial:    04:c7:70:9c:a8:ce:57:cc:bf:6f:cb:fb:d3:a9:cf:06:b0:a8
  altNames:  ipsecgw.example.com
  flags:     serverAuth clientAuth
  OCSP URIs: http://ocsp.int-x3.letsencrypt.org
  certificatePolicies:
             2.23.140.1.2.1
             1.3.6.1.4.1.44947.1.1.1
             CPS: http://cps.letsencrypt.org

Em seguida, descrevemos a nova conexão no ipsec.conf :

conn remote-access
    dpddelay = 30s //   DPD ,     
    left = %defaultroute
    leftid = "CN=ipsecgw.example.com"
    leftcert = fullchain.pem //         
    leftsendcert = always
    leftsubnet = 0.0.0.0/0 //      
    right = %any
    rightid = %any
    rightauth = eap-mschapv2 // ,  EAP-MSCHAP2
    rightsendcert = never
    eap_identity = %identity 
    rightsourceip = 10.1.1.0/24 //Strongswan       
    rightdns = 10.0.0.1,10.0.0.3 //   DNS
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add //      
    dpdaction = restart // ,      DPD

Não esqueça de editar o arquivo / etc / sysconfig / certbot, indicando que também atualizaremos o certificado como autônomo, adicionando CERTBOT_ARGS = "- autônomo" a ele.

Além disso, não se esqueça de ativar o timer certbot-renew.timer e defina o gancho para reiniciar o Strongswan no caso de emitir um novo certificado. Para fazer isso, coloque um script simples do bash em / etc / letsencrypt / renewal-hooks / deploy / ou edite o arquivo / etc / sysconfig / certbot novamente.

Reiniciamos o Strongswan, ativamos o mascaramento da rede 10.1.1.0/24 no iptables e configuramos os dispositivos móveis.

Android


Instale o aplicativo Strongswan no Google Play .

Lançamos e criamos um novo

perfil


Salvamos o perfil, conectamos e, após um segundo, não precisamos nos preocupar com alguém que possa nos espionar.

Verificamos:
sudo strongswan statusall
Security Associations (3 up, 0 connecting):
remote-access[109]: ESTABLISHED 2 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{269}:  INSTALLED, TUNNEL, reqid 55, ESP in UDP SPIs: c706edd1_i e5c12f1d_o
remote-access{269}:   0.0.0.0/0 ::/0 === 10.1.1.1/32
        mama[101]: ESTABLISHED 34 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{265}:  INSTALLED, TUNNEL, reqid 53, ESP in UDP SPIs: c8c83342_i c51309db_o
        mama{265}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
    keenetic[99]: ESTABLISHED 36 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{263}:  INSTALLED, TUNNEL, reqid 52, ESP SPIs: c3308f33_i c929d6f1_o
    keenetic{263}:   10.0.0.0/23 === 10.0.4.0/24


janelas


Windows das versões atuais foi agradavelmente surpreendido. Toda a configuração da nova VPN ocorre chamando dois cmdlets do PowerShell:

Add-VpnConnection -Name "IKEv2" -ServerAddress ipsecgw.example.com -TunnelType "IKEv2"
Set-VpnConnectionIPsecConfiguration -ConnectionName "IKEv2" -AuthenticationTransformConstants SHA256128 -CipherTransformConstants AES128 -EncryptionMethod AES128 -IntegrityCheckMethod SHA256 -PfsGroup PFS2048 -DHGroup Group14 -PassThru -Force

E mais uma coisa, se o Strongswan estiver configurado para emitir endereços IPv6 para os clientes (sim, ele também poderá fazê-lo):

Add-VpnConnectionRoute -ConnectionName "IKEv2" -DestinationPrefix "2000::/3"

Parte Quatro, Final. Cortamos uma janela para a Europa


Tendo visto os stubs dos provedores “O site foi bloqueado pela decisão do calcanhar esquerdo do quinto vice-promotor da vila Trudovye Mozoli, do condado de Bogozabyt”, um pequeno VPS discreto apareceu (com o nome de domínio bem conhecido rkn.example.com) a milhares de quilômetros de macacos que gostam de acenar com um banhammer e bloquear redes de tamanho / 16 de cada vez. E girar sobre esse pequeno VPS foi uma criação maravilhosa de colegas do NIC.CZ, chamados BIRD. O pássaro da primeira versão morria constantemente em pânico pela atividade de macacos com cassetetes, que baniam quase 4% da Internet no auge de sua atividade laboral, deixando uma profunda reflexão durante a reconfiguração; portanto, foi atualizada para a versão 2.0.7. Se os leitores estiverem interessados, publicarei um artigo sobre a transição do BIRD para o BIRD2, no qual o formato de configuração mudou drasticamente,mas a nova versão se tornou muito mais rápida e não há problemas com a reconfiguração com um grande número de rotas. E como usamos o protocolo de roteamento dinâmico, é necessário que haja uma interface de rede através da qual você precise rotear o tráfego. Por padrão, o IPSec não cria interfaces, mas devido à sua flexibilidade, podemos usar os túneis GRE clássicos, que protegeremos no futuro. Como bônus, os hosts ipsecgw.example.com e rkn.example.com se autenticarão usando certificados de renovação automática do Lets Encrypt. Sem PSK, apenas certificados, apenas incondicional, não há muita segurança.Por padrão, o IPSec não cria interfaces, mas devido à sua flexibilidade, podemos usar os túneis GRE clássicos, que protegeremos no futuro. Como bônus, os hosts ipsecgw.example.com e rkn.example.com se autenticarão usando certificados de renovação automática do Lets Encrypt. Sem PSK, apenas certificados, apenas incondicional, não há muita segurança.Por padrão, o IPSec não cria interfaces, mas devido à sua flexibilidade, podemos usar os túneis GRE clássicos, que protegeremos no futuro. Como bônus, os hosts ipsecgw.example.com e rkn.example.com se autenticarão usando certificados de renovação automática do Lets Encrypt. Sem PSK, apenas certificados, apenas incondicional, não há muita segurança.

Acreditamos que o VPS está preparado, o Strongswan e o Certbot já estão instalados.

No host ipsecgw.example.com (seu IP é 1.1.1.1), descrevemos a nova interface gif0:
sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="1.1.1.1"
PEER_OUTER_IPADDR="5.5.5.5"
MY_INNER_IPADDR="10.255.255.1/30"
PEER_INNER_IPADDR="10.255.255.2/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

Espelhado no host vps.example.com (seu IP é 5.5.5.5):

sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="5.5.5.5"
PEER_OUTER_IPADDR="1.1.1.1"
MY_INNER_IPADDR="10.255.255.2/30"
PEER_INNER_IPADDR="10.255.255.1/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

Nós aumentamos as interfaces, mas como o iptables não possui uma regra que permita o protocolo GRE, o tráfego não passará (que é o que precisamos, pois não há proteção dentro do GRE contra os fãs de qualquer tipo de "pacote" legislativo).

Cooking VPS


Primeiro, obtemos outro certificado para o nome de domínio rkn.example.com. Crie links simbólicos em /etc/strongswan/ipsec.d conforme descrito na seção anterior.

Edite o ipsec.secrets adicionando uma única linha a ele:

rkn.example.com     : RSA key.pem

Edite ipsec.conf:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
    strictcrlpolicy = yes
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn rkn
    left = %defaultroute
    right = ipsecgw.example.com
    authby = pubkey
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    leftid = "CN=rkn.example.com"
    rightid = "CN=ipsecgw.example.com"
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route

No lado do host, ipsecgw.example.com também é adicionado ao ipsec.conf na seção de configuração, o parâmetro strictcrlpolicy = yes, que inclui uma verificação estrita da CRL. E descreva outra conexão:

conn rkn
    left = %defaultroute
    right = rkn.example.com
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/rkn.exapmle.com.pem
    leftid = "CN=ipsecgw.example.com"
    rightid = "CN=rkn.example.com"
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route
    dpdaction = restart

As configurações são quase espelhadas. O leitor atento já podia prestar atenção a alguns pontos:

  • left / rightsubnet =% dinâmico - instrui o Strongswan a aplicar políticas a todos os tipos de tráfego entre pares
  • rightrsasigkey. IKE SA IKE AUTH ERROR , Strongswan RSA- . openssl. (ipsecgw RKN) sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > ~/ipsecgw.example.com.pem sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > ~/rkn.example.com.pem, scp ,

Não esqueça de configurar o firewall e renovar automaticamente os certificados. Após reiniciar o Strongswan nos dois servidores, inicie o ping no lado oposto do túnel GRE e veja uma conexão bem-sucedida. No VPS (rkn):

sudo strongswan status
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   5.5.5.5/32 === 1.1.1.1/32
Security Associations (1 up, 0 connecting):
         rkn[33]: ESTABLISHED 79 minutes ago, 5.5.5.5[CN=rkn.example.com]...1.1.1.1[CN=ipsecgw.example.com]
         rkn{83}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: cb4bc3bb_i c4c35a5a_o
         rkn{83}:   5.5.5.5/32 === 1.1.1.1/32


E no lado do host ipsecgw
sob o spoiler
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   1.1.1.1/32 === 5.5.5.5/32
Security Associations (4 up, 0 connecting):
remote-access[10]: ESTABLISHED 5 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{12}:  INSTALLED, TUNNEL, reqid 7, ESP in UDP SPIs: c7a31be1_i a231904e_o
remote-access{12}:   0.0.0.0/0 === 10.1.1.1/32
    keenetic[8]: ESTABLISHED 22 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{11}:  INSTALLED, TUNNEL, reqid 6, ESP SPIs: cfc1b329_i c01e1b6e_o
    keenetic{11}:   10.0.0.0/23 === 10.0.4.0/24
        mama[4]: ESTABLISHED 83 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{8}:  INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: c4a5451a_i ca67c223_o
        mama{8}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
         rkn[3]: ESTABLISHED 83 minutes ago, 1.1.1.1[CN=ipsecgw.example.com]...5.5.5.5[CN=rkn.example.com]
         rkn{7}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: c4c35a5a_i cb4bc3bb_o
         rkn{7}:   1.1.1.1/32 === 5.5.5.5/32


O túnel está instalado, pings vão, no tcpdump é visível que apenas o ESP fica entre os hosts. Parece possível se alegrar. Mas você não pode relaxar sem verificar tudo até o fim. Estamos tentando reemitir o certificado para VPS e ...

Chef, está tudo quebrado


Começamos a entender e deparar com um recurso desagradável do Let's Encrypt, que é bonito em todo o resto - com qualquer reemissão do certificado, a chave privada associada a ele também muda. A chave privada mudou - e o público mudou. À primeira vista, a situação é desesperadora para nós: mesmo que possamos extrair facilmente a chave pública durante a reemissão do certificado usando o gancho no certbot e passá-la para o lado remoto via SSH, não está claro como fazer o Strongswan remoto relê-lo. Mas a ajuda veio de onde eles não esperaram - o systemd pode monitorar as alterações no sistema de arquivos e executar os serviços associados ao evento. É isso que vamos usar.

Criaremos um usuário do serviço de observador de chaves em cada um dos hosts com os direitos mais restritos, geraremos chaves SSH para cada um deles e as trocaremos entre os hosts.

No host ipsecgw.example.com, crie o diretório / opt / ipsec-pubkey no qual colocamos 2 scripts.

sudo vi /opt/ipsec-pubkey/pubkey-copy.sh

#!/bin/sh
if [ ! -f /home/keywatcher/ipsecgw.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/ipsecgw.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/ipsecgw.example.com.pem rkn.example.com:/home/keywatcher/ipsecgw.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/ipsecgw.example.com.pem;
    logger "Public key ipsecgw.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key ipsecgw.example.com.pem has not been uploaded to remote host due to error";
  fi
  else
    logger "Public key ipsecgw.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh

#!/bin/sh
/usr/bin/cp /home/keywatcher/rkn.example.com.pem /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
logger "Public key of server rkn.example.com has been updated, restarting strongswan daemon to re-read it"
/usr/bin/systemctl restart strongswan
exit 0

No VPS (o host rkn.example.com), criamos de maneira semelhante um diretório com o mesmo nome, no qual também criamos scripts semelhantes, alterando apenas o nome da chave. Código, para não confundir o artigo, em

Spoiler
sudo vi /opt/ipsec-pubkey/pubkey-copy.sh
#!/bin/sh
if [ ! -f /home/keywatcher/rkn.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/rkn.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/rkn.example.com.pem ipsecgw.example.com:/home/keywatcher/rkn.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/rkn.example.com.pem;
    logger "Public key rkn.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key rkn.example.com.pem has not been uploaded to remote host";
  fi
  else
    logger "Public key rkn.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh


#!/bin/bash
/usr/bin/cp /home/keywatcher/ipsecgw.example.com.pem /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem;
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
logger "Public key of server ipsecgw.example.com has been updated, restarting connection"
/usr/bin/systemctl restart strongswan
exit 0


O script pubkey-copy.sh é necessário para extrair a parte pública da chave e copiá-la para o host remoto ao emitir um novo certificado. Para fazer isso, no diretório / etc / letsencrypt / renewal-hooks / deploy nos dois servidores, crie outro microscript:


#!/bin/sh
/opt/ipsec-pubkey/pubkey-copy.sh > /dev/null 2>&1
/usr/bin/systemctl restart strongswan
exit 0

Metade do problema foi resolvido, os certificados são reemitidos, as chaves públicas são extraídas e copiadas entre os servidores e chegou a hora do systemd com suas unidades de caminho.

No servidor ipsecgw.example.com no diretório / etc / systemd / system, crie o arquivo keyupdater.path

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/rkn.example.com.pem
[Install]
WantedBy=multi-user.target

Da mesma forma no host VPS:

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/ipsecgw.example.com.pem
[Install]
WantedBy=multi-user.target

E, finalmente, em cada servidor, criamos um serviço associado a esta unidade, que será iniciado quando a condição (PathChanged) for atendida - alterando o arquivo e fechando-o após a gravação. Criamos os arquivos /etc/systemd/system/keyupdater.service e escrevemos:

[Unit]
Description= Starts the IPSec key updating script
Documentation= man:systemd.service
[Service]
Type=oneshot
ExecStart=/opt/ipsec-pubkey/key-updater.sh
[Install]
WantedBy=multi-user.target

Não se esqueça de reler as configurações do systemd com o sudo systemctl daemon-reload e atribua a inicialização automática às unidades de caminho via sudo systemctl enable keyupdater.path && sudo systemctl start keyupdater.

Assim que o host remoto gravar o arquivo que contém a chave pública no diretório inicial do usuário do keywatcher e o descritor de arquivos for fechado, o systemd iniciará automaticamente o serviço correspondente, que copiará a chave no local desejado e reiniciará o Strongswan. O túnel será instalado usando a chave pública correta do segundo lado.

Você pode expirar e apreciar o resultado.

Em vez de uma conclusão


Como acabamos de ver o inferno IPSec não é tão assustador como ele é pintado. Tudo o que foi descrito é uma configuração totalmente operacional atualmente em uso. Mesmo sem muito conhecimento, você pode configurar uma VPN e proteger seus dados com segurança.

Obviamente, os momentos da configuração do iptables permaneceram fora do escopo do artigo, mas o artigo em si já era volumoso e muito foi escrito sobre o iptables.

Há pontos no artigo que podem ser aprimorados, seja a recusa de reiniciar o daemon Strongswan, a releitura de suas configurações e certificados, mas não consegui isso.

No entanto, as reinicializações do daemon não foram assustadoras: um ou dois pings entre pares são perdidos, os clientes móveis restauram a conexão eles mesmos.

Espero que os colegas nos comentários indiquem a solução correta.

All Articles