Axottle

Changelog.

Большие изменения Axottle — с контекстом, ограничениями и объяснением того, что поменялось в ежедневной работе.

Первое включение, страница статуса и страница подписок.Читать обновление

v1.5.2 · обновление за 2–3 августа 2026

Разбор того, что вскрывается только на живом сервере.

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

Панель перестала врать про служебного пользователя

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

Причина в одну строку. Пояснение к коду попало внутрь текста SQL-запроса: для Go это часть строки, для PostgreSQL — синтаксическая ошибка, и запись падала при каждом вызове.

Теперь она проходит. Заодно неудачная попытка перестала выглядеть как «никто и не пытался»: панель пишет, на чём именно споткнулась, а синхронизация сообщает об этом в результате, а не только в лог. Раньше она в любом случае заканчивалась зелёной.

Применение схемы синхронизируется с Remnawave

Локальная копия того, что происходит в Remnawave, обновлялась ровно одним способом: вы нажимали «Синхронизировать» на странице подключения. С этого момента она расходилась с настоящей панелью, и признаться в этом было нечему.

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

Теперь применение синхронизируется само, перед тем как что-то отправлять в Remnawave. Шаг не обязательный: недоступная панель не роняет деплой, который отработал бы и по старым данным. Но результат виден в диалоге применения, так что «применили по устаревшему снимку» больше не подразумевается молча. Применение из-за этого стало заметно дольше на панелях с большим числом пользователей.

Кроме того, панель обновляет эту копию сама раз в десять минут.

Схема не применяется на домен, которого ещё нет в DNS

Домен входной ноды уходит в хост Remnawave, по которому подключаются все клиенты, и по нему же панель проверяет шлюз. Если A-записи у домена нет, не работает ничего: ни клиенты, ни проверки, ни маскировочный сайт. Наружу это выходит десятком разных на вид ошибок вроде «no such host».

Раньше панель спокойно всё это публиковала и оставляла разбираться вкладке «Здоровье» постфактум. Теперь перед отправкой она резолвит каждый адрес, который собирается опубликовать, и останавливается, если домена в DNS нет.

Проверка нарочно узкая, чтобы ей можно было доверять, а не отключить в первую неделю. Останавливает только ответ «домен не найден». Таймаут резолвера говорит о сервере панели, а не о вашем домене, и права вето на все деплои не получает. Домен, который резолвится не на адрес ноды, показывается, но ничего не блокирует: Cloudflare под оранжевым облаком, свой CDN и балансировка по нескольким адресам отсюда выглядят одинаково подозрительно, хотя все три законны. Ноды по голому IP не проверяются, там нечего резолвить.

Остановку снимает переключатель в диалоге. «Запись едет, применяю заранее» это нормальная рабочая ситуация. Ненормально было то, что панель принимала это решение за вас и молча.

Вкладка «Здоровье» написана для оператора

Список проверок показывал то, что вернул сервер, как есть. Из десятка строк половина называлась «Health-проверка», потому что названия были заведены для шести типов проверок из полутора десятков. Под ними шёл текст на английском:

skipped because L1 reachability failed dial tcp: lookup de1.example.dev on 127.0.0.53:53: no such host

Это правда, но правда для того, кто писал проверку. Оператор видел одинаковые заголовки, английские строки и код gateway_unreachable и не понимал ни что сломалось, ни куда идти.

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

Статус «Не реализовано» переименован в «Не выполнена». Почти всегда это проверка, которой не хватило данных для запуска, а читалась она как недоделка панели.

Remnawave можно поставить за реверс-прокси, и это рекомендуемый способ

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

Первым пунктом теперь идёт установка за реверс-прокси с доменом и сертификатом, помеченная как рекомендуемая. Это не вкусовщина: только так веб-интерфейс Remnawave вообще работает. Если прокси на сервере нет, установщик поднимает Caddy; если 80 и 443 уже держит ваш caddy или nginx, он допишет туда site-блок; если порты заняты чем-то ещё, честно скажет об этом и предложит локальный вариант, вместо того чтобы драться за порт.

Установщик не виснет и не спрашивает лишнее

Переустановка сервера без терминала показала сразу несколько поломок.

Вопрос про домен панели задавался всегда, даже если домен уже передан флагом. С терминалом оператор молча набирал его второй раз и ничего не замечал. Без терминала это уходило в бесконечный цикл на полной скорости: за полчаса 27 МБ предупреждений в логе и ни одного ответа, которого неоткуда было взять. Теперь переданное значение принимается сразу, а при отсутствии терминала установщик останавливается и называет флаг, которым это чинится.

Меню способа доступа к Remnawave не показывалось вовсе, если сам Axottle ставился на домен. Режим навязывался, а следом навязывались домен, DNS-запись и сертификат панели, которой всё это могло быть не нужно. Многие держат Remnawave на loopback и работают с ней только из Axottle. Теперь вопрос задаётся всегда.

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

Вопросы, у которых нет флага, вешали неинтерактивную установку намертво. И права на каталог Remnawave выставлялись раньше, чем в нём появлялся compose-файл, что убивало установку сразу после создания .env.

Обновление Remnawave работает и когда она на отдельном сервере

Кнопка обновления раньше была доступна только для Remnawave, стоящей на одной машине с Axottle: панель правит compose-файл и дёргает docker сама, а до чужого сервера ей не дотянуться. Теперь ту же работу там выполняет уже установленный агент.

Бэкап, его проверка и восстановление базы остались за панелью в обоих случаях, и правило «без бэкапа обновления не будет» для отдельного сервера ровно то же.

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

Панель видит и правит стек Remnawave

Панель работает под непривилегированным пользователем, которого никто не добавлял в группу docker. Стоя на одном сервере с Remnawave, она не находила ни compose-проект, ни базу и показывала ошибку обнаружения с единственной подсказкой про недоступный сокет. При этом панель Docker не просто смотрит, а управляет им: обнаружение читает compose-проект, бэкап запускает выгрузку внутри контейнера базы, обновление пересоздаёт стек.

Отдельно от этого обновление умирало на первом же шаге: каталог с настройками Remnawave принадлежит root, и панель не могла переписать compose-файл. Падало безопасно, версия не менялась и данные не трогались, но прогон бэкапа тратился впустую, а сообщение оператору ничего не объясняло.

Установщик теперь выдаёт панели и то, и другое, в том числе при повторном запуске на существующей установке. Стоит сказать прямо: членство в группе docker на этом хосте равносильно правам root. Это ровно тот доступ, который вы дали, попросив Axottle управлять развёртыванием, и более узкой двери к той же работе не существует.

Плашка SelfSteal объясняет, что ей мешает

На карточке ноды плашка знала только «можно» и «нельзя». После того как вы настроили домен и сертификат, она продолжала висеть без единой подсказки, что не так.

Теперь она перечисляет конкретные препятствия, ведёт на нужную вкладку и даёт кнопку «Проверить снова». В зелёном состоянии предлагает перейти в раздел SelfSteal или поставить сайт сразу. Крестик её прячет, но запоминает именно то состояние, которое вы закрыли: как только всё сойдётся, зелёная плашка появится снова.

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

v1.5.1 · обновление за 1–2 августа 2026

Axottle работает и со второй, и с третьей Remnawave.

31 июля Remnawave выпустила третью версию, а на следующий день сделала её версией по умолчанию. Всё, что ставилось после этого, ставилось сломанным: панель разворачивалась, но не запускалась, а бесконечно перезагружалась. Этот релиз чинит установку и заодно закрывает вопрос на будущее: Axottle теперь одинаково работает и со второй версией Remnawave, и с третьей, а обновлять её можно кнопкой из панели.

Установка Remnawave снова работает

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

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

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

Панель понимает и вторую, и третью версию

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

Под капотом там было четыре несовместимости. Третья версия убрала у пользователей идентификатор, по которому Axottle к ним обращался, поэтому теперь везде используется тот, что есть в обеих версиях. Часть настроек подписки переехала в заголовки ответа, и панель перестала читать их целиком. У хостов одиночный тег ещё в прошлой версии заменили списком, а мы всё это время читали поле, которого уже нигде нет. И наконец, изменился формат создания API-ключа, причём дважды: сначала поменялось тело запроса, а в третьей версии ключ ещё и перестал выдаваться без специального заголовка, то есть создать его старым способом стало невозможно в принципе.

Всё это проверено не по документации, а на двух живых панелях, поднятых рядом: 2.8.1 и 3.1.0. Прогон по всему API, которым пользуется Axottle, зелёный на обеих.

Обновление Remnawave кнопкой из панели

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

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

Откат разный в зависимости от того, где всё сломалось. Если не скачался образ, ничего ещё не запускалось: возвращается только версия в конфиге, базу никто не трогает. Если панель не поднялась или ответила не той версией, возвращается и версия, и база из того самого бэкапа. Если не удался и откат, вы получите номер бэкапа для восстановления руками, а не общую фразу про ошибку.

Пока обновление умеет только панель, которая стоит на том же сервере, что и Axottle. Для панели на отдельном сервере кнопка честно скажет, что недоступна: агенту, который там работает, такую задачу пока не выдают.

Установщик спрашивает, какую версию ставить

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

Если реестр недоступен или установка идёт без вопросов, ставится версия по умолчанию, а не падает вся установка.

Переезд не меняет версию панели

При переносе Remnawave на другой сервер туда ставится ровно та версия, что работала на старом. Раньше переезд мог заодно и обновить панель до третьей версии, необратимо обновив её базу по дороге.

Поддержка на базовом тарифе

Раздел поддержки открывался с баннером «лицензия не включает» и надписью «нет данных» на тарифах, где очередь, каналы и инциденты вполне работают. Виноваты были два запроса аналитики, без которых остальное прекрасно живёт. Теперь закрытые тарифом запросы просто не уходят, а виджеты без данных не рисуются.

v1.5.0 · обновление за 16–29 июля 2026

Поддержка клиентов теперь живёт внутри Axottle.

Самое крупное здесь — поддержка клиентов. Раньше вы отвечали людям где-то сбоку от панели: в личных сообщениях, в чате, в чужом хелпдеске. Теперь переписка живёт внутри Axottle, вместе с нодами и подключениями, про которые эти люди и пишут.

Поддержка клиентов внутри панели

Клиент пишет вашему боту в Telegram, и в панели появляется тикет. Отвечать можно тремя способами, как удобнее: из панели, из отдельной страницы для операторов или прямо из Telegram, где на каждый тикет заводится своя тема в рабочей группе. Всё это одна и та же переписка, просто три двери в неё.

Ответить можно от имени бота или с обычного аккаунта Telegram, если клиенты уже привыкли писать туда. Аккаунт для этого лучше завести отдельный, служебный: Telegram не любит автоматизацию на живых номерах.

Картинки, гифки, стикеры, видео и файлы ходят в обе стороны. Вложения по умолчанию лежат в базе панели, но можно подключить S3 или совместимое хранилище и проверить подключение кнопкой. Есть лимит на общий объём: когда место кончается, панель говорит об этом в Health Center и в Telegram, а не молча перестаёт принимать файлы.

Роли семь штук, от владельца до наблюдателя. Оператора можно добавить по @username или по Telegram ID, аккаунт в панели ему для этого не нужен. При закрытии тикета клиент видит пять звёзд и может оценить обслуживание.

Искусственный интеллект в поддержке, если он вам нужен

ИИ включается по частям и по умолчанию не отвечает никому.

Первая ступень — подсказки. Модель пишет черновик ответа, оператор его читает и отправляет сам. Клиент до этого момента не видит ни слова.

Вторая ступень — автономные ответы. Здесь есть два режима областей. Белый список: ИИ отвечает только по темам, которые вы разрешили. Чёрный: отвечает по всему, кроме тем, которые вы за собой оставили. Порог уверенности задаёте вы. Если модель не уверена или вообще не сообщила уверенность, тикет уходит человеку. Это правило без исключений: любая непонятная ситуация заканчивается живым оператором, а не догадкой.

Отвечает ИИ по вашей базе знаний. Уроки в неё попадают через утверждение, никакой другой путь к активному знанию не ведёт. Урок можно отправить в карантин, и он перестаёт использоваться в ту же секунду. Когда знаний не хватает, вы выбираете поведение: либо сразу звать человека, либо собрать симптомы и дать безопасный общий совет вроде «переподключитесь» или «смените сервер».

Учить ИИ можно в тренировочном чате: разговариваете с ним как клиент, а потом одной кнопкой сворачиваете разговор в черновик урока.

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

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

Вход через Telegram и точные права

Можно входить в панель через Telegram, без пароля. Сессия теперь живёт в cookie, а не в токене в браузере.

Права стали подробными: 36 разрешений, разложенных по 16 разделам панели. Ноды и Connection Units делятся на просмотр, создание, изменение, удаление и операции, у остальных разделов пара «смотреть» и «управлять». Отдельно вынесены восстановление из бэкапа, лицензия и управление аккаунтами. Меню показывает только то, до чего у человека есть доступ, и поиск тоже. Один суперпользователь защищён от удаления и понижения, чтобы нельзя было случайно запереть себя снаружи.

Панель открывается с телефона

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

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

Вёрстка от 1024 пикселей не изменилась ни в одном разделе.

Переезд Remnawave на другой сервер

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

Ссылки на подписку не меняются: домен подписки переносится как есть. JWT-секреты переносятся вместе с базой, иначе восстановленная панель отвергла бы все выданные токены, включая свой собственный.

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

Старый сервер при этом не меняется нигде, кроме явной остановки контейнера, так что откатиться можно всегда.

Безопасность

Мы прочитали панель насквозь и нашли семь проблем. Четыре закрыты в этом обновлении, и две из них стоит объяснить.

Раньше все секреты (коды двухфакторной аутентификации, ключи CDN и S3, сессии Telegram, бэкапы) шифровались одним и тем же ключом, который лежит в открытом репозитории. Теперь каждая установка получает свой ключ. Обновление не требует остановки: старые записи перешифровываются сами при первом чтении. Если панель всё ещё сидит на публичном ключе, она пишет об этом в лог, и axottle doctor показывает провалившуюся проверку.

Второе: лог запросов писал полный токен подписки целиком, то есть журнал сервера превращался в список живых ссылок. Теперь остаются первые восемь символов.

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

Отдельно про диагностические архивы. Раньше архив, который вы отправляете в поддержку, нёс адреса всех, кто подключался, и всех нод, к которым подключались. Теперь каждый адрес, по которому можно кого-то опознать, маскируется до вида 8.x.x.8, а в манифесте написано, сколько адресов замаскировано. Loopback и маски подсетей оставлены как есть: они никого не опознают, а диагностика без них бесполезна.

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

Здоровье и ноды

Проверка VLESS перестала зря пропускать юниты. Раньше она сравнивала адрес ключа с доменом ноды посимвольно, и любой юнит, у которого клиентский адрес отличался, вечно висел в статусе «пропущено» при живом туннеле.

После успешного подключения панель узнаёт, с какого адреса туннель на самом деле выходит наружу. Это видно в карточке ноды и помогает поймать момент, когда трафик молча пошёл не туда: например, мимо WARP.

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

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

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

Внешний вид

Панель по умолчанию розовая. Цвет взят из логотипа: тело аксолотля и его рот. Прежняя зелёная схема осталась и переключается в настройках рядом со светлой и тёмной темой.

Заодно зелёный перестал работать на две роли сразу. Раньше он был и акцентом интерфейса, и статусом «в порядке»; теперь он только статус. Все сочетания текста и фона в обеих палитрах проверены на контраст.

Следите только за важным.

Анонсы больших релизов и изменения, требующие внимания оператора, публикуем в Telegram.

Следить за релизами