GeneZharov / netm

UNIX-way network manager with CLI

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Тут будет описание сетевого менеджера.
Пока что это просто рабочие записи и наброски.


┃ TODO

   Зелёный заголовок менее заметен чем чёрный, хотя должно быть наоборот

   wpa_supplicant не убивается после suspend
      wpa_cli 'TERMINATE' command timed out
      kill не убивает wpa_supplicant, а вот wpa_daemon убивает.
      Проблема есть не всегда, только иногда после suspend, когда отвалиается 
         соединение и не поднимается само.
      Проблема должна быть решена новой версией wpa_daemon, который запускает 
         wpa_supplicant не через эмуляцию терминала.

   Демонизировать openvpn
   Обзор сетевых менеджеров;
   Настраиваемость цвета имён запускаемых скриптов (ныне зелёный) на случай 
      другой раскраски терминала;
   Заменить zsh на bash;
   Комментарии и документация на английском;
   Пакет для генты
   Пакеты для других ОС

   ━━━━ Отложено
   iw не подключает к точкам доступа, если в имени есть пробел:
      $ iw wlp3s0 connect -w 'Torro1 WiFi'
         wlp3s0 (phy #0): failed to connect, status: 1: Unspecified failure
      $ echo $?
         0
   Дефолтные конфиги
      │ Пока что это не очень нужно
      Сейчас, если в каталоге лежит только один конфиг, то я могу его не 
      упоминать и поднимать соединение одной буквой из начала имени каталога. 
      Но если положить в каталог ещё один конфиг, то уже приходится уточнять 
      какой именно конфиг использовать. В случае nest реально используется 
      только один и уже не очень удобно. Возникает желание снять атрибут 
      исполняемости со второго конфига, что не есть правильный путь. Возможно 
      надо добавить соглашение именований конфигов для выбора конфига по 
      умолчанию, чтобы не писать постоянно netn n/w, а писать netn n, даже, 
      если в nest лежит несколько конфигов. Можно использовать заглавную букву 
      или дописывать к имени: nest/wlan-default. Последнее кажется симпатичнее. 
      Можно продолжить эту мысль на имена каталогов.
   Перенести в конфиг?
      - дефолтное время timeout'а
      - цвет текста
      - адрес для пингования
   Конфиги для /var/log/net (syslog + logrotate)
      Это очень зависимая от конкретной ОС технология.
      Нельзя полагаться на то, что у пользоателя будет тот же syslog.
   Конфиг для подключения к инэту с помощью SIM-карты


┃ IO демонов
   │ Можно настроить syslog на то, чтобы логи dhcp клались в отдельный файл
   wpa_supplicant
      -B моментально форкается, не дожидаясь настройки соединения
      -s писать в syslog вместо stdout, не везде доступно, смотри ниже
      -f писать в файл вместо stdout
      По умолчанию не пишет ничего на стандартные потоки, если видит, что 
      запустили не из терминала. Можно принудить его всё таки выводить логи с 
      помощью -d
   dhcpcd
      После того как настроит соединение, делает форк. До форка пишет на 
      stderr. Пишет все логи в syslog. -B для запрета форканья, при этом все 
      логи идут на stderr и в syslog.
   dhclient
      После того как настроит соединение, делает форк. С ключём -v перед форком 
      будет писать на stderr, иначе вообще ничего не пишет на стандартные 
      потоки. Пишет все логи в syslog. -nw для того чтобы форк был сделан 
      сразу, без ожидания пока настроится соединение.

   ━━━━ Опция wpa_supplicant -s
   Чтобы эта фича была доступа, wpa_supplicant должен быть скомпилирован с 
   опцией CONFIG_DEBUG_SYSLOG.

   Команда для тестирования:
      wpa_supplicant -s -d -D nl80211 -i wlp3s0 -c /etc/netm/nest/_wlan/wpa_supplicant.conf

   # Gentoo
      Раньше для этого надо было использовать use-флаг debug. Сейчас такого 
      флага у этого пакета нет. В новой версии опция включена по умолчанию:
         net-wireless/wpa_supplicant-2.4-r1 — ещё нет опции
         net-wireless/wpa_supplicant-2.4-r3 — уже есть опция

   # Ubuntu
      Работает:
         wpasupplicant-0.7.3-6ubuntu2 — допотопная яндексовая убунта
         wpasupplicant-2.1-0ubuntu1 — ubuntu 14 LTS

   # Debian
      Работает:
         wpasupplicant-2.3-1+deb8u1 — debian 8

   # openSUSE
      Не работает: wpa_supplicant-2.2-5.2.1.x86_64 — opensuse 13.2
      │ Существует единственный пакет wpa_supplicant, никаких других подобных 
      │ пакетов не нашёл. Беглое гугление не показало способа установить нужным 
      │ образом скомпилированный пакет. Скорее всего верный способ — 
      │ пересобрать самому.

   # CentOS (можно считать стабильной версией Fedora)
      Не работает:
         wpa_supplicant-2.0 — CentOS 7

   # Arch
      ???


┃ Команды

   # new
      netn ξ ξ ξ... — остановить все соединения и поднять заданные

   # up
      netu ξ ξ ξ... — остановить заданные соединения и поднять снова
      netu — остановить все работающие соединения и поднять снова
         --quiet — подавить вывод на stdout
         --resume — не опускать работающие соединения, используется при старте 
            службы, чтобы поднять работавшие ранее соединения.

   # down
      netd ξ ξ ξ... — остановить заданные соединения
      netd — остановить все работащие соединения
         --quiet — подавить вывод на stdout
         --suspend — не очищать список работающих соединений, используется при 
            выключении службы, чтобы потом возобновить работу с того же места.

   # status
      nets — показать ныне работающие соединения


┃ Все возможные задачи
   • Опустить все соединения и поднять набор новых.
      │ В новом месте после долгого перерыва, когда я уже не помню что сейчас 
      │ работает и с чем конфликтует.
   • Показать текущие соединения.
   • Дополнительно поднять одно соединение или опустить одно соединение.
      │ Включить/выключить яндексовый vpn, чтобы не грузить яндексовые сети, 
      │ когда мне не нужны их сервисы и вообще не хочется там светиться.
   • Перезапустить текущие соединения.
      │ Почти всегда помогает, если внезапно отвалился инэт и не хочется 
      │ разбираться.
   • Опустить все соединения.
      │ Перед долгой автономной работой.


┃ Планировка команд для поднятия соединений
   Какие возможны варианты поднятия соединений:
   1) предварительно опускать все работающие соединения
   2) предварительно опускать только запрашиваемые работающие соединения
   3) предварительно не опускать работающие соединения

   3-я задача выглядит не обязательной и мало полезной. 2-я задача оправданна, 
   так как смысла поднимать уже работающее соединение действительно нет. К тому 
   же команда для перезапуска конкретного соединения кажется востребованной. 
   Таким образом удобно сделать отдельные команды для 1-й и 2-й задачи, а 3-ю 
   задачу отбросить как не нужную.

   Так как 2-я задача может использоваться для рестарта конкретных соединений, 
   то для единообразия её же использую для рестарта всех ныне имеющихся 
   соединений.


┃ Бездействие, если запрашиваемое соединение уже поднято
   Решил убрать функционал по бездействию в случае, если соединение уже 
   поднято:
      $ netu lair/wlan
         Это соединение уже поднято
   так как практической пользы тут нет. Как правило, если я захотел сделать 
   такую штуку, то я вижу, что в действительности соединение не работает и 
   возможно не работают соответствующие процессы. Так что заявление о том, что 
   соединение уже поднято выглядит нелепо. Гораздо лучше прямо подчиниться 
   желанию пользователя — поднять соединение предварительно остановив возможную 
   предыдущую версию.


┃ Именования

   # Расширения конфигов
      Для исполняемых файлов не принято писать расширение. Видимо потому что 
      всё их использование состоит в том, что их запускают, поэтому на каком 
      языке они реализованы не важно для этой задачи. А вот для текстового 
      файла важно расширение, чтобы и людям и программам было сразу понятно что 
      делать с файлом.

      Но конфиги — это не обычный бинарник из /usr/bin. Они часто редактируется 
      пользователем, поэтому к ним отношение скорее как к исходникам.

      С другой стороны без расширений конфиги будут гораздо легче смотреться в 
      nets и на stdout при запуске. Там совершенно не нужно знать на каком 
      именно ЯП реализован конфиг.

   # Подчёркивания для служебных файлов vs заглавная буква в имени конфига
      Решил не именовать конфиги с большой буквы.
      - некраисво смотрится в сочетании с путём, где все остальные каталоги 
         начинаются с маленькой: nest/Wlan up
      - неединообразно с _helpers
      - подчёркивание традиционно считается обозначением служебных сущностей

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

      _helpers/common именую с маленькой буквы для подчёркивания единообразия с 
      остальными конфигами. К тому же это единственный конфиг, который был до 
      этого внезапно с большой буквы. И, наконец, мне просто надоело всё время 
      писать эту большую букву.

      Использую именно подчёркивания, а не постфикс '.d' для каталогов, потому 
      что оно удобным образом сортирует исполняемые файлы.


┃ Timeout
   Не получилось написать хаскельный таймаут. Смотри 
   "~/d/d/hs/recipes/timeouts.nt". Решил использовать бинарник timeout из 
   coreutils, что совсем неплохо. Проверил, что эта команда доступна вместе с 
   ключём --foreground в разных ОС:
      gentoo, timeout-8.21
      centos-7, timeout-8.22
      opensuse-13.2, timeout-8.23
      debian-8, timeout-8.23


┃ Nesting configs (owning)

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

   Сканирующий конфиг в некотором роде фиктивный, он умеет только проксировать 
   команду поднятия соединений в другой, реальный конфиг. Поэтому с ним 
   возникает 3 проблемы:
   • перезапуск всех соединений с помощью netu перезапустит реальный конфиг, и 
      дополнительно к этому заново запустит фиктивный конфиг, который породит 
      ещё один реальный;
   • перезапуск фиктивного соединения с помощью netu породит ещё один реальный 
      конфиг;
   • netd можно попросить завершить реальный конфиг и останется фиктивный 
      конфиг, не обеспечивающий сам по себе подключения к сети;
   • nets не показывает какой конфиг кого породил, поэтому не понятно что 
      вообще произошло;

   В такой ситуации следует запускать дочерний конфиг с ключём:
      netu  --owner=shoko/auto  shoko/tascom
      netu  -o shoko/auto  shoko/tascom

   Это приводит к тому, что при рестарте всех конфигов с netu снимается 
   ответственность по запуску дочерних соединений. Также при убийстве 
   владельца, будет убиваеться и потомок.

   Более формально:
   • Если среди запрашиваемых соединений есть уже поднятые, но без родителя или 
      с другим родителем, то будет ошибка;
   • netd и netu дополнительно завершат дочерние соединения запускаемых 
      конфигов;
   • netd не позволит завершить соединение, указав его в аргументах, если им 
      владеет другой конфиг. Но если вместо этого указать владельца, то его 
      потомок будет завершён вместе с ним;
   • nets будет показать какой конфиг кем владеет;

   Можно указывать владельцем соединение, уже кому-то подчинённое, тогда 
   образуется целое дерево подчинения конфигов:
      auto/ifaces
      └─ auto/wlan
         ├─ shoko/tascom-wlan
         └─ shoko/vpn

   TODO: Можно дать возможность указывать для netu владельца отдельно для 
   каждого соединения. Например: netu shoko/tascom:shoko/auto


┃ Причины разработки
   Раньше я пользовался Network Manager и вот что мне в нём не нравилось:
   • Изначально порочная идея ограничивать возможный функционал соединений 
      тем, что понимает менеджер. Было бы гораздо лучше дать пользователю 
      возможность писать скрипт для обслуживания своего соединения. Из-за 
      порочной идеи страдает функциональность компа: я не могу настроить все 
      нужные мне соединения. Плюс сетевой менеджер не даёт возможности 
      управлять всеми аспектами тех соединений, которые вроде бы должен уметь 
      поднимать.
   • Скудная информативность. Если по какой-либо причине не удалось поднять 
      соединение, то мне просто сообщается о том, что это не удалось без 
      каких-либо разъяснений.
   • Раздражают графические апплеты и менюшки.
   • Не востребованая замороченность на безопасности: привязка к gnome keyring, 
      запросы паролей и т.п.
   • Всякие мелкие бесящие заморочки, свойственные gui.

   Я посмотрел какие есть альтернативы и оказалось, что они все также не 
   подходят.


┃ wpa_supplicant
   wpa_supplicant сделан так, чтобы работать в единственном экземпляре, по 
   крайней мере на одном интерфейсе, иначе они будут конфликтовать и мешать 
   друг другу работать. При этом у меня нет возможности узнать наверняка 
   запущен ли уже экземпляр wpa_supplicant до начала работы моего скрипта. Ну 
   просто потому что при старте демона, можно задать произвольный свой 
   pid-файл, своё местоположение управлющих сокетов, в конце концов, своё имя 
   для исполняемого файла.

   Мои скрипты для разных сетевых подключений однозначно не могут пользоваться 
   одним системным wpa_supplicant. Дело в том, что они могут использовать 
   разные конфиги wpa вплоть до того, что имеют одинаковые SSID, но разные 
   настройки. Либо в моём местоположении может быть доступно сразу оба SSID, а 
   wpa_cli не даёт возможности задать какой именно использовать. Короче говоря, 
   одно подключение — один конфиг wpa_supplicant, а значит и новый запуск 
   wpa_supplicant на каждое подключение. Кстати тот же подход используется в 
   родном гентушном netrc.

   Можно ещё сделать скрипт инициализации, который будет автоматически 
   стартовать сохранённые активные соединения при загрузке.

   Была мысль, что нужно обязательно сваять оповещение пользователя, если wpa 
   или dhcp отвалилось. Но если подумать, я не смогу сделать оповещение на все 
   возможные сбои. Ну например, если в ethernet-соединении без dhcp перестали 
   доходить пакеты, то из сетевого менеджера я об этом никак не узнаю. То есть 
   всё равно в общем случае проблему диагностирует пользователь и решает её 
   своими методами с помощью логов и т.п.

About

UNIX-way network manager with CLI

License:MIT License


Languages

Language:Haskell 84.2%Language:Shell 15.8%