L2TP VPN v AWS snadno a rychle
Publikováno: 19.8.2020
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.
Text vyšel původně na webu autora.
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“.
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
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).
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“.
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“.
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.
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.
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í:
Kroky v OS X (MacOS):
iOS (Nastavení – VPN – Přidat konfiguraci VPN…):
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):
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.
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á.