Авторские статьи

PAC в snap.


В Linux мире для безопасного подсоединения к удалённым серверам часто используется SSH. Любой терминал в любом дистрибутиве linux легко позволит выполнить ssh user@address-server, но когда серверов становится много, то начинаешь задумываться о менеджере SSH соединений. Несколько лет назад остановился на PAC (Perl Auto Connector), который выглядит и работает отлично. Поддерживает кроме SSH также протоколы telnet, RDP, VNC. Время шло, компоненты Virtual Terminal Emulator (VTE), GTK и Perl, которые составляют фундамент программы, ушли в своём развитии вперёд и программа сначала стала падать c segmentation fault в конце своей работы, а в разрабатываемой Ubuntu 17.04 перестала запускаться и вовсе. Решил запаковать её в snap пакет, чтобы самому и другим дать возможность и далее пользоваться хорошей программой.

PAC (Perl Auto Connector)

Разведка боем

Проект PAC в нынешнем состоянии намекает на судьбу заброшенного дитя. На основном "сайте" sites.google.com/site/davidtv/ последняя новость говорит о релизе 4.5.5.5, скачать вы можете версию pac-4.5.5.7-all.deb годовалой давности, но переход на GitHub показывает наличие 4.5.5.8 версии. На лицо вялотекущая разработка программы, когда автор программы или выдохся или реализовал задуманное и поставил точку.

Не раз указывал вам на жёсткий мир Linux. Разработчики дистрибутива создают операционную систему своей мечты и используют компоненты из родственных линукс проектов. Стороннему программисту, который, возможно, не работает над программой полный день, остаётся только одно - отслеживать изменения и вовремя подправлять своё детище. Если он этого не делает или не желает делать, то нам, пользователям, остаётся наблюдать только одно - закат для данной программы. Ситуация с PAC для меня просто показательна именно этим. Буквально за один год программа из работоспособной превратилась "не могу запуститься". Сначала, грешным делом, подумал что моя рабочая машина с разрабатываемым релизом Ubuntu 17.04 просто "бурлит" и скоро всё уляжется. Но чуть ниже по статье поймёте, что шанса выжить у программы просто нет. Но давайте обо всём по порядку.

Подготовительные работы

Делаем пустую папку на сборочном сервере и скачиваем в неё последнюю версию 4.5.5.8, чтобы порадовать пользователей, которые знают о предыдущей версии в deb, но из новой версии сами не делали или не смогли сделать пакет deb. Готовый snap пакет новой версии программы должен понравиться людям, ибо предыдущая версия в deb ставится в систему не так просто, как вы могли подумать, и одним dpkg -i вы не отделаетесь.

Создаём черновой вариант snapcraft.yml для PAC. Привожу не весь файл, а нужные сейчас для понимания фрагменты.

name: pac-vs
version: "4.5.5.8-snap1"
summary: PAC is a Perl/GTK Gnome replacement for SecureCRT/Putty/etc.
description: |
    PAC (Perl Auto Connector) is a telnet/ssh/rsh/etc connection manager/automator written 
    in Perl GTK aimed at making both administrators and switchers (from Windows) live easier.
confinement: strict
architectures: [amd64]

apps:
  pac-vs:
    command: usr/bin/run.sh
    plugs: [network, network-bind, x11, unity7, gsettings, home]

parts:
 project-files:
  plugin: copy
  files:
   pac/*  : /
   run.sh : usr/bin/run.sh
  after: [integration]

 integration:
  plugin: nil
  stage-packages:
   - libvte9
   - libvte-common
   - libvte-2.91-common
   - libcairo-perl
   - libgtk2-perl
   - libglib-perl
   - libpango-perl
   - libgnome2-gconf-perl
   - libsocket6-perl
   - libexpect-perl
   - libnet-proxy-perl
   - libfindbin-libs-perl
   - libyaml-perl
   - libcrypt-cbc-perl
   - libcrypt-blowfish-perl
   - libgtk2-gladexml-perl
   - libgtk2-ex-simple-list-perl
   ....

Пользуемся предыдущим deb пакетом программы и воруем оттуда нужные программе имена пакетов зависимостей и имена пакетов рекомендуемых программ. Добавляем собранные имена в stage-package плагина nil у кусочка по имени integration. Всё добавленное сейчас и позже будет упаковано с программой, так как snap пакет самодостаточен. Кусочек project-files с помощью плагина copy просто размещает каталог pac с новой версией в "корне" будущего пакета. Само дерево программы от автора David Torrejón Vaquerizas примерно такое до 3 уровня вложенности - tree -d -L 3

.
├── etc
│   └── bash_completion.d
├── opt
│   └── pac
│       ├── lib
│       ├── res
│       └── utils
└── usr
    └── share
        ├── applications
        ├── man
        └── pixmaps

Пробуем первую итерацию snapcraft. Созданный pac-vs_4.5.5.8-snap1_amd64.snap пробуем ставить в тестовой виртуальной машине с Ubuntu 16.04 - sudo snap install --dangerous pac-vs_4.5.5.8-snap1_amd64.snap и старт программы через вызов pac-vs выплюнул ошибку языка программирования Perl, на котором написана программа.

Perl

Программисты Perl знают про переменную @INC, в которой находятся пути к библиотекам. Раз программы в snap пакетах обладают своим "корнем", то пути внутри snap "сдвигаются" на величину $SNAP и вместо /usr/share/perl5/ будет $SNAP/usr/share/perl5/. Когда вы установите пакет в свою систему, то в переменной $SNAP будет что-то типа /snap/pac-vs/x1/ и весь путь превратится в /snap/pac-vs/x1/usr/share/perl5/. Не стал мучать переменную @INC и добавлять туда что-то своё. Вычитал про переменную PERL5LIB и решил все пути, что мне подсказала perl -V добавить в PERL5LIB, дополнив перед каждой переменной $SNAP.

У меня есть скрипт-обёртка run.sh, в основе которого лежит эталонная реализация от разработчиков по имени desktop-launch. В него добавляю в одну из первых строк
export PERL5LIB="${PERL5LIB}:${SNAP}/usr/local/lib/x86_64-linux-gnu/perl/5.22.1:${SNAP}/usr/local/share/perl/5.22.1:${SNAP}/usr/lib/x86_64-linux-gnu/perl5/5.22:${SNAP}/usr/share/perl5:${SNAP}/usr/lib/x86_64-linux-gnu/perl/5.22:${SNAP}/usr/share/perl/5.22:${SNAP}/usr/local/lib/site_perl:${SNAP}/usr/lib/x86_64-linux-gnu/perl-base"

Снова итерация по упаковке программы через snapcraft и ошибка исчезла, но появилась другая.

libunique

AppArmor запрещал приложению PAC "садиться на шину DBus" (dbus_bind). Сначала хотел было задать вопрос разработчикам - дескать какого х? Но нашёл объяснение на просторах Интернета. Шина DBus позволяет обмен сообщениями между программами и в старом мире подразумевается полное доверие ко всему что пришло в deb пакетах, но в новом мире snap нельзя так взять и позволять любой программе отправлять другой программе всё что ей вздумается. Ведь отправка сообщения может попросить программу закрыться и в мире изоляции snap что это будет за разделение софта и системы друг друга если можно закрыть вам, к примеру, музыкальный проигрыватель? Разработчики всё понимают и предоставляют нам всё новые интерфейсы, но сейчас мне нужно было как-то решить свою возникшую проблему, а не ждать красивого решения насчёт dbus. Не подумайте, что весь dbus запрещён. Запрещены небезопасные вещи, которым позже дадут интерфейс.

Маленькое расследование вывело на то, что PAC использует библиотеку libunique, которая позволяет писать single instance application. Если вы запустите второй экземпляр программы, то можно воспользоваться готовыми функциями и передать сообщение в первый экземпляр программы и там решить как быть с последующими копиями. Данная библиотека использовала шину DBus для регистрации себя и определения последующих копий программы. Посещение странички проекта заставило опустить руки. В 2013 году вывесили баннер
WARNING
Unique is now in maintenance mode, and its usage is strongly discouraged.
Applications should use the GtkApplication class provided by GTK+ 3.0.
If you are using Unique, read the GtkApplication porting guide provided by GTK+.

Это старый проект и его лучше не использовать в будущем! Упаковка программы в snap полна сюрпризов и никто не гарантирует, что весь путь будет пройден и в конце вы победите. Но просто так сдаваться не хотелось. Взгляд упал на одну из возможностей - multiple backends (changeable at runtime). Вспыхнула надежда, что не всё потеряно. Может есть вариант работы библиотеки не через DBus? Как известно - кто ищет, тот всегда найдёт! В исходниках libunique нашёл следующее:

Creates a Gkt2::UniqueBackend using the default backend defined at compile time.
You can override the default backend by setting the UNIQUE_BACKEND environment variable with the name of the desired backend.

В скрипте-обёртке run.sh добавил перед вызовом самой программы строку export UNIQUE_BACKEND="bacon" и вуаля! Теперь мы используем сокеты вместо dbus. Программа стала стартовать и показывать своё главное окно, что вселило уверенности и придало сил. Хоть продвинулись дальше, но снова вляпались в следующую проблему.
*** VTE ***: Failed to load terminal capabilities from '/etc/termcap'

Virtual Terminal Emulator (VTE)

Ничто так не прокачало мой скилл вновь, как секас с VTE. Сидишь в настроенной системе, где большинство компонент не вызывают проблем и ты даже не знаешь какие файлы и переменные за что отвечают. Вначале слово терминал в имени компоненты увёл меня не туда. Сидел сутками курил мануалы по termcap, terminfo и как всё связано с переменными TERMCAP, TERMINFO, TERM. Но что-то подсказывало, что это всё касается "физических" консолей, а "виртуальный" терминал нужно прощупать через его исходники.

GREP'анье исходников по строке "/etc/termcap" вывело на файл vte.c где нашёл кусок кода, который всё объяснил. Формируется путь к файлу так - куда-поставлен-VTE-взяв-из-переменной-сборки-TERMCAPDIR/переменная-TERM. Учитывая тот факт что часто эмулируется поведение xterm и PAC по дефолту в настройках использует именно его, то итоговый путь в Убунту становится /usr/share/vte/termcap-0.0/xterm. Дальше стоит проверка доступен ли путь и если нет, то использовать жёстко вшитый /etc/termcap. Внутри снап пакета не доступен путь /usr/share/vte/termcap-0.0/xterm, так как он лежит в системе и попытка взять тогда /etc/termcap так же вызывает ошибку, что и выводится на экран.

У пользователей традиционных Linux систем, где нет snap, уже нет давно /etc/termcap и данную проблему видело много людей, если возникали проблемы с путём аля /usr/share/vte/. Возможно поэтому сопровождающий пакета сделал символическую ссылку /usr/share/vte/termcap/ на /usr/share/vte/termcap-0.0/, что когда-то решало какую-то проблему.

Тут понял что попал в любом случае. Пути /usr/share/vte/termcap-0.0/xterm и /etc/termcap не доступны в любом случае внутри пакета snap, ибо их абсолютный адрес от корня намекает на пути в системе. Мне жутко не хотелось бы править исходники и собирать что-то. Дело даже не в лени! Дело в том, что через stage-packages прошу нужные пакеты vte запихать внутрь будущего snap пакета. Теперь придётся делать сначала snapcraft prime, потом подкидывать патченную библиотеку, заменив оригинал, и затем окончательно формировать snap пакет - snapcraft snap. Но выхода другого пока не вижу. Аккуратно поправил vte.c и попросил сначала обратится к моей переменной окружения PATH2XTERMFILE.

const gchar *envVAS;
if ((envVAS = g_getenv ("PATH2XTERMFILE"))) {
    wpath = g_strdup(envVAS);
}
else { wpath = g_strdup("/etc/termcap");  } 

Собрал патченную библиотеку и в стартовом скрипте run.sh добавил
export PATH2XTERMFILE="$SNAP/usr/share/vte/termcap-0.0/xterm"
Теперь к сожалению красота сборки через единый snapcraft.yaml рухнула и вынужден собирать snap пакет, грубо втыкая нужный патченный файл. Теперь собирать итоговый snap пакет PAC нужно так:
snapcraft prime
cp -f vte-0.28.2/src/.libs/libvte.so.9.2800.2 prime/usr/lib/libvte.so.9.2800.2
snapcraft snap

Очень печально что разработчики не использовали традиционную переменную TERMCAP, которая как раз и служила многие годы для указания полного пути к файлу termcap, хранящего описания возможностей терминалов. Была бы поддержка переменной TERMCAP, то весь изврат можно было бы избежать, но, к сожалению, пришлось реализовать всё вот так. Проблема исчезла вместе с надписью. Стало возможным нажимать клавиши Backspace и Enter и они стали делать то что нужно от них. Заработали клавиши управления курсором и стало возможным передвигать курсор влево-вправо внутри команды. Думаете проблемы с жёстко вшитыми (hardcoded) путями закончились?

SSH

PAC умеет работать с различными протоколами для удалённого соединения, но мне лично он нужен был прежде всего ради SSH. И что я вижу? Невозможно получить доступ к моим /home/vasilisc/.ssh/id_rsa и /home/vasilisc/.ssh/known_hosts. WTF?! Какого хрена вообще ползать по моей папке? Разработчики snap в почтовой рассылке объяснили что проект ssh формирует путь не через $HOME/.ssh/, а через /home/$USER/.ssh/. Вроде путь один и тот же, но дьявол прячется в мелочах. $HOME внутри снап пакета указывает НЕ на ~/, а тянется по умолчанию в его домик ~/snap/имя-пакета-снап/цифра-ревизии/ ($HOME = $SNAP_USER_DATA). Поэтому если бы ssh использовал $HOME/.ssh/, то мне лишних телодвижений делать не нужно. Путь /home/$USER/.ssh/ нельзя назвать жёстко вшитым, но он начинается с корня системы и внутри снап не доступен.

Пришлось править opt/pac/lib/pac_conn и добавить к существующим опциям параметры, указывающие где обитают файлы известных хостов и конфигурационный файл, если в дальнейшем захочется что-то добавить или переопределить.

$key = $key . ' -q -o "UserKnownHostsFile=' . $ENV{'SNAP_USER_COMMON'} . '/ssh/known_hosts"';
$key = $key . ' -F "' . $ENV{'SNAP_USER_COMMON'} . '/ssh/config"';

SNAP_USER_COMMON отличается от SNAP_USER_DATA тем, что не поддерживает версионность и значит информация пользователя не будет потеряна, оставшись в старой ревизии, при обновлении в будущем новой версией снап пакета. Давно мечтал начать использовать данную переменную, но вначале с ней было всё не гладко. Теперь проблемы позади, разработчики поправили и можно смело её использовать. Всё в run.sh переопределил на использование SNAP_USER_COMMON, который тянется в ~/snap/pac-vs/common/. Как это будет работать в реале покажет лишь время.

Если будет нужна авторизация, то нужно в свойствах конкретного соединения указать на созданный вам заранее id_rsa. Можно затереть своим старым ключом id_rsa, id_rsa.pub и файлом known_hosts предварительно созданные вам в ~/snap/pac-vs/common/ssh/. Мне было реально влом заново вбивать все свои сервера. Свой старый pac.yml подправил на предмет путей, чтобы они вели куда нужно (~/snap/pac-vs/common/.config/pac/) и разместил свой старый конф по адресу ~/snap/pac-vs/common/.config/pac/pac.yml .

Когда стартанул PAC в snap со всеми моими настройками, то скупые, мужские слёзы покатились по щекам. Сделал же! Смог же! Кто молодец? Я молодец!

PAC богат функционалом, из которого лично проверил работоспособность SSH, Telnet, RDP, VNC, ssh с помощью mosh, WebDAV. Что потенциально может вызвать проблемы?

  • PAC для работы со своей локальной машиной вместо GNOME Terminal очень плохая идея! Дело в том, что хоть и попросил добавить внутрь snap два пакета coreutils и util-linux - это не решает всей ситуации. Программа внутри snap ограничена и даже, для примера, если вы захотите узнать свободное место на вашем локальном ПК через df, то получите отлуп и так почти по многим командам. Рассуждал так. Менеджер сессий PAC создан для доступа к удалённым серверам и там вы сможете делать всё что угодно, а увеличивать локальные возможности - смысла мало. Нужно просить добавить больше пакетов, запрашивать коннект к бо́льшему количеству интерфейсов в snapcraft.yaml и ради чего?
  • Из вышеперечисленного довода предвижу неработоспособность PAC с последовательным портом через cu или remote-tty. Нужные пакеты добавлены и команды доступны, но тупо не проверял работу в боевых условиях.
  • Если вам нужно реализовать ssh tunnel, чтобы через несколько прыжков оказаться на нужном сервере, то возможно вы огребёте проблем. У меня в текущем конфигурационном файле PAC был такой прыжок, реализованный через ProxyCommand, но он не заработал в PAC-snap. Мне нужно реализовать по-другому, но пока руки не дошли.

Если интересно пощупать PAC в snap, то командуйте sudo snap install pac-vs или через GNOME Software.
Мой труд в лице run.sh, который делает при первом старте массу подготовительных шагов и запускает программу, легко изучить при установленном pac-vs, глянув /snap/pac-vs/current/usr/bin/run.sh

Другие мои snap пакеты в Ubuntu Store.
Первый snap пакет. Java программа LanguageTool. sudo snap install languagetool
Второй snap пакет. GTK программа DeaDBeeF. sudo snap install deadbeef-vs
Третий snap пакет. Java программа TuxGuitar. sudo snap install tuxguitar-vs
Четвёртый snap пакет. Java программа Vuze. sudo snap install vuze-vs
Пятый snap пакет. Java программа osddm. sudo snap install osddm

Дата последней правки: 2018-12-12 21:29:13

RSS vasilisc.com   


Разделы

Главная
Новости
Ворох бумаг
Видео Linux
Игры в Linux
Безопасность
Статьи об Astra Linux
Статьи о FreeBSD
Статьи об Ubuntu
Статьи о Snappy
Статьи об Ubuntu Phone
Статьи о Kubuntu
Статьи о Xubuntu
Статьи о Lubuntu
Статьи об Open Source
Карта сайта