Привет всем,

Хотелось бы сегодня поделиться историей перехода на использование OpenConnect клиента, в качестве альтернативы AnyConnect.

Чиним AnyConnect

Стоит сразу же отметить что AnyConnect не доставляет каких либо хлопот в работе из под Windowsили MacOS. И до недавнего времени я стабильно работал на ArchLinux, после очередного обновления как раз таки все сломалось.

При запуске или установки клиента наблюдались такие симптомы:

Migrating /opt/cisco/anyconnect directory to /opt/cisco/secureclient directory
egrep: warning: egrep is obsolescent; using grep -E
Extracting installation files to /tmp/vpn.TskZHp/vpninst364692758.tgz...
Unarchiving installation files to /tmp/vpn.TskZHp...
Starting Cisco Secure Client Agent...
Function: errorCB File: ../../../../vpn/Common/Xml/CVCSaxParser.cpp Line: 119 xml errorCB: Document is empty
Function: startParser File: ../../../../vpn/Common/Xml/CVCSaxParser.cpp Line: 206 Invoked Function: xmlParseDocument Return Code: -1 (0xFFFFFFFF) Description: unknown
Function: parseManifestFile File: ../../../../vpn/Downloader/ManifestInfo.cpp Line: 492 Invoked Function: XmlParser::parseXml Return Code: -33554423 (0xFE000009) Description: unknown
Function: main File: ../main.cpp Line: 98 Failed to parse input manifest
Done!
Exiting now.

В процессе поиска решения проблемы выяснилось, что для работы AnyConnect версии 4.X/5.X, нужна зависимость в качестве библиотеки libxml2 версии 2.11.5. В моей системе был представлен пакет с версией 2.12.0-1.

Для решения данной проблемы, из исходников собираем libxml2 2.11.5-1.

C гита тянем репозиторий:

[tony@ThinkCentre ~]$ cd /opt/
[tony@ThinkCentre opt]$ sudo git clone https://gitlab.archlinux.org/archlinux/packaging/packages/libxml2.git
Cloning into 'libxml2'...
remote: Enumerating objects: 475, done.
remote: Counting objects: 100% (44/44), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 475 (delta 15), reused 14 (delta 4), pack-reused 431
Receiving objects: 100% (475/475), 87.74 KiB | 440.00 KiB/s, done.
Resolving deltas: 100% (138/138), done.

Проваливаемся во внутрь репозитория и переключаемся на релиз 2.11.5-1:

[tony@ThinkCentre opt]$ sudo chown -R tony:tony /opt/libxml2
[tony@ThinkCentre opt]$ cd /opt/libxml2/
[tony@ThinkCentre libxml2]$ git checkout tags/2.11.5-1

Далее запускаем сборку пакета:

[tony@ThinkCentre libxml2]$ makepkg -si

После сборки, нужные либы копируем в каталог с anyconnect:

[tony@ThinkCentre libxml2]$ sudo mkdir /opt/cisco/anyconnect/libxml
[tony@ThinkCentre libxml2]$ sudo cp pkg/libxml2/usr/lib/libxml2.so.2 /opt/cisco/anyconnect/libxml/
[tony@ThinkCentre libxml2]$ sudo cp pkg/libxml2/usr/lib/libxml2.so.2.11.5 /opt/cisco/anyconnect/libxml/

Теперь остается немного модифицировать systemd файлик сервиса - vpnagentd, добавив переменную окружения LD_LIBRARY_PATH.

[tony@ThinkCentre libxml2]$ sudo vim /etc/systemd/system/vpnagentd.service 
---
[Unit] 
Description=Cisco AnyConnect Secure Mobility Client Agent 

[Service] 
Type=simple
Restart=on-failure
ExecStartPre=/opt/cisco/anyconnect/bin/load_tun.sh
ExecStart=env 'LD_LIBRARY_PATH=/opt/cisco/anyconnect/libxml:$LD_LIBRARY_PATH' /opt/cisco/anyconnect/bin/vpnagentd -execv_instance
ExecReload=/bin/kill -HUP $MAINPID 
PIDFile=/var/run/vpnagentd.pid
KillMode=process

[Install] 
WantedBy=multi-user.target

В значение ExecStart добавили строку:

ExecStart=env 'LD_LIBRARY_PATH=/opt/cisco/anyconnect/libxml:$LD_LIBRARY_PATH' /opt/cisco/anyconnect/bin/vpnagentd -execv_instance

Сохраняемся и перечитываем конфигурацию systemd:

[tony@ThinkCentre libxml2]$ sudo systemctl daemon-reload

Далее просто перезапускаем сервис:

[tony@ThinkCentre libxml2]$ sudo systemctl restart vpnagentd

Теперь остается только надеяться что клиент не сломается при обновлении системы =) openconnect-error2.png

Переходим на OpenConnect

При разрешении каких-то проблем связанных с vpn, не раз натыкался на рекомендации к использованию OpenConnect. По сути это клиентское приложение, которое поддерживает несколько протоколов для подключения к vpn-сетям построенных на интерпрайз решениях, таких как:

  • Cisco AnyConnect
  • Palo Alto Networks
  • Fortinet
  • Juniper Network Connect.

Этот софт никак не связан компаниями из списка выше, поддерживается только сообществом.

Основая мотивация разработки OpenConnect, это устранение недостатков в работе AnyConnect из под Linux. Краткий список всего предоставлен на сайте проекта.

Итак, OpenConnect ставится в одну комманду из под любого пакетного менеджера:

# ArchLinux
sudo pacman -S openconnect networkmanager-openconnect webkit2gtk-4.1 gcr

# Ubuntu
sudo add-apt-repository universe
sudo apt-get install openconnect network-manager-openconnect network-manager-openconnect-gnome

Также есть прила в Google Play Store, если же вы используете vpn на андроид устойствах.

Для создания профиля и дальнейнего подключения можем использовать стандартную панельку networkmanger в трее. openconnect-connect1.png

Либо можем подключатся тупо через консоль, командой:

[tony@ThinkCentre ~]$ sudo openconnect --user=tony vpn.myorg.com

# Для запуска в фоном режиме
[tony@ThinkCentre ~]$ sudo openconnect --background --user=tony vpn.myorg.com

Для того, чтобы разорвать vpn-сессию, достаточно выполнить команду:

[tony@ThinkCentre ~]$ sudo kill -9 `pgrep openconnect`

Что бы каждый раз не вводить пароль для запуска из под sudo, в файлике sudoers создадим исключение на запуск данных команд без пароля.

[tony@ThinkCentre scripts]$ sudo EDITOR=/sbin/vim visudo
---
tony ALL=(ALL:ALL) NOPASSWD: /sbin/openconnect, /sbin/kill -9 `pgrep openconnect`

Кастомизация в 3Blocks

На данном этапе все основные настройки, необходимые для работы, выполнены. В заключении я решил обновить конфигурацию i3blocks (это статус бар, работающий совмество с i3wm), добавив индикатор статуса vpn-сессии.

Напишим маленький скритец, который будет грепом чекать запущенный процесс OpenConnect. И далее принтовать сообщение:

[tony@ThinkCentre ~]$ vim .config/i3/scripts/vpn.sh 
---
#!/bin/bash 

vpn_status=$(ps -aux | grep openconnect | grep -Po 'server=\K.*' | cut -d ' ' -f 1)

if [ $vpn_status ]; then
	echo -e "<span color='green'>󰒄 $vpn_status</span>\n"
else
	echo -e "<span color='red'>󰒄 Down</span>\n"
fi

Делаем скрипт исполняемым:

[tony@ThinkCentre ~]$ chmod +x .config/i3/scripts/vpn.sh 

Ну и вносим изменения в конфигу - i3blocks.conf:

[tony@ThinkCentre ~]$ vim .config/i3/i3blocks.conf 
---
[vpn]
command=~/.config/i3/scripts/vpn.sh
interval=5
markup=pango

Релоудим i3wm, и у нас появится вот такой индикатор: openconnect-i3blocks1.png

И в конце хотелось бы отметить что openconnect может также сплитировать трафик, настраивается это достаточно просто, путем указания параметров к команде запуска.

Также есть нюанс с файлом resolv.conf, после разрыва vpn сессии в нем останутся прописаны dns-сервера предлагаемые вашей организации. Что бы изменить dns-сервера на локальные, достаточно перезепустить Network manager. При запуски vpn-сессии через network-manager-applet такой проблемы нету.