Skip to content

Axottle v1.5.2

Choose a tag to compare

@ri1su ri1su released this 03 Aug 08:01
2d2ebc2

Обновление за 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 или поставить сайт сразу. Крестик её прячет, но запоминает именно то состояние, которое вы закрыли: как только всё сойдётся, зелёная плашка появится снова.

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


Обновление

Обновиться можно кнопкой в панели (нужен polkit) или скриптом на сервере:

sudo /opt/axottle/installer/upgrade.sh

Миграции применяются при старте, останавливать панель заранее не нужно.

Если вы ставили панель до этого релиза, доступ к Docker и права на каталог Remnawave выдаются повторным запуском установщика.