L2TP VPN v AWS snadno a rychle

✍️ Vláďa Smitka
📅 07. 07. 2016

Tento článek vznikl na základě podnětů k předchozímu článku o zprovoznění proxy serveru na Digital Ocean. V něm jsem zmiňoval, že proxy server rozhodně nenahrazuje VPN, které zajišťuje plně šifrovaný přístup. Podíváme se tedy, jak si zprovoznit vlastní VPN server. Existuje několik typů VPN, vybral jsem L2TP s IPsec a se sdíleným klíčem, protože je podporována na velkém množství prostředí a Windows, Android i iOS mají již zabudované klienty. Osobně bych preferoval VPN typu IKEv2 (především proto, že nemá problémy s NAT), ta však není bez externí aplikace podporovaná na zařízeních s Android. Naopak IKEv2 je podporovaná na Blackberry OS10, kde zrovna L2TP není.

Konfiguraci si ukážeme tentokrát v prostředí AWS, nicméně použitý Cloud Init skript však stejně dobře funguje i na Digital Ocean.

Nejprve je potřeba založit instanci EC2 (virtuálni server) v AWS.

Zvolte tedy "Launch Instance" a vyberte Amazon Linux 2 AMI, RedHat  nebo odpovídající Centos verze 7 či 8. Dále vyberte požadovanou velikost instance, provozování VPN pro malý počet uživatelů není příliš náročné, takže postačí t2.micro. Pokračujte v konfiguraci tlačítkem "Next: Configure Instance Details".

Cloud Init user data v Amazon AWS EC2

Zde v detailech instance vás zajímá políčko "User data", které je skryté pod "Advanced Details". Do tohoto políčka vložte připravený Cloud Init skript (je o trochu delší než u proxy):

#cloud-config
packages:
 - libreswan
 - firewalld
 - ppp
  
write_files:
  - path: /etc/ipsec.conf
    content: |
      config setup
        protostack=netkey
        nhelpers=0
      
      conn l2tp-psk
        authby=secret
        auto=add
        dpdaction=clear
        dpddelay=30
        dpdtimeout=120
        ikev2=no
        keyingtries=5
        left=%defaultroute
        leftid=%myid
        leftprotoport=17/1701
        pfs=no
        rekey=no
        right=%any
        rightprotoport=17/%any
        rightsubnet=vhost:%priv
        type=transport
  
  - path: /etc/ipsec.secrets
    content: |        
      %any %any: PSK "{PSK}"
  
  - path: /etc/xl2tpd/xl2tpd.conf
    content: |        
      [lns default]
      ip range = 10.0.1.10-10.0.1.254
      local ip = 10.0.1.1
      refuse chap = yes
      refuse pap = yes
      require authentication = yes
      name = l2tpd
      ppp debug = yes
      pppoptfile = /etc/ppp/options.xl2tpd
      length bit = yes
  
  - path: /etc/ppp/options.xl2tpd
    content: |   
      ipcp-accept-local
      ipcp-accept-remote
      require-mschap-v2
      ms-dns 8.8.8.8
      ms-dns 8.8.4.4
      asyncmap 0
      auth
      hide-password
      name l2tpd
      proxyarp
      lcp-echo-interval 30
      lcp-echo-failure 4
      mtu 1400
      noccp
      connect-delay 5000
  
  - path: /etc/ppp/chap-secrets
    content: |  
      # client     server     secret               IP addresses
      {user}          l2tpd     {pass}               *
  
  - path: /etc/sysctl.conf
    content: | 
      net.ipv4.ip_forward = 1
      net.ipv4.conf.all.rp_filter = 0
      net.ipv4.conf.default.rp_filter = 0
      net.ipv4.conf.eth0.rp_filter = 0
      net.ipv4.conf.all.send_redirects = 0
      net.ipv4.conf.default.send_redirects = 0
      net.ipv4.conf.all.accept_redirects = 0
      net.ipv4.conf.default.accept_redirects = 0
  
  - path: /etc/cron.daily/update.sh
    content: |
      #!/bin/bash
      /usr/bin/yum -y update
      
  - path: /usr/local/bin/l2tp_ppp_fix.sh
    content: |
      #!/bin/bash
      if ! modprobe -q l2tp_ppp; then
        sed -i '/^ExecStartPre/s/^/#/' /usr/lib/systemd/system/xl2tpd.service
        systemctl daemon-reload
      fi
  
  
runcmd:
  - RELEASE=$(rpm -E %{rhel}) && rpm -i https://dl.fedoraproject.org/pub/epel/epel-release-latest-$RELEASE.noarch.rpm
  - yum install xl2tpd -y
  - sysctl -p /etc/sysctl.conf
  - chmod a+x /etc/cron.daily/update.sh
  - firewall-offline-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="{myip}" accept'
  - firewall-offline-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" accept'
  - firewall-offline-cmd --zone=public --add-port=500/udp
  - firewall-offline-cmd --zone=public --add-port=4500/udp
  - firewall-offline-cmd --remove-service=ssh
  - firewall-offline-cmd --zone=public --add-masquerade
  - firewall-offline-cmd --zone=public --add-interface=eth0
  - sh /usr/local/bin/l2tp_ppp_fix.sh
  - systemctl start xl2tpd ipsec firewalld
  - systemctl enable xl2tpd ipsec firewalld

Cloud Init na GitHubu.

Ve skriptu si opět dosaďte vlastní hodnoty za 4 proměnné:

{PSK} - sdílený klíč pro připojení do VPN, určitě si nechte vygenerovat nějaký složitější

{jmeno} - uživatelské jméno do VPN

{heslo} - heslo do VPN

{ip} - vaše IP adresa pro přístup k SSH (pro samotné zprovoznění není potřeba, bude se hodit až pro budoucí správu)

Opět platí, že můžete zduplikovat řádek s nastavením uživatelského jména a hesla a řádek s nastavením IP adresy pro správu.

Další bod, který vás bude zajímat je "6. Configure Security Group", kde se nastavuje firewall na straně AWS, zde je potřeba povolit UDP porty 500 a 4500 pro IPsec s L2TP. Po nastavení pravidel budete ještě vyzváni k vytvoření/vybrání SSH klíčů pro přístup ke stroji (v instanci je vytvořen uživatel ec2-user).

Nasatvení security group v Amazon AWS

Nyní zbývá pouze zkontrolovat údaje a spustit instanci. Vytvoření instance a její nakonfigurování potrvá několik minut. Až bude připravena, uvidíte status "running" a zelenou ikonku u "Status Checks".

Běžící VPS EC2 v Amazon AWS

Nastavení VPN klienta

V tomto okamžiku stačí nastavit klienta a začít VPN používat. Nastavení si ukážeme na Windows 7.

Nejprve je potřeba v "Centru síťových připojení a sdílení" přidat nové připojení. "Centrum" lze otevřít příkazem "control /name Microsoft.NetworkAndSharingCenter".

Nastavení L2TP VPN na Windows 7 - centrum připojení

Vybereme "Připojit k firemní síti", necháme vytvořit nové připojení, vybereme "Použít moje připojení k Internetu", zadáme IP adresu našeho serveru a připojení si pojmenujeme. Konfigurace bude potřebovat ještě doladit, zaškrtneme si tedy "Nepřipojovat nyní". V dalším kroku můžeme zvolit zapamatování uživatelského jména a hesla a dále průvodce zavřít. V "Centru" si nyní zvolíme "Změnit nastavení adaptéru" (lze také otevřít příkazem "ncpa.cpl"). Pravým tlačítkem klikneme na námi vytvořené připojení a vybereme "Vlastnosti".

Zde bude potřeba na kartě "Zabezpečení" vybrat typ sítě VPN L2TP a v dialogu pod "Upřesnit nastavení" zadat PSK klíč, který jsme si nastavili v Cloud Init skriptu.

Nastavení L2TP VPN na Windows 7 - upřesnit

Pokud provozujete L2TP VPN server u Amazonu, tak narazíte na problém, že Windows v základním nastavení neumí navázat L2TP tunel na stroj, který je za NAT (to se netýká zdaleka jen Amazonu). Je potřeba provést drobnou úpravu v registru - v klíči "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\PolicyAgent" vytvořit novou DWORD vlastnost s názvem "AssumeUDPEncapsulationContextOnSendRule" a hodnotou 2 (REG soubor, který vlastnost nastaví je možné si stáhnout). Po změně je třeba restartovat počítač.

Digital Ocean přiřazuje veřejné IP adresy přímo strojům, takže pro něj není úprava registru nutná.

Pokud se vše podařilo, můžete se nyní připojit ke své VPN.

Nastavení L2TP VPN na Windows 7 - připojení

Ve Windows 10 je nastavení jednodušší (úprava registru pro VPN servery za NAT je stále potřeba). Stačí otevřít z nabídky "Start" nastavení - Síť a Internet - VPN a zde stačí přidat nové připojení:

Nastavení L2TP VPN na Windows 10

Kroky v OS X (MacOS):

Nastavení L2TP VPN na Apple MAC OS

iOS (Nastavení - VPN - Přidat konfiguraci VPN...):

Nastavení L2TP VPN na Apple iOS

Android (Nastavení - Bezdrátová připojení a sítě - Další - Síť VPN - Přidat [+]) - u starších Androidů se dialog liší pouze v tom, že se jméno a heslo zadává při prvním připojení (je zde možnost si ho zapamatovat):

Nastavení L2TP VPN na Android

S tímto návodem tedy dokážete následující:

  • Vytvořit instanci v cloudu AWS od Amazonu.
  • Provést deployment jednoduchých služeb pomocí Cloud Init skriptu.
  • Provozovat L2TP VPN pomocí LibreSwan a xl2tpd.

Díky VPN se můžete bezpečně připojit k internetu z neznámých WiFi sítí - veškerý váš provoz bude šifrován.

Je vidět, že se oproti Cloud Init skriptu pro proxy je tento obsáhlejší. Může za to především obsah konfiguračních souborů. Bylo by samozřejmě možné tyto soubory stáhnout pomocí wget z nějakého úložiště, zde jsem však nechtěl, aby byl skript závislý na dalších službách. V Cloud Init skriptech je dále možné využít MedaData API, které poskytovatelé poskytují. Díky němu je možné jednoduše získat si o stroji některé informace,  které by bylo jinak potřeba složitě parsovat. Metadata se získají zavoláním webové služby na speciální adrese. Například pro získání hostname stačí přečíst odpověď:

http://169.254.169.254/latest/meta-data/hostname (u AWS)

http://169.254.169.254/metadata/v1/hostname (u Digital Ocean)

Pro deployment složitějších služeb se více hodí specializované orchestrační nástroje jako je Ansible.

Amazon AWS nabízí trial verzi zdarma, kde si můžete vše otestovat. Pro testy můžete také využít můj referral odkaz na Digital Ocean (a nebudete muset provádět úpravu registrů kvůli NATu), díky kterému získáte testovací kredit 100$ a pokud budete službu v budoucnu používat, dostanu i já kredit na další testy :-).

Pokud vaše VPS nepodporuje Cloud init, je možné využít konfigurace ve formě shell skriptu.

LibreSwan jsme použili, protože je to výchozí implementace IPsec v systémech RedHat/Centos. Pokud preferujete StrongSwan (dostupný přes Epel), je konfigurace obdobná.

V dalším návodu se podíváme, jak zprovoznit jiný typ VPN: IKEv2 s certifikátem od Let's Encrypt

Štítky: ,

2 comments on “L2TP VPN v AWS snadno a rychle”

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *


Lynt services s.r.o

Již 12 let vytváříme efektivnější kampaně, zrychlujeme weby a řešíme jejich bezpečnost. Kombinujeme marketing, vývoj a automatizaci.
poptávka služeb