OpenVPN docker image with full IPv6 support

As I mentioned earlier, I’ve developed my own tool for managing OpenVPN servers. I’ve been running several instances without any issues, and last weekend, I finally decided to add full IPv6 support. This includes both connecting to the server via IPv6 and routing IPv6 traffic within the tunnel.

Initially, I spent several hours troubleshooting how to get an IPv6 setup working in Docker. Many documents claim that Docker is entirely incompatible with IPv6, while others suggest you can enable IPv6 but must manually manage networks, NAT, and other configurations. However, this isn’t entirely true.

Basic IPv6 support has been available in Docker for years (see ipv6 option), but you used to need to handle subnets and routing manually. Now, Docker can manage all the necessary iptables configurations, including SNAT/masquerading for IPv6, if you enable the experimental and ip6tables options.

A detailed guide on the docker setup can be found here.

As for OpenVPN, I’ve added IPv6 support to the gerasiov/openvpn image (with the recommended setup described in the README), so anyone can easily set up their own IPv6-capable OpenVPN server in just five minutes.

WiFi fast roaming with OpenWRT

Having trouble with your home WiFi network when moving between access points? I did. After spending several days debugging, I found that my network was working fine with ‘psk2’ (WPA2) mode, but failing with ‘sae-mixed’ (WPA2/WPA3).

Here’s the recipe that works for me:

  1. Install the dawn and wpad-openssl packages on your OpenWRT router.

  2. Modify the dawn configuration to specify broadcast_ip, shared_key and kicking options.

  3. Add the following options to the relevant WiFi interfaces on all access points:

config wifi-iface 'wifinet1'
	option ssid 'OpenWRT'
	option device 'radio0'
	option key 'mysecretpassword'
	option network 'lan'
	option mode 'ap'
	option encryption 'psk2'
	option ieee80211w '1'
	option ieee80211k '1'
	option ieee80211r '1'
	option bss_transition '1'
	option wnm_sleep_mode '1'
	option ft_over_ds '1'
	option ft_psk_generate_local '1'
	option time_advertisement '2'
	option time_zone 'GMT0'

P.S. When you want to debug roaming with your Android phone the one of the most powerful solutions is WiFiman app.

Борьба со спамом в 2020 (rpamd, SpamAssassin и нейросети)

Уже 15 лет (ужас какой!) использую для фильтрации спама SpamAssassin, и что-то стали возникать к нему притензии. С одной стороны, кажется, спама в интернете стало сильно меньше, чем в конце нулевых. По моим ощущениям, мне стало в месяц приходить ~300 писем вместо нескольких тысяч. (Возможно дело в том, что крупные почтовые сервисы его довольно успешно фильтруют, благодаря своим ресурсам, и “обычные пользователи” стали сильно менее доступны для спамеров.) С другой же стороны, стал замечать, что SA успешно отфильтровывает примерно половину спама (с достаточно консервативными настройками без false-positive). С третьей стороны не байесом же единым, за последние десять лет и нейросети выросли и какой-нибудь SVM кажется кто-то должен уже был внедрить (по крайней мере Саша Петров мне еще в своей дипломной работе его прикручивал и вроде как неплохие результаты получал, хотя до продакшн решения не доделал).

В общем решил я посмотреть на то, что у нас нового появилось в этой области: количество инструментов увеличилось, но всё это просто классификаторы (практически все на наивном байесе, хотя некоторые, вроде как заявляется, и более точные, чем тот, что внутри SpamAssassin), в отличие от SA, который еще с кучей эвристик, нацеленных именно на анализ почты (корректность заголовков, работа с RBL, скоринг для хостов, сетей и автономных систем, участвовавших в передаче письма, DMARC, DKIM, SPF и прочее).

Но на фоне всего этого болота заметил довольно развитый и живой проект rspamd. По сути примерно такой же комбайн, как SpamAssassin, только вместо перла C и lua, ну и комьюнити сильно меньше. Зато встроенный milter, вроде как более “правильный” байес, встроенная реализация dkim (можно выкинуть opendkim), встроенный грейлистинг (он вообще сейчас от спама помогает?) и даже есть экспериментальный нейросетевой классификатор.

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

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

Ну раз так, то устроем side-by-side сравнение на живом трафике!

Дано:

  • Свежая чистая инсталляция почтового сервера: postfix + dovecot.
  • На postfix полностью отключены все аутлупы по rbl и фильтрации HELO, которые я использовал раньше.
  • rspamd 1.9.4 с чистой базой и дефолтными настройками. (add_header = 7)
  • SpamAssassin (через spamass-milter) с +/- дефолтными настройками (включил по максимуму разные модули, в том числе pyzor, razor и txrep) и тоже чистой базой. (required_score 7.0)
  • Немножко скриптов, которые отправляют на дообучение (в оба сервиса) те письма, которые были классифицированы неправильно (в тот момент, когда я перекладываю письмо в папку Junk или обратно).
  • Почтовый поток порядка нескольких тысяч писем в месяц, из которых две-три сотни – это спам.
  • Система “Спамографопостроитель 1.0”, которая рисует в реальном времени гистограммы оценок по всем полученным письмам.

Немного подробнее по гистограммам: они обновляются в реальном времени и рисуются в четырёх вариантах: общие оценки для rspamd и SA, оценки байесовского фильтра для rspamd и SA. Вертикальной чертой на каждом графике отображена граница спам/не спам, так что слева от нее мы видим не спам и фолс-негатив, а справа спам и фолс-позитив. Пока оценок мало + фильтры не натренированы графики должны быть довольно шумными, но, хочется надеяться, дальше ситуация исправится. Опять же по этим графикам можно будет прикинуть, насколько корректно выбрана граница для классификации.

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

А пока: давайте наблюдать!

PS. Дорогие спамеры, не могли бы насыпать мне побольше образцов спама на spam@gerasiov.net. Пожалуйста!

Выписка из интернет-банка Авангард, Тинькофф, Сбербанк и др. в формате OFX

Нашел у себя в блоге старый, неопубликованный черновик. Публикую.

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

В принципе, многие банки умеют экпортировать выписки в формате CSV или XLS и их (иногда немного помучавшись) можно скормить в тот же GnuCash. Но самый простой способ – это сгенерировать из банковского отчета файл OFX (универсальный открытый формат для банковских выписок) и его уже импортировать в бухгалтерское ПО.
Для этой задачи существует универсальная платформа ofxstatement, позволяющая генерировать такие выписки и куча плагинов, умеющих парсить выписки различных банков.

Список банков/плагинов есть на странице самого ofxstatement в README. Можно установить необходимый плагин руками. В частности репозиторий ofxstatement-russian содержит плагины для Авангарда, ТинькоффБанк, АльфаБанк, Сбербанк. Ну или можно поставить в Debian/Ubuntu пакеты ofxstatement и ofxstatement-plugins (если используете стабильный дистрибутив, то плагины лучше ставить из backports, там они более актуальные).

Back to the Windows

“простым смертным” надо просто клик хере и у них 99% функционала работает, а на остальное им пофигу. А нам чуть что так либо виртуалка либо на свободный раздел либо несовместимость форматов либо ещё какая хрень. А годов уже далеко не двадцать и жизни осталось не бесконечность. — Никита Ющенко про виндузовый рай

Началось всё с того, что у меня в ноутбуке стоит SSD Transcend TS256GMTS400. (При чем не от производителя ноутбука, а купленный на амазоне и установленный самостоятельно.) Вроде бы работает нормально, но изредка (иногда раз в неделю, иногда пять раз за день) вдруг подвисает на пять-десять секунд, после чего происходит пачка таймаутов операции чтения на ata, выполняется hard link reset и всё работает дальше как ни в чем не бывало. При чем обычное чтение всего устройства проходит без проблем.
Возможно в фоне ядро вызывало TRIM на устройстве, а эта операция на некоторых SSD приводит (или раньше приводила) к заметным проседаниям производительности (вплоть до вот таких подвисаний). Не знаю деталей, посмотрел я на версию прошивки, глянул в интернете, вроде на скриншотах много где указана версия старше, при чем значительно, так что надо обновлять. Более-менее привычная задача.
Тут-то всё и завертелось…
Вначале я залез на сайт производителя. (Ну если быть совсем честным, я туда залез чуть раньше, когда пытался понять какая версия прошивки сейчас актуальная, и уже тогда начал подозревать…) Производитель явно не отличается дружелюбностью. В разделе Support/Download для данного SSD лежит одна единственная ссылка на нечто, называемое SSD Scope. Какая-то утилита, которая работает под виндой и выводит “состояние здоровья” вашего накопителя. Правда на скриншотах было видно, что один из пунктов в интерфейсе называется “Firmware status/upgrade”. Так что, выходило, что надо качать и ставить этот софт под винду.
Так как это прошивка для SSD, подключаемого по M.2, да еще и того, на котором стоит система, то обойтись виртуалкой с пробросом в нее физического устройства скорее всего не получится (а даже если и получится, то как-то слишком рискованно). Переставить SSD в другой компьютер тоже проблематично: и интерфейс редкий и разбирать X240 крайне много мороки (чертовы китайцы!). Значит нужна живая винда. =(
Надо сказать, что на тот момент у меня на ноутбуке даже были какие-то остатки предустановленной винды. Проблема только в том, что из коробки винда стояла где-то на sda3, при этом sda1 был EFI boot раздел с ейным загрузчиком. Когда я поставил SSD, я первым делом сделал EFI boot раздел на sdb1 (то есть на этом самом SSD), sda переразбил, снеся всё ненужное, а виндовый загрузчик положил на sdb1. И даже заставил эту винду загружаться. Проблема только в том, что потом, в какой-то момент, я переносил данные с другого ноутбука, и, совсем забыв про винду, перезаписал в числе прочего и EFI boot раздел целиком. Так что винда у меня вроде как была, но её загрузчика уже не было.
Ну ок, починять свой загрузчик винда умеет аж со времен Windows NT 4.0, значит надо забутиться с инсталляционного носителя и восстановить, делов-то. Не тут-то было. Во-первых, как выяснилось, у винды до сих пор туго с загрузочными USB. Нельзя просто взять и записать ISO образ на USB, как уже давно делается в приличном обществе. Надо либо запускать встроенный мастер создания инсталляционного носителя (который будет качать все 4 ГБ из Интернета), либо использовать сторонние инструменты вроде rufus (которые берут данные из iso образа, но всё равно копируют файлы весьма медленно). Ну и, понятно, работает это всё только под виндой, благо у меня есть некоторое количество виртуалок, пробросить внутрь которых USB накопитель не представляется сложным.
Попробовал восстановить загрузчик… Два раза… Оба раза было так: загружается инсталлятор, я ему говорю, что хочу починить свою винду, он радостно говорит “у вас поврежден загрузчик, щас починю”, после чего рисует какой-то BSOD и… больше с этого USB диска уже загрузиться не получается, потому что, судя по всему, загрузчик он чинит сам у себя. “Разрешите я выстрелю себе в ногу, сэр!”
Черт с ним. Решил поставить винду с нуля. Фиг. Не нравится ей что-то. Пишет что на данный раздел установить винду невозможно, потому что диск имеет разметку GPT. После некоторого чертыхания, удаление раздела, затирания данных на разделе и т.п. таки удалось уговорить инсталлятор, что ставить можно и нужно и винда-таки поставилась…
Уже во времена приснопамятного Windows NT 4.0 виндовый загрузчик был достаточно умный. Он поддерживал менюшки, chainload других загрузчиков и всё такое. Конечно инсталлятор не мог понять всякие там линуксы, биэсди и прочее, тупо затирал MBR своим stage 1 bootloader, и в меню добавлял только другие найденные инсталляции той же винды. Но то был прошлый век. Сегодня у нас всё технологичнее, есть UEFI, с его стандартизованным процессом выбора загрузчика и т.п. Но фиг там. Винда заставила меня биться в истерике… первый раз…

21 век. Космические корабли, всё такое… Для совместимости и интероперабельности в области загрузки персональных компьютеров изобретен стандарт (U)EFI, со специальным разделом, куда разные ОС могут складывать свои загрузчики, чтобы потом их запускать из начальной микропрограммы EFI.
А долбаный Windows 10 ПРОДОЛЖАЕТ УДАЛЯТЬ ЗАГРУЗЧИКИ других операционных систем. Но так как теперь по стандарту они ему не мешают, он, для надежности, при инсталляции переформатирует все найденные EFI Boot разделы!

Реальность оказалась еще более фееричной. После того, как починил загрузку рабочей системы, я вернулся к исходной задаче, то есть к перепрошивке SSD. Загрузился в винду, поставил SSD Scope, перешел в раздел с информацией о прошивке… “Для вашего устройства есть более новая прошивка, скачать?” – радостно спросила меня программа. “Конечно да”, – ответил я. После чего ничего не произошло. Но в Диспетчере задач (а надо сказать, что диспетчер задач и прогрессбар файловых операций – это две реально отличные новые фишки в восьмой винде) было видно, что что-то оно-таки качает. Через некоторое время вдруг всплыло окошко “Новая прошивка скачана. Открыть?”
На самом деле об этом можно было догадаться раньше. Как можно из винды обновить прошивку накопителя, с которого, возможно, эта винда и загружена? Конечно инженеры Трансценда тоже об этом подумали. И, конечно, решили, что безопаснее будет, если пользователь загрузится с чего-то другого. Например с USB. К сожалению, это не прошивка BIOS и не устройства на какой-нибуть legacy шине, типа PCI, поэтому из DOS этого сделать не получится. Windows PE, конечно, более-менее подойдёт, но весит много, сложна в лицензировании и не все просто с поддержкой аппаратуры. Какую ОС выбрать для такого носителя, чтобы она +/- везде загрузилась и увидела все устройства без всяких там миллионом драйверов? Ну да, вы правильно догадались. SSD Scope просто скачал мне архив, в котором лежал образ специального Линукса, руководство и программка под винду, которая умеет переформатировать флэшку и записать на нее выбранный образ. Так со мной случилась истерика второй раз.
Но и это еще не все. Воспетая Никитой стратегия “клик хере” не сработала, флэшка записывалась, но при загрузке с нее не оказывалось ни иксов, ни программы прошивки. Разбираться не стал, выдрал прошивальщик с файлами из архива, загрузился по сети в GParted Live, запустил прошивальщик и… он сказал, что щас всё с SSD сотрёт полностью. Не знаю, что в такой ситуации делают “простые смертные”, а мне пришлось еще сдампить всё содержимое вначале на диск, а потом после перепрошивки обратно на SSD.
В общем задача решена: SSD, вроде, больше не подвисает, но лулзов и потраченного времени, как по мне, так несколько слишком. Единственное что не могу понять, так это какая из всего этого мораль, видимо придётся додумывать читателям.

i386, amd64, crypto

Есть у меня очень удобный Eee PC 1015B. Маленький, живет 6 часов от батарейки, потерять не жалко… Ну точнее как не жалко, сама железка стоила 10 тысяч несколько лет назад или даже дешевле, а сегодня таких почему-то больше не делают, так что, если потерять, то не понятно будет чем заменить. Это с одной стороны. С другой стороны, там есть некоторое количество информации, приватность которой меня волнует. Понятно, что надо всё шифровать и т.п.
В тот момент, когда я эту железку купил, шифрование всего диска требовало каких-то телодвижений, а мне было то ли некогда, то ли лень, то ли всё сразу, поэтому я ограничился тем, что все, что очень надо, шифровал в юзерспейсе. Некоторое время назад, инсталлируя очередной ноутбук, использовал cryptsetup прямо из инсталлятора и обнаружил, что он вообще ничего не требует и нормально работает. Так что подумал о том, чтобы всё-таки зашифровать содержимое EeePC.
Решил не париться, проинсталлировать его с нуля, заодно перейти с i386 на amd64, который теперь уже совсем-совсем дозрел. Но так как в нетбуке стоит слабенький Brazos, были некоторые опасения, не станет ли он совсем тормозить из-за дополнительного шифрования. Поэтому померил его производительность старым добрым бенчмарком “Собери ядро 3.16”.
Тестируемая система:
ASUS EeePC 1015B
AMD Brazos C-50 (1ГГц, 2 ядра (на самом деле что-то вроде HyperThreading), 64bit)
RAM 4GB
SSD 256GB (какой-то A-Data)
Результаты:
i386 без шифрования

$ time make -j2 modules
real 241m20.022s
user 443m10.388s
sys 21m6.952s

i386 (chroot на amd64 хосте) с шифрованием

$ time make -j2 modules
real 244m18.927s
user 445m4.748s
sys 21m45.132s

Как видно, включение шифрования почти не дало падения производительности на задачах, где надо не очень интенсивно читать/писать много маленьких файлов.
После этого я решил заодно проверить, насколько сейчас оптимизирована компиляция под amd64 и собрал то же ядро с тем же конфигом, но на amd64 хосте. Результат получился не совсем ожиданный (для меня). Под amd64 всё собралось заметно быстрее:
amd64 с шифрованием

$ time make -j2 modules
real 222m59.369s
user 381m12.240s
sys 29m23.844s

Выигрыш – 10%.
График:

Удаление письма из хранилища dovecot

Отправил случайно в список рассылки письмо на много десятков мегабайт и оно разлетелось по всем разработчикам, что не есть хорошо, потому что у всех почта на нашем сервере и сразу полгига места ушло.
Решил удалить его прямо у пользователей из Maildir’ов. Вначале убедился, что ищутся правильные письма:
doveadm search -A FROM git@lvk.cs.msu.su LARGER 10M HEADER X-Git-Newrev 252417435200cca7d6ac33b8be24018100513527
Вроде, всё Ok, пытаюсь удалить:
doveadm -D expunge -A FROM git@lvk.cs.msu.su LARGER 10M HEADER X-Git-Newrev 252417435200cca7d6ac33b8be24018100513527
Получаю:

To avoid accidents, search query must contain MAILBOX in all search branches

Ну, в принципе, логично и правильно, от греха… Но у меня-то случай особый! =) Понятия не имею кто по каким папкам раскладывает коммит-логи, так что надо всё-таки удалять из всех, а не только из явно перечисленных. Пришлось в изысканиях дойти до исходников, где нашел, что можно указать не конкретную папку, а globe:
doveadm -D expunge -A mailbox '*' FROM git@lvk.cs.msu.su LARGER 10M HEADER X-Git-Newrev 252417435200cca7d6ac33b8be24018100513527
Вот так сработало.

The smallest video monitoring daemon ever

Как-то раз я уезжал и захотелось мне устроить небольшой видеомониторинг, чтобы с телефона контролировать происходящее под окнами.
При чем без всяких детекторов движения и всякой прочей ерунды. Просто иногда поглядывать, убеждаться, что машина на месте и продолжать предаваться отдыху.
Всякие системы мониторинга типа Motion или ZoneMinder поднимать было неохота, поэтому написал на коленке простенький скриптик, грабящий картинку с веб-камеры и копирующий ее на удаленный сервер.
Сейчас вот разбирал мусор, нашел его и решил куда-нить кинуть.

Лицензирование ПО в современном мире

Рассказывал сегодня про лицензирование ПО (в первую очередь про свободные лицензии).

Исходник тут.
Очень понравилось как работает libreoffice-presenter-console. (Надо ставить отдельно пакетом.) Must Have.

Update Seagate firmware from Linux

Нашел тут вчера пару Seagate Barracuda 7200.12 (ST31000528AS). Тех самых, на которых надо обязательно обновлять прошивку. И задался вопросом как бы ее обновить.
С Виндой и загрузочным CD как-то не задалось, поэтому попытался понять, как сделать это из-под линукса. Почему-то гугл давал много ссылок но ни одной по теме, поэтому пришлось поискать.
Итак, вам понадобятся:

  1. Файл с новой прошивкой
  2. Утилита hdparm
  3. Готовность к тому, что диск в результате будет испорчен

Прошивка:
Скачиваем iso с сайта Seagate (в моем случае это был Barracuda12-ALL-CC49.iso), вытаскиваем из него RAM-образ (у меня он назывался PH-CC49.ima), монтируем его как loop-устройство и находим в нем архив с прошивками LOD.zip
В архиве обнаружилось несколько LOD-файлов с прошивками, что несколько запутывает, но судя по этому файлу это версии прошивок для дисков одного семейства, но с разным числом головок, и в моем случае нужна была прошивка PHCC494H.LOD
А вот для Seagate Barracuda ES.2 история была чуть другая. Я скачал файл ES2SN06C-1D2DMoose.iso, но в нем была только какая-то ненужная ерунда, а прошивка была интегрирована в загрузочный образ. Так что мне потребовалось вначале вытащить загрузочный образ командой geteltorito ES2SN06C-1D2DMoose.iso > boot.img и уже в нем обнаружился 1D2DSN06.LOD.
В ряде мест упоминалось, что прошивку можно залить при помощи утилиты sg_write_buffer, но у меня это не заработало. Зато сработала команда hdparm --fwdownload
Была прошивка:
# smartctl -a /dev/sdb
Model Family:     Seagate Barracuda 7200.12
Device Model:     ST31000528AS
Firmware Version: CC38

Заливаем новую:
# hdparm --fwdownload PHCC494H.LOD /dev/sdb
Выключаем компьютер по питанию (перезагрузки недостаточно), включаем назад:
# smartctl -a /dev/sdb
Model Family:     Seagate Barracuda 7200.12
Device Model:     ST31000528AS
Firmware Version: CC49

Всё получилось!
Еще раз делаем это на свой страх и риск с готовностью потерять диск совсем (ну hdparm у вас это уточнит). И конечно загрузившись не с того диска, который перепрошиваем.
 
And one more time for Google spider =)
You can update Seagate HDD firmware from Linux with hdparm command.
First you should find the propper firmware in LOD format (E.g. dowload iso from vendor site, get .IMA image from it, and extract LOD.ZIP archive with firmwares from that image.)
If you don’t see image file in .iso, you can try to extract it from ElTorito boot, like I did for my Seagate Barracuda ES.2:
geteltorito ES2SN06C-1D2DMoose.iso > boot.img
And inside this boot.img I found 1D2DSN06.LOD.
Then upload firmware into hdd with
# hdparm --fwdownload <firmware.LOD> /dev/<HDD>
That’s it!