Связка OpenVPN на Windows Server и Mikrotik с миграцией этого добра в Linux

Доброго!

Каждому предприятию рано или поздно, внезапно, становится необходим удаленный доступ.
С необходимостью организовать удаленный доступ к своим сетям на предприятии сталкивается практический каждый АйТишник.

Меня, как и многих, эта потребность накрыла с грифом “вчера”. Проанализировав все «за» и «против», а также перелопатив тонны информации и поковырявшись немного в теории, я решил приступить к установке.

В целях безопасности, был выбрал OpenVPN в следующей реализации: на сервер с операционной системой Windows Server 2012 была установлена виртуальная машина, на ней также, Windows Server 2012, а на нем, в свою очередь, сервер OpenVPN, который выпускал и подписывал сертификаты.

Для удобства обзовем его «сервер сертификации». Далее, взял сертификат сервера, затолкнул его в Mikrotik, а на самом маршрутизаторе Mikrotik поднял OpenVPN с учетными записями, профилями. Для выпуска сертификата клиента также использовал сервер сертификации.

Реализация, конечно, аховая, и, хотя на тот момент моего опыта в подобных вещах было, скажем, не достаточно, в вопросах обеспечения безопасности, это было не самое плохое решение.

Данная связка поработала какое-то время и мне была выдана новая вводная: перенести сервер сертификации на Linux, при этом связь с Mikrotik сохранить — клиенты не должны пострадать.

Мои знания по Linux на тот момент заканчивались на Ubuntu 16.04LTS с графическим интерфейсом, которая использовалась как терминал для подключения по RDP к серверу Windows. То есть, sudo apt-get -f install -y, и ни сантиметра больше.

Изучив вопрос, какая OS из Linux семейства более устойчива и перспективна для моей организации, я остановился на CentOS 7 Minimal.

Для начала я решил немного покопаться в теории, понять как это вообще устроено и работает. Посмотрел видео уроки на канале www.youtube.com/channel/UCKdRgZWgy42YxoFcTJ30LTA (Вообще не реклама, просто они попались мне первыми). Девушка с приятным голосом ознакомила меня с основами работы в выбранной OS.

Для начала я запустил на своем компе Hyper-V, установил туда CentOS 7 Minimal, во время установки создал пользователя Admin и полностью закрыл ssh для root. Попрощавшись с красивым разноцветным экраном, погрузился в черно-белый мир терминала.

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

В скрипте я постарался автоматизировать установку минимально необходимых утилит для сервера, отключить Selinux, подключить репозиторий Epel, установить OpenVPN, и пр. Ниже сам скрипт, он простой, но его можно использовать. Разбирать его не буду, но если кому-то потребуется, пишите отвечу.

После использования скрипта появиться уже настроенный сервер OpenVPN, подмигивающий зеленым глазом.

#!/bin/bash
cd /etc/sysconfig/
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' selinux
sudo setenforce 0
cd /home/Admin
sudo yum update -y
sudo yum install epel-release -y
sudo yum install mc -y
sudo yum install nano -y
sudo cp /usr/share/mc/syntax/sh.syntax /usr/share/mc/syntax/unknown.syntax
sudo yum install chrony -y
sudo systemctl start chronyd
sudo systemctl enable chronyd
sudo yum install net-tools -y
sudo yum install iftop -y
sudo yum install htop -y
sudo yum install lsof -y
sudo yum install dos2unix -y
sudo yum install wget -y
sudo yum install tcpdump -y
sudo yum install openvpn -y
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.3/EasyRSA-3.0.3.tgz
sudo tar -xvzf EasyRSA-3.0.3.tgz
sudo chown -R Admin:Admin /var/log
sudo chmod 755 /var/log
mkdir /var/log/openvpn
mkdir /etc/openvpn/ccd	
sudo chown -R Admin:Admin /etc/openvpn/ccd
sudo chown -R Admin:Admin /var/log/openvpn
chmod 755 /etc/openvpn/ccd
chmod 755 /var/log/openvpn
echo >/var/log/openvpn/openvpn-status.log
echo >/var/log/openvpn/openvpn.log
sudo chown -R Admin:Admin /etc/resolv.conf
chmod 755 /etc/resolv.conf
echo  nameserver 8.8.8.8 >>/etc/resolv.conf
cd /etc/openvpn/ 
sudo /home/Admin/EasyRSA-3.0.3/easyrsa init-pki
sudo chown -R Admin:Admin /etc/openvpn
chmod 755 /etc/openvpn
 echo  set_var EASYRSA_DN "org" >/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_COUNTRY "RU" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_KEY_SIZE 4096 >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_PROVINCE "LIP" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_CITY "Lipetsk" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_ORG "Cool-Admin" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_EMAIL "xxx.ru" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_OU "Our_ORG" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_CN "changeme" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_CERT_EXPIRE 3650 >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_DH_KEY_SIZE=2048 >>/home/Admin/EasyRSA-3.0.3/test
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-ca nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-server-full Serv nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-client-full Client1 nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa --vars=vars gen-dh
sudo /home/Admin/EasyRSA-3.0.3/easyrsa --vars=vars gen-crl
 mkdir keys
sudo chown -R Admin:Admin /etc/openvpn/keys
chmod 755 /etc/openvpn/keys
sudo cp /etc/openvpn/pki/ca.crt /etc/openvpn/keys
sudo cp /etc/openvpn/pki/dh.pem /etc/openvpn/keys
sudo cp /etc/openvpn/pki/crl.pem /etc/openvpn/keys
sudo cp /etc/openvpn/pki/issued/Serv.crt /etc/openvpn/keys
sudo cp /etc/openvpn/pki/private/Serv.key /etc/openvpn/keys
echo port 443 						>/etc/openvpn/server.conf
echo proto udp					>>/etc/openvpn/server.conf
echo dev tun						>>/etc/openvpn/server.conf
echo ca /etc/openvpn/keys/ca.crt			>>/etc/openvpn/server.conf		
echo cert /etc/openvpn/keys/Serv.crt			>>/etc/openvpn/server.conf
echo key /etc/openvpn/keys/Serv.key		>>/etc/openvpn/server.conf
echo dh /etc/openvpn/keys/dh.pem			>>/etc/openvpn/server.conf
echo crl-verify /etc/openvpn/keys/crl.pem		>>/etc/openvpn/server.conf
echo client-config-dir /etc/openvpn/ccd		>>/etc/openvpn/server.conf
echo topology subnet					>>/etc/openvpn/server.conf
echo server 172.21.0.0 255.255.255.0		>>/etc/openvpn/server.conf
echo route 172.21.0.0 255.255.255.0			>>/etc/openvpn/server.conf
echo push \"dhcp-option DNS 8.8.8.8\"		>>/etc/openvpn/server.conf
echo push \"dhcp-option DNS 8.8.4.4\"		>>/etc/openvpn/server.conf
echo keepalive 10 120				>>/etc/openvpn/server.conf
echo persist-key					>>/etc/openvpn/server.conf
echo persist-tun					>>/etc/openvpn/server.conf
echo status /var/log/openvpn/openvpn-status.log	>>/etc/openvpn/server.conf
echo log-append /var/log/openvpn/openvpn.log	>>/etc/openvpn/server.conf
echo verb 2						>>/etc/openvpn/server.conf
echo mute 20						>>/etc/openvpn/server.conf
echo daemon						>>/etc/openvpn/server.conf
echo mode server					>>/etc/openvpn/server.conf
echo user nobody					>>/etc/openvpn/server.conf
echo group nobody					>>/etc/openvpn/server.conf
sudo chown -R Admin:Admin /etc/sysctl.conf
chmod 755 /etc/sysctl.conf
echo net.ipv4.ip_forward=1 >>/etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
sudo systemctl enable openvpn@server
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server

Установка OpenVPN прошла не совсем успешно.

Не зная про особенности политики прав на Linux системах, я потратил массу времени на изучение логов и присвоения всем файлам требуемых прав.

Когда кнопка OpenVPN стала зеленой, я очень обрадовался, но как оказалось, это было только начало. По простоте душевной, я рассчитывал подменить корневые сертификаты и файл crl.pem, надеясь, что все заработает. В итоге, мне понадобилось перенести с сервера на Windows следующие файлы:

Serv.crt — Сертификат сервера
Serv.key — Ключ сервера
Ca.crt — Корневой сертификат
Ca.key — Корневой ключ
Crl.pem — Файл отозванных сертификатов
Dh.pem — ключ Диффи-Хеллмана
Index.txt — Файл с информацией об актуальных сертификатах
Serial — он тоже отвечает за актуальность сертификатов

Также потребовалась папка certs_by_serial, файл vars, и все клиентские ключи и сертификаты.
На Mikrotik сертификаты оставались на месте, поэтому все заработало.

Проблемы появились, когда я попытался отозвать сертификат, это не работало от слова совсем — файл index.txt нужно было перевести в формат unix, а я этого сразу не сделал. Воспользовался утилитой dos2unix.

Теперь сертификаты отзывались, но продолжали работать без каких-либо проблем, потому что Mikrotik не знал о том, что они отозваны и ему нужно было как-то об этом сообщить.

Прочитав инструкции, а также проконсультировавшись с Александром ЭРИ (огромное спасибо!), я поднял на сервере сертификации простой http сервер Apache и опубликовал на нем файл отозванных сертификатов. Полностью закрыл к нему доступ, кроме как к опубликованному файлу с одного ip.

В терминале Mikrotik, во вкладке /System/Certificates/CRL указал путь к опубликованному crl.pem. Тут следует уточнить, что Mikrotik принимает для вкладки CRL только http и абсолютный адрес, т.е. выглядеть должно было приблизительно вот так: 127.0.0.1/crl/1.crl
Все заработало, по крайней мере для версий 6.4.2.х RouterOS, но клиентские конфигурации приходилось создавать руками, и это для меня было прискорбно и вызывало массу неудобств. Когда через неделю мне потребовалось создать конфигурации для порядка 50 клиентов, я решил ускорить этот процесс и для этого использовал кусочек чужого скрипта, найденного на просторах интернета.

Скрипт работает так: после запуска указываем «имя клиента», отвечаем на вопрос «установить пароль или нет», после этого забираем уже готовый файл конфигурации «клиент.ovpn», с интегрированными в него сертификатами и настройками. Чтобы его использовать, надо находиться /etc/openvpn. Я подпишу коментами строки, в которых путь необходимо заменить на свой. Также необходимо создать файл с настройками клиента, что-бы скрипт подставлял их в процессе создания конфигурации.

#!/bin/bash
function newClient () {
	echo ""
	echo "Tell me a name for the client."
	echo "Use one word only, no special characters."

	until [[ "$CLIENT" =~ ^[a-zA-Z0-9_]+$ ]]; do
		read -rp "Client name: " -e CLIENT
	done

	echo ""
	echo "Do you want to protect the configuration file with a password?"
	echo "(e.g. encrypt the private key with a password)"
	echo "   1) Add a passwordless client"
	echo "   2) Use a password for the client"

	until [[ "$PASS" =~ ^[1-2]$ ]]; do
		read -rp "Select an option [1-2]: " -e -i 1 PASS
	done

	#cd /etc/openvpn/easy-rsa/ || return
	case $PASS in
		1)
		sudo /home/admin/EasyRSA-3.0.3/easyrsa build-client-full "$CLIENT" nopass
		;;
		2)
		echo "You will be asked for the client password below"
			./easyrsa build-client-full "$CLIENT"
		;;
	esac
# Generates the custom client.ovpn
	cp /etc/openvpn/client-template.txt "$home/home/admin/IT/Temp/$CLIENT.ovpn" 
#Директория в которой хранится файл с настройками клиента.
#Директория, в которой сформируется файл конфигурации
	{
		echo "<ca>"
		cat "/etc/openvpn/pki/ca.crt" #Директория хранения корневого сертификата
		echo "</ca>"

		echo "<cert>"
		awk '/BEGIN/,/END/' "/etc/openvpn/pki/issued/$CLIENT.crt" #Директория с созданным #сертификатом клиента
		echo "</cert>"

		echo "<key>"
		cat "/etc/openvpn/pki/private/$CLIENT.key" #Директория с созданным ключом клиента
		echo "</key>"

} >> "$home/home/admin/IT/Temp/$CLIENT.ovpn" #Директория, в которой сформируется файл #конфигурации

	echo ""
	echo "Client $CLIENT added, the configuration file is available at $home/admin/IT/OVPN/Temp/$CLIENT.ovpn."
	echo "Download the .ovpn file and import it in your OpenVPN client."
exit 0;
}
newClient

Через некоторое время новая вводная на запрет удаленного доступа вынудила убить и этот сервер, и работающую связку с Mikrotik. Был создан новый сервер OpenVPN, для сотрудников IT-отдела, который теперь работает полностью на CentOS. Но это уже совсем другая история.

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

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 36

    +1
    При наличии WireGuard есть ли ещё веские причины создавать новые сети на основе OpenVPN?
      0
      Спасибо за подсказку, но об этом слышу впервые. Почитаю, разберусь
        0
        Нет поддержки авторизации через сторонний сервис (radius, active directory и пр.)
          +1

          Конечно ipsec ike v2
          Mikrotik его умеет с аппаратным ускорением

            +1
            WireGuard не поддерживает tcp и соединение через HTTP CONNECT прокси.
              0
              Wireguard это туннель в чистом виде. А дальше в него заворачивайте что угодно, хоть tcp хоть прокси.
                0
                Речь о том, что сам туннель не может быть tcp. А это создает сложности в ограниченных сетях. Допустим, вы подключились к публичной сети, а там разрешены наружу только http и https, что делать будете?
                  0
                  В такой сети все равно нужен DNS который пока UDP. Как вариант маскироваться под него. Хотя честно говоря на практике пока таких сетей не встречал.
                    0
                    Честно говоря, я тоже не встречал, но часто натыкался на упоминания одно время. Тут в соседней ветке комментариев так же указали, что провайдер трафику на 443 порту дает больший приоритет. В общем, это не та фича, без которой жить нельзя, но она бы не помешала. UDP можно тоже зарезать, локальный DNS-сервер будет форвардить все запросы, а его адрес раздаваться по DHCP, к другим адресам запросы на 53 порт не разрешать. Ну и понятно, что пакеты от WireGuard уже не пройдут.
            0
            github.com/Nyr/openvpn-install
            Вот если что репозиторий со скриптом, реализующим базовые потребности в настройке openVPN-сервера и генерации клиентских ключей и конфигов
            Второй сниппет с кодом очень сильно напоминает часть кода из репозитория.
              0
              Он скорее всего оттуда и есть. Я делал это давно, не помню откуда взял. Там написано что второй скрипт не мой
              +1
              StopDisablingSelinux
              Серьёзно. Хватит. Не нужно отключать системы безопасности только по той причине, что вам лень их настраивать.

              Другой вопрос — что мешало взять вам какой-нибудь pfsense/opnsense и настраивать vpn с пользователями, сертификатами и прочим в красивых окошках веб-интерфейса?

              Вопрос номер три — вы уверены, что с «proto udp» у вас всё заработает? Насколько помню, mikrotik не умеет openvpn через udp, только через tcp.

              «sudo chown -R Admin:Admin /var/log»
              А вот это вообще ад. Привет поломанным логам всего подряд. Пожалуйста, не надо создавать статьи из вредных советов, вы — не Григорий Остер.
                0
                Я действительно на тот момент не знал как это работает. Постарался быть объективным. В инструкциях которые мне попадались, Selinux отключали. Я не искал и не копал. Это важно, не спорю
                  0
                  Зачем вы его вообще отключали? Не вижу в списке пакетов, которым он мог бы помешать
                    0
                    Selinux мог помешать запуску Openvpn на порту. На тот момент не было понимания как его разрешить. И подробного описания в инструкциях по которым я это собирал, было только отключение, либо permissive
                      0
                      Почему бы тогда не использовать стандартный порт? Провайдер режет?
                        +1
                        у меня не то чтоб режет, но приоритет трафика дает низкий.

                        ещё на центосах включен жесткий firewalld по умолчанию

                        cat <<EOF > /etc/firewalld/services/openvpnextra.xml
                        <?xml version="1.0" encoding="utf-8"?>
                        <service>
                          <port protocol="udp" port="8080"/>
                          <port protocol="tcp" port="8080"/>
                        </service>
                        EOF
                        
                        firewall-cmd --permanent --zone=public --add-service=openvpnextra
                        


                        По selinux

                        semanage port -a -t openvpn_port_t -p tcp 8080
                        semanage port -a -t openvpn_port_t -p udp 8080


                        И смотреть аудит дальше какого параметра ещё не хватило…
                          0
                          Небольшая поправочка, пакет openvpn добавляет правило с таким именем при установке, так что надо делать modify:
                          semanage port -m -t openvpn_port_t -p tcp 8080
                          semanage port -m -t openvpn_port_t -p udp 8080

                          Про firewalld хорошее замечание (я про него постоянно забываю). В принципе указанного вами должно хватить, у меня так и настроено. Идущие в комплекте права на selinux дают все необходимое из коробки.
                            0
                            нет, именно `-a` потому как на дефолтном порту openvpn тоже запущен (4 сервера с разными параметрами).

                            но если не запущен на 1194, то на второй строчке нужно всетаки -a чтоб не перетереть tcp версию.
                              0
                              Мы оба неправы. Я помнил, что нужен ключ -m, но неправильно помнил почему.
                              -a не сработает, если порт уже используется другим правилом

                              [root@server]# semanage port -l | grep ssh
                              ssh_port_t                     tcp      22
                              [root@server]# semanage port -a -t ssh_port_t -p tcp 443
                              ValueError: Port tcp/443 already defined
                              [root@server]# semanage port -m -t ssh_port_t -p tcp 443
                              [root@server]# semanage port -l | grep ssh
                              ssh_port_t                     tcp      443, 22
                      0
                      selinux — это полдня втыкания в аудит, если запускать что-то не типовое. Если человеку он не нужен — то и не стоит с ним заниматься.
                        0
                        Есть тупой способ:

                        Включаем аудит
                        semodule -DB
                        Ищем что нужно добавить
                        ausearch -ts today | audit2allow
                        Добавляем разрешений в модуль
                        ausearch -ts today | audit2allow -M module_name
                        Собираем и применяем модуль
                        semodule -i module_name.pp
                        Проверяем установку
                        semodule -l | grep module_name
                        Повторить сначала, если не помогло
                        Выключаем аудит
                        semodule -B

                        И так до победного, потом делаем результирующий модуль, в котором есть все нужные разрешения, а лишнее, конечно, удаляем. Полдня превращаются в полчаса
                    0
                    Я хочу постоянно поднимать уровень своего образования, а путь который проще в моем случае не туда. Поэтому сделано было так.
                      0
                      Второй вопрос. Да вы правы, не заработает. Скрипт писал после, и адаптировал его под сервер на Linux. Когда писал статью не заметил.
                        –1
                        «sudo chown -R Admin:Admin /var/log»
                        А вот это вообще ад.
                        Я и сейчас не вижу ничего плохого в этой строке. Можете объяснить?
                          0
                          Есть немало программ, запускающихся не от рута. И если они создают свои лог-файлы, то конечно их создают с правами пользователя, под которыми запущен процесс. Вы этой командой сломали запись логов всем программам, работающим не от рута
                            –2
                            В моем случае это осознанный поступок. Пользователь всего-лишь один. Сервер только для OpenVPN. Ничего другого там не могло быть. Может для многопользовательской системы это действительно важно, но для моей задачи это нормально.
                              0
                              Это для любой системы важно, многопользовательская или нет тут ни при чем, речь о системных сервисах. Это даже не системозависимо, на винсервере тоже можно поломать права и жить очень весело. Зачем делать сразу неправильно, чтобы однажды словить проблему? Тот же OpenVPN в вашем конфиге после инициализации дропает рутовые права со своего процесса. Благо, ему ничего не надо делать с файлами в собственной папке от непривилегированного пользователя, иначе бы вы долго бились «а почему оно не работает».
                                0
                                Я с вами согласен, был неправ. Все стало по местам.
                                0
                                Я соглашусь с Kanlas — не стоит менять права на системных папках. Лучше там создать подпапку с Вашими правами и писать лог туда.

                                Пользователей у Вас не один и не два. Тут имеются ввиду системные записи.
                                cat /etc/group | wc -l


                                После таких изменений прав обычно первым страдает Xserver. Правда сейчас многогие сервисы перешли на лог в журнале
                          0
                          sudo chown -R Admin:Admin /etc/sysctl.conf
                          chmod 755 /etc/sysctl.conf
                          echo net.ipv4.ip_forward=1 >>/etc/sysctl.conf


                          Можно же просто использовать sudo с echo, зачем ломать права на файлы и папки. И chown без sudo в данном случае все равно не сработает. Ну и echo без одинарных кавычек не по феншую, можно нарваться на выполнение непойми какой команды или интерпретации спецсимвола, вместо вывода текста. Далее такие же ошибки.
                            0
                            Можно же просто использовать sudo с echo, зачем ломать права на файлы и папки.
                            Согласен, учту. Это верно.

                            И chown без sudo в данном случае все равно не сработает
                            Срабатывает. Прежде чем отправить я проверил скрипт в машине на CentOS.

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

                              Моя невнимательность, там ведь сначала владелец меняется.
                              Если можно подробнее, я мог что-то упустить

                              Лучше всего расскажет статья
                            0

                            Организовывать шлюз на базе pfsense если на обоих концах статические адреса. Или opensense если на одном конце адрес есть, а на точках нет. Ddns адреса тоже будут работать — проверенно. Мне пришлось искать помощи что бы дописали pfsense под работу без статики на конечных точках, но теперь всё работает. Отличный гибкий фаеврвол для защиты сети офиса. Openvpn и ipsec сервер с gui, менеджером сертификатов и т.д. все что нужно и не нужно в нем есть. Работает на базе китайского мини ПК с 2 Гб ОЗУ и 30 Гб m.ssd. легко создаются резервные копии, администрирование через web gui. У меня работает для обмена данными с магазинами через openvpn, объединение удаленных сегментов сетей через ipsec, раздача интернета внутри офиса
                            Общее количество подключений около 70.

                              +1
                              Кучу echo тяжело читать, есть конструкция
                              cat << EOF > file
                              . так удобней.

                              Закрывать доступ к списку отзыва не понятно. Сертификаты (открытая часть) и список отзыва должны быть доступны для чтения всем на мой взгляд. Их можно открыть виндовой (и линуксовой) утилитой и посмотреть.

                              п.с. О, я в телевизоре)
                                0
                                Спасибо, я посмотрю эту конструкцию

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое