Цифровой дворник

Практические заметки о сетях, self-hosting, виртуализации, мониторинге, автоматизации и локальном ИИ.

Telegram: @digclean

Робот-дворник собирает статьи в своём блоге

1) Боль: хватит жить на чужом Telegraph

Telegraph классный для быстрых заметок, но это чужой сервис. Нет контроля над доменом, нет нормального RSS, картинки лежат «где-то там», а аналитику нельзя встроить. Для «Цифрового дворника» хотелось полноценный блог, которым мы управляем сами.

2) Что хотели от платформы

  • self-hosted без внешних SaaS;
  • Markdown-редактор;
  • один Go-бинарник + SQLite (без MySQL/PostgreSQL);
  • single-user режим и аскетичный UI без отвлекающих «порталов»;
  • HTTPS через Caddy (Let's Encrypt);
  • картинки — на своём paste-хостинге (paste.example.ru);
  • каталог по тегам и RSS из коробки;
  • веб-аналитика Umami (umami.example.ru);
  • в Telegram-канал — только превью с обложкой и аннотацией, читать — на сайте (articles.example.ru).

3) Альтернативы и почему не они (кратко)

  • Ghost — мощно, но стек Node + внешняя БД, тяжеловато ради одного блога.
  • WordPress — перебор по функциональности и операционным хлопотам.
  • Hugo/Jekyll — требуют сборки/деплоя, нет живого редактора в браузере.
  • Notion/Obsidian Publish — не self-hosted и/или платно/закрыто.
  • Telegraph — оставили запасным вариантом для набросков, но не для основного блога.

Выбор платформы: тяжёлые комбайны против маленького бинарника

4) Почему WriteFreely

  • один бинарник на Go;
  • хранение в SQLite;
  • single-user режим, минимализм;
  • Markdown и RSS из коробки;
  • есть HTTP API для автопубликации из пайплайна.

5) Как ставили (кратко)

  • LXC-контейнер с systemd и выделенным пользователем приложения;
  • сервис writefreely.service, автозапуск и перезапуск при падениях;
  • Caddy как reverse_proxy перед приложением + автоматический Let's Encrypt;
  • регистрация и федерация отключены (single-user блог без чужих аккаунтов).

6) Грабли по пути — только то, что реально встретили

  • writefreely --config — это интерактивный конфигуратор, а не путь к файлу. В юните systemd нужен флаг -c /opt/writefreely/config.ini, иначе сервис «уходит» в диалоговый режим и не стартует.
  • Бинд на 127.0.0.1 + reverse proxy с другого хоста = 502. Если прокси живёт вне контейнера с приложением, слушаем внутренний IP (например, 10.0.x.x:8080), а в Caddy проксируем именно на него, а не на loopback.
  • API v0.17.2 игнорирует поле appearance (режим тизеров на главной). Пришлось сделать анонсы чистым CSS (ограничение высоты + затухание), без участия API.

7) Что не получилось пока — Instant View

Встроенный редактор Telegram (instantview.telegram.org) сейчас не может забрать страницу блога из РФ: «Can't fetch page». Внешний входящий трафик на 80/443 до лабы режется, а IV-редактор ходит снаружи, поэтому он банально не видит наш сайт. Сам шаблон (XPath) готов и лежит в проекте — как только появится доступ снаружи (или настроим прокси), подключим IV и вернём красивый ⚡️-превью в канале. Это ограничение сети, а не блога.

Instant View: дверь пока заперта, превью отложено

8) Итог

Теперь у нас свой аккуратный блог на articles.example.ru, а в Telegram остаются лаконичные превью. Картинки — с нашего paste.example.ru, каталог — по тегам, RSS работает, аналитику даёт umami.example.ru. Минимум движущихся частей, максимум контроля.

#selfhosting #openclaw #lifehacks

Обложка

Есть такой классический сетевой ритуал: зайти на железку, снять конфиг, сохранить в файл, потом когда-нибудь использовать его для восстановления или сверки.

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

Это когда устройство не вываливает весь конфиг сразу, а показывает его кусками:

--More--

или:

....press ENTER to next line, CTRL_C to break, other key to next page....

На экране это выглядит нормально: нажал Enter или Space, поехали дальше.
А вот если в этот момент логируется сессия или копируется вывод, эта служебная строка может попасть прямо в файл с конфигом.

Потом кто-то берёт этот файл, вставляет обратно в устройство, и железка начинает честно выполнять вот это:

....press ENTER to next line....

Спойлер: такой команды обычно нет.

В итоге получаем:

% Unrecognized command, and error detected at '^' marker.

и небольшую экскурсию в мир грусти.


Главное правило

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

Пагинация — это не часть конфигурации.
Это мусор интерфейса терминала, который очень убедительно притворяется командами.


Huawei / Huawei-like GPON / коммутаторы

Для Huawei и похожих CLI обычно помогает:

screen-length 0 temporary
display current-configuration

или, если на конкретной модели команда короче:

screen-length 0 temporary
display current-config

Ключевое слово здесь — temporary.
Оно отключает пагинацию только на текущую сессию, без изменения постоянных настроек.


Cisco IOS / IOS-XE

terminal length 0
show running-config

После этого конфиг выводится целиком, без --More--.


Cisco ASA

terminal pager 0
show running-config

На ASA используется именно terminal pager 0, а не terminal length 0.


Juniper JunOS

Можно отключить длину экрана в CLI:

set cli screen-length 0
show configuration

Или использовать вариант на одну команду:

show configuration | no-more

Второй способ удобен, когда не хочется менять параметры текущей CLI-сессии.


MikroTik RouterOS

Обычно экспорт нормально уходит без классической терминальной пагинации:

/export

Для более компактного вывода:

/export terse

Если надо сохранить сразу в файл на самом устройстве:

/export file=backup

Потом файл можно скачать с роутера.


Тут всё зависит от модели и версии прошивки. Часто встречаются варианты:

terminal length 0
terminal datadump
disable clipaging

После этого уже:

show running-config

или аналогичная команда просмотра конфигурации.

Если команда не сработала — лучше посмотреть ? в CLI, потому что у одного и того же вендора синтаксис может отличаться от линейки к линейке.


Linux-серверы и системные команды

На Linux проблема обычно не в сетевом CLI, а в pager’ах вроде less.

Для systemctl:

systemctl --no-pager status nginx

Для journalctl:

journalctl --no-pager -u nginx

Можно принудительно заменить pager на cat:

PAGER=cat команда

Что чистить, если уже попало

Если конфиг уже снят с мусором, ищем и удаляем строки вида:

--More--
---- More ----
....press ENTER to next line, CTRL_C to break, other key to next page....

А также управляющие хвосты терминала, которые могут выглядеть как странные символы или ANSI-последовательности.

Перед применением такого конфига лучше хотя бы быстро поискать:

grep -Ei "more|press ENTER|next page|CTRL_C" backup.cfg

Если что-то нашлось — это не конфиг, это привет от терминала.


Мини-чек-лист перед сохранением конфига

  • [ ] Отключили пагинацию.
  • [ ] Сняли конфиг.
  • [ ] Проверили, что нет --More--, press ENTER, next page.
  • [ ] Сохранили оригинальный файл.
  • [ ] Для восстановления используем очищенный файл.
  • [ ] Не удаляем служебные команды типа commit / quit, если они являются частью CLI-логики устройства.

Особенно это важно на устройствах, где конфиг состоит из профилей. Например, на Huawei GPON внутри line-profile, vlan-profile, rule-profile, specific-profile команды commit и quit могут быть не мусором, а нормальной частью применения настроек.


Короткий вывод

Отключить пагинацию — это 5 секунд.

Не отключить — это потом полчаса смотреть на:

% Unrecognized command

и думать, почему железка пытается выполнить человеческую просьбу «press ENTER to next line».


#network #lifehacks

Обложка

Цикл «Не светим лишнего». Выпуск 1.

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

Самый очевидный пример — корпоративные веб-системы: мониторинг, helpdesk, Wiki, Git, панели виртуализации, внутренние отчёты. Дальше идут SSH и RDP, WinBox, интерфейсы камер, контроллеры Wi-Fi, IPMI, iDRAC и iLO. Разработчикам нужны dev- и test-контуры, registry, CI/CD и временные стенды. Подрядчику надо на два часа попасть к конкретной камере или серверу. Дежурному инженеру — ночью зайти с домашнего Интернета и починить аварию. С удалённой площадки требуется доступ к одной служебной системе, но тащить ради неё всю сеть в туннель не хочется.

Есть и менее очевидные точки входа. Например, технологический Wi-Fi на объекте: обычный сотрудник получает только Интернет и почту, а инженер после дополнительной авторизации — доступ к оборудованию. Или временный демонстрационный контур, который должен открываться заказчику на время показа и снова исчезать. Или админская панель нового проекта, которую разработчики выставили «на недельку», а нашли через полгода.

Три разные двери

Тут полезно разделить три вещи, которые в разговоре часто смешивают.

Первая дверь — сетевая достижимость. Есть ли вообще маршрут до ресурса, опубликован ли он через NAT или reverse proxy, отвечает ли его адрес из Интернета. Если порт закрыт молча, сканер видит одно. Если отвечает SSH-баннер, веб-сервер или страница входа — уже совсем другое.

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

Третья дверь — авторизация самого ресурса. Логин в Grafana, SSH-ключ, пароль Windows, сертификат, TOTP, роль в корпоративной системе. Именно здесь приложение понимает, кто пришёл и что ему разрешено делать внутри.

Эти двери не заменяют друг друга. Если ресурс имеет отличный пароль, это ещё не повод круглосуточно показывать всему Интернету его версию, баннер, TLS-стек и форму входа. И наоборот: если доступ ограничен по IP, нельзя считать, что конкретный пользователь уже опознан. За одним разрешённым NAT может сидеть целый офис.

Почему не оставить только VPN

VPN — нормальная и привычная технология. Когда человеку действительно нужна приватная L3-связность с несколькими сетями и произвольными протоколами, он часто остаётся лучшим выбором.

Но VPN не всегда удобен как единственный ответ. На машине уже может работать другой корпоративный или личный VPN. Могут пересекаться адресные пространства, меняться DNS и default route, включаться kill switch. Для разового подрядчика приходится заводить профиль, выдавать инструкцию, потом не забыть всё отозвать. А иногда ради одной веб-панели пользователь получает возможность ходить в целую подсеть.

Поэтому дальше мы будем смотреть не на «замену VPN», а на набор инструментов. Где-то достаточно статического allow-list. Где-то лучше выдать временную запись на час. Где-то пригодится port knocking. Для веб-систем логичен авторизующий reverse proxy. Для RDP и SSH — web-bastion. А если хочется открывать firewall только при живой браузерной сессии, можно сделать TOTP-портал с heartbeat.

Что мы хотим получить в итоге

Нормальная схема должна отвечать на несколько простых вопросов:

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

И главное — доступ должен быть минимальным. Подрядчику по камерам не нужна сеть гипервизоров. Разработчику тестового проекта не нужен IPMI. Дежурному админу может понадобиться много, но только после сильной авторизации и на ограниченное время.

С чего начнём

В следующих выпусках пойдём от простого к сложному. Сначала обычный firewall и VPN, затем статические и временные списки, port knocking и SPA. Дальше — captive portal, reverse proxy, TOTP и наша любимая идея с живым WebSocket heartbeat. В финале соберём всё в одну комбинированную архитектуру и прикинем лабораторный стенд на MikroTik.

Смысл цикла не в том, чтобы объявить один метод правильным. Задача проще: перестать светить наружу всё подряд и научиться выдавать ровно тот доступ, который нужен человеку сейчас.

Документация и источники

#network

Обложка

В предыдущих публикациях мы поставили OpenClaw на сервер с помощью Cursor, подключили DeepSeek и Telegram, дали помощнику память и правила работы, а в финале собрали готовые промпты и практические подсказки. Всё это было подготовкой. Теперь перейдём к задаче, которую действительно можно встретить в обычном офисе.

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

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

Врезка: общий IP

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

Сначала важный дисклеймер

VPS, VPN, VDI, API и AI-агенты являются обычными техническими инструментами. Законность их применения определяется не названием программы, а целью, полномочиями пользователей и выполняемыми действиями.

Описанные ниже схемы нельзя использовать, чтобы:

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

Разные IP-адреса не доказывают независимость компаний и не превращают незаконную деятельность в законную. Здесь мы решаем другую задачу: нормально разделяем инфраструктуру организаций, которые действительно ведут самостоятельную деятельность.

Вариант первый: обычный VPS без всякого AI

Самая простая схема выглядит так.

Организация регистрирует аккаунт у хостинг-провайдера, заключает договор и оплачивает небольшой VPS. На сервере поднимается VPN-шлюз либо полноценное удалённое рабочее место.

Почему лучше оформлять аккаунт и договор на ту организацию, которая будет использовать сервер? Потому что тогда происхождение IP легко объясняется документами: есть клиент хостинга, договор, счета, платежи и конкретный корпоративный ресурс.

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

Врезка: варианты схем

VPN-шлюз

Для VPN подойдёт недорогой Linux-VPS с публичным IPv4-адресом. Бухгалтер подключается к VPN перед работой с конкретной организацией, и её интернет-трафик выходит через адрес этого VPS.

Плюсы:

  • можно использовать самый младший тариф;
  • не требуется переносить все программы на сервер;
  • у организации появляется отдельный стабильный выходной IP;
  • доступ легко отозвать, удалив профиль конкретного пользователя.

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

VDI или удалённое рабочее место

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

Такой вариант лучше изолирует данные, но стоит дороже. Для Windows могут потребоваться лицензии, больше памяти и процессорных ресурсов. Отдельно придётся проверить работу КЭП, КриптоПро, токенов и нужных плагинов. Поэтому самый дешёвый тариф обычно подходит для VPN-шлюза, но не всегда подходит для VDI.

Врезка: VDI

Сервер нельзя просто выставить в интернет

Здесь часто совершают главную ошибку: создают Windows-сервер, открывают наружу RDP на порту 3389 и считают задачу законченной. Делать так не стоит.

Минимальные требования выглядят следующим образом:

  • доступ к VDI или RDP разрешается только через VPN либо защищённый шлюз с MFA;
  • межсетевой экран пропускает только необходимые порты;
  • SSH доступен только администратору, желательно с разрешённых адресов и только по ключу;
  • вход по паролю для root отключается после первоначальной настройки;
  • для бухгалтера создаётся отдельная учётная запись без административных прав;
  • каждому пользователю выдаётся отдельный VPN-профиль — один общий ключ на всех использовать не надо;
  • операционная система и приложения регулярно обновляются;
  • включаются резервное копирование и журналирование входов;
  • данные для подключения передаются через защищённый канал, а не обычным сообщением в общем чате.

Бухгалтеру не нужны пароль root, панель управления хостингом или API-ключ. Ему выдаётся только персональный VPN-профиль либо собственная учётная запись удалённого рабочего места.

И ещё один важный момент: отдельный IP не заменяет полномочия. Для сдачи электронной отчётности представителем используется МЧД, а сертификаты и доступы должны принадлежать тем лицам, которым они действительно выданы.

Вариант второй: наш метод через OpenClaw или Cursor

Теперь начинается то, ради чего мы устанавливали помощника.

Регистрируем аккаунт на нужную организацию у хостинг-провайдера. В качестве примера — не рекламы — можно взять Timeweb Cloud или Fatmetal. У Timeweb Cloud есть публичный API и MCP-интеграция, а Fatmetal предоставляет MCP-сервер, через который агент может получать каталог тарифов, создавать VPS, узнавать их адреса и управлять состоянием серверов.

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

Сам ключ не надо вставлять в текст запроса, отправлять в Telegram или сохранять в статье. Он подключается к Cursor через настройки MCP и переменные окружения, а в OpenClaw — через защищённую конфигурацию skill. В запросе агенту остаётся только имя нужного подключения.

Документацию по API/MCP и правила работы мы даём помощнику вместе с понятным заданием.

Врезка: MCP

Пример задания помощнику

Ты работаешь только в проекте ACCOUNTING-GATEWAY организации <НАЗВАНИЕ>.

Сначала покажи:
1. какие инструменты API/MCP тебе доступны;
2. какой минимальный тариф подходит для VPN-шлюза;
3. регион размещения, наличие публичного IPv4 и итоговую ежемесячную стоимость;
4. какие ресурсы будут созданы и какие изменения выполнены.

До отдельной команды «ПОДТВЕРЖДАЮ СОЗДАНИЕ» ничего не создавай.

После подтверждения:
- создай минимальный KVM VPS на поддерживаемой версии Ubuntu или Debian;
- добавь SSH-ключ администратора и отключи вход root по паролю;
- настрой облачный и локальный firewall: разреши только VPN-порт, а SSH — только с адреса <ADMIN_IP>;
- установи self-hosted AmneziaVPN/AmneziaWG по официальной документации либо подготовь сервер для установки из приложения AmneziaVPN;
- создай отдельные профили для администратора и каждого указанного пользователя;
- не показывай приватные ключи в чате и не записывай их в журнал;
- сохрани конфигурации в защищённый каталог с правами 0600;
- проверь внешний IP через VPN и просканируй публичные порты;
- выдай итоговый отчёт без секретов: провайдер, проект, ID сервера, тариф, стоимость, IP, открытые порты и список созданных пользователей.

Не удаляй и не заменяй существующие серверы без отдельного подтверждения.

AmneziaVPN специально рассчитана на установку собственного VPN на арендованный сервер. Официальное приложение может само подключиться к VPS по SSH и развернуть серверную часть. Поэтому помощнику необязательно изобретать собственный установочный скрипт: он может создать VPS, закрыть firewall и подготовить SSH-доступ, после чего администратор завершит установку через приложение.

Можно ли автоматически менять VPS и IP

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

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

Поэтому автоматическую миграцию стоит применять при понятном событии:

  • отказе или закрытии старого VPS;
  • плановом переносе между площадками;
  • компрометации сервера или ключей;
  • попадании адреса в блок-лист;
  • невозможности продолжать работу у текущего провайдера.

Во многих облаках можно пересоздать VPS, сохранив публичный IP. Например, Timeweb Cloud относит свои IPv4 к «плавающим»: адрес можно перенести между сервисами внутри аккаунта. Для корпоративного шлюза это обычно лучше, чем менять и сервер, и адрес одновременно.

Если IP действительно требуется заменить, агент должен сначала создать и проверить новый контур, зафиксировать причину и старый/новый адрес, дождаться подтверждения администратора, безопасно передать новые индивидуальные профили и только после этого выводить старый сервер из эксплуатации. Рассылка VPN-ключей открытым текстом через Telegram или электронную почту в такой сценарий не входит.

Превращаем процедуру в приватный skill OpenClaw

Чтобы не писать большой запрос каждый раз, процедуру можно оформить в собственный skill. Skill в OpenClaw — это каталог с файлом SKILL.md, в котором описано, когда и как помощник должен выполнять задачу.

Для инфраструктурной операции лучше сделать skill приватным, запускать его только явной командой и запретить модели вызывать его самостоятельно. Каркас может выглядеть так:

---
name: accounting-gateway
description: Создание и контролируемая миграция VPN-шлюза организации через разрешённый MCP/API хостинга.
user-invocable: true
disable-model-invocation: true
metadata:
  openclaw:
    requires:
      env:
        - HOSTING_API_TOKEN
---

# Accounting Gateway

Работай только с организацией, аккаунтом и проектом, явно указанными пользователем.

Перед началом обязательно запроси:

- название организации;
- подтверждение полномочий на управление её инфраструктурой;
- провайдера и проект;
- допустимый бюджет;
- регион;
- административный IP;
- список пользователей;
- основание для создания или миграции.

Сначала покажи план, стоимость и изменения. Для создания дождись точной фразы
«ПОДТВЕРЖДАЮ СОЗДАНИЕ». Для миграции — «ПОДТВЕРЖДАЮ МИГРАЦИЮ».

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

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

При миграции не удаляй старый сервер до проверки нового, подтверждения администратора
и фиксации причины, старого и нового IP.

В финале выдай только несекретный отчёт: ID ресурсов, стоимость, IP, открытые порты,
результаты проверки и список пользователей без ключей.

Файл можно предложить OpenClaw через Skill Workshop, проверить сформированный вариант и только после ревью применить. Это важнее, чем скачать случайный готовый skill из каталога: наш помощник получает реальный доступ к облаку, серверам и секретам.

Что в результате получает бухгалтер

После настройки бухгалтеру не надо знать, что такое API, MCP, cloud-init или таблица маршрутизации. У него остаётся простой порядок работы:

  1. выбрать организацию;
  2. запустить её виртуальную машину или VPN-профиль;
  3. войти под своей учётной записью;
  4. выполнить работу;
  5. отключиться.

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

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

Полезные ссылки

#openclaw #lifehacks

Обложка

Представь: ты лежишь на диване, пишешь в Telegram: «Сколько занято места на основном диске?» — и через несколько секунд получаешь ответ. Или: «Перезапусти контейнер с медиасервером». И он перезапускает. Никаких ноутбуков, никакой возни с терминалом — всё в одном чате, у тебя в кармане.

Раньше за такое брали месяц жизни, рюкзак скриптов и немного седых волос. Сейчас — один вечер и примерно пять баксов на API. Я прошёл путь от «ну ща опять писать свои кроны» до «бот сам всё делает» за пару часов. И да, без ручного кодинга — только Cursor (ИИ-редактор кода), OpenClaw (агент), DeepSeek API и Telegram-бот. Дальше — как это повторить без боли, оторванно от любой «моей конкретной лабы». Пойдём по шагам. Будет просто, честно и без заклинаний.

Шаг 1. Cursor — наш «монтажник»

Сверхкратко: Cursor — это редактор кода с ИИ, который не только подсказывает, но и может сам выполнять команды в терминале. Агентный режим, Composer — всё это fancy-мод, где он берёт твой промпт «сделай вот это» и реально лезет в консоль, редачит конфиги, перезапускает сервисы. В нашем сценарии Cursor — это руки, которые всё соберут.

Что нужно до старта: – У тебя есть Proxmox (или любая домашняя виртуализация) и SSH-доступ к хосту. Не важно, где крутится — дома, на даче, в гараже — главное, чтобы ты мог зайти по SSH. – Ты готов наделить агента доступом к твоему Proxmox через API-токен, чтобы тот управлял контейнерами/ВМ. Да, именно токен — никого не пустим, кроме него, и в любой момент отзовём.

Дальше — по пунктам:

1) Скачиваем Cursor. Заходим на cursor.com, ставим, регистрируемся. Есть бесплатный тариф — нам хватит, мы не пишем гигабайт кода, мы настраиваем.

2) В Cursor открываем терминал (обычно это панель снизу, можно через меню View → Terminal), подключаемся по SSH к серверу, где будет жить агент. Стандартно: – «ssh user@hostname» — тут у каждого своё, главное — чтобы Cursor видел терминал и мог в нём действовать. – Не забываем ключи/пароли — как обычно входишь, так и тут.

3) Настраиваем на стороне Proxmox доступ по токену. Можно через UI: Datacenter → Permissions → API Tokens. Или одной командой в консоли Proxmox (я так и сделал, быстрее): pveum user token add root@pam!openclaw --privsep 0 Эта штука создаёт токен с именем openclaw для root@pam и отключает привилегии-сепарацию, чтобы агенту не пришлось упираться в ограничения, когда он, например, рестартит контейнер. Не забываем потом аккуратно ограничить, что нужно, но для старта — так быстрее.

4) Ставим OpenClaw на сервер через Cursor. В терминале (внутри Cursor) даём ИИ-промпт типа: «Установи OpenClaw на этот сервер: curl -fsSL https://openclaw.ai/install.sh | bash, потом запусти onboarding». Cursor воспримет это как задачу: выполнит установочный скрипт, дождётся, спросит, куда ставить, как запускать, и проведёт первичную настройку (onboarding). Если где-то не поймёт — спросит тебя. Тут главное — не стесняться отвечать по-человечески, он нормально такие штуки переваривает.

На что обратить внимание во время установки: – OpenClaw спросит базовые вещи о том, где хранить конфиги и как стартовать сервисы. Я всегда соглашаюсь на дефолты, а потом в конфиге поправляю — так быстрее. – Если сервер чистый, возможно, подтянутся зависимости. Нормально. Пусть тянет. – После onboarding у тебя будет базовый конфиг OpenClaw и запущенный gateway (его фронт, который принимает запросы от каналов — в нашем случае от Telegram).

И да, сразу лайфхак: держи отдельное окно терминала с правами рута. Иногда удобнее самому подсказать системе путь, поправить права на папку или логи посмотреть. Cursor умный, но ты здесь главный.

Шаг 2. DeepSeek — мозг помощника

Агент без мозга — это просто симпатичный автомат. Нам нужен LLM-провайдер, который будет думать дёшево и шустро. Я выбрал DeepSeek — регаемся на platform.deepseek.com, кидаем на баланс $5 (хватит надолго, правда), создаём API-ключ. Без фокусов, всё стандартно: «Create API key», копируем куда-нибудь в секретики (я кидаю в менеджер паролей — не в блокнот на рабочем столе, ага).

Дальше снова подключаем Cursor-руки: – В чат с Cursor (или в Composer/Agent Mode) даём задачу: «Добавь в конфиг OpenClaw провайдера deepseek, вот ключ, вот формат: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }». – Подставляем свой ключ вместо многоточия. Просим Cursor найти файл конфигурации (обычно это openclaw.json в рабочей директории OpenClaw) и аккуратно вставить этот блок. – Затем просим перезапустить gateway, чтобы изменения подхватились. Формулировка из серии: «Перезапусти gateway, чтобы конфиг обновился» — норм. Cursor поймёт и сделает.

После этого у нас — живой, мыслящий помощник. Он уже умеет рассуждать, объяснять свои шаги, анализировать твои команды. И — самое приятное — ты за это не платишь космос: DeepSeek реально экономит.

Врезка: помощник подключён

Шаг 3. Telegram — лицо помощника

Без Telegram всё это было бы просто милым CLI-аттракционом. Но мы хотим, чтобы ассистент жил там, где мы живём — в чате.

Делаем так: 1) Открываем Telegram, пишем @BotFather. 2) Команда /newbot, даём боту имя и username (должен заканчиваться на bot). Например, «homelabhelperbot», но ты придумай что-нибудь своё. BotFather вернёт токен вида 123456:ABC-DEF... — это пароль от твоего бота, никому не показываем. Реально никому. Даже соседу-админу, который «только посмотреть». 3) Узнаём свой Telegram ID. Самый простой способ — написать любому сервисному боту типа @userinfobot. Он в ответ скажет твой numeric ID. Сохраняем его туда же, где и ключи.

Теперь подключаем Telegram к OpenClaw через Cursor: – Говорим Cursor: «Настрой Telegram в OpenClaw: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [мой Telegram ID]. Мой ID: <число>». – Смысл: – botToken — это тот самый токен от BotFather. – dmPolicy: “allowlist” — политика приватности: отвечать только тем, кто явно разрешён. – allowFrom — массив ID, кому разрешено писать этому боту (вначале просто ты). Остальным — тишина и покой. Удобно, если бот видит публичные чаты: ничего лишнего он не скажет.

Просим Cursor перезапустить gateway, чтобы Telegram-канал подхватился. Через минуту можно уже написать своему боту «привет», и он ответит чем-то приветливым, если всё ок.

Врезка: Telegram подключён

Шаг 4. Кормим знаниями

Сейчас у нас есть мозг (DeepSeek), руки (Cursor+OpenClaw), и лицо (Telegram). Чего не хватает? Памяти о твоей конкретной инфраструктуре. Без неё бот будет гадать: «А где у нас там сервис на 8080?», «А как подключаться к контейнеру номер N?». Нам нужна база знаний.

Самый простой и рабочий подход — три файла в рабочей папке агента: – MEMORY.md — что где живёт, какие сервисы, порты, дисклеймеры, карта твоего хозяйства. – TOOLS.md — как подключаться: какие хосты, какими методами, где лежат ключи. Креды — не в открытом виде в файле, а ссылками на хранилище секретов или описание, откуда брать (и пусть Cursor спросит, когда надо). – AGENTS.md — правила поведения: «не трогай прод без бэкапа», «если делаешь апдейт — сперва план/пруф/подтверждение», «всё логируем».

Тут меня ждал приятный сюрприз: Cursor очень неплохо оформляет это дело, если ты ему нормальным человеческим языком расскажешь, как у тебя всё устроено. Пример диалога с Cursor: – Я: «Создай файлы MEMORY.md, TOOLS.md, AGENTS.md в рабочей папке OpenClaw. Заполни их по моему описанию. Я сейчас пришлю список сервисов и как мы к ним подключаемся». – Дальше я диктую: – MEMORY.md: перечисляю свои сервисы (без подробных секретов), какие запущены в контейнерах/ВМ, на каких портах крутятся (типа «reverse-proxy слушает 80/443», «медиасервер на 8096» и т.д.), что из этого важное, что второстепенное, где бэкапы. – TOOLS.md: говорю, как подключаемся к Proxmox через API-токен (тот, что мы создали), что SSH-ключи лежат в определённой директории (без выкладывания приватного! просто путь и заметку: «доступ у Cursor есть в рамках агента, спрашивай у меня, если что»), какие команды можно выполнять для статуса, где логи смотреть. – AGENTS.md: расписываю правила. Мои любимые пункты: – «Никогда не перезагружай хосты без явного разрешения». – «Перед обновлением системных пакетов — спроси подтверждение». – «Если видишь, что диск близок к заполнению — сформируй план: что чистим, что архивируем, что переносим. Не действуй втихую». – «Если не уверен — задай уточняющие вопросы в чат перед любыми деструктивными действиями». – «Все изменения — с кратким отчётом в конце в чат».

Cursor на основе твоего описания создаст эти файлы, положит рядом с конфигом OpenClaw, и — барабанная дробь — теперь твой помощник знает контекст. На вопрос «что у меня крутится на 8080?» он уже не будет импровизировать, а залезет в MEMORY.md и ответит по факту твоей инфры.

Плюс: когда ты добавляешь новый сервис, достаточно дописать пару строк в MEMORY.md и, при необходимости, в TOOLS.md (как к нему подключаться, как проверять). Универсально, без плясок со скриптами. Хочешь — диктуй Cursor голосом через диктовку, он всё превратит в аккуратные записи.

Финал: что получилось

Теперь у меня в Telegram живёт ассистент, который: – Понимает мою инфраструктуру. – Может проводить проверки и выполнять команды. – Думает через DeepSeek, пишет по-русски, объясняет шаги. – Не говорит с чужими — dmPolicy: “allowlist” рулит.

Примеры живых запросов из чата: – «Проверь статус сервисов». Агент идёт по TOOLS.md: если там указано, как проверять — делает. Например, дергает systemctl или контейнерные статусы, смотрит логи, умеет объяснить, если что-то лежит. – «Сколько занято места на диске». Он знает, как залогиниться по SSH и что запустить (df -h, zfs list — зависит от твоих инструментов, ты это опишешь в TOOLS.md), и вернёт внятный ответ. – «Обнови конфиг роутера». Тонкий момент: для сетевых устройств опиши в TOOLS.md, как ты к ним подключаешься и как безопасно применять конфиги (и обязательно правило в AGENTS.md — без бэкапа и плана — ни шагу). Агент выполнит твой протокол: снимет копию, применит изменения, проверит доступность, отчитается. – «Перезапусти контейнер с медиасервером». Тут пригодится Proxmox API-токен: агент умеет через него дёргать контейнеры/ВМ. Ты только укажи, какой ID или как искать по имени — и добавь это в MEMORY.md, чтобы он не путал «media» и «media-test».

Всё это — из Telegram, с телефона. Если утром в дороге надо быстро проверить «жив ли reverse-proxy», набираешь одну строку — и готово. Если у тебя привычка каждую субботу обновлять контейнеры, поручаешь боту: «Сделай апдейт, но сперва список, что именно поменяется». Он сделает план, ты согласуешь, он применит, пришлёт отчёт. Красота.

Что дальше можно прикрутить: – Мониторинг. Попроси агента раз в день/неделю делать сводку: температура, место, аптайм, статусы ключевых сервисов. Он сам кинет тебе отчёт в чат. – Автоалерты. Если в логах повторяется ошибка — пинг тебе в личку. Ты задаёшь правила словами, агент оформляет. – Канал с постами. Если нравится публичность — сделай отдельный канал, куда агент будет постить апдейты: «контейнеры обновлены», «сделан снепшот», «свободно 20% места». А в личке останутся приватные вопросы и команды.

И да, главный кайф — ты не писал ни строчки кода руками. Все «закрутки гаек» сделал Cursor: где нужно — поправил конфиг, где нужно — перезапустил gateway, где нужно — уточнил у тебя, как правильно. Ты не борешься с синтаксисом и флагами, ты говоришь с ассистентом человеческим языком.

Как это выглядит в задачах для Cursor (чтобы было под рукой)

Вот те самые фразы, которые у меня реально сработали. Можно копировать и адаптировать:

  • Установка OpenClaw: «Установи OpenClaw на этот сервер: curl -fsSL https://openclaw.ai/install.sh | bash, потом запусти onboarding. Если потребуются права рута — запроси. По окончании покажи, где лежит openclaw.json и как перезапускать gateway».

  • Добавление DeepSeek: «Добавь в конфиг OpenClaw провайдера deepseek, вот ключ, вот формат: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }. Вставь в openclaw.json и перезапусти gateway».

  • Подключение Telegram: «Настрой Telegram в OpenClaw: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [<мой Telegram ID>]. После правок перезапусти gateway».

  • Память и правила: «Создай рядом с openclaw.json файлы MEMORY.md, TOOLS.md, AGENTS.md. Я пришлю описание инфры — оформи в структурированные списки и таблицы. Сформируй чек-лист для AGENTS.md: как подтверждать опасные операции, как логировать, как делать бэкапы перед изменениями».

  • Проксмокс-токен (на стороне Proxmox, если нужно через CLI): pveum user token add root@pam!openclaw --privsep 0

Важные оговорки (чтобы не наступить на грабли)

  • Токены и ключи — это пароли. Храним в менеджере паролей. В чат не кидаем. В конфиги вставляем через Cursor, не публикуем скриншоты в чат-поддержку.
  • allowFrom — твой белый список в Telegram. Пока ассо правильно не настроен, пусть отвечает только тебе. Потом можно расширить, если есть семья/коллеги.
  • Агент — это исполнитель. Его надо научить твоим правилам: «без бэкапа — ни шага», «всё опасное — с подтверждением», «сначала план, потом действие». Пропиши это в AGENTS.md, и ты удивишься, насколько послушнее становится система.
  • DeepSeek дешёвый, но не бесплатный. Следи за расходами — обычно это копейки, но метрика рулит.
  • OpenClaw — это шина. Если ты хочешь, чтобы агент реально умел, скажем, лезть в контейнеры или в роутер — опиши путь: куда подключаться, какие команды, где конфиги. Без магии: «не знаешь — спроси». Он спросит.

Маленькие трюки, которые сэкономили мне время

  • Попроси Cursor после каждого шага оставлять в чате короткий «что сделал / как откатить». Иногда очень выручает.
  • В MEMORY.md добавь раздел «Критично важные сервисы». Пусть в отчётах они идут первыми.
  • В TOOLS.md положи раздел «Диагностика»: команды для быстрого анализа проблем сети/диска/CPU. Потом ты просто пишешь: «Запусти стандартную диагностику» — и получаешь понятный отчёт.
  • Если боишься, что агент что-то поломает — напиши: «Все операции — в dry-run, кроме явно подтверждённых». Для многих действий dry-run — это просто «покажи план и команды». Работает.
  • Раз в неделю проси бота: «Проведи самоаудит: что можно оптимизировать». Он предложит: чистка логов, ротация бэкапов, архивирование. Иногда попадаются шикарные идеи.

Что получилось в итоге (по ощущениям)

  • Субъективно — как будто у тебя появился дежурный дежурный. Пока ты на встрече, он проверил статусы. Пока ты делал кофе, он собрал отчёт. Пока ты думал «надо бы перезапустить медиасервер» — он уже спрашивает: «сделать сейчас?».
  • Важные штуки стали ближе. Раньше «посмотреть место на диске» — это лезть в SSH, вспоминать логины, пароли, команды. Сейчас — одна строка в чате. Разница чувствуется.
  • Никакой запертой магии. Ты в любой момент можешь открыть конфиг, посмотреть MEMORY.md, поправить AGENTS.md, и агент станет другим — без перекомпиляций и отпусков в ретрит.

Мораль

ИИ-агенты — это не магия, а инструмент. Ты объясняешь словами, что нужно, агент делает. Если он не понял — уточняет. Один вечер — и у тебя есть свой цифровой ассистент по дому, который сидит в Telegram, знает твою инфру и вежливо выполняет просьбы. И да, всё это без «я сейчас напишу скриптик на коленке» — за тебя писарем и монтажником выступил Cursor.

Если кратко по чек-листу: – Ставим Cursor (бесплатка ок). – На сервере ставим OpenClaw: curl -fsSL https://openclaw.ai/install.sh | bash, запускаем onboarding. – Заводим Proxmox API-токен: pveum user token add root@pam!openclaw --privsep 0. – Берём DeepSeek API-ключ, добавляем в openclaw.json: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }. – Делаем Telegram-бота через @BotFather, настраиваем: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [<твой Telegram ID>]. – Кормим MEMORY.md, TOOLS.md, AGENTS.md. – С радостью переписываемся с собственным ассистентом и больше не бегаем по серверам ради мелочи.

А у тебя есть свой помощник? Что бы ты поручил ему в первую очередь?

#openclaw #selfhosting

Обложка

Разбираю виртуальную карту Qplus Онлайн — что это и где подвох

Наткнулся на Qplus (qplus.ru) — кошелёк, который позиционируют как наследника QIWI: запущен Киви вместе с банком «Евроальянс» (лицензия ЦБ №1781) после отзыва лицензии у КИВИ Банка в 2024. Решил разобраться, стоит ли вообще смотреть в эту сторону. Сам не пользовался — только сайт, их блог и отзывы.

💳 Что за карта

• Долларовая, виртуальная, выпуск в Сингапуре • Выпуск — 40$, из них 25$ сразу на баланс карты (т.е. 15$ — просто плата за эмиссию) • Реквизиты появляются сразу в приложении • Пополнение — с рублёвого счёта кошелька, курс конвертации свой, смотри в момент операции • Лимиты «лайт»-статуса: ~15 000 ₽ за раз и ~40 000 ₽ в месяц; выше статус (3 уровня идентификации) — выше лимиты

📊 Что обещают оплачивать

• ChatGPT/OpenAI, Cursor AI — «0% комиссии» (на словах) • Steam, PS Store (Турция/США), Roblox, PUBG • Booking, Airbnb, подарочные карты Apple US

⚠️ Что смущает (по отзывам и фактам)

• Карта сингапурская — часть сервисов режет по стране выпуска: например, Claude (Anthropic) скорее всего не примет • Лайт-лимиты душат: 15к/раз и 40к/мес — для серьёзных покупок мало, придётся идти в идентификацию • Отзывы средние: otzovik ~3.2 (рекомендуют 55%), в RuStore ~690 отзывов; формулировки в духе «сыроват, но по функционалу как QIWI» • Комиссии «0%» проверяй на своём платеже — по отдельным операциям они есть • Бренд QIWI после отзыва лицензии — репутация подмочена, хотя за кошельком стоит банк с лицензией, а не шарашкина контора

Вывод: рабочий инструмент с оговорками, не серебряная пуля. Если брать — начинать с малой суммы и проверять, что твой сервис реально принимает карту.

А вы пользовались Qplus? 👇 🔥 — да, пользуюсь 👍 — нет, но присматриваюсь 👎 — пробовал, не зашло

#lifehacks

Обложка

Боль – Proxmox-сервер живёт в чужой сети, за чужим NAT. Шлюз не мой, портов не даёт, статику режет (только DHCP). Белого IP нет вообще. Классика «сервер лежит непонятно где».

Но снаружи у меня всё работает: – HTTPS для lab.example (Caddy, сертификаты Let's Encrypt) – SSH-доступ к роутерам – Мониторинг, фото, локальные LLM — открываются из любого интернета

Решение Три кита, на которых вывез всю историю: 1) Виртуальная сеть, изолированная от внешней шизофрении – Поднял вторую сеть br1 (198.51.100.0/24) без IP на хосте. Внутри неё живут сервисы: Beszel, Uptime Kuma, Immich, Ollama, Hermes. – Шлюз и NAT — отдельный LXC-контейнер с Caddy (198.51.100.1): он делает masquerade из внутренней сети в наружу, ip_forward=1.

Врезка: схема NAT/туннель– Зачем? Сервисы получают стабильную адресацию и жизнь, независимую от капризов внешнего мира.

2) Туннель, который сам уходит из-под NAT – Контейнер с Caddy инициирует SSH reverse-туннель к моему MikroTik с белым IP (203.0.113.20). – Внешние порты 443 и 80 на роутере редиректятся на 8443 и 8080, которые поднял SSH-туннель, — и уже по туннелю трафик попадает в Caddy. – Схема: интернет → MikroTik (белый IP) → SSH reverse → Caddy → сервисы в br1. – Снаружи всё приходит на 443/80, внутри туннеля — на 8443/8080.

3) Один вход — одна дверь – Весь внешний трафик встречает Caddy: раздаёт по доменам, сам продлевает TLS-сертификаты, на нём же ACL для админок. Одна точка входа — меньше боли и хаоса.

Бонус: SSH reverse-туннель, или «костыль, который стал фичей» Суть – Обычный SSH-туннель (-L) тянет удалённый порт к тебе. Reverse (-R) делает наоборот: машина за NAT сама стучится наружу и «пробрасывает» свой локальный порт на стороне сервера. – Натурально подходит для железок за CGNAT, подвалов и «дач».

Правильная картинка в моём кейсе:

Caddy (за NAT)  ──ssh -R──>  MikroTik (белый IP)
      │                           │
      └── на MikroTik открыты 8443/8080 → идут в мой localhost:443/80

Команды — как у меня Шаг 1. На MikroTik — разрешить SSH-форвардинг:

/ip ssh forwarding-enabled=both

Шаг 2. На MikroTik — локально перенаправить внешние 443/80 на 8443/8080 (куда слушает sshd для -R):

/ip firewall nat add chain=dstnat protocol=tcp dst-port=443 action=redirect to-port=8443
/ip firewall nat add chain=dstnat protocol=tcp dst-port=80  action=redirect to-port=8080

Шаг 3. На MikroTik — пропустить эти порты в firewall (до drop-правила):

/ip firewall filter add chain=input protocol=tcp dst-port=8443,8080 action=accept

Шаг 4. На Caddy (Linux) — поднять сам reverse-туннель:

ssh -R 8443:localhost:443 -R 8080:localhost:80 \
    -N -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes \
    admin@203.0.113.20
  • -R 8443:localhost:443 — «порт 8443 на MikroTik идёт в мой localhost:443»
  • -N — только туннель
  • ServerAliveInterval=30 — keepalive, чтобы NAT не рвал соединение
  • ExitOnForwardFailure — падаем, если порт не поднялся

Шаг 5. Завернул это в systemd-сервис (mt-tunnel.service), чтобы жил после ребута и сам переподключался.

Итог: открываю https://router.lab.example — попадаю в Winbox роутера за NAT. Один вход — и весь дом за ним.

Почему это «костыль», но рабочий – SSH — это TCP поверх TCP: на потере пакетов ведёт себя хуже UDP-туннелей. – Одно длинное соединение, которое надо держать живым. – Ключ от роутера лежит на Caddy: его компрометация = доступ к роутеру.

Почему не WireGuard – Пробовал — не завёлся в непривилегированном LXC (нет /dev/net/tun). – SSH уже был настроен, ключи были — 5 минут до рабочего результата. – «Правильный» вариант — WG с TUN:

# на хосте PVE, в конфиге контейнера
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0

потом mknod /dev/net/tun c 10 200 внутри — и WG поднимается как надо.

Цифры и железки – Proxmox PVE 9.2: – br0 (192.0.2.0/24, DHCP, шлюз 192.0.2.1 — MAC от VMware, статику режут) – br1 (198.51.100.0/24, без IP на хосте) – Caddy lxc-gw: 198.51.100.1 (шлюз br1), NAT masquerade br1→wan, ip_forward=1 – SSH reverse-туннель: Caddy → admin@203.0.113.20 (MikroTik), 443→8443, 80→8080, keepalive=30 c, systemd-сервис mt-tunnel – MikroTik: /ip ssh forwarding-enabled=both; dstnat redirect 443→8443, 80→8080; firewall input accept tcp 8443/8080 (до drop) – Сертификаты: Let's Encrypt для lab.example (валиден до ноября 2026) – Сервисы в br1: – Beszel — 198.51.100.12 – Uptime Kuma — 198.51.100.14 – Immich — 198.51.100.15 – Hermes — 198.51.100.16 – Ollama — 198.51.100.17

Вывод Сервер может жить за любым NAT — хоть у соседа, хоть на «даче». Пока есть исходящий интернет, все сервисы доступны снаружи через один туннель и один шлюз. Костыль? Да. Рабочая фича? Тоже да.

#network #selfhosting

Обложка

Вводные: пинги живые, а интернета как будто нет Две недели подряд ловил одинаковую картину: «интернета нет», а пинги бодрые. Браузер — унылый, мессенджеры — кое-как, игры и апдейты — рандом. Где-то пробивалось, где-то всё падало разом, будто кто-то водит шторку по списку доменов. Пропадали точечно — кептив-порталы, DoT, игровые логины, AI и облака. Типичный «фильтр-рондо». Пока включишь голову и гонишь connect-check руками — волна уже ушла, журнал пустой, виноватых нет.

Разовые прогоны хороши как «температура прямо сейчас», но бессильны против турбулентности. Мне нужна была история. Причём не в виде личных записей «кажется, около двух ночи падал OAuth у BNET и тормозил Steam CM», а нормальная хронология: кто упал, во сколько и сколько длилось.

Сел и перевёл connect-check в постоянный мониторинг на Uptime Kuma с публичной статус-страницей. Хотел, чтобы и самому видеть, и друзьям дать «смотри сюда» вместо десяти скриншотов.

Как делал: хроника работ 1) База: список ресурсов из resources.conf У меня уже был аккуратный список ресурсов для connect-check — группами: РФ-сервисы, банки, зарубежные платформы, игры (HTTPS и отдельные портовые пробы), инфраструктура (облака/IX), обновления систем и пакетных менеджеров, AI/LLM. Его и взял за основу. В терминах Kuma это — канарейки: маленькие, но громкие.

2) Площадка: Uptime Kuma в контейнере на зарубежном VPS Поднял Uptime Kuma в Docker: образ louislam/uptime-kuma:2. Спереди — Caddy, чтобы не думать про сертификаты: авто-TLS и редиректы. Корень сайта уехал на /status/netscan, чтобы не путать гостей и себя: открыл — сразу видишь общее состояние.

3) Импорт: Socket.IO API вместо REST У Kuma нет REST, у неё Socket.IO. Написал небольшой импортёр под свой resources.conf: пробегает по секциям, создаёт мониторы, присваивает теги по группам, задаёт параметры: – интервал 120 секунд (две минуты); – timeout 45 секунд; – HTTP и TCP по типу цели; – расширенные HTTP-коды успеха: не только 200, но и 400/429/500/503 в ряде точек — чтобы увидеть «жив ответ сервера» вместо ложной тревоги от временного 500; – ignoreTls там, где встречаются self-signed у банков/внутренних шлюзов; – expected_block/пауза для платформ, где блок-страницы и редиректы — это норма (YouTube, Meta, Telegram, Discord), чтобы не маячили фальшивые «зелёные» от их капч и заглушек.

Часть госсайтов принудительно гоню на HTTP: у ряда из них :443 формально «жив», но по сути мёртв, а реальный сервис отдают по 80-му.

4) Публичная статус-страница: /status/netscan Собрал страницу через addStatusPage и saveStatusPage. Имя: «Netscan — доступность ресурсов». Описание: «Публичная статистика проверок ресурсов (netscan / ConnectCheck). Интервал ~2 мин.» Поставил автообновление на 60 секунд, добавил подпись: «Источник списков: netscan resources.conf». Без логина, только статусы. Каждая секция из resources.conf стала группой на странице.

5) Алерты в Telegram Без этого мониторинг — просто музей графиков. Подключил Telegram-уведомления: падение — пилик, восстановление — тоже пилик. Волну фильтрации видно не только на дашборде: телефон сам шепчет «что-то с банками» или «просели AI-шлюзы».

6) Тонкая настройка под точку проверки Важно: все проверки идут С зарубежного VPS. Это картина «с этой точки». Для «как видит абонент в РФ» я оставил локальный connect-check — сравниваем две линии. Где расхождение — там и ответ: фильтрует дорога в/из страны или локальные сети.

Что получилось: живая, публичная картина сети На странице /status/netscan сейчас 346 мониторов, разбитых на 11 групп. HTTP/HTTPS и TCP-пробы примерно в пропорции 228 к 118. Интервал ~2 минуты — это около 720 проверок в сутки на каждый монитор. Получается плотная, ритмичная лента событий. Если кто-то «присел» даже на 5–10 минут — видно.

Врезка: статус-страница Netscan

Группы и состав 1) RU popular — 89 Государственные и популярные сервисы: Госуслуги, Президент/Правительство/Госдума, Яндекс/VK/OK/Mail/Дзен, медиа (Rutube, IVI, Okko, Кинопоиск, РБК, ТАСС, РИА, Известия, Ведомости), маркетплейсы (Ozon, Wildberries, Avito, HH), транспорт (РЖД, Туту, 2ГИС), операторы (МТС, МегаФон, Билайн, t2, Ростелеком), ритейл и прочее.

2) Banks — 17 Сбербанк, СберБанк Онлайн, Т-Банк×2, ВТБ, Альфа, Газпромбанк, РСХБ, Совкомбанк, МТС Банк, ПСБ, Райффайзен, Росбанк, плюс Bitrix24/Zoom (деловые сервисы в контексте бэкофиса), DNS Shop и ЦИАН — маркеры «жизни вокруг платежей».

3) Significant — 15 Большие публичные платформы: Google/Gmail/Play, App Store, Microsoft/Teams, YouTube, Instagram, Facebook, X, Discord, Telegram, WhatsApp, Wikipedia.

4) Video — 6 IVI, Okko, Rutube, VK Видео, Кинопоиск, Яндекс Видео.

5) Games HTTPS — 44 Battle.net/Blizzard/BNET login, Steam CDN (Dota/CS2), Epic×4, Riot, Ubisoft×2, Xbox, PSN×3, Nintendo, EA, Roblox×3, Minecraft, GOG, VK Play, War Thunder, Мир танков×2, Мир кораблей, Lesta, Tarkov, Genshin/HoYoverse×4, Twitch×3, Kick×3, loot.farm×2.

6) Games TCP — 66 Портовые пробы и узлы сессий: Battle.net HTTPS/account/OAuth/EU/US/version/download, BNET login :1119 EU/US/KR, CDN Akamai, Steam CM, Epic :443, GOG, Faceit, Xbox Live, PSN и т.д. Это те точки, где «логин не проходит» и «матчмейкинг крутится вечность».

7) Infra HTTPS — 12 Служебные веб-интерфейсы и точки проверки инфраструктуры.

8) Infra TCP — 26 Облака и CDN на портах: AWS S3 EU-North, Azure×4, Cloudflare×3, DigitalOcean×2, Hetzner×2, OVH×3, Selectel×6, GitHub×3. Хорошая лакмусовая бумажка для «облако целиком просело» против «упал только чей-то фронт».

9) Geo / IX — 10 DE-CIX, AMS-IX, LINX, DATAIX, Eurasia Peering, HE Looking Glass, Selectel speed. Тут и латентность видна, и «зевки» обменных узлов.

10) Updates — 35 Обновления всего, чем живёт домашняя инфраструктура: Debian/Ubuntu/Arch/Fedora/Kali/Alma/Rocky/openSUSE, Alpine, Docker Hub×2, PyPI/npm/crates/Maven/NuGet, Homebrew, Flathub, Snapcraft, Windows Update/Winget/VS Code, Chrome Omaha, Apple mesu/configuration/gdmf, Mozilla, Microsoft download CDN, Yandex mirror×2. Когда это краснеет — админ страдает.

11) AI / LLM — 26 OpenAI/ChatGPT/API, Anthropic×3, Cursor×2, Gemini×3, Grok/xAI×3, DeepSeek×2, Mistral×2, Hugging Face, Groq, Together, Perplexity, Poe, Copilot, GigaChat, YandexGPT/Алиса. Если тут краснеет пачкой — это не «случайно лёг таб», это волна по AI.

Поведение и «волны» – Интервал 2 минуты даёт ~720 точек в сутки на каждый монитор. Любая точечная фильтрация больше пары минут засвечивается на дашборде — не через день, а почти сразу. – Вчерашняя волна 28.07 по банкам РФ в такой конфигурации выглядела бы как красные карточки в группе Banks в реальном времени. Алерт в Telegram, потом спокойная зелень, а в истории — чёткий коридор времени для разбирательства. – В группах Games TCP хорошо видно, когда «ломит логин»: краснеют именно :1119 у BNET или CM-узлы Steam, при этом витрина магазинов по HTTPS — зелёная. Можно сразу говорить пользователю: «играть — да, логиниться — нет». – В Infra TCP и Geo/IX ловятся скачки латентности и мимолётные недоступности на уровне облаков/обменников. Если одновременно краснеют Cloudflare и пара IX — это уже сетевое, а не «у сервиса рука дрогнула». – В Updates — отдельная боль. Когда PyPI/npm и Docker Hub дружно уходят в «серое», любые CI/CD и домашние апдейты превращаются в квест.

Технические детали, чтобы всё честно – Контейнер: louislam/uptime-kuma:2. – Перед ним Caddy с авто-TLS. Корень сайта редиректит на /status/netscan. – Импорт мониторов через Socket.IO API: создаю monitors с тегами по секциям, интервал 120с, timeout 45с, тип HTTP/TCP по ресурсу. – Публичная страница собрана addStatusPage + saveStatusPage: группы совпадают с секциями resources.conf. – Страница автообновляется каждые 60 секунд. Внизу подпись: «Источник списков: netscan resources.conf». – Подстройка под реальные условия: – гос-ресурсы — чаще HTTP; :443 иногда «ждёт лучшей жизни»; – банки — ignoreTls для мест с самоподписанными цепочками; – расширенные acceptedstatuscodes (400/429/500/503) там, где сам факт ответа важнее «строгой 200»; – для YouTube/Meta/Telegram/Discord — пауза и expectedblock, чтобы не считать заглушки «здоровьем». – Проверки идут с зарубежного VPS — это важно для интерпретации. Для российского абонента картинка может отличаться: держу локальный connect-check как второй взгляд с земли. – Алерты — в Telegram. Этого хватает для «вскипает чайник — посмотрел — понятно».

Живые цифры – 346 мониторов в 11 группах: примерно 228 HTTP и 118 TCP. – Интервал ~2 минуты — около 720 проверок/сутки на каждый монитор. – Суммарно это сотни тысяч проверок в день. Хватает, чтобы увидеть и «пульс» сервисов, и редкие, но показательные «провалы». – Публикация статуса: «Netscan — доступность ресурсов» по пути /status/netscan. Описание на странице: «Публичная статистика проверок ресурсов (netscan / ConnectCheck). Интервал ~2 мин.» Автообновление — 60 секунд.

Что это даёт в быту – Когда «интернета нет» при живых пингах — захожу на /status/netscan и сразу вижу, кого именно «подстригли»: кептивы, банки, игровые логины, AI, облака, репозитории обновлений. – Можно аргументированно разговаривать с поддержкой: «в 13:42–13:58 пачкой шли ошибки на PSN и Xbox Live, при этом Cloudflare и IX — зелёные, проблема, похоже, на маршруте до конкретной AS». – Для своих — одна ссылка вместо поэмы в мессенджере. Для себя — история для ретроспективы и автоматические алерты, а не «кажется, это было позавчера». – Для лабы — набор «канареек» по всем категориям. Если зеленеют не там, где надо, или внезапно краснеет банк/облако/AI — собираюсь быстрее.

Грабли и почему именно так – Разовый connect-check — отличная диагностика «прямо сейчас», но он не ловит всплески и не даёт истории. А фильтрация сегодня — это волны. Они приходят и уходят быстрее, чем ты успеваешь сделать первый скриншот. – Почему Uptime Kuma? Простая, самодостаточная, контейнером завернул, Socket.IO — и поехали. Плюс приятная публичная страница, которую не стыдно показывать. – Зачем расширенные коды и ignoreTls? Чтобы не путать «сервер отвечает, но ругается» с «канал физически закрыт». Для сетевой картины важнее факт досягаемости, чем идеальный HTTP-ритуал. – Почему 2 минуты? Компромисс: волна видна в течение минут, а не дней, и при этом не жрёт VPS до костей. Меньше интервал — шумнее и дороже, больше — зияют дыры.

Дальше по плану – Вторую точку мониторинга хочу запустить из домашней сети: сравнивать «зарубежный взгляд» и «домашний абонент». Либо второй зарубежный VPS — для географии. – Добавить несколько UDP-мониторов для игр (где это адекватно), но аккуратно: Kuma тут не всесилен. – Свести «красные всплески» к недельным сводкам: какие группы страдали чаще, в какие часы. Это полезно не только для цифровой гигиены, но и для планирования обновлений.

Выводы – Разовый прогон — фотоснимок. Постоянный мониторинг — хроника с таймкодами и будильником. – При «интернета нет» и живых пингах публичная /status/netscan даёт конкретику: фильтруются ли кептивы, падают ли банки, захлебнулся ли OAuth у игр, дергают ли AI/облака или задушили репозитории апдейтов. – Волны фильтрации становятся видны сразу — на шкале минут, а не «вчера где-то в районе вечера». – Алерты в Telegram снимают главную боль: не надо сидеть и таращиться в зелёные кирпичики — телефон сам позовёт, когда надо вмешаться.

❓ Вопрос

Какие канарейки добавить в netscan, чтобы ловить «нет интернета при живых пингах» точнее? Отдельные проверки DoT/DoH/QUIC, больше игровых узлов, UDP-пробы, больше зеркал обновлений — или, наоборот, реже, но точнее? И из какой точки мира/сети вы бы хотели вторую (третью) перспективу?

#monitoring

Обложка

Вводные и исходные данные

У вас бывало: телефон орёт «без интернета», на ноуте Windows уныло пишет «подключение без доступа», а пинги — как на подбор, зелёные, 0% потерь? У меня это расцвело на две недели. Причём не «упал провайдер», не «роутер сдох», а что-то совсем точечное: то игры не логинятся, то AI молчит, то push'и у умных ламп залипают, зато сайт районной библиотеки бодро открывается. Живой канал, но местами как будто ножницами выстрижено.

Фон: обычный homelab-дворик. Встаю утром, варю кофе, иду VLAN’ы кормить:

  • Домашний Wi‑Fi → сегмент 10.0.10.0/24, роутер 10.0.10.1.
  • Гостевая сеть → своя подсеть 10.0.20.0/24, NAT на тот же WAN.
  • IoT-живность → 10.0.30.0/24, без выхода в локалку, только наружу.
  • Аплинк один, серый NAT, никаких белых адресов не светим.
  • Роутер от производителя «которого нельзя называть», с нормальным firewall'ом.
  • Для проверки связности — самописная утилита connect-check: ~500 тестов в один прогон (кептив-порталы ОС, DNS/DoT/DoH, QUIC, игры, AI-платформы, облака, банки, IoT-порты, CDN, скорость). Отчёт — один HTML-файл.

Врезка: карта VLAN и подключений

До 16 июля всё было как в рекламе провайдеров (которых мы тут не называем). А вот дальше пошла странная пила: устройства вроде в сети, но «интернета нет». Я достал свой connect-check и начал вести дневник замеров.

Как и что делал — хроника, инструменты, команды

Как появился connect-check (спойлер: не сразу)

Сначала никакой утилиты не было. Я просто реверсил трафик телефонов: смотрел, куда они вообще стучатся, когда решают «есть ли интернет». Поднял tcpdump, отфильтровал по устройству — и увидел, что к части ресурсов SYN уходит, а ответа нет вообще: ни RST, ни SYN-ACK. Просто тишина. Так впервые вылезли кептив-порталы — connectivitycheck.gstatic.com и его соседи.

Дальше — проще: раз режут эти, наверняка режут и похожие. Накидал список «канареек» (connectivitycheck.android.com, msftconnecttest.com, captive.apple.com и прочие) и стал проверять их руками, пачками. А потом из этого выросла маленькая консольная утилитка, которая гоняет адреса пачками и отдаёт один HTML-отчёт. Со временем список ресурсов и сервисов разросся до 500+ проверок — туда попали игры, AI-платформы, облака, IoT-порты, банки, DNS/DoT/DoH, QUIC.

16.07. Старт. Симптом: телефоны «без интернета», браузер кое-как живёт, игры не логинятся

  • Прогон connect-check с Android в домашнем Wi‑Fi:
    • 40 OK, 7 предупреждений, 8 провалов.
  • Первое, что проверяю при «интернета нет»:
    • Кептив-порталы ОС. На Android это connectivitycheck.gstatic.com/generate204 и connectivitycheck.android.com/generate204.
    • curl -I http://connectivitycheck.gstatic.com/generate_204
    • curl -I http://connectivitycheck.android.com/generate_204
    • Ожидается HTTP/204 No Content. Фактически: таймауты (WinINet на Windows выдаёт 12002), а ping connectivitycheck.gstatic.com — 0% потерь, DNS резолвит. Значит, кто-то душит именно эти URL.
  • DNS и пинги:
    • ping 1.1.1.1 → ок.
    • ping 8.8.8.8 → ок.
    • dig connectivitycheck.gstatic.com A @1.1.1.1 → A-запись есть.
    • А вот HTTP к generate_204 — молчит. Сразу ловушка: Android и Windows считают, что интернет отсутствует, потому что их «проверки доступа» не отвечают.

Вечер 16.07. «Может, это Wi‑Fi шалит?» Перепрыгнул на второй SSID (5 ГГц, DFS, канал 52)

  • Прогон connect-check:
    • 14 OK, 6 warn, 37 fail — стало хуже.
  • Возвращаюсь на основной SSID — снова «нормально плохое»:
    • 41 OK, 6 warn, 8 fail.
  • Вывод: не в радио. DFS может добавлять спецэффектов, но главная беда где-то за радиоинтерфейсом.

18.07 утро. Первая волна нарастает

  • Прогон:
    • 120 OK, 18 warn, 19 fail.
  • Бьём DoT (DNS-over-TLS) — подозрение на фильтрацию порта 853:
    • echo | openssl s_client -connect dns.google:853 -servername dns.google -brief → зависает/таймаут.
    • echo | openssl s_client -connect 8.8.8.8:853 -servername dns.google → таймаут.
    • echo | openssl s_client -connect 9.9.9.9:853 -servername dns.quad9.net → таймаут.
    • echo | openssl s_client -connect 1.1.1.1:853 -servername cloudflare-dns.com → соединяется.
  • На Android в настройках частного DNS «Автоматически» → телефон объявляет сеть «без интернета». Ставлю «Выключено» — статус возвращается, браузер оживает. Диагноз: порт 853 фильтруется точечно (Cloudflare пропускают), Android при этом падает в обморок.

20–21.07. Пик. Резко ложится почти всё иностранное, задевает и часть наших

  • 20.07 утро:
    • 228 OK, 12 warn, 5 fail — пока терпимо.
  • 20.07 (гостевая сеть 10.0.20.0/24):
    • 154 OK, 25 warn, 61 fail — гостям сегодня лучше книжку.
  • 20.07 полдень:
    • 220 OK, 17 warn, 2 fail — как будто «кто-то» отпустил.
  • 20.07 вечер:
    • 116 OK, 31 warn, 93 fail — опять душит.
  • 21.07 утро:
    • 114 OK, 27 warn, 99 fail — держат под водой.
  • 21.07 день:
    • 105 OK, 61 warn, 80 fail — в строю лишь самое житейское.

Что именно резалось в пик (проверял точечными коннектами):

1) Кептив-порталы ОС — системно. Это и делает «нет интернета» при живом канале. – curl -I http://connectivitycheck.gstatic.com/generate_204 → таймаут. – curl -I http://www.msftconnecttest.com/connecttest.txt → таймаут. – curl -I http://captive.apple.com/hotspot-detect.html → таймаут. – Статистика по gstatic: 0/8 успешных подряд — стабильный ноль.

Врезка: кептив-порталы режут точечно

2) DoT :853 — чёткая политика: – dns.google, 8.8.8.8, 9.9.9.9 → не коннектится. – 1.1.1.1 → коннектится. – tcpdump -i wan -n host 8.8.8.8 and port 853 → SYN уходит, ответа нет. Строгое «нет» на SYN/ACK.

Врезка: DoT режут выборочно

3) Игры — входы и CDN/CM: – Battle.net, включая login :1119 на *.actual.battle.net → нет рукопожатия. – nc -vz eu.actual.battle.net 1119 → Operation timed out. – Steam CDN/CM, Epic, Riot, Ubisoft, GOG, Xbox Live, PlayStation Network, Nintendo, EA, Roblox, Minecraft: – Формально это TCP/443, но TLS-рукопожатие залипает на ClientHello. – curl -sI https://store.steampowered.com → может открыться, а лаунчер — не логинится: SNI/DPI по доменам и шаблонам. – Трассы выглядят как обычно до границы, дальше молчание: – mtr -T -P 443 battle.net → маршруты до 198.51.100.x, затем тишина.

4) AI-платформы — отрезаны подчистую: – OpenAI (включая ChatGPT и API), Claude/Anthropic, Gemini, AI Studio, Grok/xAI, DeepSeek, Mistral, Hugging Face, Groq, Together, Poe, Notion AI, Cursor. – Браузер: WinINet 12002 (таймаут) или 12057 (TLS/DNS). – curl -sS https://api.openai.com/v1/models → дожидается полминуты и роняет коннект.

5) Облака: – AWS S3 CDN (в частности, репы amazonlinux) — регулярно в fail. – curl -I https://some-bucket.s3.amazonaws.com/… → периодические таймауты.

6) IoT-порты — push/шины: – MQTT :8883 (Tuya, Aqara) → conn. timeout. – Google mtalk :5228/:5229 → timeout. – Apple push :5223 → timeout. – XMPP :5222 → timeout. – В логах умного дома: «облако недоступно», девайсы падают в оффлайн. Локальные сценарии работают, удалённые уведомления — нет.

7) QUIC (UDP/443): – curl —http3 -I https://www.google.com → долго, потом откат на HTTP/2. – curl —http3 -I https://www.cloudflare.com → аналогично. – tcpdump -i wan udp port 443 and host 203.0.113.10 → Handshake не складывается, пакеты отваливаются. DPI глушит HTTP/3.

8) DNS-имена точечно: – dig +time=2 +retry=1 iot.yandex.ru @1.1.1.1 → ок. – dig iot.yandex.ru @10.0.10.1 (локальный резолвер, форвард к аплинку) → SERVFAIL/timeout. Значит не весь DNS умер, а выборочно по именам у аплинка. – Аналогично: api.alice.yandex.net, ok.ru, copilot.microsoft.com, clouddrive.nabucasa.com — то не резолвит, то резолвит, но дальше 443 молчит.

9) NTP: – time.google.com, ntp.yandex.ru — временами не отвечают по UDP/123. На графике — ступеньки дрейфа часов. В другие минуты — живут.

22.07 10:57 — будто тумблер щёлкнули

  • Прогон:
    • 286 OK, 17 warn, 2 fail (AWS S3 + Росбанк). Всё остальное — отпустило.
  • Проверяю DoT:
    • dns.google:853 — снова нет.
    • 1.1.1.1:853 — по-прежнему да.
  • Кептив-порталы:
    • gstatic generate_204 → начал стабильно давать 204. Android и Windows радостно вернули «интернет есть».

28.07 ночь — вторая волна, на этот раз российские сервисы в прицеле

  • Прогон:
    • 257 OK, 15 warn, 30 fail.
  • В fail — банки и маркетплейсы:
    • Сбер, Т‑Банк, ВТБ, Альфа, РСХБ, ПСБ, Росбанк.
    • Ozon, РЖД, Дзен, OK.ru, Okko, Почта России.
  • Параллельно опять хромает игры и немного CDN для магазинов. Картина будто «настроить другое правило».

29.07 00:09 — полное восстановление

  • Прогон:
    • 264 OK, 40 warn, 0 fail. Впервые за эти две недели — идеально по фейлам.
  • QUIC по-прежнему местами не любит Google/Cloudflare, но уже в warn — с откатом на TCP/443 всё открывается.

05.08 постскриптум — остаточные артефакты

  • Прогон:
    • 423 OK, 79 warn, 3 fail.
  • Fail:
    • Ведомости — HTTP 502 (их косяк, похоже).
    • Rambler Почта, Proton Mail — TCP :443/:80 закрыт/фильтруется.
  • Warn: 23 сайта с недогруженными ассетами с CDN:
    • fonts.gstatic.com, counter.yadro.ru, static.criteo.net, www.gstatic.com — часть запросов не уходит/не доходит, но основные страницы открываются.

И ещё детали, которые я докручивал в процессе

  • Трассировки:
    • mtr -T -P 443 api.openai.com → доходит до 198.51.100.x, дальше тишина. С ICMP — зелёный.
  • Сравнение сетей:
    • Домашний Wi‑Fi и гостевая сеть (разные VLAN’ы, один WAN) ловят одинаковую пилу. Значит, не межсетевик и не NAT в моём роутере.
  • Локальный DNS:
    • unbound на 10.0.10.2, форвардил на аплинк → та же точечная резка по именам.
    • Прямой dig @1.1.1.1 — чаще ок, чем через аплинк-резолвер. Но DoT к dns.google стабильно не работает.
  • Режимы браузера:
    • HTTP/2 по TCP — чаще жив.
    • HTTP/3 (QUIC) — регулярно отправляют «в угол».
  • Игровые лаунчеры:
    • Локальный браузер может открыть маркетплейс, а логин/патч — нет. Смотрел в tcpdump — ClientHello уходит, ответа нет. DPI по SNI и/или набору JA3-отпечатков.

Что в итоге вышло — сухие цифры и факты

  • 16.07 (Android, домашний Wi‑Fi): 40 OK, 7 warn, 8 fail.
  • 16.07 вечер (Android, второй SSID 5 ГГц DFS ch52): 14 OK, 6 warn, 37 fail.
  • 16.07 вечер (Android, обратно): 41 OK, 6 warn, 8 fail.
  • 18.07 утро: 120 OK, 18 warn, 19 fail.
  • 20.07 утро: 228 OK, 12 warn, 5 fail.
  • 20.07 (гостевая сеть): 154 OK, 25 warn, 61 fail.
  • 20.07 полдень: 220 OK, 17 warn, 2 fail.
  • 20.07 вечер: 116 OK, 31 warn, 93 fail.
  • 21.07 утро: 114 OK, 27 warn, 99 fail.
  • 21.07 день: 105 OK, 61 warn, 80 fail.
  • 22.07 утро: 241 OK, 17 warn, 39 fail.
  • 22.07 (ещё сеть): 109 OK, 30 warn, 73 fail.
  • 22.07 10:57: 286 OK, 17 warn, 2 fail.
  • 28.07 ночь: 257 OK, 15 warn, 30 fail.
  • 29.07 00:09: 264 OK, 40 warn, 0 fail.
  • 05.08: 423 OK, 79 warn, 3 fail (+ 23 сайта с частично не грузящимися ассетами CDN).

Паттерны фильтрации, подтверждённые тестами:

  • Системные кептив-порталы (connectivitycheck.gstatic.com, connectivitycheck.android.com, www.msftconnecttest.com, captive.apple.com) — точечно в молоко. Поэтому ОС дружно помечают сети как «без интернета».
  • DoT :853 — фильтрация. dns.google/8.8.8.8/9.9.9.9 закрыты/таймаут. 1.1.1.1 открыт.
  • Игровые экосистемы — отрезает логин/патч:
    • Battle.net (включая :1119), Steam CDN/CM, Epic, Riot, Ubisoft, GOG, Xbox Live, PlayStation Network, Nintendo, EA, Roblox, Minecraft.
  • AI-платформы — таймауты/DNS: OpenAI, ChatGPT, OpenAI API, Claude/Anthropic, Gemini, AI Studio, Grok/xAI, DeepSeek, Mistral, Hugging Face, Groq, Together, Poe, Notion AI, Cursor.
  • Облака — регулярно AWS S3 CDN (например, amazonlinux).
  • IoT-порты — MQTT :8883, Google mtalk :5228/:5229, Apple push :5223, XMPP :5222.
  • QUIC (UDP/443) — глушится DPI, при живом TCP/443.
  • DNS по именам — точечные дыры: iot.yandex.ru, api.alice.yandex.net, ok.ru, copilot.microsoft.com, clouddrive.nabucasa.com.
  • NTP — time.google.com, ntp.yandex.ru иногда молчат по UDP/123.
  • Российские сервисы тоже ловили:
    • 22.07: Госуслуги/Президент/Правительство/Госдума, Wildberries, 2ГИС.
    • 28.07: банки (Сбер, Т‑Банк, ВТБ, Альфа, РСХБ, ПСБ, Росбанк), Ozon, РЖД, Дзен, OK.ru, Okko, Почта России.

Динамика по волнам:

Врезка: волны фильтрации

  • 16–18.07 — первая волна: телефоны «без интернета» (кептивы), DoT, игры.
  • 20–21.07 — пик: до 61–99 сбоев за прогон, ложится почти всё зарубежное, местами и РФ-сервисы.
  • 22.07 10:57 — резкий откат до 2 сбоев (AWS S3 + Росбанк).
  • 28.07 — вторая волна: 30 сбоев, в основном РФ‑сервисы и игры.
  • 29.07 — полное восстановление — 0 сбоев.
  • 05.08 — хвост: 3 сбоя + кучка CDN-ассетов в warn.

Важно: весь этот цирк проходил при зелёной базовой связности:

  • Пинги к 1.1.1.1/8.8.8.8 — без потерь.
  • DNS в целом резолвит (кроме точечной резки по именам).
  • Скорость по iperf к 198.51.100.50:5201 (мой тестовый узел за NAT’ом друга) — как обычно.
  • Приложения, которые не попадают под SNI/DPI-правила, работали.

Выводы и что делать

1) «Нет интернета» ≠ нет интернета. Если пинги зелёные и DNS в целом жив, а телефон/Windows врут — первым делом смотрите кептив-порталы:

Если тут таймауты — ОС решит, что «интернета нет», и начнёт творить дичь (не все приложения станут выходить в сеть).

2) DoT (порт 853) может фильтроваться точечно. На Android:

  • Настройки → Сеть и интернет → Частный DNS → Выключено.
  • «Автоматически» при заблокированном dns.google:853 превратит вашу сеть в «без интернета», хотя TCP/443 и DNS по UDP/53 живут.

Проверка с хоста:

  • echo | openssl s_client -connect dns.google:853 -servername dns.google -brief.
  • echo | openssl s_client -connect 1.1.1.1:853 -servername cloudflare-dns.com -brief.

3) Это очень похоже на SNI/DPI-фильтрацию и тестовые волны ТСПУ:

  • Маркируются конкретные домены/семейства (игры, AI, облака).
  • Режутся push-порты и QUIC.
  • Ломаются именно «проверочные» домены OS, чтобы техника считала сеть оффлайн.
  • Наблюдается волнами, с резкими включениями/откатами.

4) Как диагностировать самостоятельно (минимальный чек-лист):

5) Что делать, кроме «подождать, пока отпустит»:

  • Собирать фактуру: даты/время, домены, порты, IP назначения (dstIP), скриншоты ошибок (WinINet 12002/12057), логи утилит.
  • Отправлять письмо в ЦМУ ССОП: info@noc.gov.ru.
    • Указать:
    • Номер ТСПУ (если известен; его провайдер обычно светит в договорах/ЛК).
    • Оператора (название не пишу здесь, но в письме — указывать).
    • Примеры недоступных сайтов/сервисов (с точными доменами).
    • Время и длительность каждого инцидента (волны).
    • Трассировки (traceroute/mtr) и результаты повторных попыток не реже 1 раза в 5 минут.
    • dstIP/порты, на которых фиксировались отказы.
    • Скриншоты ответов/таймаутов, желателен pcap-файл.
  • Важно: показывайте, что это не «у вас роутер», а репродуцируется на разных VLAN/сетях/устройствах (домашний Wi‑Fi, гостевая сеть, мобильный).
  • На смартфонах до разбора симптомов отключайте «Частный DNS» и не пугайтесь «без интернета» — это диагноз ОС по сломанным кептив-порталам, а не факт отсутствия канала.

6) Для гигиены лабы:

  • Разведите мониторинг системных URL ОС (gstatic/msftconnecttest/captive.apple) отдельной метрикой — это золотой индикатор.
  • Храните эталонный набор доменов по категориям: игры, AI, облака, банки, IoT. Один прогон — и картинка дня ясна.
  • Автоматизируйте записи о волнах: таймстемпы, OK/warn/fail. У меня это делает connect-check, отчёт — один HTML, открывается даже оффлайн.

Мой личный срез по «что это было»

  • По совокупности: точечная SNI/DPI-фильтрация, вероятно, волны настройки/тестов ТСПУ. Это объясняет, почему одновременно падали:
    • Кептив-порталы (ОС теряют уверенность, заявляют «без интернета»).
    • DoT :853 (частично), QUIC (UDP/443).
    • Семейства доменов (игры, AI, облака) и отдельные DNS-имена.
    • IoT-порты для уведомлений/шины.
  • Наличие «окна» 22.07 10:57 (практически полное восстановление) и второго всплеска 28.07 по РФ-сервисам выглядит как переключение профилей/политик, а не «сломался провод».
  • Полное восстановление 29.07 в 00:09 — характерный «сменили правило/откатили конфиг».

Вопрос к вам

Кто ещё ловил такие волны? С той же симптоматикой: живые пинги/DNS, но «без интернета» из‑за кептивов, закрытый DoT (кроме 1.1.1.1), отключенный QUIC, массовые таймауты игр/AI/облаков, и потом резкий откат? Чем мерили, есть ли у вас числа по дням/часам? Писали ли в ЦМУ ССОП на info@noc.gov.ru и что ответили?

🔧 Утилита диагностики: https://github.com/cooler58/connect-check/releases

#monitoring #network

Обложка

Вводные. Лаба на Proxmox, всё в LXC. Внутрянка на br1 (198.51.100.0/24). Снаружи — один вход через Caddy: обратный прокси, TLS сам. Админки и мониторинг — за ACL: только мой IP, остальным 403. ComfyUI (SD 1.5) живёт в lxc-comfy (198.51.100.18), раньше пыхтел на CPU, в этот день переехал на GPU: Radeon 760M, ROCm-торч, HSAOVERRIDEGFX_VERSION=11.0.0, ollama временно стопнул, чтобы не бодалась за GPU. ComfyUI слушает 8188, в мир — comfy.example-lab.ru. Параллельно ставил Frigate в свежем lxc-frigate.

Симптом. «Комфи 403, остальное открывается». photos.example-lab.ru — ок, beszel/uptime — ок, а comfy.example-lab.ru — 403, позже 502. Подозрение на ACL: «может, IP не тот?»

Хроника.

1) Логи Caddy: с телефона (открывал из Telegram) подряд два respond “Access denied” 403. Потом — 502: connect refused к 198.51.100.18:8188.

2) Внутри lxc-comfy: – ss -tlnp | grep 8188 → LISTEN 0.0.0.0:8188 (python) – curl http://127.0.0.1:8188/ → 200, UI отдался – curl http://198.51.100.18:8188/ -I → 200

Значит, жив и слушает на всех интерфейсах.

3) Снаружи (с хоста/через Caddy/с соседнего контейнера): – bash -lc '>/dev/tcp/198.51.100.18/8188' → Connection refused – tcpdump -i any -n port 8188 внутри lxc-comfy → 0 пакетов – tcpdump -i br1 -n host 198.51.100.18 and port 8188 → SYN доходит и прилетает RST

Если бы отвечал ComfyUI, был бы SYN-ACK. Значит, откликается кто-то другой.

4) Исключаем банальное: PVE firewall — пусто, ebtables — пусто, nft/iptables в контейнерах — ACCEPT, ip_forward=0 (но у нас L2-мост). Чисто.

Разгадка — ARP. – ip neigh show 198.51.100.18 → lladdr «чужой MAC» – А у lxc-comfy MAC другой. – bridge fdb show | grep «чужой MAC» → этот MAC висит на порту lxc-frigate.

Бинго: у lxc-frigate оказался тот же IP 198.51.100.18. ARP резолвит адрес в «чужой MAC», трафик уезжает во Frigate, там 8188 не слушается — оттого RST. 403 здесь просто шум от ACL на первых попытках, корень — дубль IP.

Фикс. – Перекинул lxc-frigate на 198.51.100.19: pct set <frigate_id> --net0 name=eth0,bridge=br1,ip=198.51.100.19/24,gw=198.51.100.1 pct reboot <frigate_id> – ip neigh flush 198.51.100.18 – Проверка: 198.51.100.18 снова указывает на MAC lxc-comfy. – comfy.example-lab.ru → 200, UI летает на GPU.

Мораль. Когда «не открывается», сперва проверь, твой ли это вообще адрес. Дубль IP — тихий убийца: ICMP может отвечать «кто-то один», а TCP будет резать RST с чужого контейнера. Диагностика по тропинке: ss (слушает?) → tcpdump (доходит?) → ARP/fdb (чей MAC?).

А вы чем страхуете лабу от дублей: DHCP-резервы, IPAM, arpwatch на br1 или что-то своё?

#network #lifehacks