В то время как все нормальные люди отдыхают, системные администраторы переносят сервисы в дни минимальных нагрузок. В очередной раз мне пришлось перенести работающий шлюз на старой версии freebsd на современную centos 7. Так как я переносил шлюзы уже много раз, предполагал, что возникнут непредвиденные трудности. Они и возникли с openvpn.
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Мои предположения оправдались. Теоретически все выглядело понятно и достаточно просто. Шлюзы я много раз переносил и уже приноровился. Последовательность действий всегда примерно одинаковая:
- Берем свободный внешний ip и настраиваем на нем новый сервер.
- Переносим настройки фаервола, переносим таблицу маршрутов, делаем заготовки для переноса сетевых настроек.
- Запускаем на новом сервере идентичные сервисы, отлаживаем их работу.
- Цепляемся какой-нибудь виртуалкой к новому шлюзу и все проверяем.
- Выключаем старый шлюз, убираем его из автозагрузки, если он на виртуалке, и переносим его сетевые настройки на новый шлюз.
- Вместо пятого пункта, можно просто на 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.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.
В случаи если у вас easy-rsa версии 3 (он ставится вместе с openvpn на FreeBSD 11 и новее), все это делается через единственный скрипт easyrsa.real :
./easyrsa.real gen-crl
Этого в моем случаи было достаточно что бы выпустить новый crl когда просрочился старый
А зачем держать 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 компаниях такое может быть, но и тут с течением времени меняется руководство, которое хочет все удешевить, новые ИТ специалисты не компетентные, и все превращается в бардак...(
>Для генерации файла отзывов сертификатов (Certificate Revocation List (CRL) использовался алгоритм вычисления хэша md5
вот это как выяснил?
Уже точно не помню. Скорее всего где-то нагуглил похожую проблему.
Понятно. Тоже сертификаты давно сгенерированы, хотелось посмотреть. Буду пробовать решение из статьи. Спасибо за статью.
Добрый.
Готовые решения
https://pritunl.com/ https://client.pritunl.com/ - развертывание сервера-клиента с веб-гуи за 5 мин
https://www.pfsense.org/ - не только OpenVPN. Лучший программный firewall на данный момент.
Есть рус. яз. комьюнити - https://forum.pfsense.org/
Как в бесплатной версии pritunl создать 10 тоннелей на одном сервере с разными параметрами?
на pf можно сейчас собрать сквид? не пакетом натянуть, а именно собрать? В своё время чтот не получилось и пришлось уйти на микротик.