Ошибки OpenVPN - CRL has expired и CRL signature failure

В то время как все нормальные люди отдыхают, системные администраторы переносят сервисы в дни минимальных нагрузок. В очередной раз мне пришлось перенести работающий шлюз на старой версии freebsd на современную centos 7. Так как я переносил шлюзы уже много раз, предполагал, что возникнут непредвиденные трудности. Они и возникли с openvpn.

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Мои предположения оправдались. Теоретически все выглядело понятно и достаточно просто. Шлюзы я много раз переносил и уже приноровился. Последовательность действий всегда примерно одинаковая:

  1. Берем свободный внешний ip и настраиваем на нем новый сервер.
  2. Переносим настройки фаервола, переносим таблицу маршрутов, делаем заготовки для переноса сетевых настроек.
  3. Запускаем на новом сервере идентичные сервисы, отлаживаем их работу.
  4. Цепляемся какой-нибудь виртуалкой к новому шлюзу и все проверяем.
  5. Выключаем старый шлюз, убираем его из автозагрузки, если он на виртуалке, и переносим его сетевые настройки на новый шлюз.
  6. Вместо пятого пункта, можно просто на dhcp поменять для клиентов дефолтный шлюз и ждать, когда они обновят свои сетевые настройки.

Правильнее и удобнее делать все по 6-му пункту, так как так проще откатиться назад в случае нештатной ситуации. Можно оставить два шлюза одновременно работающими и отлаживать их одновременно. К сожалению, чаще всего так сделать не получается по разным причинам (много клиентов с ручными настройками сети, dhcp сервер на этом же шлюзе и т.д.)

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

В этот раз я поленился все проверить заранее. Даже не то, что поленился. Просто праздники и у меня много времени в запасе. Решил сразу все делать на месте, прикинув простой план в голове.

Сложность возникла с переносом настроек и сертификатов openvpn сервера. Было много разных туннелей под разные задачи с разными настройками. Но не в этом суть, перенести их дело техники. Первой проявилась следующая проблема.

Я перенес настройки и сертификаты openvpn первого тоннеля, запустил его. На вид все в порядке, тоннель запустился без ошибок. Стал подключаться клиентом - он не подключается. В логе сервера ошибка:

TLS: Initial packet from [AF_INET]77.37.227.11:52871, sid=ba15g8a4 4d8aew18
VERIFY ERROR: depth=0, error=CRL has expired: CN=user10
OpenSSL: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

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

Решение проблемы нашлось достаточно быстро, ошибка весьма популярная. Не буду на ней останавливаться подробно, я воспользовался вот этой статьей - https://bozza.ru/art-287.html, там есть вся необходимая информация.

Я проверил свой файл, оказалось, он действительно был просрочен.

openssl crl -inform PEM -in crl.pem -text -noout

OpenSSL: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

Отредактировал конфиг openssl.cnf, увеличил срок жизни файла и пересоздал его.

openssl ca -gencrl -keyfile keys/server/ca.key -cert keys/server/ca.crt -out keys/server/crl.pem -config openssl.cnf

Закинул новый файл в директорию с openvpn и перезапустил тоннель. Еще порадовался, что быстро решил проблему. Но как оказалось, мои проблемы только начались. При подключении клиента к новому openvpn серверу, снова выскакивала ошибка, но уже принципиально другая:

TLS: Initial packet from [AF_INET]77.37.227.11:52871, sid=ba15g8a4 4d8aew18
VERIFY ERROR: depth=0, error=CRL signature failure: CN=user10
OpenSSL: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

Тут наскоком решить вопрос не получилось. Стал опять шерстить англоязычный поиск на релевантную тему. Похожих запросов именно с crl почти не было, а там где были, не было решений. И вообще было не очень понятно, в чем тут дело. Но худо бедно картинка началась складываться. Я так же не мог добавить новый сертификат к списку отзыва со старыми настройками openssl, получал ошибку.

Дело оказалось вот в чем. Я переносил сертификаты openvpn с очень старого сервера freebsd 8.2, который настраивали примерно в 2010 году. Для генерации файла отзывов сертификатов (Certificate Revocation List (CRL) использовался алгоритм вычисления хэша md5, который не поддерживается в Centos 7, так как считается небезопасным.

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

Для того, чтобы в CentOS 7 можно было работать с md5, нужно добавить в окружение следующие переменные:

NSS_HASH_ALG_SUPPORT=+MD5
OPENSSL_ENABLE_MD5_VERIFY=1

Для этого достаточно просто в консоли ввести:

export OPENSSL_ENABLE_MD5_VERIFY=1
export NSS_HASH_ALG_SUPPORT=+MD5

Можно добавить эти переменные в easy-rsa/vars. Это позволит вам продолжать вести старый список отзывов для openvpn. Для того, что служба openvpn применила эти переменные и начала нормально работать с md5, необходимо привести конфиг systemd к следующему виду:

# cat /usr/lib/systemd/system/openvpn@.service
[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
Type=notify
PrivateTmp=true
ExecStart=/usr/sbin/openvpn --cd /etc/openvpn/ --config %i.conf
Environment="OPENSSL_ENABLE_MD5_VERIFY=1 NSS_HASH_ALG_SUPPORT=+MD5"

[Install]
WantedBy=multi-user.target

После этого все запускаемые тоннели или добавленные в автозагрузку скрипты запуска для openvpn в systemd (в /etc/systemd/system/multi-user.target.wants), будут созданы с этими значениями окружения.

После этих изменений мои клиенты openvpn стали нормально подключаться к серверу. К счастью, сертификаты клиентов были сгенерированы c применением хэша sha1, который пока еще не запретили.

Если у вас еще нет своего vpn сервера, рекомендую мою подробную статью на эту тему - настройка openvpn сервера.

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

10 комментариев

  1. Владислав

    В случаи если у вас easy-rsa версии 3 (он ставится вместе с openvpn на FreeBSD 11 и новее), все это делается через единственный скрипт easyrsa.real :
    ./easyrsa.real gen-crl
    Этого в моем случаи было достаточно что бы выпустить новый crl когда просрочился старый

  2. Владислав

    А зачем держать openvpn сервер на той же системе которая работает в роли роутера раздающего интернет? Или "шлюз" имелось в виду чисто сервер опенвнп и ничего больше? У меня это разные системы + для ВПН подключений используется полностью ИП.
    Да и зачем для таких задач было с фряхи переезжать, она отлично справляется в роли маршрутизатора/файрвола. netgraph - самая сильная сетевая подсистема, а правила на ipfw легче осваивать и рулить ими чем iptables'ом.

    • Openvpn можно держать где угодно, но я обычно ставлю на шлюзы, которые раздают интернет. Так удобнее. Не вижу смысла плодить лишние сущности, если клиентов не очень много, а сети небольшие.

      Для Freebsd сейчас не найти специалистов. Да и система там была очень старая. Нужно либо ее обновлять через несколько релизов, либо заново все настраивать. Так как вся информационная система работала на centos, принял решение шлюз и openvpn сервер тоже настроить на centos.

      • Владислав

        Если эти сущности можно плодить не в ущерб, то я считаю это правильным. Нынче не проблема отрезать +1 ВМ-ку на 10-20гб диска и 2гб озу под отдельный vpn сервер.
        У меня в свое время в одной компании был товарищ, который не любил плодить сущности, в итоге у него на офисном маршрутизаторе был openvpn (включая site-to-site), unifi controller (с постоянной утечкой памяти), asterisk, и как практика показала это не очень хорошая идея скопом все на одну систему скидывать. Когда что-то случалось страдало все остальное.

        Найти BSD специалиста можно, и им может быть даже просто высококвалифицированный linux админ - во фряхе для первого знакомства не намного больше отличий чем между дистрами линукса, шарящий человек умеющий читать маны без проблем разберется. В случаи с задачей роутер+впн, вместо apt/yum ввести pkg install openvpn и прописать пару строчек в rc.conf много ума не нужно.

        Стандартизация и уход от зоопарков систем это правильно, вот бы так все и везде делали... Разве что в солидных или IT компаниях такое может быть, но и тут с течением времени меняется руководство, которое хочет все удешевить, новые ИТ специалисты не компетентные, и все превращается в бардак...(

  3. >Для генерации файла отзывов сертификатов (Certificate Revocation List (CRL) использовался алгоритм вычисления хэша md5
    вот это как выяснил?

    • Уже точно не помню. Скорее всего где-то нагуглил похожую проблему.

      • Понятно. Тоже сертификаты давно сгенерированы, хотелось посмотреть. Буду пробовать решение из статьи. Спасибо за статью.

  4. Добрый.

    Готовые решения

    https://pritunl.com/ https://client.pritunl.com/ - развертывание сервера-клиента с веб-гуи за 5 мин

    https://www.pfsense.org/ - не только OpenVPN. Лучший программный firewall на данный момент.
    Есть рус. яз. комьюнити - https://forum.pfsense.org/

    • Как в бесплатной версии pritunl создать 10 тоннелей на одном сервере с разными параметрами?

    • на pf можно сейчас собрать сквид? не пакетом натянуть, а именно собрать? В своё время чтот не получилось и пришлось уйти на микротик.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar