Настройка MikroTik в качестве OVPN-сервера с использованием клиентских сертификатов и списка отзыва

Передо мной возникла задача настроить MikroTik в качестве OVPN сервера с использованием клиентских сертификатов и возможностью их отзыва. В интернетах на данную тему чёткого How-To я не нашёл, поэтому решил изобрести свой собственный велосипед. В этой статье я опишу схему настройки данного чуда, получившуюся и работающую у меня.

Использование PKI ROS


Касательно PKI есть два варианта:

1. С использованием встроенного в ROS PKI:

  • + можем выдавать и отзывать сертификаты непосредственно на микротике, иначе нам придётся после каждого отзыва вручную обновлять crl на нём
  • — случайное удаление с микротика CA-сертификата, используемого для подписи и отзыва сертификатов — фатально, импорт ранее выгруженных сертификата и ключа CA не поможет, а дальнейшее использование будет возможно только с использованием openssl и ручной загрузкой crl после каждого отзыва (конечно, если у вас есть актуальный бэкап всего этого)
  • + если мы бэкапим весь конфиг микротика, то вместе с ним бэкапится и CA

2. С использованием стороннего PKI — openssl, или windows server PKI (НЕ используйте доверенные CA типа StartSSL, они выдают клиентские сертификаты не только вам):

  • + защищены от недостатка первого варианта
  • — в случае openssl необходимо вручную загружать crl на микротик после каждого отозванного сертификата
  • + в случае windows server PKI теоретически можно реализовать проверку подлинности через механизм SCEP, но пока не проверял
  • — в случае windows server PKI нужен домен, без него этот самый PKI работать не будет

Я буду рассматривать только первый вариант, т.к., во-первых, он мне подходит, во-вторых, он более гибкий. Так же я не буду подробно останавливаться на параметрах сертификатов и прочих разных параметрах стандартных инструментов ROS, т.к. их исчерпывающее описание есть на официальной MikroTik Wiki.

Настраиваем OVPN-сервер на ROS


1. Настройка PKI

1.1. Сертификат CA:

/certificate add name=template-CA country="" state="" locality="" organization="" unit="" common-name="test-CA" key-size=4096 days-valid=3650 key-usage=crl-sign,key-cert-sign


/certificate sign template-CA ca-crl-host=127.0.0.1 name="test-CA"


Примечание: ca-crl-host= — обязательный параметр, иначе список отзыва не будет создан; полный путь к списку отзыва будет указан в параметрах сертификата, графа "[1]Точка распределения списка отзыва (CRL)"; в принципе, можно указать любой из ip-адресов нашего микротика, тот что укажем — и будет прописан в сертификате. Доменные имена параметром не поддерживаются, к сожалению.

1.2. Сертификат сервера:

/certificate add name=template-SRV country="" state="" locality="" organization="" unit="" common-name="test-srv-OVPN" key-size=4096 days-valid=1095 key-usage=digital-signature,key-encipherment,tls-server


/certificate sign template-SRV ca="test-CA" name="test-srv-OVPN"


Примечание: для сертификата сервера key-usage лучше не менять, почему так — описано здесь (а если очень хотим поменять — то там же написано что нужно прописать в конфиге клиента для этого).

Примечание: в отличие от SSTP — OVPN не проверяет соответствие common-name сертификата сервера fqdn'у этого сервера.

1.3. Шаблон для сертификатов клиентов:

/certificate add name=template-CL country="" state="" locality="" organization="" unit="" common-name="test-client-ovpn-template" key-size=4096 days-valid=365 key-usage=tls-client


1.3.1 Сертификат первого клиента:

/certificate add name=template-CL-to-issue copy-from="template-CL" common-name="test-client-ovpn-1"


/certificate sign template-CL-to-issue ca="test-CA" name="test-client-ovpn-1"


1.3.2. Сертификат второго и последующих клиентов:

См. п. 3.1, но меняем значение параметров.

common-name="test-client-ovpn-1"


Для первой команды, это значение должно быть уникальным в пределах одного CA.

name="test-client-ovpn-1"

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

1.4 В будущем, для отзыва сертификатов используем команду:

certificate issued-revoke %cert-name%


Где %cert-name% — поле name= подписанного сертификата, то есть отображаемое PKI микротика.

2. Настройка OVPN сервера


Примечание: можно настроить в режиме tun («ip» в ROS), а можно в режиме tap («ethernet» в ROS). Режим tun — обычный туннель. Режим tap — эмуляция полноценного ethernet, в частности в режиме tap клиентов можно объединить в режим моста и они будут прекрасно друг друга видеть. В теории в режиме tap можно запустить DHCP-сервер, но в текущей версии ROS это не реализовано.

2tun. Режим tun


2tun.1. Задаём пул адресов для OVPN-клиентов (можно задать непосредственно в PPP-profile):

/ip pool add name=OVPN_srv_pool ranges=192.168.100.2-192.168.254


2tun.2. Создаём PPP-profile для OVPN-сервера:

/ppp profile add name=OVPN_server local-address=192.168.100.1 remote-address=OVPN_srv_pool


Опционально! Остальные параметры по вашему вкусу и в соответствии с вашими целями. Например: dns=192.168.100.1 use-ipv6=no

2tun.3. Настраиваем режим аутентификации пользователей:

/ppp aaa set accounting=yes


2tun.4. Добавляем пользователей:

/ppp secret add name=test-user-1 password=P@ssword1 service=ovpn profile=OVPN_server


/ppp secret add name=test-user-2 password=P@ssword2 service=ovpn profile=OVPN_server


2tun.5. Включаем OVPN-сервер:

/interface ovpn-server server set auth=sha1 cipher=blowfish128 default-profile=OVPN_server mode=ip netmask=24 require-client-certificate=yes certificate=test-srv-OVPN enabled=yes


2tap. Режим tap


2tap.1. Задаём пул адресов для OVPN-клиентов (можно задать непосредственно в PPP-profile):

/ip pool add name=OVPN_srv_pool ranges=192.168.100.2-192.168.254


2tap.1+. Создаём мост для OVPN-подключений:

/interface bridge add name=OVPN_bridge arp=enabled


Примечание: IP для моста назначать совершенно не обязательно, он и так имеется в PPP-profile (кроме того если указать адрес для моста, но не указать local-address= в PPP-profile, то клиент не подключится).

Примечание: arp должен быть включён, иначе клиенты друг-друга не увидят.

2tun.2. Создаём PPP-profile для OVPN-сервера:

/ppp profile add name=OVPN_server local-address=192.168.100.1 remote-address=OVPN_srv_pool bridge=OVPN_bridge


Опционально! Остальные параметры по вашему вкусу и в соответствии с вашими целями. Например: dns=192.168.100.1 use-ipv6=no

2tap.3. Настраиваем режим аутентификации пользователей:

/ppp aaa set accounting=yes


2tap.4. Добавляем пользователей:

/ppp secret add name=test-user-1 password=P@ssword1 service=ovpn profile=OVPN_server


/ppp secret add name=test-user-2 password=P@ssword2 service=ovpn profile=OVPN_server


2tap.5. Включаем OVPN-сервер:

/interface ovpn-server server set auth=sha1 cipher=blowfish128 default-profile=OVPN_server mode=ethernet netmask=24 require-client-certificate=yes certificate=test-srv-OVPN enabled=yes


Примечания для обоих режимов:

1. Наличие пользователя является обязательным, даже не смотря на авторизацию по сертификатам; можно создать одного пользователя на всех клиентов и прописать один и тот же логин/пароль в конфигах клиентов, но это лишает возможности отследить подключение и действия конкретного пользователя — неудобно, несколько небезопасно.

2. RADIUS-аутентификацию я не рассматриваю просто потому, что не тестировал. Могу лишь предположить, что работать она будет только для username/password, а сертификаты будут всё так же проверяться на микротике.

3. Следите за тем, что бы пул адресов соответствовал подсети, указываемой в настройках OVPN-сервера. ROS'овский OVPN-сервер не будет разбираться принадлежат ли одной сети local-address= сервера и назначаемый из пула адрес клиента, более того, если, к примеру, использовать маску 29, а в качестве пула прописать ranges=192.168.100.0/29, клиенту может быть в лёгкую назначен броадкастовый 192.168.100.7, как это было у меня. Точно такая же ситуация может возникнуть, если указанный пул больше, чем подразумевает маска — только проблема выявится не сразу, а чуть погодя.

3. Экспорт сертификатов для настройки клиентов


3.1. Экспорт сертификата CA:

/certificate export-certificate test-CA export-passphrase=""


Примечание: Нам нужен только сам сертификат, закрытый ключ НЕ нужен, поэтому параметр export-passphrase="" должен быть пустым.

3.2. Экспорт сертификатов клиентов:

/certificate export-certificate test-client-ovpn-1 export-passphrase=private-key-password1


/certificate export-certificate test-client-ovpn-2 export-passphrase=private-key-password2


Примечание: export-passphrase= — обязательный параметр для экспорта закрытых ключей; используем для каждого клиента свой пароль; НЕ используем тот же самый пароль, который указывали в пунктах 2.4 для пользователей!

3.3. Извлекаем полученные файлы сертификатов и ключей из микротика любым удобным способом (как правило, я таскаю туда-сюда файлы прямо из винбокса).

Настройка Windows-клиента


1. Получаем OVPN-дистрибутив с openvpn.net.
2. Устанавливаем, все опции оставляем по-умолчанию, в том числе tap-интерфейс, который понадобится для любого режима настройки.
3. Идём в OpenVPN\config (по-умолчанию C:\Program Files\OpenVPN\config) и создаём там файл client.ovpn (или копируем из OpenVPN\sample-config).
4. Создаём конфигурацию клиента, или вносим правки с sample-config.

Содержимое client.ovpn с небольшими комментариями
# Режим, в котором работает OVPN сервис
client

# Внимание! Указываем только один параметр из двух
# Для режима tup указываем параметр
dev tun
# Для режима tap указываем параметр
dev tap

# Этот параметр указываем только в случае использования режима tap, а вместо MyTap подставляем имя tap интерфейса в windows (ipconfig /all, или сетевые подключения в панели управления)
dev-node MyTap

# Используемый протокол. ROS'овский OVPN-сервер работает только в режиме tcp
proto tcp

# Адрес сервера, к которому будем подключаться, и порт. Вместо ovpn.my.domain — dns-имя или же ip-адрес. Можно указать несколько серверов.
remote ovpn.my.domain 1194
;remote my-server-2 1194


# Этот параметр нужен только в случае использования более чем одного сервера; При указании этого параметра при подключении клиент случайном образом выбирает один из указанных серверов
;remote-random

# Тайм аут между попытками определить ip-адрес по указанному DNS-имени сервера, в секундах (или бесконечность — infinite)
resolv-retry infinite

# Если указан этот параметр, то клиент будет использовать динамический исходящий порт для подключения
nobind

# Разрешают клиенту сохранять настройки туннеля при переподключении, а так же не перечитывать файлы ключей
persist-key
persist-tun


# Настройки прокси
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]


# Отключает сообщения о повторяющихся пакетах
;mute-replay-warnings

# Пути к файлам сертификатов
# ca — сертификат CA, которым выданы сертификат клиента И сертификат сервера
# cert — сертификат клиента
# key — закрытый ключ сертификата клиента
ca cert_export_test-CA.crt
cert cert_export_test-client-ovpn-1.crt
key cert_export_test-client-ovpn-1.key


# auth-user-pass сообщает клиенту, что он должен использовать имя пользователя и пароль для аутентификации (но не вместо сертификатов, а вместе с сертификатами)
# auth-user-pass говорит OVPN-клиенту использовать логин и пароль (но не вместо сертификатов, а вместе с сертификатами)
# user-pwd.txt указывает на файл, в котором хранятся логин и пароль; первая строка в файле — логин, вторая — пароль; при отсутствии этого аргумента логин и пароль будут запрашиваться каждый раз при подключении
# Примечание: В случае использования сертификата с закрытым ключом, к которому и так нужно вводить ключ при каждом подключении, я не считаю необходимым заставлять пользователя помнить ещё и логин с паролем
--auth-user-pass user-pwd.txt

# Сообщает клиенту, что он должен проверять сертификат сервера на предмет правильности используемых key-usage
remote-cert-tls server

# Ключ для шифрования начала процесса аутентификации (handshake), дополнительная мера безопасности. Имеет смысл при использовании только логина/пароля, без сертификатов.
;tls-auth ta.key 1

# Задание особого метода шифрования, по-умолчание используется blowfish128.
;cipher x

# Использование lzo-сжатия. Не поддерживается OVPN на ROS.
;comp-lzo

# Уровень лога. Чем больше значение — тем подробнее.
verb 3

# Блокирование повторяющихся сообщений в логе
;mute 20

# Выше были приведены параметры, которые присутствуют в «родном» примере конфига для клиента + 1 необходимый нам параметр
# Ниже я приведу ещё несколько, на мой взгляд, полезных параметров.

# Маршрут, устанавливаемый при запуске подключения
# Маршрут указывает не на шлюз, а непосредственно на подключение
route 192.168.88.0 255.255.255.0

# Пауза перед установкой маршрутов после установления подключения (в секундах)
route-delay 5

# Если мы хотим задать OVPN-подключение в качестве основного шлюза
route-gateway 192.168.100.1
redirect-gateway def1 //Спасибо пользователю
@bibliary за правку. Согласно докам этот вариант верен, но протестировать на момент редактирования не имею возможности.



Примечание: для применения параметров маршрутизации, прописанных в конфиге, сам сервис OVPN, или же OVPN GUI должны быть запущены с правами администратора.

Примечание: список большинства параметров здесь но он несколько устаревший.

Настройка MikroTik-клиента


1 Импорт сертификатов

1.1 Кладём в микротик файл сертификата CA и файл сертификата и файл ключа клиента любым удобным способом

1.2 Импортируем сертификат CA

/certificate import file-name=cert_export_test-CA.crt passphrase=""


1.3 Импортируем сертификат и ключ клиента

/certificate import file-name=cert_export_test-client-ovpn-1.crt passphrase=""


/certificate import file-name=cert_export_test-client-ovpn-1.key passphrase=private-key-password1


2. Настраиваем клиент

/interface ovpn-client add name=OVPN_client connect-to={ovpn.my.domain|xxx.xxx.xxx.xxx} port=1194 mode={ip|ethernet} user=test-user-1 password=P@ssword1 profile=default certificate=cert_32 auth=sha1 cipher=blowfish128 add-default-route={no|yes} disabled=no


Значения в {} указываете в соответствии с предыдущими настройками и вашими потребностями.

Для экспериментов использовалось следующее оборудование и ПО:
RouterBoard 2011UiAS-2HnD с RouterOS 6.32.2 на борту — 2 шт., один в качестве сервера, другой в качестве клиента; оба служат пограничными шлюзами — дома и на работе.

Ноутбук с Windows 10 Pro x64 на боту — 1 шт., в качестве клиента; служит для работы и в качестве лаборатории.

Для познания использовались следующие ресурсы:

Спасибо за внимание.
Share post

Comments 21

    +1
    самый главный минус в том, что микротик не умеет UDP. Поэтому пришлось ставить на отдельном сервере.
      +1
      Ну его ещё научат, я думаю. ROS ещё и близко не законченный продукт.
        +1
        Не думаю что научат. А сейчас наверное самый хороший способ запустить OpenVPN сервер на микротик это MetaRouter и OpenWRT
          +1
          Да, я как раз об этом думал в данный момент.
            0
            Вероятно будет поддержка UDP в 7 версии, может быть не сразу, но вроде обещали. Вопрос то наболевший уже. P.S.: Ответил и понял, что занимаюсь некропостингом. )
              0
              а когда 7 выйдет?
            +1
            Они неоднократно заявляли, что не собираются работать над поддержкой UDP и LZO-компрессии в OpenVPN. Вместо этого, они настаивают, чтобы люди пользовались SSTP, что, как мне кажется, не является решением проблемы.
            0
            Да это и то что жать трафик он не может. Сам пытался SoftEther к нему посредством OpenVPN присоединить — не дался. И судя по форуму и заявлениям сжатия и udp не будет.
              0
              Мне больше всего не нравится то, что нет возможности настроить OpenVPN только по сертификатам, без аутентификации по паролю.
                0
                + также нет tls-auth
                  –1
                  ну это не самая большая проблема; да, чуток мороки добавляет, но совсем чуток.
                +3
                Нет смысла делать PKI на ROS. Извлечь его оттуда и перенести на комп потом может быть проблемой. А это потребуется как только возникнут любые затруднения с ROSовским пониманием OpenVPN. Например, если WAN-мобильные пользователи (через *G-модемы, планшеты, телефоны) начнут испытывать затруднения вида tcp-in-tcp из-за большого round-trip time своих линков, единственное решение — отказ от TCP, что означает миграцию на OpenVPN на нормальной ОС.

                Вообще, OpenVPN на ROS создаёт впечатление решения «на, отвали». Да и вообще, RouterOS вызывает множество вопросов: почему нельзя реализовать хоть мало-мальски вменяемый DNS-сервер, хотя бы на уровне фич dnsmasq? Что мешает сделать нормальные обновления DNS, почему поддерживается только создание-или-изменение A-записей (даже AAAA не может, не говоря уже о записях других типов, а также удалении записей). Почему скриптовый язык так убог, зачем и кому он вообще нужен, когда есть TCL, и опыт Cisco наглядно демонстрирует, что это отлично работает? Почему в CRS любых серий нет аппаратного LACP?

                Зато во всех, даже мелких железках за 1600р есть поддержка BGP и MPLS. Видимо это самое нужное, то, что чаще всего используется на микротиках.
                  0
                  Вообще-то если рядом еще radius поднять (вроде есть пакет под ROS) можно вполне авторизацию WiFI как у больших сделать с сертификатами и авторизацией по username. Причем в домашних условиях и на одной маленькой железке. Мечта параноика. By the way — готового how-to никто случайно не видел :-).?
                    0
                    Так тут речь не про WiFi, а про OpenVPN. WiFi как раз в микротиках достаточно нафиченный. Но RADIUS я всё равно не стал бы делать на микротике. Слишком много там сделанного по-марсиански сделанного криво или просто недоделанного — не верится, что они сделали вменяемый радиус-сервер.
                      0
                      НЕТ, радиус-сервера нормального на ROS нет, а вот в качестве радиус-клиента ROS работает практически как часы.
                  0
                  Большое спасибо автору за статью! Специально для нубов разжевано до не могу.
                  После полной настройки клиента и сервера столкнулся с проблемой не критического характера, но паранойя не дает оставить все как есть.
                  Случай следующий, во время подключения клиента ovpn к серверу на микротике появляется строка в логе «duplicate packet, dropping» всех уровней логирования, в том числе и error (скриншот: prntscr.com/9ta8p2).
                  Вопрос, что это и как его победить? :)
                    0
                    Судя по тому, что я читал тогда о OVPN — это вполне нормальная ситуация. Наблюдается она при любой реализации ovpn-клиента и ovpn-сервера. В частности, android -> win точно так же дублировались пакеты.
                    0
                    # Если мы хотим задать OVPN-подключение в качестве основного шлюза
                    route-gateway 192.168.100.1

                    При этом при подключении в логах клиента есть о прописке роута на 192.168.100.0, но о gateway ни слова :( Ну и ничего не меняется в маршрутизации трафика.
                      +1
                      Поправлю автора — что бы менять шлюз по умолчанию и загонять весь траффик в vpn нужно указывать не route-gateway 192.168.100.1, а redirect-gateway def1
                        0
                        Спасибо, поправил. Не имею возможности проверить, поэтому добавил с пояснением.
                      0
                      Спасибо за статью!
                      А есть у микротика некий аналог «push» — что бы давать клиентам команды маршрутизации в сеть сервера?

                      Only users with full accounts can post comments. Log in, please.