Это старая версия документа!
Дата написания: апрель 2017 г.
Автор: Graf
L2TP/IPsec VPN |
---|
Сервер
В качестве сервера используется Slackware Linux 14.2 64-bit с ядром 4.4.38, без DE и всем, что с ними связанно.
Eth1 - смотрит в Интернет - 77.77.77.77 (vpn.mydom.ru)
Eth0 - смотрит в локальную сеть - 192.168.3.250
Клиентам VPN будут выдан диапазон IP адресов из этой же локальной сети - 192.168.3.0/24, хотя этого и не рекомендуют делать, но у меня нет DHCP и каждому клиенту я лично буду выдавать логин, пароль и ip-адрес. Это позволит осуществлять двусторонний обмен данными и ip-адреса не будут пересекаться.
Берем openswan_slackbuild.tar.gz, распаковываем и в этот же каталог скачиваем последнюю версию openswan, на сегодня это - 2.6.49.1
# wget https://download.openswan.org/openswan/openswan-2.6.49.1.tar.gz
правим openswan.SlackBuild в части версии и запускаем его. По окончании сборки устанавливаем полученный пакет.
# upgradepkg --install-new /tmp/openswan-2.6.49.1-x86_64-1_SBo.tgz Package openswan-2.6.49.1-x86_64-1_SBo.tgz installed.
Берем xl2tpd_slackbuild.tar.gz, распаковываем и в этот же каталог скачиваем последнюю версию xl2tpd, на сегодня это - 1.3.8, переименовав под требуемый slackbuild'ом шаблон.
# wget -O xl2tpd-1.3.8.tar.gz https://github.com/xelerance/xl2tpd/archive/v1.3.8.tar.gz
Правим xl2tpd.SlackBuild в части версии и запускаем его. По окончании сборки устанавливаем полученный пакет.
# upgradepkg --install-new /tmp/xl2tpd-1.3.8-x86_64-1_SBo.tgz Package xl2tpd-1.3.8-x86_64-1_SBo.tgz installed.
IPSec
Настраиваем IPSec.
Редактируем файл /etc/ipsec.conf
# Первая значимая строка файла должна указывать версию спецификации version 2.0 # Eединственный конфигурационный раздел, который содержит информацию, используемую при запуске программы. config setup nat_traversal=yes # Разрешить поддержку NAT (NAPT, также известный как «IP Masquerade»). # Допустимые значения: "yes" и "no" (по умолчанию). virtual_private=%v4:192.168.3.0/24 # Подсеть, в которую будут попадать клиенты VPN oe=off # Включить(on) или нет(off) оппортунистическое шифрование. По умолчанию нет(off) # Оппортунистическое шифрование - это термин для описания использования туннелей # IPsec без предварительного согласования. protostack=netkey # Решить, какой стек протокола будет использоваться. # Допустимыми значениями являются «auto», «klips», «netkey» и «mast». uniqueids=yes # Следует ли сохранить уникальный идентификатор участника с любым новым # (автоматически вводимым ключом) соединением с использованием идентификатора # с другого IP-адреса. Допустимые значения: "yes" (по умолчанию) и "no". # Раздел содержит спецификацию соединения по умолчанию conn %default forceencaps=yes # Допустимые значения: "yes" или "no" (по умолчанию). # В некоторых случаях, например, когда пакеты ESP отфильтровываются # или когда удаленный узел IPsec неправильно распознает NAT, может быть полезно # принудительно инкапсулировать RFC-3948. Значение yes заставляет код обнаружения # NAT указывать удаленному узлу, что требуется инкапсуляция RFC-3948 # (ESP в пакетах UDP-порта 4500). Чтобы этот параметр имел какой-либо эффект, # необходимо установить параметр nat_traversal = yes. compress=yes # Предлагать сжатие. Допустимыми значениями являются "yes" и "no" (по умолчанию). # Раздел содержит спецификацию определенного соединения, название произвольное. conn l2tp-psk-nat # Всё начинающееся с: # left - означает локальный компьютер, на котором хранится текущий файл с настройками, т.е. наш сервер; # right - означает удалённый компьютер, то есть тот, с которым будет произведена попытка установить удалённое подключение, # по сути, все остальные. rightsubnet=vhost:%priv # Приватная подсеть за удаленным участником (right), выраженная как сеть/сетевая # маска. В настоящее время поддерживаются диапазоны IPv4 и IPv6. Если не указывать, # то предполагается, что это right/32, означающее, что right конец соединения идет # только к right участнику. # Поддерживает два волшебных сокращения vhost: и vnet:, которые могут перечислять # подсети в том же синтаксисе, что и virtual_private. # Значение %priv расширяется до сетей, указанных в virtual_private. # Значение %no означает отсутствие подсети. # При использовании vnet соединение создает экземпляр, позволяя использовать # несколько туннелей с разными подсетями. # Вышесказанное действительно и для leftsubnet. also=l2tp-psk-nonat # Значение является именем раздела, параметры которого добавляются так, как если бы # они являлись частью этого раздела. Указанный раздел должен существовать, следовать # за текущим и иметь один и тот же тип раздела. (Вложенность разрешена, может быть # более одного в одном разделе, хотя запрещается добавлять один и тот же раздел более # одного раза.) # Раздел содержит спецификацию определенного соединения, название произвольное, но в данном случае, # такое же как указанно в параметре also в разделе выше. conn l2tp-psk-nonat authby=secret # Как два шлюза безопасности должны аутентифицировать друг друга. # Допустимые значения являются "secret" для PSK и "rsasig" для цифровых подписей # RSA (по умолчанию). pfs=yes # Необходима ли полная секретность ключей (Perfect Forward Secrecy) на канале связи # соединения (при использовании PFS, проникновение протокола обмена ключами не # компрометирует ключи, согласованные ранее). # Допустимые значения: "yes"(по умолчанию) и "no". auto=add # Операция выполняемая автоматически при запуске IPsec. # Допустимые значения: # "add" (автоматическое добавление ipsec); # "route" (auto-route ipsec); # "start" (автоматическое обновление ipsec); # "ignore" (по умолчанию) (отсутствие автоматического запуска). keyingtries=1 # Сколько попыток (целое или %forever) должно быть принято для согласования # соединения (по умолчанию %forever). Значение "%forever" означает «никогда не # сдаваться» (может быть записано как "0"). rekey=no # Следует ли пересматривать соединение после истечения срока его действия. # Допустимые значения: "yes"(по умолчанию) и "no". ikelifetime=8h # Как долго должен сохраняться канал соединения (фраза: "ISAKMP SA") до # повторного обсуждения. Допустимые значения "1h"(по умолчанию)-1 час, # максимум "24h" - 24 часа. keylife=1h # То же, что и "salifetime". # Как долго должен длиться определенный экземпляр соединения, от успешных # переговоров до истечения срока действия. # Допустимые значения - целое число "s"(секунды) или десятичное число, # за которым следуют "m", "h" или "d"(минуты, часы или дни соответственно). # По умолчанию "8h", максимум "24h". type=transport # Тип соединения. Допустимые значения: # "tunnel"(по умолчанию) - туннель "host-to-host", "host-to-subnet" # или "subnet-to-subnet"; # "transport" - транспортный режим "host-to-host"; # "passthrough" - обработка IPsec вообще не требуется; # "drop" - пакеты должны быть отброшены; # "reject" - пакеты должны быть отброшены, а диагностический ICMP возвращен. left=77.77.77.77 # Внешний IP адрес сервера. leftprotoport=17/1701 # Разрешенные протоколы и порты. Может использоваться число или имя, которое будет # искаться в /etc/protocols, например, leftprotoport = icmp, или в виде # протокол/порт, например, tcp/smtp. Порты могут быть определены как число # (например, 25) или как имя (например, smtp), которое будет искать в # /etc/services. Специальное ключевое слово %any может использоваться для # разрешения всех портов определенного протокола. Чаще всего этот вариант # используется для соединений L2TP, разрешающих только пакеты l2tp (порт 1701 UDP), # например: leftprotoport = 17/1701. leftnexthop=%defaultroute # IP-адрес шлюза next-hop для подключения left участника к общедоступной сети; # По умолчанию используется значение "%direct" (имеется в виду right). # Если leftnexthop = %defaultroute и, указанные в секции config setup, # interfaces=%defaultroute, то для шлюза next-hop, будет использоваться адрес # интерфейса шлюза по умолчанию. right=%any rightprotoport=17/%any rightnexthop=%defaultroute dpddelay=60 # Интервал между keep-alive пакетами, в секундах (по умолчанию 30 секунд). # Если используется dpddelay, то необходимо, также, установить dpdtimeout. dpdtimeout=180 # Интервал времени бездействия, в секундах. По прошествии этого периода, если # не будет ответа и трафика, то будет считаться, что узел мертв и будет удален # SA (по умолчанию 120 секунд). Если используется dpdtimeout, то необходимо, # также, установить dpdaction. dpdaction=clear # Какие действия следует предпринять, когда узел объявлен мертвым. # "hold"(по умолчанию) - eroute будет переведен в состояние %hold, # "clear" - eroute и SA будут очищены. # "restart" - SA будет немедленно перезаключен. # "restart_by_peer" - все SA для мертвого узла будут пересмотрены. aggrmode=no # Использовать Агрессивный режим вместо основного режима. # Агрессивный режим менее безопасен и уязвим для атак типа «отказ в обслуживании». # Он также уязвим для атак с использованием таких программ, как ikecrack. # Он не должен использоваться, и его особенно не следует использовать с XAUTH и # групповыми секретами (PSK).
Создаем файл /etc/ipsec.secrets
# На самом деле вариантов много, см. "man ipsec.secrets", # но в нашей реализации, это, примерно, следующее: # где_ждать от_кого": ЧТО_ждать "Пароль или ключ" 77.77.77.77 %any : PSK "my_super_password"
Подправим iptables добавив в соответствующие цепочки следующее:
L2TP_IFACE="ppp+" IPTABLES="/usr/sbin/iptables" # l2tp/ipsec INPUT $IPTABLES -A INPUT -p udp --dport 1701 -j ACCEPT $IPTABLES -A INPUT -p udp --dport 500 -j ACCEPT $IPTABLES -A INPUT -p udp --dport 4500 -j ACCEPT $IPTABLES -A INPUT -i $L2TP_IFACE -j ACCEPT # l2tp/ipsec FORWARD $IPTABLES -A FORWARD -i $L2TP_IFACE -j ACCEPT # l2tp/ipsec OUTPUT $IPTABLES -A OUTPUT -p udp --sport 500 -j ACCEPT $IPTABLES -A OUTPUT -p udp --sport 4500 -j ACCEPT $IPTABLES -A OUTPUT -p udp --sport 1701 -j ACCEPT
Создадим файл /etc/sysctl.conf
net.ipv4.ip_forward = 1 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.icmp_ignore_bogus_error_responses = 1
Применим параметры ядра без перезагрузки.
# sysctl -p
Запустим IPSec и проверим работоспособность.
# /etc/rc.d/rc.ipsec start ipsec_setup: Starting Openswan IPsec U2.6.49.1/K4.4.38... # ipsec verify Checking if IPsec got installed and started correctly: Version check and ipsec on-path [OK] Openswan U2.6.49/K4.4.38 (netkey) See `ipsec --copyright' for copyright information. Checking for IPsec support in kernel [OK] NETKEY: Testing XFRM related proc values ICMP default/send_redirects [OK] ICMP default/accept_redirects [OK] XFRM larval drop [OK] Hardware random device check [N/A] Two or more interfaces found, checking IP forwarding [OK] Checking rp_filter [OK] Checking that pluto is running [OK] Pluto listening for IKE on udp 500 [OK] Pluto listening for IKE on tcp 500 [NOT IMPLEMENTED] Pluto listening for IKE/NAT-T on udp 4500 [OK] Pluto listening for IKE/NAT-T on tcp 4500 [NOT IMPLEMENTED] Pluto listening for IKE on tcp 10000 (cisco) [NOT IMPLEMENTED] Checking NAT and MASQUERADEing [TEST INCOMPLETE] Checking 'ip' command [OK] Checking 'iptables' command [OK]
Смотрим /var/log/syslog, видим что-то подобное:
ipsec_setup: ...Openswan IPsec started ipsec__plutorun: adjusting ipsec.d to /etc/ipsec.d pluto: adjusting ipsec.d to /etc/ipsec.d ipsec__plutorun: Labelled IPsec not enabled; value 32001 ignored. pluto: Labelled IPsec not enabled; value 32001 ignored. ipsec__plutorun: 002 adding connection: "l2tp-psk-nat" ipsec__plutorun: 002 adding connection: "l2tp-psk-nonat" ipsec__plutorun: 002 listening for IKE messages ipsec__plutorun: 002 adding interface eth0/eth0 192.168.3.250:500 (AF_INET) ipsec__plutorun: 002 adding interface eth0/eth0 192.168.3.250:4500 ipsec__plutorun: 002 adding interface eth1/eth1 77.77.77.77:500 (AF_INET) ipsec__plutorun: 002 adding interface eth1/eth1 77.77.77.77:4500 ipsec__plutorun: 002 adding interface lo/lo 127.0.0.1:500 (AF_INET) ipsec__plutorun: 002 adding interface lo/lo 127.0.0.1:4500 ipsec__plutorun: 002 adding interface lo/lo ::1:500 (AF_INET6) ipsec__plutorun: 002 loading secrets from "/etc/ipsec.secrets"
IPSec готов, останавливаем.
# /etc/rc.d/rc.ipsec stop ipsec_setup: Stopping Openswan IPsec...
Переходим к настройке L2TP.
L2TP
Редактируем /etc/xl2tpd/xl2tpd.conf
[global] ; IP-адрес интерфейса на котором слушает демон. По умолчанию 0.0.0.0, означающее то, что он прослушивает все интерфейсы. listen-addr = 77.77.77.77 ; Использовать отслеживание IPsec Security Association. Допустимые значения "yes" или "no"(по умолчанию). ; Если разрешено, то пакеты, полученные xl2tpd, должны иметь дополнительные поля (refme и refhim), которые позволяют ; отслеживать несколько клиентов с использованием одного и того же внутреннего NAT-адреса или за одним и тем же ; маршрутизатором NAT. Должно поддерживаться ядром. В настоящее время работает только с Openswan KLIPS в режиме "mast". ipsec saref = no [lns default] ; Диапазон ip адресов, из которого клиентам при подключении будет назначен IP-адрес. ip range = 192.168.3.50-192.168.3.150 ; Адрес локального интерфейса VPN. local ip = 192.168.3.251 ; Требовать от удаленного узла производить аутентификацию по протоколу CHAP. require chap = yes ; Запретить удаленному узлу производить аутентификацию по протоколу PAP. refuse pap = yes ; Требовать от удаленного узла аутентификацию require authentication = yes ; Запретить отладку pppd ppp debug = no ; Путь к файлу в котором содержатся параметры конфигурации pppd. pppoptfile = /etc/ppp/options.xl2tpd ; Использовать бит длины, указывающий полезную нагрузку пакета l2tp. length bit = yes
Теперь отредактируем файл /etc/ppp/options.xl2tpd
# Принимать предложение удаленного узла о нашем локальном IP адресе, даже если локальный IP адрес был указан в опциях. ipcp-accept-local # Принимать предложение от удаленного узла о его IP-адресе, даже если удаленный IP адрес был указан в опциях. ipcp-accept-remote # Разрешить аутентификацию по протоколу — MS CHAP v2. require-mschap-v2 # Разрешить аутентификацию по протоколу — MS CHAP. require-mschap # Разрешить аутентификацию по протоколу — CHAP. require-chap # Запретить аутентификацию по протоколу — PAP refuse-pap # Первичный DNS сервера для L2TP-клиентов. ms-dns 192.168.3.250 # Вторичный DNS сервера для L2TP-клиентов. ms-dns 8.8.8.8 # async карта символов - 32-bit hex; каждый бит - символ, который надо представить в виде escape-последовательности, # чтобы pppd мог его принять. 0x00000001 - это маска для '\x01', а 0x80000000 - маска для '\x1f'. asyncmap 0 # Отключить согласование протокола управления сжатием (Compression Control Protocol). noccp # Требование для удаленной стороны назвать себя перед тем как начнется обмен пакетами. auth # Использовать аппаратное управление потоком данных (напр., RTS/CTS) crtscts # Использовать lock в стиле UUCP на последовательное устройство, чтобы исключить одновременный доступ к устройству lock # При протоколировании содержимого пакетов PAP исключить строку пароля из журнала. hide-password # Использовать линии управления модемом. modem # Имя локальной системы для целей аутентификации. name l2tpd # Отправлять кадр LCP echo-request удаленной стороне каждое указанное количество секунд. # Под Linux, echo-request отправляется тогда, когда пакеты не принимаются от удаленной стороны указанное количество секунд. # Обычно удаленная сторона должна отвечать на echo-request отправкой echo-reply. lcp-echo-interval 30 # Завершить связь, если указанное количество LCP echo-requests отправлены без приема правильных LCP echo-reply. # Требует ненулевого значения для параметра lcp-echo-interval. lcp-echo-failure 4 # Отключиться, если соединение простаивает в течение указанных секунд. idle 1800 # Значение MTU [Maximum Transmit Unit]. mtu 1400 # Значение MRU [Maximum Receive Unit]. mru 1400 # Добавить запись в таблицу ARP [Address Resolution Protocol] этой системы с IP-адресом удаленного узла и Ethernet-адресом # этой системы. Чтобы удаленный узел появился в локальной сети. proxyarp
Отредактируем файл /etc/ppp/chap-secrets, внесём сюда логин, пароль и жёстко присвоим IP-адрес при подключении отдельно для каждого пользователя.
# Secrets for authentication using CHAP # client server secret IP addresses user1 * password-1 192.168.3.50 user2 * password-2 192.168.3.51 user3 * password-3 192.168.3.52
Создадим файл /etc/rc.d/rc.xl2tpd
#!/bin/sh # # xl2tpd This shell script takes care of starting and stopping l2tpd. # # description: Layer 2 Tunnelling Protocol Daemon (RFC 2661) # CONFIG_FILE=/etc/xl2tpd/xl2tpd.conf DAEMON=xl2tpd [ -x /usr/sbin/$DAEMON ] || exit 0 RETVAL=0 start() { echo -n "Starting $DAEMON : " if [ ! -d /var/run/xl2tpd ] then mkdir /var/run/xl2tpd fi /usr/sbin/$DAEMON -c $CONFIG_FILE & RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$DAEMON echo "" return $RETVAL } stop() { echo -n "Stopping $DAEMON " kill -9 `cat /var/run/xl2tpd.pid` RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$DAEMON return $RETVAL } restart() { stop start } status() { PID=`ps ax | awk '{if (match($5, ".*/xl2tpd$") || $5 == "xl2tpd") print $1}'` if test "$PID" != ""; then echo "xl2tpd is running." else echo "xl2tpd is not running." fi } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status ;; restart|reload) restart ;; condrestart) [ -f /var/lock/subsys/$DAEMON ] && restart || : ;; *) echo "Usage: $DAEMON {start|stop|status|restart|reload|condrestart}" exit 1 esac
Сделаем этот файл исполняемым.
# chmod +x /etc/rc.d/rc.xl2tpd
Всё готово! Запускаем IPSec и L2TP.
# /etc/rc.d/rc.ipsec start ipsec_setup: Starting Openswan IPsec U2.6.49.1/K4.4.38... # /etc/rc.d/rc.xl2tpd start Starting xl2tpd : # /etc/rc.d/rc.ipsec status IPsec running - pluto pid: 28314 pluto pid 28314 No tunnels up # /etc/rc.d/rc.xl2tpd status xl2tpd is running.
Для автозапуска после перезагрузки пропишем в /etc/rc.d/rc.local
# L2TP/IPSEC /etc/rc.d/rc.ipsec start /etc/rc.d/rc.xl2tpd start
Клиенты
Покажу настройку Linux-клиентов для подключения к нескольким L2TP/IPSec серверам, настроенным по текущей статье. Конфигурационные файлы будут без комментариев к параметрам, так как, большинство из них описано при настройки сервера, остальные в «man xl2tpd.conf» и «man ipsec.conf».
В Windows, думаю, и так понятно как подключаться к нескольким серверам. Поэтому, для Windows-клиентов покажу пример для одного подключения, а так же, что делать при возникновении ошибок подключения.
Для примера буду использовать:
77.77.77.77 (vpn.mydom.ru)
88.88.88.88 (vpn.yourdom.ru) - сервер за NAT'ом, внутренний IP-адрес - 10.0.0.250
Linux
Версия, разрядность и битность Slackware Linux не имеет значения. Проверялось на версиях 14.1 и 14.2, как 32, так и 64 битных. В примере будет использоваться Slackware Linux 14.1 32-bit с ядром 3.10.104.
Берем openswan_slackbuild.tar.gz, распаковываем и в этот же каталог скачиваем последнюю версию openswan, на сегодня это - 2.6.49.1
# wget https://download.openswan.org/openswan/openswan-2.6.49.1.tar.gz
правим openswan.SlackBuild в части версии и запускаем его. По окончании сборки устанавливаем полученный пакет.
# upgradepkg --install-new /tmp/openswan-2.6.49.1-i486-1_SBo.tgz Package openswan-2.6.49.1-i486-1_SBo.tgz installed.
Берем xl2tpd_slackbuild.tar.gz, распаковываем и в этот же каталог скачиваем последнюю версию xl2tpd, на сегодня это - 1.3.8, переименовав под требуемый slackbuild'ом шаблон.
# wget -O xl2tpd-1.3.8.tar.gz https://github.com/xelerance/xl2tpd/archive/v1.3.8.tar.gz
Правим xl2tpd.SlackBuild в части версии и запускаем его. По окончании сборки устанавливаем полученный пакет.
# upgradepkg --install-new /tmp/xl2tpd-1.3.8-i486-1_SBo.tgz Package xl2tpd-1.3.8-i486-1_SBo.tgz installed.
Переходим к настройке IPSec.
IPSec
Редактируем файл /etc/ipsec.conf, отступы в начале строк параметров, обязательны.
version 2.0 config setup plutodebug=all # Эти два параметра можно убрать после завершения отладки plutostderrlog=/var/log/openswan.log # и стабильной работы IPSec nat_traversal=yes protostack=netkey conn mydom-vpn authby=secret pfs=yes keyingtries=3 rekey=yes type=transport left=%defaultroute leftnexthop=%defaultroute leftprotoport=17/1701 right=77.77.77.77 rightid="vpn.mydom.ru" # Можно указать IP-адрес, можно вообще не указывать, если сервер не за NAT'ом rightprotoport=17/1701 auto=add conn yourdom-vpn # Сервер за NAT'ом authby=secret pfs=yes keyingtries=3 rekey=yes type=transport left=%defaultroute leftnexthop=%defaultroute leftprotoport=17/1701 right=88.88.88.88 rightid="10.0.0.250" rightprotoport=17/1701 auto=add