Tray icon under Mate Desktop on Linux has irrelevant appearance and doesn't handle mouse events properly

22:43

I found a great workaround:

dbus-launch someQtApp someAppOptions

It works completely OK under Mate. The icon displays the images properly and mouse clicks are handled as they should.

Thanks to http://askubuntu.com/questions/732967/dropbox-icon-is-not-working-xubuntu-14-04-lts-64 .

This workaround works for Telegram Desktop and for caja-dropbox (caja-dropbox is the Dropbox for Mate). For Dropbox, its additional setting is required to not autostart it on system startup: uncheck that in Dropbox Preferences.

(c)

TigerVNC Server & Ubuntu 16.04 Xenial Xerus

02:50

Today I tried to install TigerVNC Server on Ubuntu 16.04, and was surprised to find that Ubuntu still uses TightVNC in their main repos. Additionally, there are no PPAs for TigerVNC and Ubuntu 16.04 Xenial Xerus yet.

Installing it is simple:

Download the latest binary from TigerVNC. At the time of writing, version 1.7.0 for Ubuntu is located here for 64bit and here for x86Latest release information can be found on the TigerVNC github page.

Then run:

sudo dpkg -i tigervncserver_filename.deb

sudo apt-get install -f

vncserver

You will be prompted for a few questions the first time you start it up, but that it is it. Your VNC Server is up and running on port 5901 by default. You can connect to it using the Tiger VNC viewer on another computer by pointing it to the IP:5901.

There are a lot of options for TigerVNC server, but one of my favorite things about TigerVNC is that the connections are encrypted by default. However, I recommend only connecting to VNC servers over VPNs or SSH tunnels just to be sure.

(с)

15 базовых советов по Git для эффективной работы каждый день

02:23

(с) Эта заметка — попытка объяснить те базовые настройки и приёмы, которыми я пользуюсь каждый день. Рецепты не претендуют быть ноу-хау, но могут помочь с освоением ежедневной гигиены работы с репозиторием.

1. Используй свежее

 

Я предпочитаю работать в консоли и большая часть команд и советов в этой заметке будет про консольный клиент. Это своего рода первая рекомендация — используйте консольный клиент для ежедневной работы с репозиторием и регулярно его обновляйте. В консольном клиенте в первую очередь появляются новые возможности и исправления ошибок.

 

> git --version
git version 2.27.0

 

2. Настрой инструмент

 

Настройте себе публичный email не аффилированный с текущей компанией. Это позволит вам тонко настраивать идентификацию под разные репозитории и не задумываться о настройках по умолчанию, а GitHub будет показывать вашу активность, даже если вы смените место работы.

 

> git config --global user.email "gurugray@yandex.ru"

> cd company_project
> git config user.email "gurugray@manychat.com"

 

Если вы не пользуетесь консолью и vim'ом для редактирования, то вам стоит настроить и ваш редактор:

 

> git config --global core.editor "code --wait"

 

3. Настрой autocomplete

 

В моей практике не часто встречается разработчик, который не настраивал автокомплит если работал в консоли. Однако если вы переходите с другого инструмента, отсутствие этой функциональности сильно вас затормозит.

 

Git из коробки предоставляет набор скриптов для автокомплита, но если ваш shell, как у меня, более экзотичен — найдите и поставьте автокомплит именно для него.

 

4. Ускоряй часто используемое

 

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

 

Я перешёл на Git с SVN, потому для меня базовые псевдонимы перекочевали оттуда, а "b" — единственный однобуквенный псевдоним.

 

> git config --global alias.st "status -sb"
> git config --global alias.co "checkout"
> git config --global alias.ci "commit -a"
> git config --global alias.b "branch"

 

5. Обзорность помогает решать проблемы

 

Я часто работаю с историей проекта — нужно понять, что и когда влилось, и какие состояния проекта этому предшествовали. Часто важно знать последовательность комитов и топологию дерева истории. Git из коробки помогает показать дерево истории проекта:

 

> git log --oneline --graph --branches

 

Но для полноты картины хочется видеть и авторов, и даты и в удобной расцветке, потому мой псевдоним выглядит не так дружелюбно с параметром --pretty=format::

 

> git log --graph --date=short --branches --pretty=format:'%C(yellow)%h%C(reset) %ad | %C(75)%s%C(reset) %C(yellow)%d%C(reset) [%an]'

 

6. Следуй протоколу

 

Всегда клонируйте репозиторий, в который вносите правки по git+ssh протоколу, это работает быстрее чем по http и сэкономит время в процессе работы:

 

> git clone git@github.com:gurugray/gurugray

 

7. Разделяй источники

 

Если вы работаете с репозиториями по «форковой» модели (когда к основному репозиторию есть доступ только на чтение, а все pull-request'ы подаются из форка) называйте основной репозиторий upstream это поможет не путаться в командах отведения веток и push'а в свой origin. Не забывайте про протокол, если репозиторий открыт только для чтения, то его можно клонировать без ssh-слоя, что тоже даст экономию времени в процессе работы:

 

> git clone git://github.com/gurugray/gurugray -o upstream

 

8. Контролируй процесс

 

Не используйте команду pull, это составная команда и делает несколько действий сразу. Часто при работе с репозиторием новички допускают ошибку не понимая, как эта команда обновляет текущую ветку, и замусоривают свою историю или неправильно работают с дефолтной веткой. Я рекомендую явно обновлять репозиторий локально, затем явно обновлять свою ветку:

 

> git fetch --all
> git rebase my_feature upstream/master

 

9. Не вводи себя в заблуждение

 

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

 

> git fetch --all
> git checkout -b my_feature upstream/master

> git branch -D master

 

10. Не бойся исправлять

 

Если вы следите за чистотой истории и хотите исправить состояние проекта зафиксированное несколько комитов назад, то достаточно закомититься с параметром --fixup= и передать нужный хэш комита для последующего причёсывания истории

 

> git commit -m "Feature A is done"
> ...
> git commit -m "Feature B is done"
> git commit --fixup=fe2f857

 

> git log --oneline
a5050e7 fixup! Feature A is done
633e33f Feature B is done
...
fe2f857 Feature A is done
cb5db88 Previous commit

 

11. Не бойся быстро исправлять

 

Один из полезных псевдонимов — замена последнего комита текущим состоянием, позволяет «подклеить» текущее состояние к последнему зафиксированному, при этом не включая режим редактирования сообщения:

 

> git config --global alias.fixlast "commit --all --amend --no-edit"

 

12. Перебазируй

 

Научитесь и пользуйтесь командой rebase в интерактивном режиме и с параметром --autosquash с которым использование --fixup будет ещё более удобным, а сам ребейз помогает причёсывать историю и аккуратно оформить комиты, например по принятым у вас guidline'ам, до подачи pull-request'а для успешного его принятия.

 

> git rebase -i --autosquash cb5db88
pick fe2f857 Feature A is done
fixup a5050e7 fixup! Feature A is done
pick 733e2ff Feature B is done

 

> git log --oneline
633e33f Feature B is done
...
5778cbb Feature A is done
cb5db88 Previous commit

 

13. Сбрасывай ненужное

 

Научитесь и пользуйтесь командой reset она позволит легко манипулировать локальной историей и состоянием, например после череды правок и комитов на код-ревью «схлопнуть» последние ненужные состояния проще с её помощью:

 

> git reset @~4
> git commit --all

 

14. Контролируй деструктивный push

 

Если вы хотите запушить изменённую историю, советую использовать полный синаксис команды и не использовать ключ --force -f, это позволит не привыкать к настройкам по умолчанию и не приведёт к случайным перетираниям истории на сервере:

 

> git push origin +feature

 

15. Помни про летописца

 

Не забывайте про reflog эта команда поможет разобраться с проблемами в локальном репозитории если что-то пошло не так — спасательный круг для новичков, к которому они редко подходят:

 

> git reflog
> ...
> git reset --hard FOUND_HASH

 

Все советы выше помогут быстрее работать с репозиторием и быстрее получать ответы об истории разработки поиска ошибок и выявления узких мест в регламенте работы, но эта тема для отдельной статьи.

 

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

отсюда

Далее

Основы Ansible, без которых ваши плейбуки — комок слипшихся макарон

02:04

Я делаю много ревью для чужого кода на Ансибл и много пишу сам. В ходе анализа ошибок (как чужих, так и своих), а так же некоторого количества собеседований, я понял основную ошибку, которую допускают пользователи Ансибла — они лезут в сложное, не освоив базового.

Для исправления этой вселенской несправедливости я решил написать введение в Ансибл для тех, кто его уже знает. Предупреждаю, это не пересказ манов, это лонгрид в котором много букв и нет картинок.

Ожидаемый уровень читателя — уже написано несколько тысяч строк ямла, уже что-то в продакшене, но "как-то всё криво".

Названия

Главная ошибка пользователя Ansible — это не знать как что называется. Если вы не знаете названий, вы не можете понимать то, что написано в документации. Живой пример: на собеседовании, человек, вроде бы заявлявший, что он много писал на Ансибле, не смог ответить на вопрос "из каких элементов состоит playbook'а?". А когда я подсказал, что "ожидался ответ, что playbook состоит из play", то последовал убийственный комментарий "мы этого не используем". Люди пишут на Ансибле за деньги и не используют play. На самом деле используют, но не знают, что это такое.

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

ansible-playbook исполняет playbook. Playbook — это файл с расширением yml/yaml, внутри которого что-то такое:

---
- hosts: group1
  roles:
    - role1

- hosts: group2,group3
  tasks:
    - debug:

 

Мы уже поняли, что весь этот файл — плейбука. Мы можем показать где тут роли (roles), где таски (tasks). Но где тут play? И чем отличается play от role или playbook?

В документации это всё есть. И это пропускают. Начинающие — потому что там слишком много и всё сразу не запомнишь. Опытные — потому что "тривиальные вещи". Если вы опытный — перечитывайте эти страницы хотя бы раз в пол-года, и ваш код станет классом лучше.

Итак, запоминайте: Playbook — это список, состоящий из play и import_playbook
Вот это — одна play:

- hosts: group1
  roles:
    - role1

и вот это тоже ещё одна play:

- hosts: group2,group3
  tasks:
    - debug:

Что же такое play? Зачем она?

Play — это ключевой элемент для playbook, потому что play и только play связывает список ролей и/или тасок с списком хостов, на которых их надо выполнять. В глубоких недрах документации можно найти упоминание про delegate_to, локальные lookup-плагины, network-cli-специфичные настройки, jump-хосты и т.д. Они позволяют слегка поменять место исполнения тасок. Но, забудьте про это. У каждой из этих хитрых опций есть очень специальные применения, и они точно не являются универсальными. А мы говорим про базовые вещи, которые должны знать и использовать все.

Если вы хотите "что-то" исполнить "где-то" — вы пишете play. Не роль. Не роль с модулями и делегейтами. Вы берёте и пишете play. В которой, в поле hosts вы перечисляете где исполнять, а в roles/tasks — что исполнять.

Просто же, да? А как может быть иначе?

Одним из характерных моментов, когда у людей возникает желание сделать это не через play, это "роль, которая всё настраивает". Хочется иметь роль, которая настраивает и сервера первого типа, и сервера второго типа.

Архетипичным примером является мониторинг. Хочется иметь роль monitoring, которая настроит мониторинг. Роль monitoring назначается на хосты мониторинга (в соотв. play). Но, выясняется, что для мониторинга нам надо поставить пакеты на хосты, которые мы мониторим. Почему бы не использовать delegate? А ещё надо настроить iptables. delegate? А ещё надо написать/поправить конфиг для СУБД, чтобы мониторинг пускала. delegate! А если креатив попёр, то можно сделать делегацию include_role во вложенном цикле по хитрому фильтру на список групп, а внутри include_role можно ещё делать delegate_to снова. И понеслось...

Благое пожелание — иметь одну-единственную роль monitoring, которая "всё делает" — ведёт нас кромешный ад из которого чаще всего один выход: всё переписать с нуля.

Где тут случилась ошибка? В тот момент, когда вы обнаружили, что для выполнения задачи "x" на хосте X вам надо пойти на хост Y и сделать там "y", вы должны были выполнить простое упражнение: пойти и написать play, которая на хосте Y делает y. Не дописывать что-то в "x", а написать с нуля. Пусть даже с захардкоженными переменными.

Вроде бы, в абзацах выше всё сказано правильно. Но это же не ваш случай! Потому что вы хотите написать переиспользуемый код, который DRY и похож на библиотеку, и нужно искать метод как это сделать.

Вот тут вот притаилась ещё одна грубая ошибка. Ошибка, которая превратила множество проектов из терпимо написанных (можно лучше, но всё работает и легко дописать) в совершенный ужас, в котором даже автор не может разобраться. Оно работает, но упаси боже что-то поменять.

Эта ошибка звучит так: роль — это библиотечная функция. Эта аналогия сгубила столько хороших начинаний, что просто грустно смотреть. Роль — не библиотечная функция. Она не может делать вычисления и она не может принимать решения уровня play. Напомните мне, какие решения принимает play?

Спасибо, вы правы. Play принимает решение (точнее, содержит в себе информацию) о том, какие таски и роли на каких хостах выполнять.

Если вы делегируете это решение на роль, да ещё и с вычислениями, вы обрекаете себя (и того, кто ваш код будет пытаться разобрать) на жалкое существование. Роль не решает где ей выполняться. Это решение принимает play. Роль делает то, что ей сказали, там, где ей сказали.

Почему заниматься программированием на Ансибле опасно и чем COBOL лучше Ансибла мы поговорим в главе про переменные и jinja. Пока что скажем одно — каждое ваше вычисление оставляет за собой нестираемый след из изменения глобальных переменных, и вы ничего с этим не можете сделать. Как только два "следа" пересеклись — всё пропало.

Замечание для въедливых: роль, безусловно, может влиять на control flow. Есть delegate_to и у него есть разумные применения. Есть meta: end host/play. Но! Помните, мы учим основы? Забыли про delegate_to. Мы говорим про самый простой и самый красивый код на Ансибл. Который легко читать, легко писать, легко отлаживать, легко тестировать и легко дописывать. Так что, ещё раз:

play и только play решает на каких хостах что исполняется.

В этом разделе мы разобрались с противостоянием play и role. Теперь поговорим про отношения tasks vs role.

Таски и Роли

Рассмотрим play:

- hosts: somegroup
  pre_tasks:
    - some_tasks1:
  roles:
     - role1
     - role2
  post_tasks:
     - some_task2:
     - some_task3:

Допустим, вам надо сделать foo. И выглядит это как foo: name=foobar state=present. Куда это писать? в pre? post? Создавать role?

… И куда делись tasks?

Мы снова начинаем с азов — устройство play. Если вы плаваете в этом вопросе, вы не можете использовать play как основу для всего остального, и ваш результат получается "шатким".

Устройство play: директива hosts, настройки самой play и секции pre_tasks, tasks, roles, post_tasks. Остальные параметры для play нам сейчас не важны.

Порядок их секций с тасками и ролями: pre_tasksrolestaskspost_tasks. Поскольку семантически порядок исполнения между tasks и roles не понятен, то best practices говорит, что мы добавляем секцию tasks, только если нет roles. Если есть roles, то все прилагающиеся таски помещаются в секции pre_tasks/post_tasks.

Остаётся только то, что семантически всё понятно: сначала pre_tasks, потом roles, потом post_tasks.

Но мы всё ещё не ответили на вопрос: а куда вызов модуля foo писать? Надо ли нам под каждый модуль писать целую роль? Или лучше иметь толстую роль подо всё? А если не роль, то куда писать — в pre или в post?

Если на на эти вопросы нет аргументированного ответа, то это признак отсутствия интуиции, то есть те самые "шаткие основы". Давайте разбираться. Сначала контрольный вопрос: Если у play есть pre_tasks и post_tasks (и нет ни tasks, ни roles), то может ли что-то сломаться, если я первую таску из post_tasks перенесу в конец pre_tasks?

Разумеется, формулировка вопроса намекает, что сломается. Но что именно?

… Хэндлеры. Чтение основ открывает важный факт: все хэндлеры flush'атся автоматом после каждой секции. Т.е. выполняются все таски из pre_tasks, потом все хэндлеры, которые были notify. Потом выполняются все роли и все хэндлеры, которые были notify в ролях. Потом post_tasks и их хэндлеры.

Таким образом, если вы таску перетащите из post_tasks в pre_tasks, то, потенциально, вы выполните её до выполнения handler'а. например, если в pre_tasks устанавливается и конфигурируется веб-сервер, а в post_tasks в него что-то засылается, то перенос этой таски в секцию pre_tasks приведёт к тому, что в момент "засылания" сервер будет ещё не запущен и всё сломается.

А теперь давайте ещё раз подумаем, а зачем нам pre_tasks и post_tasks? Например, для того, чтобы выполнить всё нужное (включая хэндлеры) до выполнения роли. А post_tasks позволит нам работать с результатами выполнения ролей (включая хэндлеры).

Въедливый знаток Ansible скажет нам, что есть meta: flush_handlers, но зачем нам flush_handlers, если мы можем положиться на порядок исполнения секций в play? Более того, использование meta: flush_handlers может нам доставить неожиданного с повторяющимися хэндлерами, сделать нам странные варнинги в случае использования when у block и т.д. Чем лучше вы знаете ансибл, тем больше нюансов вы сможете назвать для "хитрого" решения. А простое решение — использование натурального разделения между pre/roles/post — не вызывает нюансов.

И, возвращаемся, к нашему 'foo'. Куда его поместить? В pre, post или в roles? Очевидно, это зависит от того, нужны ли нам результаты работы хэндлера для foo. Если их нет, то foo не нужно класть ни в pre, ни в post — эти секции имеют специальный смысл — выполнение тасок до и после основного массива кода.

Теперь ответ на вопрос "роль или таска" сводится к тому, что уже есть в play — если там есть tasks, то надо дописать в tasks. Если есть roles — надо делать роль (пусть и из одной task). Напоминаю, tasks и roles одновременно не используются.

Понимание основ Ансибла даёт обоснованные ответы на, казалось бы, вопросы вкусовщины.

Таски и роли (часть вторая)

Теперь обсудим ситуацию, когда вы только начинаете писать плейбуку. Вам надо сделать foo, bar и baz. Это три таски, одна роль или три роли? Обобщая вопрос: в какой момент надо начинать писать роли? В чём смысл писать роли, когда можно писать таски?… А что такое роль?

Одна из грубейших ошибок (я про это уже говорил) — считать, что роль — это как функция в библиотеке у программы. Как выглядит обобщённое описание функции? Она принимает аргументы на вход, взаимодействует с side causes, делает side effects, возвращает значение.

Теперь, внимание. Что из этого можно сделать в роли? Вызвать side effects — всегда пожалуйста, это и есть суть всего Ансибла — делать сайд-эффекты. Иметь side causes? Элементарно. А вот с "передать значение и вернуть его" — вот тут-то и нет. Во-первых, вы не можете передать значение в роль. Вы можете выставить глобальную переменную со сроком жизни размером в play в секции vars для роли. Вы можете выставить глобальную переменную со сроком жизни в play внутри роли. Или даже со сроком жизни плейбуки (set_fact/register). Но вы не можете иметь "локальные переменные". Вы не можете "принимать значение" и "возвращать его".

Из этого вытекает главное: нельзя на ansible написать что-то и не вызвать сайд-эффекты. Изменение глобальных переменных — это всегда side effect для функции. В Rust, например, изменение глобальной переменной — это unsafe. А в Ансибл — единственный метод повлиять на значения для роли. Обратите внимание на используемые слова: не "передать значение в роль", а "изменить значения, которые использует роль". Между ролями нет изоляции. Между тасками и ролями нет изоляции.

Итого: роль — это не функция.

Что же хорошего есть в роли? Во-первых, у роли есть default values (/default/main.yaml), во-вторых у роли есть дополнительные каталоги для складывания файлов.

Чем же хороши default values? Тем, что в пирамиде Маслоу довольно извращённой таблице приоритетов переменных у Ансибла, role defaults — самые неприоритетные (за вычетом параметров командной строки ансибла). Это означает, что если вам надо предоставить значения по-умолчанию и не переживать что они перебъют значения из инвентори или групповых переменных, то дефолты роли — это единственное правильное место для вас. (Я немного вру — есть ещё |d(your_default_here), но если говорить про стационарные места — то только дефолты ролей).

Что ещё хорошего в ролях? Тем, что у них есть свои каталоги. Это каталоги для переменных, как постоянных (т.е. вычисляемых для роли), так и для динамических (есть такой то ли паттерн, то ли анти-паттерн — include_vars вместе с {{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml.). Это каталоги для files/templates/. Ещё, оно позволяет иметь роли свои модули и плагины (library/). Но, в сравнении с тасками у playbook'и (у которой тоже всё это может быть), польза тут только в том, что файлы свалены не в одну кучу, а несколько раздельных кучек.

Ещё одна деталь: можно пытаться делать роли, которые будут доступны для переиспользования (через galaxy). После появления коллекций распространение ролей можно считать почти забытым.

Таким образом, роли обладают двумя важными особенностями: у них есть дефолты (уникальная особенность) и они позволяют структурировать код.

Возвращаясь к исходному вопросу: когда делать таски а когда роли? Таски в плейбуке чаще всего используются либо как "клей" до/после ролей, либо как самостоятельный строительный элемент (тогда в коде не должно быть ролей). Груда нормальных тасок в перемешку с ролями — это однозначная неряшливость. Следует придерживаться конкретного стиля — либо таски, либо роли. Роли дают разделение сущностей и дефолты, таски позволяют прочитать код быстрее. Обычно в роли выносят более "стационарный" (важный и сложный) код, а в стиле тасок пишут вспомогательные скрипты.

Существует возможность делать import_role как таску, но если вы такое пишете, то будьте готовы к объяснительной для собственного чувства прекрасного, зачем вы это хотите делать.

Въедливый читатель может сказать, что роли могут импортировать роли, у ролей может быть зависимость через galaxy.yml, а ещё есть страшный и ужасный include_role — напоминаю, мы повышаем навыки в базовом Ансибле, а не в фигурной гимнастике.

Хэндлеры и таски

Давайте обсудим ещё одну очевидную вещь: хэндлеры. Умение их правильно использовать — это почти искусство. В чём разница между хэндлером и таской?

Так как мы вспоминаем основы, то вот пример:

- hosts: group1
  tasks:
    - foo:
      notify: handler1
  handlers:
     - name: handler1
       bar:

У роли handler'ы лежат в rolename/handlers/main.yaml. Handler'ы шарятся между всеми участниками play: pre/post_tasks могут дёргать handler'ы роли, а роль может дёргать handler'ы из плей. Однако, "кросс-ролевые" вызовы handler'ов вызывают куда больший wtf, чем повтор тривиального handler'а. (Ещё один элемент best practices — стараться не делать повторов имён handler'ов).

Основное различие в том, что таска выполняется (идемпотентно) всегда (плюс/минус теги и when), а хэндлер — по изменению состояния (notify срабатывает только если был changed). Чем это чревато? Например, тем, что при повторном запуске, если не было changed, то не будет и handler. А почему может быть так, что нам нужно выполнить handler когда не было changed у порождающей таски? Например, потому что что-то сломалось и changed был, а до хэндлера выполнение не дошло. Например, потому что сеть временно лежала. Конфиг поменялся, сервис не перезапущен. При следующем запуске конфиг уже не меняется, и сервис остаётся со старой версией конфига.

Ситуация с конфигом не решаемая (точнее, можно самим себе изобрести специальный протокол перезапуска с файловыми флагами и т.д., но это уже не 'basic ansible' ни в каком виде). Зато есть другая частая история: мы поставили приложение, записали его .service-файл, и теперь хотим его daemon_reload и state=started. И натуральное место для этого, кажется, хэндлер. Но если сделать его не хэндлером а таской в конце тасклиста или роли, то он будет идемпотентно выполняться каждый раз. Даже если плейбука сломалась на середине. Это совершенно не решает проблемы restarted (нельзя делать таску с атрибутом restarted, т.к. теряется идемпотентность), но однозначно стоит делать state=started, общая стабильность плейбуки возрастает, т.к. уменьшается количество связей и динамического состояния.

Ещё одно положительное свойство handler'а состоит в том, что он не засоряет вывод. Не было изменений — нет лишних skipped или ok в выводе — легче читать. Оно же является и отрицательным свойством — если опечатку в линейно исполняемой task'е вы найдёте на первый же прогон, то handler'ы будут выполнены только при changed, т.е. при некоторых условиях — очень редко. Например, первый раз в жизни спустя пять лет. И, разумеется, там будет опечатка в имени и всё сломается. А второй раз их не запустить — changed-то нет.

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

… Так что handler'ы куда менее полезны и куда более проблемны, чем кажется. Если можно что-то красиво (без выкрутас) написать без хэндлеров лучше делать без них. Если красиво не получается — лучше с ними.

Въедливый читатель справедливо отмечает, что мы не обсудили listen, что handler может вызывать notify для другого handler'а, что handler может включать в себя import_tasks (который может делать include_role c with_items), что система хэндлеров в Ансибле тьюринг-полная, что хэндлеры из include_role прелюбопытнейшим образом пересекаются с хэндлерами из плей и т.д. — всё это явно не "основы").

Хотя есть один определённый WTF, который на самом деле фича, и о котором надо помнить. Если у вас таска выполняется с delegate_to и у неё есть notify, то соответствующий хэндлер выполняется без delegate_to, т.е. на хосте, на котором назначена play. (Хотя у хэндлера, разумеется, может быть delegate_to тоже).

Отдельно я хочу сказать пару слов про reusable roles. До появления коллекций была идея, что можно сделать универсальные роли, которые можно ansible-galaxy install и поехал. Работает на всех ОС всех вариантов во всех ситуациях. Так вот, моё мнение: это не работает. Любая роль с массовым include_vars, поддержкой 100500 случаев обречена на бездны corner case багов. Их можно затыкать массированным тестированием, но как с любым тестированием, либо у вас декартово произведение входных значений и тотальная функция, либо у вас "покрыты отдельные сценарии". Моё мнение — куда лучше, если роль линейная (цикломатическая сложность 1).

Чем меньше if'ов (явных или декларативных — в форме when или форме include_vars по набору переменных), тем лучше роль. Иногда приходится делать ветвления, но, повторю, чем их меньше, тем лучше. Так что вроде бы хорошая роль с galaxy (работает же!) с кучей when может быть менее предпочтительна, чем "своя" роль из пяти тасок. Момент, когда роль с galaxy лучше — когда вы что-то начинаете писать. Момент, когда она становится хуже — когда что-то ломается, и у вас есть подозрение, что это из-за "роли с galaxy". Вы её открываете, а там пять инклюдов, восемь таск-листов и стопка when'ов… И в этом надо разобраться. Вместо 5 тасок линейным списком, в котором и ломаться-то нечему.

В следующих частях

  • Немного про инвентори
  • групповые переменные, host_group_vars plugin, hostvars. Как из спагетти связать Гордиев узел. Scope и precedence переменных, модель памяти Ansible. "Так где же всё-таки хранить имя пользователя для базы данных?".
  • jinja: {{ jinja }} — nosql notype nosense мягкий пластилин. Оно всюду, даже там, где вы его не ожидаете. Немного про !!unsafe и вкусный yaml.

 

отсюда

Далее

Анализ HTTP-трафика с Mitmproxy

01:52

В практике веб-разработчика нередко возникают ситуации, когда требуется отследить и проанализировать трафик приложений, общающихся с сервером по протоколу HTTP (в качестве примера можно привести тестирование приложений для мобильных устройств или HTTP API).

Инструменты, традиционно используемые для прослушивания трафика (tshark, о котором мы уже писали, а также ngrep и tcpdump) для этой цели подходят плохо: функциональность для работы с протоколом HTTP у них ограничена.

Для анализа HTTP-трафика существует более специализированное, простое и эффективное решение. Знакомьтесь: mitmproxy. На русском языке подробных публикаций о нем почти нет. В этой статье мы поделимся своим опытом работы с mitmproxy и надеемся, что и вам он окажется полезным.



Общая информация



Mitmproxy представляет собой целый набор программных инструментов, в который входят:

  • собственно mitmproxy — интерактивная консольная программа, перехватывающая трафик «на лету»;
  • mitmdump — утилита, которую можно описать как аналог tcpdump для протокола HTTP: она перехватывает трафик и сохраняет всю информацию о нем в текстовый файл;
  • libmproxy — библиотека для Python, с помощью которой реализуется вся функциональность mitmproxy.



Само название mitmproxy происходит от аббревиатуры MITM, что означает man in the middle, или «человек посередине». Так называется метод компрометации канала связи, в котором взломщик подключается к каналу передачи между двумя контрагентами и вмешивается в протокол передачи, просматривая, удаляя и искажая информацию. mitmproxy работает похожим образом: он используется в качестве прокси-сервера, регистрируя весь HTTP-трафик. Как и любой прокси-сервер, в некоторых случаях mitmproxy может видоизменять как запросы пользователя, так и ответы на них.
Рассмотрим принципы и особенности mitmproxy более подробно.

Как это работает



В случае с незашифрованными HTTP-соединениями все просто: mitmproxy принимает соединение от клиента (например, от браузера на мобильном устройстве), отображает информацию о нем на консоли (или сохраняет в текстовый файл), а затем возвращает клиенту ответ от получателя запроса.

Mitmproxy можно использовать и для перехвата защищенного HTTPS-трафика. При запуске mitmproxy или mitmdump в директории ~/.mitmproxy создается набор файлов CA, на основе которых генерируются подменные сертификаты. Естественно, что браузер будет эти сертификаты определять как подозрительные, выдавая при каждой попытке установить SSL-соединение с помощью mitmproxy соответствующее предупреждение.

Чтобы этого предупреждения не было, можно добавить сертификат от mitmproxy в список сертификатов, используемых браузером (с подробными инструкциями можно ознакомиться здесь).
При выполнении этих двух условий клиент делает вывод о том, что устанавливаемое соединение является безопасным.

Mitmproxy может перехватывать и защищенный HTTPS-трафик. Процедура перехвата состоит из следующих шагов:

  1. Клиент устанавливает соединение с mitmproxy.
  2. Mitmproxy отправляет клиенту ответ с кодом 200 (соединение установлено).
  3. Клиент взаимодействует с mitmproxy так же, как и с удаленным сервером, и устанавливает SSL-соединение. Чтобы указать имя хоста, он использует SNI.
  4. Mitmproxy подключается к серверу и устанавливает SSL-соединение, используя указанное клиентом имя хоста.
  5. В ответе сервер передает SSL-сертификат, содержащий значения параметров CN и SAN, на основе которых затем будет создан подменный сертификат.
  6. Mitmproxy генерирует подменный сертификат и продолжает SSL-диалог с клиентом, приостановленный на этапе 3.
  7. Клиент отправляет запроc через установленное SSL-соединение.
  8. Mitmproxy передает запрос серверу через SSL-соединение, установленное на этапе 4.



Более наглядно процесс перехвата защищенного трафика можно представить в виде следующей графической схемы:

mitmproxy

Зачем это нужно



Само название mitmproxy происходит от названия одного из самых распространенных видов атак. Даже официальная документация к продукту изобилует такими словами, как «атака», «перехват» и подобными. Все это наводит на мысли о том, что этот инструмент может выступать в качестве орудия взлома. Конечно, mitmproxy (как и все продукты с аналогичным набором функций — так называемые сниферы) вполне может быть использован для нелегальных целей, но мы по вполне понятным причинам обсуждать это не будем и сосредоточимся на легальных вариантах использования.

Mitmproxy можно использовать, во-первых, для тестирования и отладки веб-приложений. С его помощью можно получать подробную информацию о том, какие запросы делает приложение и какие ответы оно получает. Также mitproxy может помочь в изучении особенностей функционирования некоторых REST API, в особенности плохо документированнных и использующих закрытые (и зачастую- очень подозрительные) технологии.

Во-вторых, Mitmproxy может работать в режиме прозрачного прокси с перехватом трафика, а это значит, что его можно использовать для анализа сетевой активности подозрительных приложений.

Тестируем Mitmproxy



Установка



Сегодня mitmproxy включен в репозитории linux-систем и может быть установлен при помощи стандартного менеджера пакетов:

$ sudo aptitude install mitmproxy



Можно также установить его другими способами:

$ pip install mitmproxy



или

$ easy_install mitmproxy



Первый запуск



Посмотрим на конкретных примерах, как работает mitmproxy. Откроем браузер (в нашем случае это Firefox) и в настройках (меню «Настройки» → «Сеть» → «Соединение») и в разделе «Ручная настройка сервиса прокси» укажем в качестве прокси-сервера машину, на которой установлен mitmproxy.

Теперь подключимся к серверу, на которому установлен mitmproxy, по ssh и выполним следующую команду:

$ mitmproxy


Консоль после этого будет выглядеть так:

mitmproxy

Чтобы выйти из этого режима, нужно нажать клавишу q. Получить справку можно, нажав комбинацию клавиш, обозначающую вопросительный знак (?).

Теперь откроем в браузере любой сайт — например, ya.ru. Все запросы к этому сайту будут выводиться на консоль:

mitmproxy

Перемещаться по списку запросов можно, нажимая на клавиши со стрелками. Вернуться в основное окно можно, нажав на клавишу q. Чтобы просмотреть подробную информацию о некотором запросе, нужно подвести к нему курсор и нажать на клавишу Enter:

mitmproxy

В поле Request отображается подробная информация о запросе (запрашиваемый хост, ПО, с помощью которого осуществлялся запрос, передаваемые заголовки), а в поле Response — информация о полученном ответе.

Переключаться между этими полями можно при помощи клавиши Tab. Вернуться к списку запросов можно, нажав на клавишу q.

Запросы и ответы на них можно изменять. Для этого нужно использовать так называемые фильтры перехвата (interception filters). Чтобы ввести фильтр, нужно нажать на клавишу i. Введем в качестве фильтра, например, ya.ru Все запросы, содержащие этот адрес, будут перехватываться. Перехваченные запросы в списке будут подсвечиваться оранжевым цветом:

mitmproxy

Такие запросы не будут обрабатываться, если мы их не примем. Чтобы принять запрос, нужно подвести к нему курсор и нажать на клавишу а, а чтобы принять все перехваченные запросы — на клавишу A.

Более подробную информацию о запросе можно просмотреть, подведя к нему курсор и нажав на клавишу E (E- первая буква в английском слове event — «событие»). Будет открыт лог событий, который имели место при обработке этого запроса:

mitmproxy

И запросы, и ответы можно редактировать. Функция редактирования может оказаться полезной при тестировании: можно, например, смоделировать определенную ситуацию и увидеть, как будет вести себя приложение, получив от сервера определенный ответ.

Подведём курсор к интересующему нас запросу, подведём к нему курсор и нажмём на клавишу Enter. Затем подведём курсор к полю Request и нажмём на клавишу E (первая буква в слове edit — редактировать). В нижней части консоли появится меню редактирования:

mitmrpoxy

Изменить можно как запрос целиком (клавиша Q), так и его отдельные параметры: путь (клавиша P), URL (U), заголовок (H), форму (F), тело ® и метод (M).

Аналогичным образом осуществляется редактирование ответа. Отредактировать можно его код (клавиша C), сообщение (M), заголовки (H) и тело ®.

Дополнительные функции



Аутентификация на прокси-сервере



В mitmproxy можно активировать режим аутентификации пользователей перед использованием прокси. Заголовки аутентификации из запросов удаляются и на вышестоящие серверы на передаются. На сегодняшний день поддерживается только базовая HTTP-аутентификация. Настройка аутентификации осуществляется при помощи следующих опций:

#запретить анонимным пользователям пользоваться прокси
$ mitmproxy --nonanonymous 

#разрешить пользоваться прокси только указанному пользователю
$ mitmrpoxy --singleuser <имя пользователя> 

#разрешить пользоваться прокси только при вводе одного из указанных в файле паролей;
$ mitmproxy —htpasswd <путь к файлу с паролями>



Привязка cookies



Функция привязки cookies (sticky cookies) полезна при работе с сервисами, требующими авторизации. Достаточно авторизоваться на таком сервисе один раз, и mitmproxy будет автоматически добавлять соответствующий cookie к каждому запросу. После этого все запросы будут передаваться на сервер без повторной авторизации.

Режим привязки cookies активируется так:

$ mitmproxy -t <фильтр>



Ко всем проксируемым запросам можно также добавлять заголовки авторизации. Для этого используется опция -u.

Режим reverse proxy



В этом режиме все запросы отсылаются к вышестоящему серверу. Mitmproxy в данном случае можно использовать в качестве временной прослойки, наблюдая и перехватывая запросы.
Режим reverse proxy активируется при помощи команды:

$ mitmproxy -P http[s]://hostname[:port]



Функция anticache



Mitmproxy может убирать из запроса заголовки if-modified-since и if-none-match. Благодаря этому всегда можно просмотреть полный ответ от сервера, даже если браузер сообщает, что запрашиваемый документ есть в кэше.

Активируется эта функция при помощи следующей команды:

$ mitmproxy --anticache 



Воспроизведение клиентских запросов



Функция воспроизведения клиентских запросов (client side replay) позволяет воспроизводить запросы из сохраненных ранее HTTP-диалогов. Запросы исполняются один за другим: отправив один запрос, mitmproxy ждет ответа от сервера, и только потом приступает к следующему. Поэтому поведение клиента может отличаться от записанного в сохраненный диалог, в котором некоторые запросы могли выполняться одновременно.

Воспроизвести клиентские запросы можно при помощи команды:

$ mitmproxy -c <путь к сохраненному диалогу>



Mitmdump



Как уже было сказано выше, Mitmdump представляет собой утилиту, работающая точно так же, как и tcpdump, только для протокола HTTP. Она перехватывает весь HTTP-трафик и записывает информацию о нем в отдельный текстовый файл.

Чтобы начать работу с mitmdump, нужно запустить mitmproxy в режиме прокси-сервера, а затем выполнить следующую команду:

$ mitmdump -w <имя файла>


Сохраненную информацию можно отфильтровать при помощи регулярных выражений, а затем сохранить в новый файл:

$ mitmdump -nr <файл1> -w <файл2> "~m post"



В приведенном примере mitmdump отбирает из файла 1 запросы, соответствующие определенному критерию (в нашем случае — POST-запросы), и записывает их в файл 2.

Mitmdump может считать уже сохраненную информацию о клиентских запросах из файла, воспроизвести эти запросы повторно, а результаты сохранить в новый файл:

$ mitmdump -nc <файл 1> -w <файл 2>


Эта функция может оказаться полезной при тестировании некоторых веб-приложений.

Заключение



В этой статье мы дали краткий обзор возможностей mitmproxy. Для желающих узнать больше приводим несколько ссылок:


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

отсюда

Далее

Wi-Fi: неочевидные нюансы (на примере домашней сети)

01:50

Сейчас многие покупают точки доступа 802.11n, но хороших скоростей достичь удается не всем. В этом посте поговорим о не очень очевидных мелких нюансах, которые могут ощутимо улучшить (или ухудшить) работу Wi-Fi. Всё описанное ниже применимо как к домашним Wi-Fi-роутерам со стандартными и продвинутыми (DD-WRT & Co.) прошивками, так и к корпоративным железкам и сетям. Поэтому, в качестве примера возьмем «домашнюю» тему, как более родную и близкую к телу. Ибо даже самые администые из админов и инженеристые из инженеров живут в многоквартирных домах (или поселках с достаточной плотностью соседей), и всем хочется быстрого и надежного Wi-Fi.
[!!]: после замечаний касательно публикации первой части привожу текст целиком. Если вы читали первую часть — продолжайте отсюда.


Несколько примечаний перед началом:

  • Стиль изложения нарочито упрощен, т.к. некоторые вещи вам, возможно, придется объяснять соседям, совершенно незнакомым с основами радиосетей, стандартом 802.11 и регуляторной политикой государства.
  • Все описанное ниже носит рекомендательный характер. Возможно, они неприменимы к вашей ситуации. Из любого правила есть исключения, которые опущены для краткости. Предельные случаи можно обсудить в комментариях.
  • Пожалуйста, обратите внимание на слово «неочевидные». Подробное доказательство некоторых тезисов требует погружения в стандарты, я этого делать не хочу (хоть и пришлось пару раз).



1. Как жить хорошо самому и не мешать соседям.


[1.1] Казалось бы – чего уж там? Выкрутил точку на полную мощность, получил максимально возможное покрытие – и радуйся. А теперь давайте подумаем: не только сигнал точки доступа должен достичь клиента, но и сигнал клиента должен достичь точки. Мощность передатчика ТД обычно до 100 мВт (20 dBm). А теперь загляните в datasheet к своему ноутбуку/телефону/планшету и найдите там мощность его Wi-Fi передатчика. Нашли? Вам очень повезло! Часто её вообще не указывают (можно поискать по FCC ID). Тем не менее, можно уверенно заявлять, что мощность типичных мобильных клиентов находится в диапазоне 30-50 мВт. Таким образом, если ТД вещает на 100мВт, а клиент – только на 50мВт, в зоне покрытия найдутся места, где клиент будет слышать точку хорошо, а ТД клиента — плохо (или вообще слышать не будет) – асимметрия. Это справедливо даже с учетом того, что у точки обычно лучше чувствительность приема — смотрите под спойлером. Опять же, речь идет не о дальности, а о симметрии.Сигнал есть – а связи нет. Или downlink быстрый, а uplink медленный. Это актуально, если вы используете Wi-Fi для онлайн-игр или скайпа, для обычного интернет-доступа это не так и важно (только, если вы не на краю покрытия). И будем жаловаться на убогого провайдера, глючную точку, кривые драйвера, но не на неграмотное планирование сети.


Обоснование (для тех, кому интересны подробности):


Вывод: может оказаться, что для получения более стабильной связи мощность точки придется снизить. Что, согласитесь, не совсем очевидно :)

[1.2] Также далеко не самым известным фактом, добавляющим к асимметрии, является то, что у большинства клиентских устройств мощность передатчика снижена на «крайних» каналах (1 и 11/13 для 2.4 ГГц). Вот пример для iPhone из документации FCC (мощность на порту антенны).

Как видите, на крайних каналах мощность передатчика в ~2.3 раза ниже, чем на средних. Причина в том, что Wi-Fi – связь широкополосная, удержать сигнал чётко в пределах рамки канала не удастся. Вот и приходится снижать мощность в «пограничных» случаях, чтобы не задевать соседние с ISM диапазоны. Вывод: если ваш планшет плохо работает в туалете – попробуйте переехать на канал 6.

2. Раз уж речь зашла о каналах…


Всем известны «непересекающиеся» каналы 1/6/11. Так вот, они пересекаются! Потому, что Wi-Fi, как было упомянуто раньше, технология широкополосная и полностью сдержать сигнал в рамках канала невозможно. Приведенные ниже иллюстрации демонстрируют эффект для 802.11n OFDM (HT). На первой иллюстрации изображена спектральная маска 802.11n OFDM (HT) для 20МГц канала в 2.4ГГц (взята прямо из стандарта). По вертикали — мощность, по горизонтали — частота (смещение от центральной частоты канала). На второй иллюстрации я наложил спектральные маски каналов 1,6,11 с учетом соседства. Из этих иллюстраций мы сделаем два важных вывода.



[2.1] Все считают, что ширина канала — 22МГц (так и есть). Но, как показывает иллюстрация, сигнал на этом не заканчивается, и даже непересекающиеся каналы таки перекрываются: 1/6 и 6/11 — на ~-20dBr, 1/11 — на ~-36dBr, 1/13 — на -45dBr.
Попытка поставить две точки доступа, настроенные на соседние «неперекрывающиеся» каналы, близко друг от друга приведет к тому, что каждая из них будет создавать соседке помеху в 20dBm – 20dB – 50dB [которые добавим на потери распространения сигнала на малое расстояние и небольшую стенку] =-50dBm! Такой уровень шума способен целиком забить любой полезный Wi-Fi сигнал из соседней комнаты, или блокировать ваши коммуникации целиком!

Почему


Вывод: если вы поставите точку рядом со стеной, а ваш сосед – с другой стороны стены, его точка на соседнем «неперекрывающемся» канале все равно может доставлять вам серьезные проблемы. Попробуйте посчитать значения помехи для каналов 1/11 и 1/13 и сделать выводы самостоятельно.
Аналогично, некоторые стараются «уплотнить» покрытие, устанавливая две точки настроенные на разные каналы друг на друга стопкой — думаю, уже не надо объяснять, что будет (исключением тут будет грамотное экранирование и грамотное разнесение антенн — все возможно, если знать как).

[2.2] Второй интересный аспект – это попытки чуть более продвинутых пользователей «убежать» между стандартными каналами 1/6/11. Опять же, логика проста: «Я между каналами словлю меньше помех». По факту, помех, обычно, ловится не меньше, а больше. Раньше вы страдали по полной только от одного соседа (на том же канале, что и вы). Но это были помехи не первого уровня OSI (интерференция), а второго – коллизии — т.к. ваша точка делила с соседом коллизионный домен и цивилизованно соседствовала на MAC-уровне. Теперь вы ловите интерференцию (Layer1) от двух соседей с обеих сторон.
В итоге, delay и jitter, может, и попытались немного уменьшиться (т.к. коллизий теперь как бы нет), но зато уменьшилось и соотношение сигнал/шум. А с ним уменьшились и скорости (т.к. каждая скорость требует некоторого минимального SNR — об этом в [3.1]) и процент годных фреймов (т.к. уменьшился запас по SNR, увеличилась чувствительность к случайным всплескам интерференции). Как следствие, обычно, возростает retransmit rate, delay, jitter, уменьшается пропускная способность.
Кроме того, при значительном перекрытии каналов таки возможно корректно принять фрейм с соседнего канала (если соотношение сигнал/шум позволяет) и таки получить коллизию. А при помехе выше -62dBm вышеупомянутый механизм CCA просто не даст воспользоваться каналом. Это только усугубляет ситуацию и негативно влияет на пропускную способность.
Вывод: не старайтесь использовать нестандартные каналы, не просчитав последствий, и отговаривайте от этого соседей. В общем, то же, что и с мощностью: отговаривайте соседей врубать точки на полную мощность на нестандартных каналах – будет меньше интерференции и коллизий у всех. Как просчитать последствия станет понятно из [3].

[2.3] По примерно тем же причинам не стоит ставить точку доступа у окна, если только вы не планируете пользоваться/раздавать Wi-Fi во дворе. Толку от того, что ваша точка будет светить вдаль, вам лично никакого – зато будете собирать коллизии и шум от всех соседей в прямой видимости. И сами к захламленности эфира добавите. Особенно в многоквартирных домах, построенных зигзагами, где окна соседей смотрят друг на друга с расстояния в 20-30м. Соседям с точками на подоконниках принесите свинцовой краски на окна… :)

[2.4][UPD] Также, для 802.11n актуален вопрос 40MHz каналов. Моя рекоммендация — включать 40MHz в режим «авто» в 5GHz, и не включать («20MHz only») в 2.4GHz (исключение — полное отсутствие соседей). Причина в том, что в присутствии 20MHz-соседей вы с большой долей вероятности получите помеху на одной из половин 40MHz-канала + включится режим совместимости 40/20MHz. Конечно, можно жестко зафиксировать 40MHz (если все ваши клиенты его поддерживают), но помеха все равно останется. Как по мне, лучше стабильные 75Mbps на поток, чем нестабильные 150. Опять же, возможны исключения — применима логика из [3.4]. Подробности можно почитать в этой ветке комментариев (вначале прочтите [3.4]).

3. Раз уж речь зашла о скоростях…


[3.1] Уже несколько раз мы упоминали скорости (rate/MCS — не throughput) в связке с SNR. Ниже приведена таблица необходимых SNR для рейтов/MCS, составленная мной по материалам стандарта. Собственно, именно поэтому для более высоких скоростей чувствительность приемника меньше, как мы заметили в [1.1].

В сетях 802.11n/MIMO благодаря MRC и другим многоантенным ухищрениям нужный SNR можно получить и при более низком входном сигнале. Обычно, это отражено в значениях чувствительности в datasheet'ах.
Отсюда, кстати, можно сделать еще один вывод: эффективный размер (и форма) зоны покрытия зависит от выбранной скорости (rate/MCS). Это важно учитывать в своих ожиданиях и при планировании сети.

[3.2] Этот пункт может оказаться неосуществимым для владельцев точек доступа с совсем простыми прошивками, которые не позволяют выставлять Basic и Supported Rates. Как уже было сказано выше, скорость (rate) зависит от соотношения сигнал/шум. Если, скажем, 54Mbps требует SNR в 25dB, а 2Mbps требует 6dB, то понятно, что фреймы, отправленные на скорости 2Mbps «пролетят» дальше, т.е. их можно декодировать с большего расстояния, чем более скоростные фреймы. Тут мы и приходим к Basic Rates: все служебные фреймы, а также броадкасты (если точка не поддерживает BCast/MCast acceleration и его разновидности), отправляются на самой нижней Basic Rate. А это значит, что вашу сеть будет видно за многие кварталы. Вот пример (спасибо Motorola AirDefense).

Опять же, это добавляет к рассмотренной в [2.2] картине коллизий: как для ситуации с соседями на том же канале, так и для ситуации с соседями на близких перекрывающихся каналах. Кроме того, фреймы ACK (которые отправляются в ответ на любой unicast пакет) тоже ходят на минимальной Basic Rate (если точка не поддерживает их акселерацию)

Еще немного математики


Вывод: отключайте низкие скорости – и у вас, и у соседей сеть станет работать быстрее. У вас – за счет того, что весь служебный трафик резко начнет ходить быстрее, у соседей – за счет того, что вы теперь для них не создаете коллизий (правда, вы все еще создаете для них интерференцию — сигнал никуда не делся — но обычно достаточно низкую). Если убедите соседей сделать то же самое – у вас сеть будет работать еще быстрее.

[3.3] Понятно, что при отключении низких скоростей подключиться к тоже можно будет только в зоне более сильного сигнала (требования к SNR стали выше), что ведет к уменьшению эффективного покрытия. Равно как и в случае с понижением мощности. Но тут уж вам решать, что вам нужно: максимальное покрытие или быстрая и стабильная связь. Используя табличку и datasheet'ы производителя точки и клиентов почти всегда можно достичь приемлемого баланса.

[3.4] Еще одним интересным вопросом являются режимы совместимости (т.н. “Protection Modes”). В настоящее время есть режим совместимости b-g (ERP Protection) и a/g-n (HT Protection). В любом случае скорость падает. На то, насколько она падает, влияет куча факторов (тут еще на две статьи материала хватит), я обычно просто говорю, что скорость падает примерно на треть. При этом, если у вас точка 802.11n и клиент 802.11n, но у соседа за стеной точка g, и его трафик долетает до вас – ваша точка точно так же свалится в режим совместимости, ибо того требует стандарт. Особенно приятно, если ваш сосед – самоделкин и ваяет что-то на основе передатчика 802.11b. :) Что делать? Так же, как и с уходом на нестандартные каналы – оценить, что для вас существеннее: коллизии (L2) или интерференция (L1). Если уровень сигнала от соседа относительно низок, переключайте точки в режим чистого 802.11n (Greenfield): возможно, понизится максимальная пропускная способность (снизится SNR), но трафик будет ходить равномернее из-за избавления от избыточных коллизий, пачек защитных фреймов и переключения модуляций. В противном случае – лучше терпеть и поговорить с соседом на предмет мощности/перемещения ТД. Ну, или отражатель поставить… Да, и не ставьте точку на окно! :)

[3.5] Другой вариант – переезжать в 5 ГГц, там воздух чище: каналов больше, шума меньше, сигнал ослабляется быстрее, да и банально точки стоят дороже, а значит – их меньше. Многие покупают dual radio точку, настраивают 802.11n Greenfield в 5 ГГц и 802.11g/n в 2.4 ГГц для гостей и всяких гаджетов, которым скорость все равно не нужна. Да и безопаснее так: у большинства script kiddies нет денег на дорогие игрушки с поддержкой 5 ГГц.
Для 5 ГГц следует помнить, что надежно работают только 4 канала: 36/40/44/48 (для Европы, для США есть еще 5). На остальных включен режим сосуществования с радарами (DFS). В итоге, связь может периодически пропадать.

4. Раз уж речь зашла о безопасности…


Упомянем некоторые интересные аспекты и здесь.
[4.1] Какой должна быть длина PSK? Вот выдержка из текста стандарта 802.11-2012, секция M4.1:
Keys derived from the pass phrase provide relatively low levels of security, especially with keys generated form short passwords, since they are subject to dictionary attack. Use of the key hash is recommended only where it is impractical to make use of a stronger form of user authentication. A key generated from a passphrase of less than about 20 characters is unlikely to deter attacks.
Вывод: ну, у кого пароль к домашней точке состоит из 20+ символов? :)

[4.2] Почему моя точка 802.11n не «разгоняется» выше скоростей a/g? И какое отношение это имеет к безопасности?
Стандарт 802.11n поддерживает только два режима шифрования: CCMP и None. Сертификация Wi-Fi 802.11n Compatible требует, чтобы при включении TKIP на радио точка переставала поддерживать все новые скоростные режимы 802.11n, оставляя лишь скорости 802.11a/b/g. В некоторых случаях можно видеть ассоциации на более высоких рейтах, но пропускная способность все равно будет низкой. Вывод: забываем про TKIP – он все равно будет запрещен с 2014 года (планы Wi-Fi Alliance).

[4.3] Стоит ли прятать (E)SSID? (это уже более известная тема)

спрятался

 

5. Всякая всячина.


[5.1] Немного о MIMO. Почему-то по сей день я сталкиваюсь с формулировками типа 2x2 MIMO или 3x3 MIMO. К сожалению, для 802.11n эта формулировка малополезна, т.к. важно знать еще количество пространственных потоков (Spatial Streams). Точка 2x2 MIMO может поддерживать только один SS, и не поднимется выше 150Mbps. Точка с 3x3 MIMO может поддерживать 2SS, ограничиваясь лишь 300Mbps. Полная формула MIMO выглядит так: TX x RX: SS. Понятно, что количество SS не может быть больше min (TX, RX). Таким образом, приведенные выше точки будут записаны как 2x2:1 и 3x3:2. Многие беспроводные клиенты реализуют 1x2:1 MIMO (смартфоны, планшеты, дешевые ноутбуки) или 2x3:2 MIMO. Так что бесполезно ожидать скорости 450Mbps от точки доступа 3x3:3 при работе с клиентом 1x2:1. Тем не менее, покупать точку типа 2x3:2 все равно стоит, т.к. большее количество принимающих антенн добавляет точке чувствительности (MRC Gain). Чем больше разница между количеством принимающих антенн точки и количеством передающих антенн клиента — тем больше выигрыш (если на пальцах). Однако, в игру вступает multipath.

[5.2] Как известно, multipath для сетей 802.11a/b/g – зло. Точка доступа, поставленная антенной в угол, может работать не самым лучшим образом, а выдвинутая из этого угла на 20-30см может показать значительно лучший результат. Аналогично для клиентов, помещений со сложной планировкой, кучей металлических предметов и т.д.
Для сетей MIMO с MRC и в особенности для работы нескольких SS (и следовательно, для получения высоких скоростей) multipath – необходимое условие. Ибо, если его не будет – создать несколько пространственных потоков не получится. Предсказывать что-либо без специальных инструментов планирования здесь сложно, да и с ними непросто. Вот пример рассчетов из Motorola LANPlanner, но однозначный ответ тут может дать только радиоразведка и тестирование.

Создать благоприятную multipath-обстановку для работы трех SS сложнее, чем для работы двух SS. Поэтому новомодные точки 3x3:3 работают с максимальной производительностью обычно лишь в небольшом радиусе, да и то не всегда. Вот красноречивый пример от HP (если копнуть глубже в материалы анонса их первой точки 3x3:3 — MSM460)

[5.3] Ну, и несколько интересных фактов для коллекции:

  • Человеческое тело ослабляет сигнал на 3-5dB (2.4/5ГГц). Просто развернувшись лицом к точке можно получить более высокую скорость.
  • Некоторые дипольные антенны имеют асммметричную диаграмму направленности в H-плоскости («вид сбоку») и лучше работают перевернутыми
  • В фрейме 802.11 может использоваться одновременно до четырех MAC-адресов, а в 802.11s (новый стандарт на mesh) — до шести!



Итого


Технология 802.11 (да и радиосетей в целом) обладает множеством неочевидных особенностей. Лично у меня вызывает громадное уважение и восхищение тот факт, что люди отточили насколько сложную технологию до уровня «воткни-работай». Мы рассмотрели (в разном объеме) разные аспекты физического и канального уровня сетей 802.11:

  • Асиметрию мощностей
  • Ограничения на мощность передачи в граничных каналах
  • Пересечение «непересекающихся» каналов и последствия
  • Работу на «нестандартных» каналах (отличных от 1/6/11/13)
  • Работу механизма Clear Channel Assesment и блокировку канала
  • Зависимость скорости (rate/MCS) от SNR и, как следствие, зависимость чувствительности приемника и зоны покрытия от требуемой скорости
  • Особенности пересылки служебного трафика
  • Последствия включения поддержки низких скоростей
  • Последствия включения поддержки режимов совместимости
  • Выбор каналов в 5ГГц
  • Некоторые забавные аспекты безопасности, MIMO и проч.


Не все было рассмотрено в полном объеме и исчерпывающем виде, равно как за бортом остались неочевидные аспекты сосуществования клиентов, балансировки нагрузки, WMM, питания и роуминга, экзотика типа Single-Channel Architecture и индивидуальных BSS — но это уже тема для сетей совсем другого масштаба. Если следовать хотя бы вышеприведенным соображениям, в обычном жилом доме можно получить вполне приличный коммунизм microcell, как в высокопроизводительных корпоративных WLAN. Надеюсь, статья была вам интересна.

отсюда

Далее

Релиз Ventoy 1.0.13

01:40

Ventoy — это инструмент с открытым исходным кодом для создания загрузочного USB-накопителя для ISO-файлов. С ним вам не нужно форматировать диск снова и снова, вам просто нужно скопировать iso файл на USB диск и загрузить его. Вы можете скопировать несколько iso-файлов и выбрать необходимый в меню загрузки. Поддерживаются и Legacy BIOS, и UEFI режимы. Протестировано 260+ ISO-файлов (список).

В этом релизе:

Добавлена поддержка образов WinPE типа «N-в-одном»;

Добавлен плагин «menu_alias», позволяющий задать псевдоним для конкретного ISO-файла;

В плагине «theme» добавлена возможность задания режима дисплея;

Добавлен вызов меню загрузки с локального диска по клавише F4;

Добавлен режим отладки по клавише F5;

Обход ограничений, присущих некоторым Legacy BIOS;

Различные оптимизации и исправления ошибок, расширен список поддерживаемых ISO-файлов.

>>> Подробности

Далее

How to pair a Low Energy (LE) Bluetooth device in dual boot with Windows & Linux

20:02

Those who dualboot know the pain of re-pairing your keyboard or mouse everytime you boot to a different OS. In this tutorial I will show how to pair a LE Bluetooth mouse in both Windows 8 and Debian simultaneously.

First pair the device in Debian, then reboot in Windows and pair the device there too. Yes, this will reset the paring in Debian, just carry on. Now we need to access the pairing keys in Windows. Download psexec.exeand open a command prompt with Administrator rights.

> cd Downloads
> psexec.exe -s -i regedit /e C:\BTKeys.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\
Services\BTHPORT\Parameters\Keys

The keys should be now exported to C:\BTKeys.reg. You should get something like:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\
7512a3185b2c\84abd4a25ee1] "LTK"=hex:6c,54,ee,80,40,47,6c,cb,fc,8e,f3,f1,c6,b2,04,9e "KeyLength"=dword:00000000 "ERand"=hex(b):1e,12,aa,37,39,cc,af,34 "EDIV"=dword:00003549 "CSRK"=hex:38,d7,aa,c1,42,06,31,25,12,b8,5a,6d,c3,90,98,f2

7512a3185b2c is the MAC address of the Bluetooth adapter, which can also be written in standard format as 75:12:A3:18:5B:2C84abd4a25ee1 is the mouse address that was assigned during the pairing. We will need those numbers in the next steps.

Now boot again to Debian. The mouse wont paired automatically, because it is now assigned to a different address and with different keys. Let's fix it.

$ cd /var/lib/bluetooth/75:12:A3:18:5B:2C/
$ ls
cache 84:AB:D4:A2:5F:E1 settings

If you look closely, the mouse address is not the same as in Windows. In my case only the fifth group is different. We need the device addresses to match, so rename the file.

$ mv 84:AB:D4:A2:{5F,5E}:E1
$ cd 84:AB:D4:A2:5E:E1/
$ ls
attributes gatt info

Now open the info file for editing and update the keys values. The relation between Windows and Bluez keys format is as follows:

  • LTK goes into Key of the LongTermKey group. Change to uppercase and remove the commas.
  • KeyLength goes into EncSize. In my case I had to replace the original value 12 with 0.
  • ERand goes into Rand. This is the tricky part. First you need to write down the ERand value in reverse, so it becomes 34afcc3937aa121e. Then convert it to decimal to get 3796477557015712286.
  • EDIV goes to EDiv. Convert from HEX to decimal normally, no reverse this time.
  • CSRK goes to Key of the LocalSignatureKey group. Uppercased and no commas.

At the end you should get this.

[LocalSignatureKey]
Key=38D7AAC14206312512B85A6DC39098F2

[LongTermKey]
Key=6C54EE8040476CCBFC8EF3F1C6B2049E
Authenticated=0
EncSize=0
EDiv=13641
Rand=3796477557015712286

Save the changes and reboot. From now on Debian and Windows will connect the mouse automatically. Awesome!

PS:

1) I did not reverse the Rand value, instead I used the decimal number regedit shows beside the hex key

2) I set EncSize to 16.

link link

Далее

Запуск иксов на Debian без физически подключенного монитора

22:39

Интересное решение как запустить Debian или Ubuntu с поднятыми иксами без физически подключенного монитора.

Опытным путем был замечен странный баг - Linux Debian/Ubuntu не стартует с поднятыми иксами при отключенном мониторе («Fatal server error: no screens found»). Есть два пути решения данной проблемы: аппаратный (подключение заглушки либо KVM свитча к VGA-порту) и программный (правим конфиги).

Внимание, никогда не покупайте VGA-S-video переходник, он никогда не будет работать без соответствующей электроники. Возможно использование только в роли заглушки. Опустим первый вариант и приступим ко второму:

1. Правим xorg.conf:

#gedit /etc/X11/xorg.conf

Section "Device"
Identifier "VNC Device"
Driver "vesa"
EndSection

Section "Screen"
Identifier "VNC Screen"
Device "VNC Device"
Monitor "VNC Monitor"
SubSection "Display"
Modes "1280x1024"
EndSubSection
EndSection

Section "Monitor"
Identifier "VNC Monitor"
HorizSync 30-70
VertRefresh 50-75
EndSection

2. Создаем и правим i915-kms.conf (для разных видеокарт - разные, в моем случае для Intel)

#gedit /etc/modprobe.d/i915-kms.conf
options i915 modeset=0

для ATI Radeon:

#echo options radeon modeset=0 > /etc/modprobe.d/radeon-kms.conf

для Nvidia:

#echo options nouveau modeset=0 > /etc/modprobe.d/nouveau-kms.conf

3. Перегружаемся:

#reboot

4. Наслаждаемся - иксы стартуют :)

Источник

Далее

Исправляем ошибку ключей репозитория

22:20

Менеджер обновления выдает сообщение

Недоступен открытый ключ для следующих ID ключей: 1397BC53640DB551

Устраняется просто — берем последние 8 символов ключа, в нашем случае:

1397BC53640DB551 ==> 640DB551

далее

sudo gpg --keyserver keyserver.ubuntu.com --recv 640DB551

sudo gpg --export --armor 640DB551 | sudo apt-key add --

 

PROFIT! (c)