"Нас Атакуют!" Изобличи козни лукавого, запрети диаволу
Подключение к VPN через Openconnect на Linux и OpenBSD
Благодаря тотальной слежке за пользователями Интернета применение VPN технологий стало неотъемлемой частью нашей профессиональной деятельности. Множество людей вынуждены использовать защищённые корпоративные ресурсы, при этом стандартные средства VPN подключений значительно ограничивают наши возможности, применяя разнообразные сетевые правила и изменяя привычное окружение клиента.
В то же время пользователям становится всё более необходимо оставаться подключёнными к нескольким сетям одновременно, выполняя отдельные задачи для разных частей организации (или вообще для разных клиентов). В такой ситуации очень часто приходится использовать несколько компьютеров, перезагружаться в разные ОС или, как минимум, постоянно переподключаться к разным VPN серверам.
В предлагаемой заметке я показываю как подобные неудобства могут быть легко устранены при использовании всего одного клиента VPN на одной и той же физической системе, под управлением Linux или OpenBSD. Приводится простой пример одновременного подключения к двум независимым VPN сетям.
Прежде чем мы продолжим, я хотел бы привести строки из Евангелия:
..................... == Вторая книга Паралипоменон == .........................
=== Глава 7, Стих 13 ===
13 Если Я заключу небо и не будет дождя, и если повелю саранче поядать землю, или пошлю моровую язву на народ Мой,
14 и смирится народ Мой, который именуется именем Моим, и будут молиться, и взыщут лица Моего, и обратятся от худых путей своих, то Я услышу с неба и прощу грехи их и исцелю землю их.
Лично для вас благая весть - Единородный Сын Божий Иисус Христос любит вас, Он взошёл на крест за ваши грехи, был распят и на третий день воскрес, сел одесную Бога и открыл нам дорогу в Царствие Небесное.
В жизни каждого случаются беды и несчастия, они преслeдуют почти неотступно нас, наши семьи и нашу страну. И мы в глубоком недоумении и с разочарованием спрашиваем "За что нам эта беда?". Нам кажется что мы живём честно, стараемся не делать зла, помогать другим - каким же образом постигают нас все эти напасти?
Господь Бог видит наши сердца и знает истинные намерения наших душ. Даже в те моменты, когда мы успешно убедили себя что делаем добро или "зло во имя добра"... И Он наказывает нас по мере наших проступков - и наказание сие постигает каждого, от простолюдина до президента, охватывая всю страну, за преступления, совершаемые в ней. Так что винить в своих бедах мы должны самих себя - а точнее, наше отступление от Библейских ценностей и Божиих заповедей. Перечитаем их прямо сейчас! Сверим курс наших жизней со Словом Божиим. И, как написано, исправив свои пути, заслужим Божие прощение - а с ним придёт и избавление от бед и несчастий. При этом мы должны пройти дорогой исправления полностью и до конца, решительно оставляя позади такие соблазнительные и уже привычные мирские удовольствия.
Покайтесь, примите Иисуса как вашего Спасителя, ибо наступают последние времена и время близко - стоит Судья у ворот.
Пожалуйста, в своих каждодневных трудах, какими бы занятыми вы себе ни казались - находите время для Бога, Его заповедей и Библии.
На главной странице этого сайта вы найдете программу для чтения Библии в командной строке - буду очень рад если программа окажется полезной. Пожалуйста, читайте Библию, на экране или в печатном виде - вы будете искренне удивлены как много там сказано лично про вас и ваши обстоятельства.
Вернёмся к нашим техническим деталям.
В заметке я рассмотрю достаточно простой и часто встречающийся случай. Предположим что по специфике работы нам необходимо подключиться к какой-либо сети клиента "A", где находится так называемый "jump host", с которого осуществляются все последующие подключения к компьютерам клиента "А". В это же самое время мне надо быть подключенным к сети клиента "Б", где находится вебсайт системы мониторинга и где я слежу за производительностью только что введённого в строй сервера. На фоне всего этого мне необходим стабильный доступ к моим собственным серверам в Интернет, откуда я получаю почту, загружаю файлы и звоню по телефону через VOIP. Компании клиентов А и Б используют свои собственные VPN сети, мои сервера находятся в открытом интернете, в датацентре одного из глобальных VPS провайдеров.
Я вынужден использовать единственную рабочую станцию под управлением OpenBSD (или Linux, если пожелаете) и мне необходимо иметь открытыми и одновременно работающими следующие программы:
Для всех VPN подключений я использую последнюю версию программы "openconnect". Доступ в интернет предоставляется моим ISP через default gateway 10.0.0.138.
Как результат, я не могу использовать стандартный скрипт "/etc/vpnc/vpnc-script", поскольку каждое VPN подключение будет изменять мою таблицу маршрутизации, делая работу с другими клиентами невозможной. Кроме того, я хочу понимать что происходит "за сценой" при подключении к каждому из клиентов и иметь полную уверенность что пакеты клиента "А" не попадают к клиенту "Б" и тому подобное.
Про типы VPN и клиентов для них
Прежде чем обсуждать подробности подключения, я приведу краткую информацию o VPN вообще и клиенте openconnect.
Типы VPN
Изначально одним из самых распространённых и наверняка самым надёжным являлся набор протоколов iPSec. Моё мнение - он и остаётся на сегодня единственным более или менее приемлемым решением.
Поскольку IPSec "на коленках" настраивался плохо и надо было всё-таки нанимать специалиста для его внедрения (что является безусловным плюсом, если интересует результат), понадобилось удешевить и упростить процесс. Так появились SSL VPNы, которыми мы и пользуемся сейчас.
Технически, IPSec работает на уровне L3 OSI модели и реализован внутри ядра ОС. Отсюда и происходят его основные преимущества - производительность, прозрачность, защищённость и т.п. Напротив, SSL VPN работает вне ядра ОС (в userspace) и использует "верхние" уровни OSI модели. SSL VPN может работать "через вебброузер" (SSL Portal VPN) или как туннель (SSL Tunnel VPN).
Реализация VPN
Для "аппаратной" реализации обоих типов VPN (IPSec и SSL VPN) традиционно используются Cisco продукты - например, старенький Cisco VPN 3000 Concentrators или поновее ASA 5500.
Естественно были предприняты (весьма успешные) попытки создания бесплатных "софтверных" конкурирующих с Cisco реализаций SSL VPN - именно таковым и является OpenVPN. (Читайте дальше про openconnect)
Клиентский доступ к VPN
В мире Windows всё просто - открыл Cisco VPN Client (Anyconnect или более старый Easy Cisco VPN Client), вбил данные - и ты уже в корпоративной сети.
В большинстве простых ситуаций подключения к единственному корпоративному VPN лично я порекомендовал бы именно такой подход - устанавливаете отдельный лаптоп с Windows, на нём используете стандартный Cisco клиент, подключаетесь к VPN. На лаптопе работает VNC server или Remote Desktop, который вы используете с вашей линукс машины. Просто и всегда работает (но такое решение нельзя назвать изящным).
Естественно, появились и альтернативные клиенты, конкурирующие с Cisco AnyConnect клиентом.
Их два на сегодня:
При этом openconnect может работать и как VPN сервер, выполняя те же функции что и OpenVPN server.
Подводя итоги
Для организации VPN инфраструктуры в вашей компании у вас есть выбор:
Клиентский доступ осуществляется:
Предлагаемое решение
Для поддержания моего окружения в работоспособном состоянии я буду создавать VPN "тоннель", используя openconnect, но при этом не допуская выполнения никаких скриптов. Необходимые изменения в таблице маршрутизации будут сделаны вручную. Таким образом я смогу сохранить маршрут "по умолчанию" и организовать доставку нужных пакетов к соответствующему клиенту.
Предоставляемое провайдером интернет соединение обеспечивает доступ к моим "открытым" серверам, но при этом default gateway не должен изменяться при подключении к VPN.
Число запущенных одновременно программ "openconnect" будет соответствовать числу VPN сетей клиентов, в моём примере двум.
Каждое VPN соединение будет создавать соответствующий "tun" интерфейс, при этом VPN сервер сообщит какой IP адрес был выдан нам как клиенту. Этот IP адрес должен быть присвоен интерфейсу "tun" вручную.
После "поднятия" интерфейса с присвоенным IP адресом, я создам соответствующее правило для маршрутизации пакетов, применяемое только ко вновь созданному "tun" интерфейсу и не изменяющее шлюза "по умолчанию".
После этого необходимая подсеть клиента станет доступной для работы.
Остальные веб-ресурсы "общего назначения" внутри клиентской сети доступны через "SSL VPN Gateway" - специальный прокси веб-сервер, предоставляемый по адресу VPN шлюза. Войдя на этот сервер под именем пользователя, используемым с openconnect, я могу ввести адрес интересующей меня страницы в корпоративной интранет сети и увидеть на экране её "отображение". Такой вид доступа является стандартным в системе SSL VPN и не требует клиентской настройки.
Реализация решения
Для быстрого создания VPN соединения я создам скрипт, выполняющий необходимые действия. Последовательное выполнение скриптов будет устанавливать нужные соединения, не влияя на уже существующие подключения.
Подключение одного VPN клиента
Скрипт для подключения к клиенту "А" приведен ниже:
........ == Послание к Ефесянам святого апостола Павла == ............ === Глава 5, Стих 19 === 18 И не упивайтесь вином, от которого бывает распутство; но исполняйтесь Духом, 19 назидая самих себя псалмами и славословиями и песнопениями духовными, поя и воспевая в сердцах ваших Господу, 20 благодаря всегда за все Бога и Отца, во имя Господа нашего Иисуса Христа, 21 повинуясь друг другу в страхе Божием. (b+/b-, c+/c-, +/-, *) > ~:$ cat vpnA.sh # Run this as root export LC_CTYPE=en_US.UTF-8 VPNHOST=vpn.clientA.com GROUP=A-VPN USER=remote1 PWD=secret1 FILE=/tmp/vpn.out # Add error handling yourself - I am too lazy for this. date echo $PWD | openconnect -b -s empty --no-xmlpost --authgroup $GROUP \ -u $USER --passwd-on-stdin $VPNHOST > \ $FILE 2>&1 # cat $FILE grep "Continuing in background" $FILE echo To stop use \"kill -HUP pid\" IP=`grep "^Connected tun" $FILE | cut -f 4 -d ' ' | cut -f 1 -d ',' ` rm $FILE if [[ `uname` == "Linux" ]] then echo Линукс ifconfig tun0 $IP up ifconfig tun0 route -A inet add -net 10.1.0.0/16 gw $IP dev tun0 route -n -4 ps -ef | grep openconnect | grep -v grep else echo ОпенБСД ifconfig tun0 inet $IP ifconfig tun0 route add -iface -net 10.1/16 $IP route -n show -inet ps -ax | grep openconnect | grep -v grep fi date
Зная диапазон адресов (10.1.0.0/16), выдаваемых клиентам VPN сервером, я могу определить правило маршрутизации, как показано выше. Я предполагаю, что все мои сервера находятся в пределах этой DMZ подсети и не требуют дальнейшей маршрутизации. Если ваша ситуация требует более сложных правил - заведите для каждого клиента отдельный лаптоп и пользуйтесь стандартным клиентом от Cisco.
Параметр "--no-xmlpost" требуется при работе со старыми или плохо сконфигурированными VPN шлюзами, "-s empty" исключает выполнение "vpnc" скриптов, поставляемых вместе с openconnect.
После запуска скрипта "vpnA.sh" команда ifconfig покажет мне новый интерфейс "tun0" с DHCP адресом из подсети 10.1/16, a route покажет новое правило для обмена пакетами с этой сетью напрямую через интерфейс "tun0". Уже существующее правило для отправки всех остальных пакетов через default gateway 10.0.0.138 останется неизменным, обеспечивая доступ к интернету в нормальном режиме, при наличии VPN подключения к сети клиента "А".
Вот как будет выглядеть результат запуска скрипта "vpnA.sh":
lo0: flags=8049mtu 33144 ... inet 127.0.0.1 netmask 0xff000000 iwn0: flags=8843 mtu 1500 ... inet 10.0.0.2 netmask 0xffffff00 broadcast 10.0.0.255 tun0: flags=51 mtu 1300 <---* ... inet 10.1.19.19 --> 0.0.0.0 netmask 0xffff0000 Routing tables Internet: Destination Gateway Flags Refs Use Mtu Prio Iface default 10.0.0.138 UGS 4 64 - 12 iwn0 10.0.0/24 link#2 UC 1 0 - 4 iwn0 10.0.0.2 127.0.0.1 UGS 0 0 33144 8 lo0 10.0.0.138 aa:bb:cc:11:44:22 UHLc 1 9 - 4 iwn0 127/8 127.0.0.1 UGRS 0 0 33144 8 lo0 127.0.0.1 127.0.0.1 UH 2 0 33144 4 lo0 10.1/16 <---**---> 10.1.19.19 US 0 0 - 8 tun0 224/4 127.0.0.1 URS 0 0 33144 8 lo0
Всего лишь одна предпоследняя строка была добавлена моим скриптом в уже существующую таблицу маршрутизации.
Подключение двух VPN клиентов
Подобным образом мы подключимся ко второй сети через VPN шлюз клиента "Б". Скрипт очень похож и отличается некоторыми параметрами команды openconnect, именем туннельного интерфейса и адресами сети.
..... == Первое послание к Тимофею святого апостола Павла == ......... === Глава 6, Стих 3 === 3 Кто учит иному и не следует здравым словам Господа нашего Иисуса Христа и учению о благочестии, 4 тот горд, ничего не знает, но заражен _страстью_ к состязаниям и словопрениям, от которых происходят зависть, распри, злоречия, лукавые подозрения. (b+/b-, c+/c-, +/-, *) > ~:$ cat vpnB.sh # Run this as root export LC_CTYPE=en_US.UTF-8 VPNHOST=vpn.clientB.ru USER=remote2 PWD=secret2 FILE=/tmp/vpn.out date echo $PWD | openconnect -b -s empty -i tun1 \ -u $USER --passwd-on-stdin $VPNHOST > \ $FILE 2>&1 # cat $FILE grep "Continuing in background" $FILE echo To stop use \"kill -HUP pid\" IP=`grep "^Connected tun" $FILE | cut -f 4 -d ' ' | cut -f 1 -d ',' ` rm $FILE if [[ `uname` == "Linux" ]] then echo Линукс ifconfig tun1 $IP up ifconfig tun1 route -A inet add -net 192.0.0.0/8 gw $IP dev tun1 route -n -4 ps -ef | grep openconnect | grep -v grep else echo ОпенБСД ifconfig tun1 inet $IP ifconfig tun1 route add -iface -net 192.0/8 $IP route -n show -inet ps -ax | grep openconnect | grep -v grep fi date
После выполнения этого скрипта мы получим уже два одновременно работающих VPN подключения:
tun1: flags=51mtu 1300 ... inet 192.168.135.236 --> 0.0.0.0 netmask 0xff000000 Routing tables Internet: Destination Gateway Flags Refs Use Mtu Prio Iface default 10.0.0.138 UGS 4 64 - 12 iwn0 ... 10.1/16 10.1.19.19 US 0 0 - 8 tun0 ... 192/8 <---**---> 192.168.135.236 US 0 0 - 8 tun1
Список UNIX процессов теперь будет показывать две копии программы openconnect с разными параметрами и использующими разные "tun" устройства.
Интернет и обе сети клиентов "А" и "Б" могут быть использованы одновременно. Убедитесь что ваша система не позволяет маршрутизировать пакеты между интерфейсами и не может работать как роутер. Неправильное использование такой конфигурации может привести к открытию клиентских сетей напрямую в интернет.
Отключить любое из VPN соединений можно посылкой сигнала "HUP" соответствующему процессу openconnect.
Я надеюсь что эта заметка сделает вашу работу более удобной и покажет на примере что же происходит "за кулисами" VPN подключения. Как мы уже видели, просто создания туннеля и соответствующего устройства недостаточно. Нам необходимо понять работу и организацию клиентских сетей и внести изменения в маршрутизацию. При этом стандартные VPN клиенты часто нарушают работоспособность нашей собственной сети, делая дальнейшую работу невозможной.
Спасибо что зашли, Будьте благословенны! Денис
16 Декабря 2013 года.