Андрей Бешков
Рано или поздно большинство системных администраторов
сталкивается с необходимостью соединить свои территориально удаленные сети с
помощью надежного, достаточно быстрого и в то же время защищенного от
прослушивания и вмешательства злоумышленников канала. Таким образом,
получается, что нам нужно создать частную виртуальную сеть (Virtual Private
Network), или VPN. В этот момент перед нами открывается развилка из нескольких
путей для претворения задуманного в жизнь:
1. Использовать
свободную реализацию IPSec (Internet Protocol Security). В качестве таковой
могут выступать FreeSWAN или FreeBSD IPSec.
2. Купить и
внедрить коммерческое решение. Например, Cisco VPN или Securepoint VPN Server, который
также основан на IPSec, или взять решение от какого-либо другого производителя,
например Windows IPSec. В данном разделе я сознательно не делю решения на
аппаратные и программные, потому что это всего лишь обзор.
3. Взять на
вооружение свободные разработки, использующие криптографические алгоритмы
собственного изготовления. Список таких приложений довольно велик. Поэтому
перечислим только те, что у всех на слуху – cipe, vpnd, tinc, – этот список
можно было бы продолжать очень долго.
4. Самостоятельно
написать программное обеспечение, реализующее все механизмы VPN.
5. Использовать
PPTP (Point to Point Tunneling Protocol).
Давайте разберемся с достоинствами и недостатками
каждой из предлагаемых методик решения проблемы.
Что же можно сказать по поводу первого решения. Последние
несколько лет при создании VPN стандартом де-факто считается IPSec. Такая
распространенность помогает нам не слишком беспокоиться о совместимости
VPN-серверов и клиентов. Все-таки единый стандарт – штука очень удобная.
Подобный способ хорош тем, что не потребует больших материальных затрат и в то
же время предлагает стойкую криптографическую защиту передаваемых данных. Но на
этом его преимущества заканчиваются, и на сцену выходят недостатки. Во-первых,
IPSec не обязательно сможет мирно сосуществовать с вашим межсетевым экраном,
особенно если тот выполняет над пакетами изуверские операции, называемые в
народе NAT. Опять же экраны с контролем состояния соединения (statefull
firewall), находящиеся между двумя точками виртуального тоннеля и управляемые
провайдером, могут не пропускать те или иные IPSec-пакеты. О
кроссплатформенности разных реализаций IPSec пока что остается только мечтать в
связи с тем, что для реализации функций IPSec приходится вносить в ядро
операционной системы и IP-стек довольно много изменений. Как гласит старинная
пословица: «Надежность заканчивается там, где начинается сложная механика», это
значит, что одна-единственная ошибка в коде, реализующем IPSec, приведет к
огромной дыре в безопасности. Вдобавок, насколько я знаю, на данный момент не
существует легко настраиваемого свободного клиента IPSec для Windows. Значит,
либо придется разбираться в настройках тех клиентов, что распространяются под
эгидой opensource, либо покупать коммерческий. Также стоит обратить внимание на
несколько большую сложность установки и настройки такого комплекса по сравнению
с остальными типами VPN. Еще одним из минусов является отсутствие технической
поддержки. Если что-то пойдет не так, как планировалось, то на
квалифицированную помощь от производителя рассчитывать трудно. Это ведь
свободный продукт, поэтому придется просить совета либо у своих более удачливых
коллег, либо в форумах и списках, посвященных данному программному обеспечению.
Впрочем, не каждый производитель проприетарного софта может похвастаться
квалифицированной службой поддержки. К тому же обычно у многих свободных
разработок существует внушительный лагерь сторонников, которые будут рады
обратить вас в свою веру и заодно помочь в настройке программы.
Второй способ выглядит довольно привлекательным в
случае, если у вас есть деньги. В обмен на довольно внушительную сумму вы,
скорее всего, получите более или менее качественную техническую поддержку,
стабильно работающее оборудование и специалистов, которые самостоятельно или по
вашим указаниям решат, как именно соединить сети для достижения наилучшего
результата. Да и с технической документацией вероятнее всего дело будет
обстоять очень хорошо. Но, как всегда в жизни, плюсов без минусов не бывает.
Выбрав решение от одного производителя, вы будете впредь очень сильно привязаны
к нему. Соответственно, если выбранный вендор не реализует те или иные
возможности в своей продуктовой линейке, значит и вы, скорее всего, не сможете
ими воспользоваться.
Третий вариант наиболее подходит для тех, кому нужно
развернуть VPN без больших затрат времени, сил и денег. В то же время нужно
отдавать себе отчет, что обычно подобные программы пишут для собственного
использования те, кто не смог или не захотел разобраться с принципами работы и
методикой настройки IPSec. Соответственно основной идеей разработки является
удобство использования и нетребовательность к ресурсам. Со временем такие
программы понемногу совершенствуются, но все же не стоит ожидать от них
запредельной надежности и безопасности. Происходит это потому, что каждый автор
использует свои собственные реализации криптоалгоритмов. Конечно, они
обеспечивают некоторую степень защищенности, но без проведения сторонней
экспертизы точно сказать, насколько надежно все это работает, довольно
затруднительно. Соответственно данный класс программ больше подходит для защиты
каналов, по которым передается информация с малым временем жизни,
предназначенная для ограниченного распространения. Внедрение такого решения
позволит защитить наши данные от начинающих злоумышленников, но не от
профессионалов в области подглядывания. Впрочем, для некоторых предприятий
вполне достаточно и таких возможностей.
Четвертый путь выглядит привлекательным только
для специалистов в области криптографии, обладающих большим количеством свободного
времени. Но, к сожалению, таких людей в мире немного, а тех, кто позволит себя
нанять, еще меньше.
Вариант решения, основанный на PPT, большей
частью используется приверженцами Microsoft. Данный стандарт реализует довольно
стойкое шифрование и аутентификацию соединений. Созданный в недрах большой
Редмондской корпорации, он не получил особого распространения в мире UNIX. Хотя
свободное программное обеспечение для работы с ним все же существует и
пользуется некоторым спросом, все же решения на основе IPSec практикуют гораздо
чаще. Происходит это, видимо, потому, что IPSec имеет более надежные процедуры
шифрования. Но политические мотивы сопротивления со стороны юниксистов
новинкам, внедряемым Microsoft, тоже не стоит сбрасывать со счетов.
Ну а большинству читателей, не воспользовавшихся
вариантами, предлагаемыми выше, видимо, придется обратиться к программе,
которой собственно и посвящена данная статья. Между делом неплохо было бы
посетить сайт проекта http://openvpn.sourceforge.net.
Ну а я продолжу свое повествование.
История разработки OpenVPN выглядит довольно
забавно и в то же время является хрестоматийной иллюстрацией принципов,
типичных для движения открытых исходников. В конце 2001 года Джеймс Йонан (James
Yonan) успешно выполнил работу над большим проектом для компании, сотрудником
которой он является и по сей день. В качестве благодарности работодатель
разрешил ему не ходить каждый день на работу и выполнять свои обязанности
удаленно. С этого момента жизнь Джеймса кардинально изменилась. Словно в
калейдоскопе мелькали страны и континенты: Египет, Кыргызстан, Монголия, Китай.
Как обычно, без русских тут не обошлось. Уж очень автора OpenVPN беспокоил тот
парадоксальный факт, что в России есть достаточно большое количество
безработных, но очень талантливых хакеров. А судя по его наблюдениям, некоторая
часть трафика шла именно через российские сети. Объездив всю центральную Азию,
Джеймс попутно продолжал искать решение, которое позволит ему работать с центральным
офисом удобно, безопасно, надежно и в то же время не будет стоить бешеных
денег. Испробовав на себе все вышеперечисленные способы создания VPN, он понял,
что на данный момент идеал, к сожалению, недостижим.
Решив разработать свой собственный пакет,
реализующий функции VPN, он в отличие от других авторов не стал заниматься
созданием своего собственного уникального криптоалгоритма с нуля. Вместо этого
был использован проверенный временем и неоднократно доказавший свою надежность
стандарт SSL, для работы с которым можно было опереться на доступную для многих
систем библиотеку OpenSSL. Стоит отметить, что такая же идея используется и в
программном обеспечении, называемом vtun.
Итак, давайте посмотрим поближе
на возможности, предоставляемые OpenVPN.
n Официально OpenVPN успешно работает под
управлением следующих операционных систем: Linux, Solaris, OpenBSD, FreeBSD,
NetBSD, Mac OS X, Windows 2000/XP. Это позволяет создавать сложные
кроссплатформенные туннели. Впрочем, не составит никакого труда портировать
OpenVPN в любую другую систему, для которой существует драйвер
tun/tap-устройств. К тому же данная разработка независима от размера и
старшинства байтов в машинном слове, что облегчает перенос на новые
операционные системы.
n Компрессия потока передаваемых данных и
управление полосой пропускания производятся с помощью библиотеки LZO. Процесс
сжатия является адаптивным, то есть попытки упаковать передаваемые данные будут
предприняты, только если есть смысл их упаковывать. Эта возможность может быть
легко отключена по желанию пользователя, как и любые другие компоненты в
случае, если вам не удалось с ними поладить, или если вы хотите поступиться
какой-то частью функционала взамен на быстродействие.
n Поддерживаются два типа туннелей: IP и
Ethernet, соответственно называемые routed и bridged. Таким образом, появляется
возможность туннелировать как IP-подсети, так и виртуальные Ethernet-адаптеры.
n Отлично работает в сетях, где адреса
распределяются с помощью DHCP. Помогает подключаться к VPN-клиентам, попадающим
в Интернет через dial-up.
n Позволяет создать туннели поверх NAT, несмотря
на то что NAT изменяет содержимое заголовков передаваемых пакетов.
n Дает возможность работать с любыми механизмами
шифрования, встроенными в OpenSSL для защиты передаваемого трафика. А это, в
свою очередь, позволяет каждому клиенту выбрать тип, режим работы (CBC, CFB,
OFB) и размер ключа шифра в соответствии с индивидуальными предпочтениями.
n Для аутентификации датаграмм, пересылаемых по
туннелю, можно использовать HMAC-дайджест.
n В случае если в передаваемых данных есть
повторяющиеся последовательности, для их сокрытия будет использован алгоритм
explicit IV.
n Каждая датаграмма помечается с помощью
специальных ID, создаваемых на основе времени отправки и номера
последовательности. Таким образом предотвращается возможность повторного
проигрывания злоумышленником последовательности записанных пакетов.
n В качестве дополнительной меры безопасности
может быть использован протокол TLS, позволяющий аутентифицировать сессию с
помощью динамического обмена сертификатами. Довольно большой оптимизации
быстродействия при динамическом обмене SSL/TLS-ключами позволяет добиться
использование мультипоточной библиотеки pthread. Таким образом, даже частый
обмен между сервером и клиентом ключами размером более чем 2048 байт
практически не влияет на скорость передачи туннелируемых данных.
n Для увеличения безопасности OpenVPN позволяет
переместить себя в chroot-окружение и снижает свои привилегии после старта так,
чтобы отлично работать от имени самого бесправного пользователя системы.
n Еще одним полезным с точки зрения безопасности
свойством является наличие ключа --mlock. Он позволяет запретить OpenVPN
записывать в процессе работы на жесткий диск какую-либо информацию, связанную с
секретными ключами и данными, передаваемыми по туннелю.
n В связи с тем, что данная программа является
всего лишь обычным пользовательским приложением, а не частью ядра, она может
вполне мирно сосуществовать с другими приложениями, использующими
tun/tap-туннели.
n OpenVPN создавался для тесной интеграции с
пользовательскими скриптами и другими высокоуровневыми приложениями. Что в свою
очередь дает возможность по первому требованию легко создавать и уничтожать
туннели.
n Позволяет удобно работать через межсетевые
экраны с контролем состояния соединения. В случае если по туннелю не передаются
данные, OpenVPN позволяет через определенные промежутки времени посылать ping,
для того чтобы не дать межсетевым экранам разорвать соединение из-за
неактивности.
В данной статье мы будем работать только с
маршрутизируемыми (routed) туннелями, а разговор о туннелях типа мост (bridge)
отложим до следующего раза. Как я уже упомянул ранее, маршрутизируемый туннель
умеет работать только с TCP/IP-трафиком. Соответственно широковещательный трафик
через него не пройдет. А это значит, что некоторые протоколы вроде Microsoft
Netbios работать поверх нашего туннеля не смогут.
Задачей на сегодня будет соединение через VPN
трех удаленных филиалов одной организации. Будем считать, что они называются
магазин, склад и офис. В каждом из филиалов стоит маршрутизатор, имеющий на
борту по два реальных и два виртуальных сетевых интерфейса. Первый из реальных
интерфейсов направлен во внутреннюю локальную сеть с серым адресным
пространством, а второй – в Интернет. Адреса для внешних интерфейсов выданы нам
провайдером и принадлежат к сети 80.80.20.0/24. Для виртуальных tun-интерфейсов
выбрана подсеть 10.3.0.0/24.
Таблица 1
|
ОС
|
Внутренний
интерфейс
|
Внешний
интерфейс
|
Виртуальные
интерфейсы
|
|
ALT Linux Compact
2.3
|
10.10.140.1
|
eth0
|
80.80.20.131
|
eth1
|
10.3.0.6
10.3.0.9
|
tun1
tun0
|
|
FreeBSD 4.10
|
10.10.120.1
|
lnc0
|
80.80.20.129
|
lnc1
|
10.3.0.1
10.3.0.10
|
tun1
tun0
|
|
Windows 2000
Professional
|
10.10.130.1
|
AMD PcNet #1
|
80.80.20.128
|
AMD PcNet #2
|
10.3.0.2
10.3.0.5
|
FreeBSD
Linux
|
Более наглядно все вышеуказанное отображено на
приведенной схеме.

Итак, начнем установку пакетов на ALT Linux. В системном
репозитарии есть все, что нам может понадобиться.
# apt-get update
# apt-get install iptables
openssl liblzo liblzo-devel openvpn
После удачного завершения установки создаем
пользователя openvpn, входящего в группу openvpn. Процессы openvpn, стартуя от
имени пользователя root, будут снижать свои права, чтобы с наименьшими
привилегиями работать от имени вышеуказанного пользователя. Согласитесь, что
дополнительная безопасность никому не помешает.
# useradd openvpn
Теперь можно приступить к тестам общей
работоспособности openvpn. Первым делом нужно посмотреть, какие из алгоритмов
шифрования нам доступны:
# openvpn
--show-ciphers
The following
ciphers and cipher modes are available for use with OpenVPN. Each cipher shown
below may be used
as a parameter to
the --cipher option. The default key size is shown as well as whether or not
it can be changed with
the --keysize
directive. Using a CBC mode is recommended.
DES-CBC 64 bit
default key (fixed)
RC2-CBC 128 bit
default key (variable)
DES-EDE-CBC 128
bit default key (fixed)
DES-EDE3-CBC 192
bit default key (fixed)
DESX-CBC 192 bit
default key (fixed)
BF-CBC 128 bit
default key (variable)
RC2-40-CBC 40 bit
default key (variable)
CAST5-CBC 128 bit
default key (variable)
RC5-CBC 128 bit
default key (variable)
RC2-64-CBC 64 bit
default key (variable)
AES-128-CBC 128
bit default key (fixed)
AES-192-CBC 192
bit default key (fixed)
AES-256-CBC 256
bit default key (fixed)
Довольно неплохо. Стоит обратить внимание на
надписи variable и fixed возле каждого наименования шифра. Они указывают,
существует ли возможность самостоятельно выбирать размер ключа.
Для аутентификации каждой получаемой
UDP-датаграммы применяется так называемый механизм дайджеста. Смотрим доступные
дайджесты:
# openvpn
--show-digests
The following
message digests are available for use with OpenVPN. A message digest is used
in conjunction with the HMAC function,
to authenticate
received packets. You can specify a message digest as parameter to the --auth
option.
MD2 128 bit
digest size
MD5 128 bit
digest size
RSA-MD2 128 bit
digest size
RSA-MD5 128 bit
digest size
SHA 160 bit
digest size
RSA-SHA 160 bit
digest size
SHA1 160 bit
digest size
RSA-SHA1 160 bit
digest size
DSA-SHA 160 bit
digest size
DSA-SHA1-old 160
bit digest size
MDC2 128 bit
digest size
RSA-MDC2 128 bit
digest size
DSA-SHA1 160 bit
digest size
RSA-SHA1-2 160
bit digest size
DSA 160 bit
digest size
RIPEMD160 160 bit
digest size
RSA-RIPEMD160 160
bit digest size
MD4 128 bit
digest size
RSA-MD4 128 bit
digest size
Сначала нужно сгенерировать статический ключ, с
помощью которого в дальнейшем будет производиться шифрование потока.
#openvpn --genkey --secret
/etc/openvpn/static.key
Внутри файла static.key должно появиться что-то
похожее на следующие данные:
#
# 2048 bit
OpenVPN static key
#
-----BEGIN
OpenVPN Static key V1-----
e0f33474467d686a677b07952b238526
017a11571de4fd598a7931d1598f2af7
9266ed5888e45b09aedce3ae5699d571
99f4276abb209c13a131315ab4bcf057
47982becf8e316d1b63e5bf6b1537227
363855b63eb5cf7e66f8f7c2a4aa8bf1
c14a7ba7836f3a3159d241f30e5cf385
26d44680342e8f0c1e6077790f79db6d
882a6a94c2886eeaf5fec5be804b0d6b
a09bb003fdc86a6cd3323511f72e4a37
f2af8939a3ebfc3716301ae83c618869
5dd326e6c914610a028a87648766bc94
6661bf72c1e51f17a5d8abb1998bec04
6366ca3b3c0de7a43765ed59625d17dc
3490e6f07059a7d200de0937b059e9e4
62d041d1392c2d4e47b3b8ba73e27b0b
-----END OpenVPN
Static key V1-----
После этого можно провести тестирование
криптосистемы с использованием только что созданного ключа.
# openvpn
--test-crypto --secret /etc/openvpn/static.key
Sat Jul 17
23:27:53 2004 0[0]: OpenVPN 1.6.0 i686-alt-linux-gnu [SSL] [LZO] [PTHREAD]
built on Jun 12 2004
Sat Jul 17
23:27:53 2004 1[0]: PTHREAD support initialized
Sat Jul 17
23:27:53 2004 2[0]: Entering OpenVPN crypto self-test mode.
Sat Jul 17
23:27:53 2004 3[0]: TESTING ENCRYPT/DECRYPT of packet length=1
Sat Jul 17
23:27:53 2004 4[0]: TESTING ENCRYPT/DECRYPT of packet length=2
Sat Jul 17
23:27:53 2004 5[0]: TESTING ENCRYPT/DECRYPT of packet length=3
------ <вырезано>
------
Sat Jul 17
23:27:54 2004 2604[0]: TESTING ENCRYPT/DECRYPT of packet length=1299
Sat Jul 17
23:27:54 2004 2605[0]: TESTING ENCRYPT/DECRYPT of packet length=1300
Sat Jul 17
23:27:54 2004 2606[0]: OpenVPN crypto self-test mode SUCCEEDED.
Судя по надписям, все работает вполне приемлемо.
Конечно, не стоит забывать, что статический ключ имеет один большой недостаток.
Если злоумышленнику удастся его раздобыть, то он сможет расшифровать все
данные, которые передавались по сети. С динамическим ключом такое развитие
событий нам бы не угрожало. В самом худшем случае можно было бы расшифровать
только малую часть трафика.
Теперь нужно создать конфигурационные файлы,
которые опишут наши туннели. Первый из них описывает туннель между машинами
Linux и FreeBSD, а второй – между Linux и Windows. Файл linux-freebsd.conf:
proto udp
dev tun
port 5000
comp-lzo
ping 15
verb 3
user openvpn
group openvpn
remote 80.80.20.129
ifconfig 10.3.0.9 10.3.0.10
route 10.10.120.0
255.255.255.0 10.3.0.10
secret /etc/openvpn/static.key
auth MD5
cipher DES-CBC
tun-mtu 1500
Файл linux-windows.conf:
proto udp
dev tun
port 5002
comp-lzo
ping 15
verb 3
user openvpn
group openvpn
remote 80.80.20.128
ifconfig 10.3.0.6 10.3.0.5
route 10.10.130.0
255.255.255.0 10.3.0.5
secret /etc/openvpn/static.key
tun-mtu 1500
auth MD5
cipher DES-CBC
Начинаем разбираться по порядку,
что означает каждая из этих опций.
n proto – протокол, используемый для передачи
данных. Может принимать значения udp, tcp-client, tcp-server. Настоятельно
рекомендуется использовать udp, потому что туннелирование поверх TCP создает
слишком большие накладные расходы. Впрочем, если нет другого выхода, то и TCP
сойдет. В таком случае нужно на одном конце туннеля установить настройки этой
переменной как tcp-server, а на другом – как tcp-client. Соответственно
отвечать за инициацию соединения будет машина со значением tcp-client. По
умолчанию эта переменная имеет значение udp, поэтому если вы с этим согласны,
то ее определение можно в дальнейшем не использовать.
n port – порт, на котором нужно ждать соединений.
Должен быть одинаковым на обоих концах туннеля. Номера портов для разных
туннелей не могут совпадать.
n dev – тип виртуального устройства туннеля.
Может принимать значения tun, tap, null. В этом случае OpenVPN будет пытаться динамически
выбрать и задействовать первое свободное устройство данного типа. Если же ему
это не удается, то нужно будет четко указать имя устройства с помощью опции
dev-node. Например, dev-node tun1.
n comp-lzo – включение упаковки потока данных. В
случае если поток все же не стоило упаковывать, размер передаваемых данных
увеличится всего на один байт. Впрочем, за все время эксплуатации данного
программного комплекса я не встречал случая, когда система адаптивной
компрессии ошиблась и стала пытаться применить сжатие там, где делать этого не
стоило.
n ping – в случае если по VPN-каналу не
передается никаких данных, приказывается отправлять ping каждые n секунд, чтобы
не позволить соединению разорваться из-за простоя. Полезно в случае, если между
конечными точками vpn находятся межсетевые экраны с контролем состояния.
n verb – уровень подробности выводимых сообщений.
Чем больше число, тем многословнее и педантичнее программа будет рассказывать о
том, что происходит у нее внутри. Верхним пределом для этой переменной является
число 11. Данная опция чаще всего используется при отладке и первоначальной
настройке туннелей.
n user, group – имя пользователя и группы, от
имени которой будет работать программа. Первоначально openvpn стартует от имени
root и, прочитав все интересующие файлы, снижает привилегии до указанного
уровня.
n remote – IP-адрес хоста, представляющего из
себя дальнюю сторону туннеля. Если его не указать, то openvpn будет пассивно
принимать все входящие соединения, не пытаясь самостоятельно соединяться с
удаленной машиной. Затем все полученные соединения должны будут пройти
авторизацию. Данный режим удобен для работы с dial-up системами, у которых
постоянно меняется IP-адрес.
n ifconfig – назначает виртуальному tun/tap
интерфейсу IP-адрес. Заодно указывает адрес удаленного виртуального интерфейса.
Это необходимо, потому что туннель работает как стандартное соединение
«точка-точка».
n route – описывает маршрут, который должны
пройти пакеты, чтобы попасть в удаленную сеть. Можно обозначить маршрут двумя способами.
Либо с помощью этой настройки, либо переменной up, значением которой необходимо
указать имя командного скрипта, отвечающего за выполнение правильной настройки
маршрутизации. В случае если вы пользовались первым способом настройки
маршрутизации, то openvpn самостоятельно удалит из таблицы маршрутов нужную
запись, когда пользователь попросит его завершить работу. Ну а если прибегали к
услугам опции up, то необходимо также описать опцию down, которая будет
указывать на скрипт, выполняющий самостоятельные действия по удалению маршрута.
n secret – указывает имя файла, в котором
хранится статический ключ, используемый для шифрования потока.
n tun-mtu – максимальный размер пакета,
передаваемого по виртуальному интерфейсу. Пакеты большего размера будут разбиваться
на несколько кусков и передаваться последовательно отдельными датаграммами.
Желательно, чтобы на обоих концах туннеля значение этой переменной было
одинаково, иначе можно провести несколько интересных часов в забавном поиске
причины, почему авторизация и передача первых пакетов проходит нормально, а
затем все начинает работать весьма медленно и нестабильно.
n auth – наименование алгоритма, используемого
для аутентификации приходящих пакетов. В моем случае это MD5. Хотя никто не
мешает взять любой другой.
n cipher – алгоритм, используемый для шифрования
пакетов. Blowfish выбран потому, что является весьма стойким и в то же время
достаточно быстрым. В случае если хочется повысить надежность шифрования, нужно
использовать переменную keysize и указывать большой размер ключа. По умолчанию
Blowfish использует ключ длиной 128 бит, хотя максимально возможный размер –
448 бит.
На этом установку и первоначальную настройку
пакета на Linux-машине можно считать завершенной. Переходим на FreeBSD. Как
человек рассудительный и здравомыслящий, предпочитаю устанавливать сложное
программное обеспечение из портов.
# cd /usr/ports/archivers/lzo
# make install clean
# cd ../../security/openssl
# make install clean
# cd ../openvpn
# make install clean
К сожалению, несмотря на то что перед началом
инсталляции я обновил список портов, система упрямо не хотела ставить
openvpn-1.6.0, а вместо него подсовывала openvpn-1.4.0.
Дабы не наступать на грабли и впоследствии не
ломать голову над совмещением разных версий, пришлось деинсталлировать ранее
установленную версию 1.4.0. Хотя в документации описано, как «подружить» старые
и новые версии, я решил рисковать.
# make deinstall
Отправляемся по адресу: http://www.freebsd.org/cgi/ports.cgi?query=openvpn&stype=all
и с помощью поиска выясняем, что исходные тексты самой свежей версии порта
openvpn-1.6.0 не желают скачиваться. Ну на нет и суда нет. Видимо, такова
судьба, и нам придется снова пойти в обход. Берем отсюда бинарный пакет ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-4-stable/All/openvpn-1.6.0.tgz
и устанавливаем его с помощью утилиты pkg_add.
# pkg_add openvpn-1.6.0.tgz
Не забываем добавить в систему пользователя и
группу openvpn.
# adduser openvpn
Затем создаем директорию /etc/openvpn, где у нас
будут храниться файлы с настройками и ключом. С помощью какого-либо безопасного
транспорта переносим с Linux-машины файл static.key. В качестве средства,
пригодного для этой цели, можно использовать scp, sftp, архив с паролем или
просто дискету, переданную доверенным лицом. Теперь давайте посмотрим на
содержимое конфигурационных файлов.
Файл freebsd-linux.conf:
dev tun
port 5000
comp-lzo
ping 15
verb 3
user openvpn
group openvpn
remote 80.80.20.131
ifconfig 10.3.0.10 10.3.0.9
route 10.10.140.0
255.255.255.0 10.3.0.9
secret
/etc/openvpn/static.key
auth MD5
cipher DES-CBC
tun-mtu 1500
comp-lzo
Файл freebsd-windows.conf:
dev tun
remote 80.80.20.128
port 5001
ifconfig 10.3.0.1 10.3.0.2
route 10.10.130.0
255.255.255.0 10.3.0.2
secret
/etc/openvpn/static.key
ping 10
verb 3
tun-mtu 1500
user openvpn
group openvpn
auth MD5
cipher DES-CBC
comp-lzo
Я думаю, что, пользуясь предыдущими объяснениями,
будет довольно легко понять все используемые настройки. Права на директорию
/etc/openvpn и файлы в ней должны позволять чтение только пользователю root и
группе wheel.
Если очень хочется, то можно выполнить проверку
доступных шифров так же, как мы делали это для Linux.
Наконец-то мы готовы к запуску первого из наших
туннелей. На Linux-машине выполняем следующую команду:
# openvpn --config
/etc/openvpn/linux-freebsd.conf
И соответственно на FreeBSD делаем так:
# openvpn --config
/etc/openvpn/freebsd-linux.conf
На терминале Linux должны появляться следующие
надписи:
Tue Jul 20
23:14:07 2004 0[0]: OpenVPN 1.6.0 i686-alt-linux-gnu [SSL] [LZO] [PTHREAD]
built on Jun 12 2004
Tue Jul 20
23:14:07 2004 1[0]: Static Encrypt: Cipher 'DES-CBC' initialized with 64 bit
key
Tue Jul 20
23:14:07 2004 2[0]: Static Encrypt: Using 128 bit message hash 'MD5' for HMAC
authentication
Tue Jul 20
23:14:07 2004 3[0]: Static Decrypt: Cipher 'DES-CBC' initialized with 64 bit
key
Tue Jul 20
23:14:07 2004 4[0]: Static Decrypt: Using 128 bit message hash 'MD5' for HMAC
authentication
Tue Jul 20
23:14:07 2004 5[0]: LZO compression initialized
Tue Jul 20
23:14:07 2004 6[0]: TUN/TAP device tun0 opened
Tue Jul 20
23:14:07 2004 7[0]: /sbin/ifconfig tun0 10.3.0.9 pointopoint 10.3.0.10 mtu 1500
Tue Jul 20
23:14:07 2004 8[0]: /sbin/route add -net 10.10.120.0 netmask 255.255.255.0 gw
10.3.0.10
Tue Jul 20
23:14:07 2004 9[0]: Data Channel MTU parms [ L:1541 D:1541 EF:41 EB:19 ET:0
EL:0 ]
Tue Jul 20
23:14:07 2004 10[0]: Local Options hash (VER=V3): '0777768b'
Tue Jul 20
23:14:07 2004 11[0]: Expected Remote Options hash (VER=V3): '199e889a'
Tue Jul 20
23:14:07 2004 12[0]: GID set to openvpn
Tue Jul 20
23:14:07 2004 13[0]: UID set to openvpn
Tue Jul 20
23:14:07 2004 14[0]: PTHREAD support initialized
Tue Jul 20
23:14:07 2004 15[0]: UDPv4 link local (bound): [undef]:5000
Tue Jul 20
23:14:07 2004 16[0]: UDPv4 link remote: 80.80.20.129:5000
Tue Jul 20
23:14:07 2004 17[0]: read UDPv4 [ECONNREFUSED]: Connection refused (code=111)
Tue Jul 20
23:14:14 2004 18[0]: Peer Connection Initiated with 80.80.20.129:5000
Ну а FreeBSD-машина должна говорить что-то вроде
этого:
Tue Jul 20
23:14:14 2004 0: OpenVPN 1.6.0 i386-portbld-freebsd4.10 [SSL] [LZO] built on
Jun 8 2004
Tue Jul 20 23:14:14
2004 1: Static Encrypt: Cipher 'DES-CBC' initialized with 64 bit key
Tue Jul 20
23:14:14 2004 2: Static Encrypt: Using 128 bit message hash 'MD5' for HMAC
authentication
Tue Jul 20
23:14:14 2004 3: Static Decrypt: Cipher 'DES-CBC' initialized with 64 bit key
Tue Jul 20
23:14:14 2004 4: Static Decrypt: Using 128 bit message hash 'MD5' for HMAC
authentication
Tue Jul 20
23:14:14 2004 5: LZO compression initialized
Tue Jul 20
23:14:14 2004 6: gw 80.80.120.129
Tue Jul 20
23:14:14 2004 7: TUN/TAP device /dev/tun0 opened
Tue Jul 20
23:14:14 2004 8: /sbin/ifconfig tun0 10.3.0.10 10.3.0.9 mtu 1500 netmask
255.255.255.255 up
Tue Jul 20
23:14:14 2004 9: /sbin/route add -net 10.10.140.0 10.3.0.9 255.255.255.0
add net
10.10.140.0: gateway 10.3.0.9
Tue Jul 20 23:14:14
2004 10: Data Channel MTU parms [ L:1541 D:1541 EF:41 EB:19 ET:0 EL:0 ]
Tue Jul 20
23:14:14 2004 11: Local Options hash (VER=V3): '199e889a'
Tue Jul 20
23:14:14 2004 12: Expected Remote Options hash (VER=V3): '0777768b'
Tue Jul 20
23:14:14 2004 13: GID set to openvpn
Tue Jul 20
23:14:14 2004 14: UID set to openvpn
Tue Jul 20
23:14:14 2004 15: UDPv4 link local (bound): [undef]:5000
Tue Jul 20
23:14:14 2004 16: UDPv4 link remote: 80.80.20.131:5000
Tue Jul 20
23:14:18 2004 17: Peer Connection Initiated with 80.80.20.131:5000
Как только увидите надпись «Peer Connection
Initiated with», считайте, что дело сделано. Теперь с помощью команды ping
можно проверить, видны ли оконечные адреса из соединяемых частных сетей. В
нашем примере это 10.10.120.1 и 10.10.140.1. Не забываем настроить компьютеры,
находящиеся в наших локальных сетях так, чтобы они считали машины Linux и
FreeBSD шлюзами по умолчанию.
Кстати, стоит отметить, что openvpn может вполне
успешно работать и без всяких конфигурационных файлов. Дело в том, что все
параметры можно передать в программу и из командной строки. К примеру, для
поднятия того же самого туннеля можно было скомандовать вот так:
# openvpn --remote
80.80.20.128 --dev tun --port 5001 --ifconfig 10.3.0.1 10.3.0.2 --route
10.10.130.0 255.255.255.0 10.3.0.2 \
--secret
/etc/openvpn/static.key --ping 10 --verb 3 --tun-mtu 1500 --user openvpn
--group openvpn --auth MD5 --cipher DES-CBC
Хотя, с моей точки зрения, данный способ выглядит
несколько громоздко.
Стоит отметить один интересный факт: дистрибутив
openvpn для Linux устанавливает в систему скрипт /etc/rc.d/init.d/openvpn,
который помогает удобно управлять нашими туннелями с помощью команды service
openvpn. Главной особенностью скрипта является способность поднять туннели для
всех *.conf-файлов, находящихся в /etc/openvpn. Таким образом, нам не надо
придумывать, как автоматически запустить требуемое количество экземпляров
openvpn с нужными настройками после перезагрузки системы.
Во FreeBSD тоже есть скрипт подобного
предназначения. Сразу после инсталляции он обычно находится в
/usr/local/etc/rc.d/openvpn.sh.sample. Посмотрев внутрь него, понимаем, что он
совершенно бесполезен, так как практически ничего не умеет делать. Поэтому нам
придется смастерить свой собственный вариант такого скрипта. Для этого нужно
создать файл openvpn.sh и внести в него следующие данные:
#! /bin/sh
case x$1 in
xstart)
/usr/local/sbin/openvpn --config /etc/openvpn/freebsd-linux.conf &
/usr/local/sbin/openvpn --config /etc/openvpn/freebsd-windows.conf &
;;
xstop)
killall -SIGTERM
openvpn
route delete
10.10.130.0
route delete
10.10.140.0
;;
*) echo >&2
"Usage: $0 {start|stop}"
esac
Обязательно кладем файл в /usr/local/etc/rc.d/ и
даем ему право на выполнение. Стоит обратить внимание на наличие знака «&»
после запуска каждого экземпляра openvpn. Сделано это потому, что данная
программа жестко привязывается к терминалу, с которого была запущена.
Соответственно при отсутствии этого знака второй процесс openvpn не запустится
до тех пор, пока терминал не освободится, а этого при правильном развитии
событий не должно произойти никогда. Вторым важным моментом является наличие
команд route, удаляющих записи о маршрутах в той ветке скрипта, которая отвечает
за выполнение действия stop. Удалять маршруты приходится вручную, потому что к
моменту завершения работы openvpn выполняется от лица одноименного пользователя
и группы, а изменять таблицу маршрутизации имеет право только root. Конечно,
можно было бы портировать под FreeBSD версию скрипта, поставляющуюся в
комплекте с Linux-версией программы, но сейчас заниматься этим как-то недосуг.
Возможно, я сделаю это в следующей статье.
Настало время перейти к настройке
Windows-системы. На первый взгляд здесь все довольно просто. Берем дистрибутив
для этой платформы на родном сайте программы http://prdownloads.sourceforge.net/openvpn/openvpn-1.6.0-install.exe.
Затем запускаем только что скачанный инсталлятор и методично жмем на кнопки
«Далее» и «ОК». После установки в систему будет добавлен новый сетевой
интерфейс со странным именем «Подключение по локальной сети 3».

Если присмотреться внимательно к свойствам
данного подключения, то можно заметить что оно представляет собой не что иное,
как интерфейс tap.

Тут стоит сделать одну важную оговорку: под
Windows не существует различия между tun- и tap-устройствами. А еще точнее было
бы сказать, что такая реализация tap-драйвера позволяет устройству работать в
любом из двух режимов.
Для нас столь длинное название устройства
неудобно, поэтому переименовываем его во что-нибудь более краткое и
информативное. Например, в Linux. Затем с помощью меню «Пуск –> Программы
–> Open –> VPNAdd a new TAP-win32 virtual ethernet adapter» создаем еще
один виртуальный интерфейс и переименовываем его во FreeBSD. Думаю, название
каждого из этих интерфейсов достаточно красноречиво говорит об их
предназначении. Надеюсь, что все еще помнят, зачем мы создавали файл
static.key. Если это действительно так, то копируем его в C:\Program
Files\OpenVPN\config\ под именем staic.txt. По непонятной причине файлы с
расширением .key openvpn, работающие под Windows, не воспринимаются как
секретные ключи. Затем создаем конфигурационные файлы наших туннелей. Стоит
обратить внимание на тот факт, что для успешной работы у этих файлов должно
быть расширение .ovpn.
Файл windows-freebsd.ovpn:
remote 80.80.20.129
dev-node FreeBSD
dev tun
port 5001
ifconfig 10.3.0.2 10.3.0.1
secret static.txt
ping 10
verb 3
route 10.10.120.0
255.255.255.0 10.3.0.1
auth MD5
cipher DES-CBC
comp-lzo
Файл windows-linux.ovpn:
remote 80.80.20.131
dev tun
dev-node Linux
port 5002
ifconfig 10.3.0.5 10.3.0.6
secret static.txt
ping 10
verb 3
route 10.10.140.0 255.255.255.0
10.3.0.6
tun-mtu 1500
comp-lzo
В сущности, все тесты, которые мы использовали до
этого, отлично работают и под управлением Windows. Поэтому, если есть желание,
можете выполнить openvpn с параметрами --show-digests и --show-ciphers.
Единственное, на что стоит обратить внимание, – это обязательное наличие в
конфигурационном файле записи dev-node с именем используемого устройства. К
сожалению, Windows умеет автоматически находить и использовать нужное
виртуальное устройство туннеля только в том случае, если оно в системе
представлено в единственном числе. Кстати, стоит отметить тот факт, что в
случае работы устройства tun под Windows использовать для туннеля какие попало
адреса из подсети 10.3.0.0 не получится, придется выбирать из таблицы, выводимой
командой openvpn --show-valid-subnets.
Как и под UNIX-системами, можно поднять туннель
вызовом openvpn с указанием имени используемого конфигурационного файла, а
можно и без него, просто перечислив все нужные ключи в командной строке. Есть
еще два способа запуска туннеля. Первый из них состоит в том, что нужно с
помощью проводника перейти в директорию C:\Program Files\OpenVPN\config\ и
щелкнуть правой клавишей на файле конфигурации. В ниспадающем меню выбрать
«Start OpenVPN on this config file». А можно поступить более умно и включить
службу OpenVPN, которая самостоятельно будет заботиться о том, чтобы запустить
по одному экземпляру программы для каждого конфигурационного файла.

На этом радостном этапе установку и настройку
можно считать завершенными. На обоих UNIX-машинах сначала останавливаем, а
затем снова запускаем сервисы openvpn.
# service openvpn stop
# service openvpn start
#
/usr/local/etc/rc.d/openvpn.sh stop
#
/usr/local/etc/rc.d/openvpn.sh start
То же самое проделываем и под управлением Windows.
После этого все вышеописанные туннели должны
правильно подняться и заработать без сбоев. Соответственно таблица интерфейсов,
получаемая с помощью ifconfig, на Linux должна выглядеть так:
inet
addr:10.10.140.1 Bcast:10.10.140.255 Mask:255.255.255.0
UP
BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1
RX
packets:7716 errors:0 dropped:0 overruns:0 frame:0
TX
packets:5266 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX
bytes:8046612 (7.6 Mb) TX bytes:401033 (391.6 Kb)
Interrupt:10 Base address:0x1080
eth1 Link
encap:Ethernet HWaddr 00:0C:29:07:61:3A
inet
addr:80.80.20.131 Bcast:80.80.20.255 Mask:255.255.255.0
UP
BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1
RX
packets:7866 errors:0 dropped:0 overruns:0 frame:0
TX
packets:5466 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX
bytes:8046612 (7.6 Mb) TX bytes:401033 (391.6 Kb)
Interrupt:10 Base address:0x1080
lo Link
encap:Local Loopback
inet
addr:127.0.0.1 Mask:255.0.0.0