IPIP IPsec VPN туннель между Linux машиной и Mikrotik за NAT провайдера

Linux: Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)

  • Eth0 1.1.1.1/32 внешний IP
  • ipip-ipsec0 192.168.0.1/30 будет наш туннель

Miktoik: CCR 1009, RouterOS 6.46.5

  • Eth0 10.0.0.2/30 внутренний IP от провайдера. Внешний IP NAT провайдера динамический.
  • ipip-ipsec0 192.168.0.2/30 будет наш туннель

IPsec туннель на Linux машине будем поднимать с помощью racoon. Не буду описывать подробности, есть хорошая статья у vvpoloskin.

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

sudo install racoon ipsec-tools

Настраиваем racoon, он условно будет выступать в роли ipsec сервера. Так как mikrotik в main режиме не может передавать дополнительный идентификатор клиента, а внешний ip адрес через который он коннектится к Linux динамический, использовать preshared key (авторизацию по паролю) не получится, так как пароль должен сопоставляться либо с ip адресом подключающегося хоста, либо с идентификатором.

Будем использовать авторизацию по RSA ключам.

Демон racoon использует ключи в формате RSA, а mikrotik — в формате PEM. Если генерировать ключи утилитой plainrsa-gen идущей вместе с racoon, то конвертировать публичный ключ для Mikrotika в формат PEM с ее помощью не получится — она конвертирует только в одну сторону: PEM в RSA. Сгенерированный plainrsa-gen ключ не смогли прочитать ни openssl, ни ssh-keygen, поэтому с их помощью также не получится выполнить конвертацию.

Мы сгенерируем PEM ключ с помощью openssl, а затем конвертируем его для racoon с помощью plainrsa-gen:

#  Генерируем ключ
openssl genrsa -out server-name.pem 1024
# Извлекаем публичный ключ
openssl rsa -in server-name.pem -pubout > server-name.pub.pem
# Конвертируем
plainrsa-gen -i server-name.pem -f server-name.privet.key
plainrsa-gen -i server-name.pub.pem -f server-name.pub.key

Полученные ключи положим в папку: /etc/racoon/certs/server. Не забываем установить владельцем пользователя, от чьего имени запускается демон racoon (обычно root), права 600.

Настройку mikrotik опишу при подключении через WinBox.

Ключ server-name.pub.pem загрузим в mikrotik: Меню «Files» — «Upload».

Открываем раздел «IP» — «IP sec» — вкладка «Keys». Теперь генерируем ключи — кнопка «Generate Key», затем экспортируем публичный ключ mikrotika «Expor Pub. Key», скачать его можно из раздела «Files», правой кнопкой по файлу — «Download».

Импортируем публичный ключ racoon, «Import», в выпадающем списке поля «File name» ищем загруженный ранее нами server-name.pub.pem.

Публичный ключ mikrotik нужно сконвертировать

plainrsa-gen -i mikrotik.pub.pem -f mikrotik.pub.key

и положить в папку /etc/racoon/certs не забыв про владельца и права.

Конфиг racoon с комментариями: /etc/racoon/racoon.conf

log info; # Уровень логирования, при отладке используем Debug или Debug2.

listen {

    isakmp 1.1.1.1 [500]; # Адрес и порт, на котором будет слушать демон.
    isakmp_natt 1.1.1.1 [4500]; # Адрес и порт, на котором будет слушать демон для клиентов за NAT.
    strict_address; # Выполнять обязательную проверку привязки к указанным выше IP.
}

path certificate "/etc/racoon/certs"; # Путь до папки с сертификатами.

remote anonymous { # Секция, задающая параметры для работы демона с ISAKMP и согласования режимов с подключающимися хостами. Так как IP, с которого подключается Mikrotik, динамический, то используем anonymous, что разрешает подключение с любого адреса. Если IP у хостов статический, то можно указать конкретный адрес и порт.

    passive on; # Задает "серверный" режим работы демона, он не будет пытаться инициировать подключения.
    nat_traversal on; # Включает использование режима NAT-T для клиентов, если они за NAT. 
    exchange_mode main; # Режим обмена параметрами подключения, в данном случае ---согласование.
    my_identifier address 1.1.1.1; # Идентифицируем наш linux хост по его ip адресу.
    certificate_type plain_rsa "server/server-name.priv.key"; # Приватный ключ сервера.
    peers_certfile plain_rsa "mikrotik.pub.key"; # Публичный ключ Mikrotik.

    proposal_check claim; # Режим согласования параметров ISAKMP туннеля. Racoon будет использовать значения подключающегося хоста (инициатора) для срока действия сессии                   и длины ключа, если его срок действия сессии больше, или длина его ключа короче, чем у инициатора. Если срок действия сессии короче, чем у инициатора, racoon использует собственное значение срока действия сессии и будет отправлять сообщение RESPONDER-LIFETIME.
    proposal { # Параметры ISAKMP туннеля.

        encryption_algorithm aes; # Метод шифрования ISAKMP туннеля.
        hash_algorithm sha512; # Алгоритм хеширования, используемый для ISAKMP туннеля.
        authentication_method rsasig; # Режим аутентификации для ISAKMP туннеля - по RSA ключам.
        dh_group modp2048; # Длина ключа для алгоритма Диффи-Хеллмана при согласовании ISAKMP туннеля.
        lifetime time 86400 sec; Время действия сессии.
    }

    generate_policy on; # Автоматическое создание ESP туннелей из запроса, пришедшего от подключающегося хоста.
}

sainfo anonymous { # Параметры ESP туннелей, anonymous - указанные параметры будут использованы как параметры по умолчанию. Для разных клиентов, портов, протоколов можно              задавать разные параметры, сопоставление происходит по ip адресам, портам, протоколам.

    pfs_group modp2048; # Длина ключа для алгоритма Диффи-Хеллмана для ESP туннелей.
    lifetime time 28800 sec; # Срок действия ESP туннелей.
    encryption_algorithm aes; # Метод шифрования ESP туннелей.
    authentication_algorithm hmac_sha512; # Алгоритм хеширования, используемый для аутентификации ESP туннелей.
    compression_algorithm deflate; # Сжимать передаваемые данные, алгоритм сжатия предлагается только один.
}

Конфиг mikrotik

Возвращаемся в раздел "IP" — "IPsec"

Вкладка "Profiles"
Параметр
Значение

Name
На ваше усмотрение (по умолчанию default)

Hash Algorithm
sha512

Encryption Algorithm
aes-128

DH-Group
modp2048

Proposhal_check
claim

Lifetime
1d 00:00:00

NAT Traversal
true (ставим галочку)

DPD
120

DPD Maximum failure
5

Вкладка "Peers"
Параметр
Значение

Name
На ваше усмотрение (далее MyPeer)

Address
1.1.1.1 (IP linux машины)

Local Address
10.0.0.2 (IP WAN интерфейса mikrotik)

Profile
default

Exchange Mode
main

Passive
false

Send INITIAL_CONTACT
true

Вкладка "Proposal"
Параметр
Значение

Name
На ваше усмотрение (далее MyPeerProposal)

Auth. Algorithms
sha512

Encr. Algorithms
aes-128-cbc

Lifetime
08:00:00

PFS Group
modp2048

Вкладка "Identities"
Параметр
Значение

Peer
MyPeer

Atuh. Method
rsa key

Key
mikrotik.privet.key

Remote Key
server-name.pub.pem

Policy Tamplate Group
default

Notrack Chain
пусто

My ID Type
auto

Remote ID Type
auto

Match By
remote id

Mode Configuration
пусто

Generate Policy
no

Вкладка "Policies — General"
Параметр
Значение

Peer
MyPeer

Tunnel
true

Src. Address
192.168.0.0/30

Dest. Address
192.168.0.0/30

Protocol
255 (all)

Template
false

Вкладка "Policies — Action"
Параметр
Значение

Action
encrypt

Level
requier

IPsec Protocols
esp

Proposal
MyPeerProposal

Скорее всего у вас, как и у меня, на WAN интерфейсе настроен snat/masquerade, это правило надо скорректировать, чтобы исходящие пакеты ipsec уходили в наш туннель:
Переходим в раздел "IP" — "Firewall".
Вкладка "NAT", открываем наше правило snat/masquerade.

Вкладка "Advanced"
Параметр
Значение

IPsec Policy
out: none

Рестартуем демона racoon

sudo systemctl restart racoon

Если при рестарте racoon не запускается, значит в конфиге имеется ошибка, в syslog racoon выводит информацию о номере строки, в которой обнаружена ошибка.

Демон racoon при загрузке ОС стартует раньше поднятия сетевых интерфейсов, а мы указали в секции listen опцию strict_address, необходимо добавить в файл systemd юнита racoon
/lib/systemd/system/racoon.service, в секцию [Unit], строку After=network.target.

Сейчас наши ipsec туннели должны подняться, смотрим вывод:

sudo ip xfrm policy

src 192.168.255.0/30 dst 192.168.255.0/30 
    dir out priority 2147483648 
    tmpl src 1.1.1.1 dst "IP NAT через который подключается mikrotik"
        proto esp reqid 0 mode tunnel
src 192.168.255.0/30 dst 192.168.255.0/30 
    dir fwd priority 2147483648 
    tmpl src "IP NAT через который подключается mikrotik" dst 1.1.1.1
        proto esp reqid 0 mode tunnel
src 192.168.255.0/30 dst 192.168.255.0/30 
    dir in priority 2147483648 
    tmpl src "IP NAT через который подключается mikrotik" dst 1.1.1.1
        proto esp reqid 0 mode tunnel

Если туннели не поднялись, смотрите syslog, либо journalctl -u racoon.

Теперь необходимо настроить L3 интерфейсы, чтобы можно было маршрутизировать трафик. Есть разные варианты, мы будем использовать IPIP, так как его mikrotik поддерживает, я бы использовал vti, но, к сожалению, в mikrotik его до сих пор не реализовали. От IPIP он отличается тем, что дополнительно может инкапсулировать multicast и ставить метки (fwmark) на пакеты, по которым можно их фильтровать в iptables и iproute2 (policy-based routing). Если нужна максимальная функциональность — тогда, например, GRE. Но не стоит забывать, что за дополнительную функциональность платим большим оверхедом.

Перевод неплохого обзора туннельных интерфейсов можно посмотреть тут.

На Linux:

# Создаем интерфейс
sudo ip tunnel add ipip-ipsec0 local 192.168.255.1 remote 192.168.255.2 mode ipip
# Активируем
sudo ip link set ipip-ipsec0 up
# Назначаем адрес
sudo ip addr add 192.168.255.1/30 dev ipip-ipsec0

Теперь можно добавить маршруты для сетей за mikrotik

sudo ip route add A.B.C.D/Prefix via 192.168.255.2

Чтобы наш интерфейс и маршруты поднимались после перезагрузки, нужно описать интерфейс в /etc/network/interfaces и там же в post-up добавлять маршруты, либо прописать все в одном файле, например, /etc/ipip-ipsec0.conf и дергать его через post-up, не забудьте про владельца файла, права и сделать его исполняемым.

Под катом пример файла

#!/bin/bash
ip tunnel add ipip-ipsec0 local 192.168.255.1 remote 192.168.255.2 mode ipip
ip link set ipip-ipsec0 up
ip addr add 192.168.255.1/30 dev ipip-ipsec0

ip route add A.B.C.D/Prefix via 192.168.255.2

На Mikrotik:

Раздел «Interfaces», добавляем новый интерфейс «IP tunnel»:

Вкаладка «IP tunnel» — «General»
Параметр
Значение

Name
На ваше усмотрение (далее IPIP-IPsec0)

MTU
1480 (если не указывать, то mikrotik начинает резать mtu до 68)

Local Address
192.168.0.2

Remote Address
192.168.0.1

Ipsec Secret
Деактивируем поле (иначе будет создан новый Peer)

Keepalive
Деактивируем поле (иначе интерфейс будет постоянно выключаться, так как у mikrotika какой-то свой формат этих пакетов и с linux не работает)

DSCP
inherit

Dont Fragment
no

Clamp TCP MSS
true

Allow Fast Path
true

Раздел «IP» — «Addresses», добавляем адрес:

Параметр
Значение

Address
192.168.0.2/30

Interface
IPIP-IPsec0

Теперь можно добавлять маршруты в сети за linux машиной, при добавлении маршрута, gateway будет наш интерфейс IPIP-IPsec0.

PS

Так как наш сервер linux является транзитным, то на нем имеет смысл задать параметр Clamp TCP MSS для ipip интерфейсов:

создаем файл /etc/iptables.conf со следующим содержимым:

*mangle
-A POSTROUTING -o ipip+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT

и в /etc/network/interfaces
post-up iptables-restore < /etc/iptables.conf

В сети за mikrotik у меня работает nginx (ip 10.10.10.1), делаем доступным его из интернета, добавим в /etc/iptables.conf:

*nat
-A PREROUTING -d 1.1.1.1/32 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 10.10.10.1
#На mikrotik, в таблице mangle, надо добавить правило route с назначением 192.168.0.1 для пакетов с адресом источника 10.10.10.1 и портов 80, 443.

# Так же на linux работает OpenVPN сервер 172.16.0.1/24, для клиентов которые используют подключение к нему в качестве шлюза даем доступ в интернет
-A POSTROUTING -s 172.16.0.0/24 -o eth0 -j SNAT --to-source 1.1.1.1
COMMIT 

Не забывайте добавить соответствующие разрешения в iptables, если у вас включены фильтры пакетов.

Будьте здоровы!

Источник: habr.com

Добавить комментарий