Поднимаем свой VPN – L2TP/IPsec на Ubuntu

L2TP/IPSec на Ubuntu

Добрый день, уважаемые гости и читатели. Как и обещал в статье про PPTP, теперь расскажу как поднять на Ubuntu еще один тип VPN – L2TP/IPsec, где сам канал будет организован средствами L2TP, а поверх него для защиты передаваемых данных будет использоваться IPsec. Все описанные действия производились на Ubuntu 14.04.5 LTS. Напоминаю, что дешевые VPS во Франции для запуска своего VPN вы можете посмотреть здесь.

На новых Ubuntu, например 18 или 20 лучше воспользоваться вариантом с Docker, если он у вас установлен. Если вам это интересно, переходите сразу сюда.

Для установки L2TP/IPsec нам понадобятся права root пользователя или sudo.

1. Установим необходимые пакеты:

apt-get install openswan xl2tpd

После окончания установки, нам понадобится отредактировать несколько конфигурационных файлов. Для изменения файлов вы можете пользоваться любым удобным для вас способом.

Важно: при редактировании всех, указанных ниже файлов, оставляйте в конце файла пустую строку. При ее отсутствии, службы могут работать некорректно.

Теперь вам необходимо определиться с локальной подсетью для клиентов VPN. Вы можете сделать себе подсеть из любой сети/подсети, которая не маршрутизируется в интернете:

10.0.0.0/8
172.16.0.0/12
192.168.0.0/16

2. Открываем файл /etc/ipsec.conf, стираем его содержимое и добавляем следующую конфигурацию:

version 2.0
config setup
    dumpdir=/var/run/pluto/
    nat_traversal=yes
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v6:fd00::/8,%v6:fe80::/10
    protostack=netkey
    force_keepalive=yes
    keep_alive=60
conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    ikelifetime=8h
    keylife=1h
    ike=aes256-sha1,aes128-sha1,3des-sha1
    phase2alg=aes256-sha1,aes128-sha1,3des-sha1
    type=transport
    left=0.0.0.0
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=10
    dpdtimeout=20
    dpdaction=clear

Не забудьте изменить 0.0.0.0 в параметре left на внешний IP вашего сервера.

Для обеспечения безопасности, IPSec будет использовать shared-key – совместно используемый ключ. Он один для всех пользователей, периодически его можно изменять в целях безопасности.

3. Открываем /etc/ipsec.secrets и добавляем строку в представленном ниже формате:

0.0.0.0 %any: PSK "syrz3qfkbe2koeer7o1m"

Здесь необходимо заменить 0.0.0.0 на внешний IP вашего сервера, а строку в кавычках на ваш собственный общий ключ. Быстро сгенерировать рандомную строку вы можете например моим сервисом или такой командой на вашей Ubuntu:

openssl rand -hex 10

4. Теперь убедимся, что нужные нам пакеты установились из зависимостей в первом шаге:

apt-get install ppp lsof

5. Открываем файл /etc/xl2tpd/xl2tpd.conf, стираем его содержимое и добавляем следующее:

[global]
ipsec saref = yes
saref refinfo = 30

[lns default]
ip range = 192.168.1.2-192.168.1.254
local ip = 192.168.1.1
require authentication = yes
refuse pap = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
;ppp debug = yes
;debug avp = yes
;debug network = yes
;debug state = yes
;debug tunnel = yes

Здесь в ip range вы указываете пул адресов, которые будут выдаваться клиентам, подключающимся к вашему L2TP/IPsec VPN, а в local ip – локальный ip шлюза из этой подсети, но не входящий в пул (обычно первый адрес в подсети). Последние строки вы можете раскомментировать в случае, если вам нужен более подробный лог соединения.

6. Создаем файл /etc/ppp/options.xl2tpd и добавляем следующее содержимое:

require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
auth
mtu 1460
mru 1460
crtscts
hide-password
modem
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

Адреса DNS можете указать другие, если необходимо.

7. Пользователей будем добавлять в файл /etc/ppp/chap-secrets:

#username	server		password		IP
user1		l2tpd		password1		*
user2		l2tpd		password2		*

8. Открываем стандартный файл /etc/sysctl.conf и добавляем в конец файла параметры для форвардинга пакетов и отключения ICP-редиректов:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1

9. Открываем стандартный файл /etc/rc.local и добавляем в конец файла перед строкой exit 0:

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done

10. Посмотрите название сетевого интерфейса командой ifconfig. Если он начинается на eth, то смело добавляем правило iptables следующей командой:

iptables -t nat -A POSTROUTING -j SNAT --to-source 0.0.0.0 -o eth+

Не забудьте заменить 0.0.0.0 на внешний IP вашего сервера. Если название сетевого интерфейса отличается, то в eth+ замените буквенный префикс на префикс вашего интерфейса.

11. Сохраняем правила NAT в файл командой:

iptables-save > /etc/iptables.conf

12. Открываем файл /etc/network/interfaces и добавляем в конец файла строку:

pre-up /sbin/iptables-restore < /etc/iptables.conf

Таким образом, правила iptables будут добавляться автоматически при перезагрузке сервера.

Теперь можно перезагрузить сервер для применения всех изменений. После этого вы можете выполнить команду ipsec verify для проверки корректности настройки IPsec. У меня вот такие результаты:

Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                                 [OK]
Linux Openswan U2.6.38/K3.13.0-144-generic (netkey)
Checking for IPsec support in kernel                            [OK]
 SAref kernel support                                           [N/A]
 NETKEY:  Testing XFRM related proc values                      [OK]
        [FAILED]

  Please disable /proc/sys/net/ipv4/conf/*/accept_redirects
  or NETKEY will accept bogus ICMP redirects!

        [OK]
Checking that pluto is running                                  [OK]
 Pluto listening for IKE on udp 500                             [OK]
 Pluto listening for NAT-T on udp 4500                          [OK]
Two or more interfaces found, checking IP forwarding            [FAILED]
Checking NAT and MASQUERADEing                                  [OK]
Checking for 'ip' command                                       [OK]
Checking /bin/sh is not /bin/dash                               [WARNING]
Checking for 'iptables' command                                 [OK]
Opportunistic Encryption Support                                [DISABLED]

На некоторые предупреждения и ошибки можно не обращать внимания. Теперь вы можете попробовать подключиться к вашему L2TP/IPsec VPN используя логин, пароль и общий ключ, который указывали в конфигурации.

UPD 2023:

На новых системах уже нет возможности сохранять правила iptables способом, описанным выше. И вообще, желательно отказаться от iptables-save по той простой причине, что есть сервисы, которые сами добавляют свои правила в iptables после перезагрузки машины (например Docker) и могут возникнуть конфликты с уже сохраненными через iptables-save правилами.

Поэтому проще делать следующим образом:

Сначала вы создаете iptables.sh и прописываете в него все собственные правила, например так:

#!/bin/sh
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# ICMP
iptables -A INPUT -p icmp -j ACCEPT

# SSH 
iptables -A INPUT -s 5.5.5.5/32 -p tcp --dport 22 -j ACCEPT

# Веб-сервер
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Zabbix Agent
iptables -A INPUT -s 5.5.5.5/32 -p tcp --dport 10050 -j ACCEPT

iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Затем добавляете файлу права на запуск: chmod +x /root/iptables.sh и добавляете в крон:

@reboot root /root/iptables.sh >/dev/null 2>&1

Поднимаем L2TP/IPsec через Docker на 1 минуту

Предполагается, что у вас уже установлен Docker. Если нет – можете прочитать, как его установить.

Получаем образ:

docker pull teddysun/l2tp

Создаем файл /etc/l2tp.env и добавляем следующее содержимое:

VPN_IPSEC_PSK=syrz3qfkbe2koeer7o1m
VPN_USER=user1
VPN_PASSWORD=password1

Если на вашем сервере несколько внешних интерфейсов, то нужно указать IP, на котором будет работать VPN. Добавляем строчку:

VPN_PUBLIC_IP=5.5.5.5

Не забудьте заменить IP на ваш внешний IP.

Этих параметров уже достаточно для запуска, остальные будут по умолчанию. Вы можете изменять и другие параметры, а также добавлять и изменять пользователей. Я не буду на этом останавливаться, вы можете ознакомиться с подробностями здесь.

Убедитесь, что в вашем iptables открыты 500 и 4500 UDP порты.

Запускаем контейнер с именем l2tp:

docker run -d --privileged -p 500:500/udp -p 4500:4500/udp --name l2tp --restart=always --env-file /etc/l2tp.env -v /lib/modules:/lib/modules teddysun/l2tp

На этом всё. Логи можно посмотреть с помощью команды docker logs l2tp