IPSec Tout-Puissant

Bonjour mes amis. Ce n'est pas un secret que beaucoup d'entre nous ont au moins une fois, mais ont dû faire face à la nécessité de configurer un VPN. Étant un lecteur actif de Habr, j'ai remarqué que malgré l'abondance d'articles sur IPSec, pour beaucoup, cela semble toujours être quelque chose de compliqué et de surchargé. Dans cet article, je vais essayer de dissiper ces mythes en utilisant ma propre configuration pleinement fonctionnelle comme exemple. Dans quatre exemples, nous passerons en revue la configuration de la solution Linux (Strongswan) la plus populaire, d'un simple tunnel avec authentification latérale avec clés PSK à une connexion d'hôte à hôte avec authentification des deux côtés basée sur des certificats de Let's Encrypt. Intéressant? Bienvenue chez cat!

Contexte


Initialement, le VPN n'était prévu que pour l'organisation du canal entre le mini-routeur des parents et le serveur "chevet" domestique, qui fait office de routeur.

Après une courte période de temps, Keenetic a été ajouté à cette société à partir de deux appareils.
Mais une fois démarré, il s'est avéré difficile d'arrêter, et bientôt des téléphones et un ordinateur portable sont apparus sur le diagramme, qui voulaient se cacher de l'œil publicitaire omniprésent de MT_Free et d'autres réseaux WiFi non cryptés.

Puis le bien-aimé ILV est finalement devenu plus fort le Banhammer, dont il est incroyablement tombé amoureux en se balançant publiquement dans toutes les directions, et afin de neutraliser son souci des simples mortels, il a dû soutenir le secteur informatique étranger pour acquérir des VPS à l'étranger.
De plus, une certaine citoyenne qui ressemble à Shapoklyak, courant partout avec son réticule par le Paquet, et croyant probablement que «Qui aide les gens, perd du temps. Vous ne pouvez pas devenir célèbre pour ses bonnes actions », je voulais jeter un œil au trafic de quelqu'un d'autre et le prendre au crayon. Nous devrons également nous défendre contre un tel amour non sollicité et VPN dans ce cas exactement ce que le médecin a ordonné.

Pour résumer un court résumé. Il était nécessaire de trouver une solution qui pourrait idéalement clôturer plusieurs tâches à la fois:

  • Interconnexion entre les routeurs Linux
  • Construisez un tunnel entre Linux et Keenetic Household
  • Donner accès aux ressources domestiques et à Internet aux appareils portables (téléphones, ordinateurs portables) provenant de réseaux non fiables
  • Créez un tunnel crypté en toute sécurité vers le VPS distant

N'oubliez pas le merveilleux principe KISS - Keep It Simple, Stupid. Moins il y aura de composants impliqués et plus il sera facile de configurer chacun d'eux - le plus fiable.

Aperçu des solutions existantes


Passez brièvement en revue ce qui est maintenant:

PPTP

Grand-père Lénine de tous les protocoles. Mort, "Pourri sur la moisissure et le miel de tilleul."

L2TP

Est-ce que quelqu'un d'autre qu'un fournisseur l'utilise?

Le

projet Wireguard se développe. Scié activement. Il est facile de créer un tunnel entre deux pairs ayant une adresse IP statique. Dans d'autres cas, des béquilles, des vélos à roues carrées et un ruban électrique bleu sont toujours prêts à aider, mais ce n'est pas notre façon. Avantages d'

OpenVPN

:

  • Prise en charge de plusieurs plateformes - Windows, Linux, OpenWRT et ses dérivés, Android
  • Cryptage fort et prise en charge des certificats.
  • Flexibilité de personnalisation.

Et les inconvénients:

  • Travaillez entièrement dans l'espace utilisateur.
  • Support limité des routeurs domestiques - krenenko-kosenko sur Mikrotik (sans nuire aux autres avantages des glandes) et normal dans OpenWRT.
  • Difficultés de configuration des clients mobiles: vous devez télécharger ou créer votre propre programme d'installation, copier les configurations quelque part.
  • S'il y a plusieurs tunnels, les danses attendent avec l'édition des unités systemd sur le serveur.

OpenConnect (implémentation open-source du protocole Cisco Anyconnect)
Une solution très intéressante sur laquelle, malheureusement, il y a pas mal d'informations.

Avantages:

  • La prise en charge relativement large de diverses plates-formes - Windows, Android, Mac basées sur l'application native Cisco Anyconnect du magasin - est une option idéale pour fournir un accès au réseau interne d'appareils portables.
  • Cryptage fort, prise en charge des certificats, connectivité 2FA
  • Le protocole lui-même est entièrement basé sur TLS (contrairement à OpenVPN, qui est facilement détecté sur le port 443). En plus de TLS, DTLS est également pris en charge - pendant la session établie, le client peut passer à la transmission de données via UDP et vice versa.
  • Excellente coexistence sur un port d'un VPN et d'un serveur Web à part entière utilisant le sniproxy.
  • Configuration facile du serveur et des clients.

Là aussi, ce n'était pas sans inconvénients:

  • Travaillez entièrement dans l'espace utilisateur.
  • TCP en plus de TCP est une mauvaise idée.
  • Il n'y a pas de support d'équipement de qualité client.
  • La complexité de l'installation de tunnels entre deux Linux: théoriquement possible, pratiquement - il vaut mieux passer du temps sur quelque chose de plus utile.
  • S'il y a plusieurs tunnels, des danses avec plusieurs configs et éditant des unités systemd attendent.

Cela semblerait être une impasse, mais après avoir regardé de plus près et passé un peu de temps à étudier, j'ai réalisé qu'IPSec basé sur IKEv2 est capable de remplacer tout le reste. Avantages

IPSec IKEv2

:

  • Avec l'avènement d'IKEv2, le protocole lui-même est devenu plus facile à configurer, par rapport à la version précédente, mais au prix de perdre la compatibilité descendante.
  • Grâce à la standardisation, le travail est assuré n'importe où et sur n'importe quoi - la liste peut être maintenue indéfiniment. Linux, Mikrotik (dans les dernières versions de RouterOS), OpenWRT, Android, iPhone. Windows a également un support natif à partir de Windows 7.
  • Haute vitesse: traitement complet du trafic dans l'espace noyau. La partie espace utilisateur n'est nécessaire que pour définir les paramètres de connexion et surveiller l'intégrité du canal.
  • La possibilité d'utiliser plusieurs méthodes d'authentification: en utilisant à la fois PSK et certificats, et dans n'importe quelle combinaison.
  • Plusieurs modes de fonctionnement: tunnel et transport. Comment ils diffèrent peuvent être lus, y compris sur Habré.
  • Paramètres peu exigeants pour les nœuds intermédiaires: si dans la première version d'IKE il y avait des problèmes causés par NAT, alors IKEv2 a des mécanismes intégrés pour surmonter NAT et la fragmentation native des messages IKE, ce qui vous permet d'établir une connexion sur des canaux avec une courbe MTU. Pour l'avenir, je dirai que dans la pratique, je n'ai jamais rencontré de réseau WiFi, où qu'un client puisse établir une connexion.

Les inconvénients, cependant, ont également:

  • Vous devez passer du temps à étudier et à comprendre comment cela fonctionne.
  • Une fonctionnalité qui peut dérouter un débutant: IPSec, contrairement aux solutions VPN conventionnelles, ne crée pas d'interfaces réseau. Seules les politiques de traitement du trafic sont définies, tout le reste est résolu au moyen d'un pare-feu.

Avant de procéder à la configuration, nous supposons que le lecteur connaît déjà un peu les concepts et termes de base. Pour aider un débutant, vous pouvez recommander un article de Wikipedia et Habr lui-même, sur lequel il existe déjà des articles très intéressants et utiles sur ce sujet.

Commencer la configuration


Après avoir décidé de la décision, nous procédons à la configuration. Le schéma de réseau dans mon cas a la forme suivante (retiré sous le spoiler)

Schéma de réseau

ipsecgw.example.com est le serveur domestique qui est le centre du réseau. IP externe 1.1.1.1. Un réseau interne 10.0.0.0/23 et une autre adresse 10.255.255.1/30 pour établir une session BGP privée avec VPS;
mama est un routeur Linux basé sur un petit nettop silencieux installé par les parents. Le FAI émet une adresse IP dynamique. Réseau interne 10.0.3.0/24;
keenetic - Routeur Keenetic avec IPSec installé. Le FAI émet une adresse IP dynamique. Réseau interne 10.0.4.0/24;
road-warriors - appareils portables se connectant à partir de réseaux non fiables. Les adresses sont émises dynamiquement aux clients lorsqu'ils sont connectés à partir du pool interne (10.1.1.0/24);
rkn.example.com- VPS en dehors de la juridiction d'un ILV respecté. IP externe - 5.5.5.5, adresse interne 10.255.255.2/30 pour définir une session BGP privée.

Premier pas. Du simple au complexe: tunnels utilisant des clés pré-partagées (PSK)


Sur les deux boîtiers Linux, nous installons les packages nécessaires:

sudo yum install strongswan

Sur les deux hôtes, ouvrez les ports 500 / udp, 4500 / udp et autorisez le passage du protocole ESP.
Modifiez le fichier /etc/strongswan/ipsec.secrects (côté hôte ipsecgw.example.com) et ajoutez la ligne suivante:

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

Sur le deuxième côté, de même:

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

Dans ce cas, l'ID est une adresse e-mail fictive. Plus d'informations peuvent être trouvées sur le wiki officiel .

Secrets sauvés, continuant.

Sur l'hôte ipsecgw.example.com, modifiez le fichier /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        

De même, nous éditons sur l'homologue distant /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

Si vous comparez les configurations, vous pouvez voir qu'elles sont presque en miroir, seules les définitions des pairs sont échangées.

La directive auto = route oblige charon à mettre un piège pour le trafic tombant dans les directives left / rightsubnet (sélecteurs de trafic). La coordination des paramètres du tunnel et l'échange de clés commenceront immédiatement après l'apparition d'un trafic qui tombe dans les conditions données.

Sur le serveur ipsecgw.example.com dans les paramètres du pare-feu, nous interdisons le masquage pour un réseau 10.0.3.0/24. Autorisez le transfert de paquets entre 10.0.0.0/23 et 10.0.3.0/24 et vice versa. Sur l'hôte distant, nous effectuons des réglages similaires en désactivant le masquage pour le réseau 10.0.0.0/23 et en configurant le transfert.

Nous redémarrons strongswan sur les deux serveurs et essayons d'envoyer une requête ping au nœud central:

sudo systemctl restart strongswan
ping 10.0.0.1


Assurez-vous que tout fonctionne:
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


Il sera également utile de s'assurer que le paramètre make_before_break est défini sur yes dans le fichier /etc/strongswan/strongswan.d/charon.conf pour tous les homologues. Dans ce cas, le démon charon servant le protocole IKEv2 ne supprimera pas l'association de sécurité actuelle pendant la procédure de changement de clé, mais en créera d'abord une nouvelle.

Deuxième étape L'apparition de Keenetic


Une surprise agréable a été le VPN IPSec intégré dans le firmware officiel de Keenetic. Pour l'activer, accédez simplement aux paramètres du composant KeeneticOS et ajoutez le package VPN IPSec .

Nous préparons les paramètres sur le nœud central, pour cela:

Éditez /etc/strongswan/ipsec.secrects et ajoutez le PSK pour le nouveau pair:

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

Modifiez /etc/strongswan/ipsec.conf et ajoutez une autre connexion à la fin:

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

Côté Keenetic, la configuration se fait dans l'interface Web le long du chemin: Internet -> Connexions ->
Autres connexions
. C'est assez simple
(3 photos)






Si vous prévoyez de générer des volumes de trafic importants via le tunnel, vous pouvez essayer d'activer l'accélération matérielle, qui est prise en charge par de nombreux modèles. Activé par la commande matérielle du moteur de chiffrement dans la CLI. Pour désactiver et traiter les processus de chiffrement et de hachage à l'aide d'instructions générales du processeur - logiciel de moteur de cryptage

Après avoir enregistré les paramètres, nous restaurons strongswan et laissons Keenetic réfléchir pendant une demi-minute. Ensuite, dans le terminal, nous voyons une connexion réussie:

Tout fonctionne:
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


Troisième étape Protéger les appareils mobiles


Après avoir lu un tas de manuels et un tas d'articles, il a été décidé de s'arrêter à un tas d'un certificat gratuit de Let's Encrypt pour authentifier le serveur et l'autorisation classique par login et mot de passe pour les clients. Ainsi, nous nous débarrassons de la nécessité de maintenir notre propre infrastructure PKI, de surveiller l'expiration des clés et d'effectuer des gestes inutiles avec les appareils mobiles en installant des certificats auto-signés dans la liste de confiance.

Installez les packages manquants:

sudo yum install epel-release
sudo yum install certbot

Nous obtenons le certificat autonome (n'oubliez pas d'ouvrir 80 / tcp dans les paramètres iptables en premier):

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

Une fois que certbot a terminé son travail, nous devons apprendre à Strongswan à voir notre certificat:

  • dans le répertoire /etc/strongswan/ipsec.d/cacerts créez 2 liens symboliques: un vers le magasin racine des certificats de confiance dans / etc / pki / tls / certs; et une seconde avec le nom ca.pem pointant vers /etc/letsencrypt/live/ipsecgw.example.com/chain.pem
  • Deux liens symboliques sont également créés dans le répertoire /etc/strongswan/ipsec.d/certs: le premier, avec le nom certificate.pem, fait référence au fichier /etc/letsencrypt/live/ipsecgw.example.com/cert.pem. Et le second, nommé fullchain.pem, se liant à /etc/letsencrypt/live/ipsecgw.example.com/fullchain.pem
  • Dans le répertoire /etc/strongswan/ipsec.d/private, placez le lien symbolique key.pem pointant vers la clé privée générée par certbot et se trouvant le long du chemin /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem

Ajoutez l'authentification via RSA à ipsec.secrets et un tas de connexions / mots de passe pour les nouveaux utilisateurs:

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

Nous redémarrons Strongswan et lorsque nous appelons sudo strongswan listcerts, nous devrions voir les informations du certificat:

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

Ensuite, nous décrivons la nouvelle connexion dans 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'oubliez pas de modifier le fichier / etc / sysconfig / certbot en indiquant que nous mettrons également à jour le certificat en tant que autonome, en y ajoutant CERTBOT_ARGS = "- standalone".

N'oubliez pas non plus d'activer la minuterie certbot-refresh.timer et de configurer le hook pour redémarrer Strongswan en cas d'émission d'un nouveau certificat. Pour ce faire, placez un simple script bash dans / etc / letsencrypt / renouvellement-hooks / deploy /, ou modifiez à nouveau le fichier / etc / sysconfig / certbot.

Nous redémarrons Strongswan, activons le masquage pour le réseau 10.1.1.0/24 dans iptables et continuons à configurer les appareils mobiles.

Android


Installez l'application Strongswan à partir de Google Play .

Nous lançons et créons un nouveau

profil


Nous enregistrons le profil, nous nous connectons et, après une seconde, nous n'avons pas à nous soucier de la possibilité pour quelqu'un de nous espionner.

Nous vérifions:
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


les fenêtres


Windows des versions actuelles a été agréablement surpris. Toute la configuration du nouveau VPN s'effectue en appelant deux applets de commande 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

Et encore une chose, si Strongswan est configuré pour émettre des adresses IPv6 aux clients (oui, il peut le faire aussi):

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

Quatrième partie, finale. Nous ouvrons une fenêtre sur l'Europe


Ayant vu les talons du fournisseur "Le site a été bloqué par la décision du talon gauche du cinquième procureur adjoint du village Trudovye Mozoli du comté de Bogozabyt", un petit VPS discret est apparu (avec le nom de domaine bien entendu rkn.example.com) à mille kilomètres de singes qui aiment agiter avec un marteau et bloquer les réseaux de taille / 16 à la fois. Et tourner sur ce petit VPS était une merveilleuse création de collègues de NIC.CZ appelés BIRD. L'oiseau de la première version est constamment mort dans la panique de l'activité des singes avec des matraques, qui ont interdit près de 4% d'Internet au sommet de leur activité, laissant une profonde réflexion lors de la reconfiguration, il a donc été mis à jour vers la version 2.0.7. Si les lecteurs sont intéressés, je publierai un article sur la transition de BIRD à BIRD2, dans lequel le format de configuration a radicalement changé,mais la nouvelle version est devenue beaucoup plus rapide et il n'y a aucun problème avec la reconfig avec un grand nombre de routes. Et puisque nous utilisons le protocole de routage dynamique, il doit y avoir une interface réseau à travers laquelle vous devez acheminer le trafic. Par défaut, IPSec ne crée pas d'interfaces, mais en raison de sa flexibilité, nous pouvons utiliser les tunnels GRE classiques, que nous protégerons à l'avenir. En prime, les hôtes ipsecgw.example.com et rkn.example.com s'authentifieront mutuellement à l'aide de certificats auto-renouvelables Lets Encrypt. Pas de PSK, seulement des certificats, seulement du hardcore, il n'y a pas beaucoup de sécurité.Par défaut, IPSec ne crée pas d'interfaces, mais en raison de sa flexibilité, nous pouvons utiliser les tunnels GRE classiques, que nous protégerons à l'avenir. En prime, les hôtes ipsecgw.example.com et rkn.example.com s'authentifieront mutuellement à l'aide de certificats auto-renouvelables Lets Encrypt. Pas de PSK, seulement des certificats, seulement du hardcore, il n'y a pas beaucoup de sécurité.Par défaut, IPSec ne crée pas d'interfaces, mais en raison de sa flexibilité, nous pouvons utiliser les tunnels GRE classiques, que nous protégerons à l'avenir. En prime, les hôtes ipsecgw.example.com et rkn.example.com s'authentifieront mutuellement à l'aide de certificats auto-renouvelables Lets Encrypt. Pas de PSK, seulement des certificats, seulement du hardcore, il n'y a pas beaucoup de sécurité.

Nous pensons que le VPS est prêt, Strongswan et Certbot sont déjà installés.

Sur l'hôte ipsecgw.example.com (son IP est 1.1.1.1), nous décrivons la nouvelle 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"

Mis en miroir sur l'hôte vps.example.com (son IP est 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"

Nous augmentons les interfaces, mais comme iptables n'a pas de règle qui autorise le protocole GRE, le trafic ne passera pas (ce dont nous avons besoin, car il n'y a pas de protection à l'intérieur du GRE contre les fans de tout type de «packages» législatifs).

Cuisson VPS


Tout d'abord, nous obtenons un autre certificat pour le nom de domaine rkn.example.com. Créez des liens symboliques dans /etc/strongswan/ipsec.d comme décrit dans la section précédente.

Modifiez ipsec.secrets en y ajoutant une seule ligne:

rkn.example.com     : RSA key.pem

Modifiez 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

Côté hôte, ipsecgw.example.com est également ajouté à ipsec.conf dans la section de configuration du paramètre strictcrlpolicy = yes, qui inclut une vérification stricte de la liste de révocation de certificats. Et décrivez une autre connexion:

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

Les configurations sont presque reflétées. Le lecteur attentif pouvait déjà prêter attention à quelques points:

  • left / rightsubnet =% dynamic - demande à Strongswan d'appliquer des politiques à tous les types de trafic entre pairs
  • 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'oubliez pas de configurer le pare-feu et de renouveler automatiquement les certificats. Après avoir redémarré Strongswan sur les deux serveurs, commencez à envoyer une requête ping de l'autre côté du tunnel GRE et voyez une connexion réussie. Sur 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


Et du côté hôte ipsecgw
sous le 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


Le tunnel est installé, les pings vont, dans tcpdump, il est visible que seul ESP passe entre les hôtes. Il semblerait possible de se réjouir. Mais vous ne pouvez pas vous détendre sans tout vérifier jusqu'au bout. Nous essayons de réémettre le certificat pour VPS et ...

Chef, tout est cassé


Nous commençons à comprendre et à tomber sur une caractéristique désagréable de Let's Encrypt, qui est belle dans tout le reste - avec toute réémission du certificat, la clé privée qui lui est associée change également. La clé privée a changé - et le public a changé. À première vue, la situation est désespérée pour nous: même si nous pouvons facilement extraire la clé publique lors de la réémission du certificat à l'aide du hook dans certbot et la transmettre au côté distant via SSH, il n'est pas clair comment faire relire Strongswan à distance. Mais l'aide est venue de là où ils n'ont pas attendu - systemd peut surveiller les modifications du système de fichiers et exécuter les services associés à l'événement. C'est ce que nous allons utiliser.

Nous allons créer un utilisateur du service Keywatcher sur chacun des hôtes avec les droits les plus restreints, générer des clés SSH pour chacun d'eux et les échanger entre les hôtes.

Sur l'hôte ipsecgw.example.com, créez le répertoire / opt / ipsec-pubkey dans lequel nous plaçons 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

Sur VPS (l'hôte rkn.example.com), nous créons également un répertoire du même nom, dans lequel nous créons également des scripts similaires, en ne changeant que le nom de la clé. Code, afin de ne pas encombrer l'article, sous

divulgacher
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


Le script pubkey-copy.sh est nécessaire pour extraire la partie publique de la clé et la copier sur l'hôte distant lors de l'émission d'un nouveau certificat. Pour ce faire, dans le répertoire / etc / letsencrypt / renouvellement-hooks / deploy sur les deux serveurs, créez un autre microscript:


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

La moitié du problème est résolu, les certificats sont réémis, les clés publiques sont extraites et copiées entre les serveurs, et le moment est venu pour systemd avec ses unités de chemin.

Sur le serveur ipsecgw.example.com dans le répertoire / etc / systemd / system, créez le fichier keyupdater.path

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

De même sur l'hôte VPS:

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

Et enfin, sur chaque serveur, nous créons un service associé à cette unité, qui sera lancé lorsque la condition (PathChanged) sera remplie - changer le fichier et le fermer après l'enregistrement. Nous créons les fichiers /etc/systemd/system/keyupdater.service et écrivons:

[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'oubliez pas de relire les configurations systemd avec sudo systemctl daemon-reload et d'affecter le démarrage automatique aux unités de chemin via sudo systemctl enable keyupdater.path && sudo systemctl start keyupdater.

Dès que l'hôte distant écrit le fichier contenant la clé publique dans le répertoire de base de l'utilisateur du keywatcher et que le descripteur de fichier est fermé, systemd démarrera automatiquement le service correspondant, qui copiera la clé à l'emplacement souhaité et redémarrera Strongswan. Le tunnel sera installé à l'aide de la bonne clé publique du deuxième côté.

Vous pouvez expirer et profiter du résultat.

Au lieu d'une conclusion


Comme nous venons de voir l' enfer IPSec n'est pas aussi effrayant que cela est peint. Tout ce qui a été décrit est une configuration entièrement opérationnelle actuellement utilisée. Même sans beaucoup de connaissances, vous pouvez configurer un VPN et protéger de manière fiable vos données.

Bien sûr, les moments de configuration d'iptables sont restés en dehors de la portée de l'article, mais l'article lui-même s'est avéré déjà volumineux, et beaucoup a été écrit sur iptables.

Il y a des points dans l'article qui peuvent être améliorés, que ce soit le refus de redémarrer le démon Strongswan, la relecture de ses configurations et certificats, mais je n'ai pas pu y parvenir.

Cependant, les redémarrages du démon n'étaient pas effrayants: un ou deux pings entre pairs sont perdus, les clients mobiles rétablissent eux-mêmes la connexion.

J'espère que mes collègues dans les commentaires proposeront la bonne solution.

All Articles