Удаленный доступ: вход и список разрешенных адресов

В этом руководстве вы узнаете, как открыть Marinara Engine с другого устройства – с телефона, ноутбука или из контейнера Docker. Здесь разобран основной вариант – вход. Дальше идут список разрешенных адресов, прокси со входом, HTTPS, раздел Admin Access и сообщение о заблокированном сохранении (CSRF). Почти все настройки из этого руководства живут в файле .env на сервере, а не в приложении.

Небольшой словарь, который понадобится по ходу чтения:

Подключение откуда угодно через Tailscale

Tailscale – это частная сеть для ваших собственных устройств. С ней Marinara можно открыть на телефоне или ноутбуке, дома или в поездке, не открывая порты на роутере и не выставляя Marinara в публичный интернет. Marinara доверяет устройствам, которые подключаются напрямую через Tailscale, поэтому задавать вход не нужно.

  1. Установите Tailscale на компьютер, на котором работает Marinara, и на второе устройство. Скачать его можно на странице tailscale.com/download.
  2. Войдите в Tailscale на обоих устройствах с одним и тем же аккаунтом.
  3. Запустите Marinara через start.sh, start.bat, start-termux.sh или установщик Windows. Они разрешают подключаться другим устройствам. Если вместо этого вы запускаете pnpm start, сначала добавьте HOST=0.0.0.0 в файл .env (см. Где лежит файл .env).
  4. Узнайте адрес Tailscale компьютера с Marinara. Откройте на нем приложение Tailscale или выполните tailscale ip -4. Адрес начинается с 100., например 100.101.102.103.
  5. На втором устройстве включите Tailscale и откройте в браузере http://100.101.102.103:7860. Подставьте свой адрес и свой PORT, если вы его меняли. Marinara откроется без страницы входа.

Если страница не загружается, проверьте, что Tailscale включен на обоих устройствах и что сервер слушает HOST=0.0.0.0.

Примечание: В установках Docker это не работает. Трафик Tailscale попадает в контейнер через шлюз Docker, поэтому Marinara не видит, что он пришел из Tailscale. Сначала задайте вход (Вариант 1), а затем публикуйте порт за пределами 127.0.0.1.

Резервные копии, импорт, обновления и другие опасные действия с удаленного устройства по-прежнему требуют секрета администратора. См. Раздел Admin Access и опасные действия.

Что Marinara блокирует по умолчанию

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

  1. Loopback (127.0.0.1 или ::1) – сама машина, на которой работает сервер. Посетители, которых передает дальше обратный прокси или туннель на той же машине, сюда не относятся; см. раздел Обратные прокси и туннели на том же компьютере.
  2. Устройства Tailscale в вашей сети tailnet. Tailscale – это программа для частной сети, и ее адреса лежат в диапазоне 100.64.0.0/10.
  3. Клиенты Docker на том же хосте. Marinara распознает обычный диапазон моста 172.16.0.0/12 и точный шлюз контейнера по умолчанию, а это покрывает и Docker Desktop, и собственные пулы адресов.

Все остальное – телефон в той же сети Wi-Fi или клиент из интернета – блокируется, пока не выбран один из вариантов ниже. Заблокированное устройство, открывшее Marinara в браузере, видит темную страницу настройки. Ее заголовок читается This Marinara Engine install needs a login before remote devices can connect. На странице есть форма для одноразового кода настройки из журнала сервера, поэтому вход можно задать прямо с этого устройства.

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

Где лежит файл .env

Все настройки доступа находятся в файле .env в корне проекта, рядом с package.json. Если такого файла еще нет, скопируйте пример:

cp .env.example .env

Откройте .env в любом текстовом редакторе. Большинство настроек доступа – Basic Auth, список разрешенных адресов, секрет администратора и доверенные источники CSRF – применяются за пару секунд без перезапуска. Перезапуск все же нужен нескольким низкоуровневым настройкам: PORT, HOST и путям к сертификату HTTPS.

Бывает, что другие устройства вообще не достают до сервера: вместо ошибки 403 они получают тайм-аут. Скорее всего, сервер слушает только локальную машину. Разрешите ему слушать все сетевые интерфейсы:

HOST=0.0.0.0

Скрипты запуска (start.bat, start.sh) выставляют HOST=0.0.0.0 сами. При прямом запуске pnpm start этого не происходит.

Адрес привязки по умолчанию в зависимости от способа запуска Marinara:

Способ запускаЗначение HOST по умолчанию
pnpm start, start-local.bat127.0.0.1
start.sh, start.bat, установщик Windows, start-termux.sh0.0.0.0
Образ Docker0.0.0.0 внутри контейнера
docker-compose.ymlПубликует порт только на 127.0.0.1

Какой вариант выбрать

Читайте по порядку и остановитесь на первом подходящем пункте.

  1. Вы подключаетесь только напрямую через Tailscale или только из контейнеров Docker на том же хосте. При pnpm start прямые клиенты Tailscale обходят вход; задайте HOST=0.0.0.0, чтобы они могли достучаться до сервера. Файл Compose по умолчанию публикует порт только на 127.0.0.1. Если вы публикуете порт за пределами loopback, чтобы до него мог достучаться устройство Tailscale, сначала задайте вход. Тогда Docker запрашивает его у каждого устройства, включая устройства Tailscale, потому что Docker видит их по адресу шлюза. См. Обход для Tailscale и Docker.
  2. Вы хотите открывать Marinara с телефона, планшета или ноутбука в домашней сети Wi-Fi. Задайте вход (вариант 1 ниже).
  3. Вы открываете Marinara в интернет. Задайте вход и используйте HTTPS.
  4. Прокси со входом в вашей сети, например tinyauth, Authelia или Authentik, уже просит каждого посетителя войти. Прочитайте раздел Прокси со входом (forward auth).

Вход – самый гибкий вариант. Он работает с любого адреса, не требует настройки на каждом устройстве, а каждый браузер остается в системе.

Вариант 1: вход (рекомендуется)

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

BASIC_AUTH_USER=alice
BASIC_AUTH_PASS=correct-horse-battery-staple

Вход в .env главнее входа, заданного в приложении, и менять его можно только в .env. Сохраните .env; изменение применяется за пару секунд, перезапуск не нужен.

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

openssl rand -base64 24

Затем выполните эти шаги на удаленном устройстве.

  1. Откройте Marinara в браузере по адресу сервера, например http://192.168.1.50:7860.
  2. Войдите на странице входа со своими именем пользователя и паролем.
  3. Приложение должно загрузиться. Браузер остается в системе до года, пока вы не выйдете. Скрипты и клиенты API отправляют имя пользователя и пароль с каждым запросом (Basic Auth).

Чтобы войти на другом устройстве, не вводя пароль, используйте код сопряжения. На устройстве, где вход уже выполнен, откройте Settings → Advanced → Access и выберите Add a device. Затем введите код на странице входа нового устройства. Код работает один раз, в течение нескольких минут. Просроченный код получает собственное сообщение; создайте новый. В разделе Signed-in devices видно каждое устройство со способом входа и датой первого входа. Выйти можно на любом устройстве, в том числе на том, которым вы пользуетесь. Пароль тоже можно изменить или убрать. Для этого Marinara запрашивает текущий пароль, если только вы не работаете на компьютере, где запущена Marinara, или не задали ADMIN_SECRET.

Если вы забыли пароль, выполните node scripts/reset-login.mjs в папке Marinara на компьютере, где запущена Marinara. В Docker выполните docker exec <container> node scripts/reset-login.mjs. Команда удаляет вход, заданный в приложении, и выводит из системы все браузеры. Если сервер слушает не только loopback, он затем печатает новый код настройки. Только если эта команда не помогает, удалите вместо нее .remote-login.json и .remote-sessions.json из папки данных. При /app/data по умолчанию выполните docker exec <container> rm -f /app/data/.remote-login.json /app/data/.remote-sessions.json; если вы изменили DATA_DIR, используйте эту папку. Вход в .env вы меняете в .env.

Сервер без монитора и без браузера? Обычная установка на сервере без монитора слушает только loopback и не печатает код настройки. На своем компьютере выполните ssh -L 7860:127.0.0.1:7860 user@server. Затем откройте там http://localhost:7860 и используйте Settings.

После 10 разных неверных паролей или кодов в течение 15 минут Marinara отклоняет попытки входа с этого адреса ответом 429 Too Many Requests, пока эти 15 минут не истекут. Верный пароль, введенный раньше, сбрасывает счетчик. У посетителей, которых передает дальше обратный прокси или туннель на хосте, счетчик общий, и вход одного из них его не сбрасывает. Перезапуск сервера тоже сбрасывает счетчик. Браузер, который уже входил раньше, по-прежнему пускают с верным паролем, поэтому чужие неверные пароли не могут закрыть вам вход с устройства, которым вы уже пользуетесь. Страница входа показывает, сколько минут ждать. Если вы забыли пароль, на странице входа есть подсказка Forgot the password?.

Браузеры входят на странице /login. Переменная BASIC_AUTH_REALM меняет realm в запросе Basic Auth для скриптов и клиентов API; страницу входа она не меняет.

Некоторые клиенты проходят без пароля, даже когда Basic Auth включен:

Важно: Basic Auth только кодирует пароль, но не шифрует его. Любой, кто слушает незашифрованное соединение, сможет его прочитать. Если Marinara открыта в интернет, используйте Basic Auth вместе с HTTPS (см. ниже).

Вариант 2: список разрешенных адресов

Список разрешенных адресов пускает определенные адреса без пароля. Это удобно, когда у ваших устройств постоянные IP-адреса. Задайте адреса или диапазоны через запятую:

IP_ALLOWLIST=192.168.1.0/24,203.0.113.42

Запись /24 в примере – это нотация CIDR. CIDR – короткий способ записать целый диапазон адресов одной строкой. Например, 192.168.1.0/24 покрывает все адреса от 192.168.1.0 до 192.168.1.255. Адрес без слеша, вроде 203.0.113.42, соответствует только одному устройству.

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

Как ведет себя список разрешенных адресов:

Смешанную схему – когда адреса из списка проходят без пароля, а все прочие входят по паролю – список создать не может. Если вы хотите, чтобы другие устройства входили по паролю, оставьте IP_ALLOWLIST незаданной и обойдитесь одним Basic Auth.

Проверку можно на время отключить, не удаляя сам список. Это выручает, когда вы разбираетесь с доступом с нового IP-адреса. Переведите флаг включения в false:

IP_ALLOWLIST_ENABLED=false

Обход для частной сети (справка)

Несколько флагов снимают блокировку для доверенной частной сети. Они нужны для особых случаев. Вход – лучший выбор. О флагах и их рисках читайте в разделе Управление доступом.

Обход для Tailscale и Docker

По умолчанию Marinara доверяет устройству, которое подключается напрямую через вашу сеть Tailscale. Она также доверяет собственному хосту контейнера Docker. Вход, список разрешенных адресов или TRUSTED_AUTH_PROXY отключает автоматическое доверие к Docker, поэтому каждому устройству тогда нужны вход или место в списке. О флагах, которые это меняют, читайте в разделе Управление доступом.

Docker Desktop, OrbStack и rootless Docker показывают каждое устройство, которое использует опубликованный порт, с адресом шлюза Docker. Если вы публикуете порт на всех интерфейсах (-p 7860:7860) и не задаете вход, то любой в вашей сети попадет внутрь. Оставьте порт на 127.0.0.1 или сначала задайте вход. Журнал сервера предупреждает об этом при запуске.

Обратные прокси и туннели на том же компьютере

Обратный прокси или туннель на машине, где работает Marinara, – например nginx, Caddy, Traefik, Cloudflare Tunnel, Tailscale Serve или Funnel либо ngrok – подключается к Marinara через loopback. Marinara распознает это по заголовкам пересылки, которые добавляет прокси: Forwarded, X-Forwarded-For, X-Real-IP, X-Forwarded-Host, X-Forwarded-Proto, CF-Connecting-IP, True-Client-IP, заголовкам идентификации Tailscale или Via. Marinara также распознает запрос, который приходит по HTTP/1.0, потому что браузеры его не используют, а nginx по умолчанию использует его в proxy_pass. Marinara также распознает запрос, в котором Host указывает на другой компьютер, например на домен или адрес в локальной сети, даже если прокси не добавляет никаких заголовков. После этого каждый такой запрос обрабатывается как запрос удаленного посетителя, которым он и является:

Ваш собственный браузер на этой машине, открытый по адресу http://127.0.0.1:7860 или http://localhost:7860, по-прежнему работает без пароля.

Caddy, Traefik, Cloudflare Tunnel, Tailscale и ngrok добавляют заголовки пересылки по умолчанию. Для nginx эту строку в блок location по-прежнему рекомендуется добавить:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Инструменты, которые пересылают соединения как есть, например socat или ssh -R, не добавляют заголовков, поэтому их трафик выглядит локальным. Не используйте их, чтобы открыть доступ к Marinara.

Если ваш прокси уже заставляет каждого посетителя войти, прежде чем что-либо пересылать, см. раздел Прокси со входом (forward auth).

Прокси со входом (forward auth)

Прокси forward auth, например tinyauth, Authelia, Authentik или oauth2-proxy, просит каждого посетителя войти, прежде чем пересылать запрос. Если такой прокси – единственный путь к Marinara, второй вход в Marinara можно пропустить. Не задавайте это без такого прокси.

Укажите адрес прокси в .env:

TRUSTED_AUTH_PROXY=192.168.1.5

Тогда Marinara впускает каждый запрос, соединение которого приходит с этого адреса. Marinara не просит для них собственный вход и не печатает код настройки. Marinara проверяет адрес самого соединения. Заголовки пересылки, например X-Forwarded-For, для этого решения она игнорирует. Запросы от прокси также проходят IP_ALLOWLIST, потому что прокси решает, кого впускать. Они не считаются локальными, поэтому для опасных действий по-прежнему нужен секрет администратора. Settings → Advanced → Access показывает Trusted login proxy: Set, пока настройка действует.

Прежде чем ее задать:

Когда задан TRUSTED_AUTH_PROXY, Marinara также отключает автоматическое доверие к Docker. Прямым посетителям, которые не являются прокси, нужны вход Marinara или список разрешенных адресов. Тогда Marinara также не показывает баннер "входа еще нет".

Если прокси работает на том же компьютере, что и Marinara, задайте TRUSTED_AUTH_PROXY=127.0.0.1 и направьте прокси на 127.0.0.1:7860, а не на localhost:7860. Прокси, который обращается к localhost, может подключиться с ::1, что не совпадает с 127.0.0.1. Тогда любой другой прокси или туннель на этом компьютере тоже получает доверие, поэтому задавайте это, только когда прокси со входом – единственный. Это не дает посетителям, которых передает прокси, прав доступа локальной машины.

Пример для Caddy, где Marinara работает по адресу 192.168.1.20:7860:

marinara.example.com {
  forward_auth tinyauth:3000 {
    uri /api/auth/caddy
  }
  reverse_proxy 192.168.1.20:7860
}

Для Authelia используйте forward_auth authelia:9091 с uri /api/authz/forward-auth. Authentik также отдает собственные страницы входа через прокси. Поместите его строки в блок route, чтобы Caddy сохранил их порядок, а путь outpost не проходил через сам forward auth:

marinara.example.com {
  route {
    reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
    forward_auth authentik-server:9000 {
      uri /outpost.goauthentik.io/auth/caddy
    }
    reverse_proxy 192.168.1.20:7860
  }
}

Для Traefik и nginx следуйте руководству вашего прокси по forward auth. Marinara нужен только адрес прокси.

Работа по HTTPS

HTTPS шифрует соединение с помощью TLS. TLS – это шифрование, которое превращает обычный адрес http в защищенный https. Всегда используйте HTTPS, если установка доступна за пределами полностью доверенной частной сети – особенно вместе с Basic Auth.

Добавить его можно двумя способами.

  1. Встроенный TLS. Укажите серверу файлы сертификата и закрытого ключа:
SSL_CERT=/path/to/cert.pem
SSL_KEY=/path/to/key.pem
  1. Обратный прокси-сервер. Поставьте перед Marinara nginx, Caddy, Traefik или Cloudflare Tunnel. Прокси-сервер берет HTTPS на себя и пересылает запросы в Marinara по обычному HTTP на той же машине. Сначала прочитайте раздел Обратные прокси и туннели на том же компьютере.

Сертификат и ключ нужны до того, как вы зададите SSL_CERT и SSL_KEY. Для локального использования их создает, например, mkcert, а для публичного домена – certbot. Если файлов нет или их не удается прочитать, сервер останавливается при запуске и показывает точные пути, по которым он искал.

Раздел Admin Access и опасные действия

Часть действий особенно чувствительна: удаление данных, создание и скачивание резервных копий, импорт и экспорт профилей, установка тем оформления и агентов, а также установка среды Local Model. Для них нужен отдельный общий секрет – секрет администратора – вдобавок к выбранному выше варианту доступа.

На машине с loopback такие действия обычно работают и без секрета администратора. С удаленного устройства секрет надо настроить. Его можно создать в приложении или задать в .env.

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

Создание секрета администратора в приложении

  1. На компьютере, где работает Marinara, откройте панель Settings (настройки), затем вкладку Advanced, затем раздел Admin Access (доступ администратора).
  2. Нажмите Make admin secret (создать секрет администратора). Marinara один раз показывает новый секрет и сохраняет его в этом браузере.
  3. На каждом удаленном устройстве откройте Settings → Advanced → Admin Access, введите секрет в поле и нажмите кнопку Save (сохранить). Заглавные буквы, пробелы и дефисы не важны.

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

В Docker браузер попадает в Marinara через сеть Docker, поэтому Marinara не считает его тем же компьютером. Вместо этого задайте первый секрет в .env (см. ниже).

Чтобы сменить секрет, нажмите Replace admin secret (заменить секрет администратора). Старый секрет перестает работать на всех устройствах. Чтобы отключить секрет, нажмите Remove admin secret (удалить секрет администратора). Marinara хранит только отпечаток секрета – в файле .admin-secret.json в папке данных. Удаление этого файла тоже удаляет секрет.

Настройка секрета администратора в .env

  1. В файле .env задайте надежное случайное значение и сохраните файл. Оно применяется за пару секунд, перезапуск не нужен.
ADMIN_SECRET=some-long-random-string
  1. На удаленном устройстве откройте Settings → Advanced → Admin Access.
  2. Вставьте то же значение в поле (подсказка в поле читается ADMIN_SECRET) и нажмите кнопку Save.
  3. Должно появиться сообщение Admin secret saved for this browser.

ADMIN_SECRET в .env имеет приоритет над секретом, созданным в приложении. Пока он задан, раздел Admin Access сообщает об этом, и менять секрет можно только в .env.

Что полезно знать

Если опасное действие на удаленном устройстве не срабатывает, Marinara показывает сообщение об ошибке с двумя способами исправления. Первый – открыть приложение через localhost. Второй – настроить секрет администратора, как описано выше.

Почему сохранение блокируется (CSRF)

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

Иногда CSRF блокирует и ваши собственные сохранения. Обычно это происходит, когда вы открываете Marinara по публичному доменному имени или на нестандартном порту, которому сервер пока не доверяет. Понять это можно по двум признакам.

Чтобы это исправить, добавьте свой адрес в список доверенных в .env:

CSRF_TRUSTED_ORIGINS=https://chat.example.com,http://203.0.113.10:7831

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

TRUSTED_HOSTS=chat.example.com

Прямым адресам в сети LAN, адресам Tailscale, IPv4 и IPv6 переменная TRUSTED_HOSTS не нужна. Локальные имена .local и .home.arpa, а также однословные имена машин принимаются автоматически. Точное имя хоста, уже перечисленное в CSRF_TRUSTED_ORIGINS, тоже принимается.

Источникам loopback, обычным адресам в сети LAN, адресам Tailscale (100.64.0.0/10) и моста Docker (172.16.0.0/12) доверие есть по умолчанию. Перечислять нужно только публичные IP-адреса и доменные имена. Изменение применяется за пару секунд, без перезапуска.

Отдельно о заблокированных локальных провайдерах

Допустим, вы подключаете Marinara к локальному провайдеру ИИ – например, к тому, который работает на вашей же машине. Запрос может быть отклонен с упоминанием "private, loopback, metadata, or reserved IP range". Это уже другая проверка безопасности – защита SSRF. SSRF – это подделка запроса на стороне сервера. Такая проверка не дает серверу обращаться к частным адресам, пока вы это не разрешите. В тексте ошибки названа точная переменная для .env, например PROVIDER_LOCAL_URLS_ENABLED. Полный список смотрите в руководстве Настройки сервера: справочник.

Доступ с телефона или планшета

Чтобы открыть Marinara с телефона или планшета в той же сети:

  1. Проверьте, что сервер слушает все интерфейсы: в .env должно быть HOST=0.0.0.0.
  2. Задайте вход (вариант 1 выше). С телефона это можно сделать на странице, которая вас блокирует, с кодом настройки из журнала сервера.
  3. Узнайте локальный IP-адрес машины с сервером (например, 192.168.1.50).
  4. На телефоне откройте в браузере http://192.168.1.50:7860. Порт по умолчанию – 7860.
  5. Войдите со своими именем пользователя и паролем.

Если страница вообще не открывается, до сервера, скорее всего, не доходит запрос. Проверьте HOST=0.0.0.0 и значение PORT. Если вместо этого приходит ошибка 403, устройство до сервера достает, но доступ ему еще не открыт. Перепроверьте выбранный вариант.

Нет доступа после обновления

Новые версии просят войти, если визит приходит через обратный прокси, туннель, Tailscale Serve или Tailscale Funnel. Старые версии пускали такие визиты без пароля. Если теперь вы видите страницу входа, страницу настройки или 403, причина в этом.

Примечание об обновлении: если вы используете Tailscale Serve или другой прокси на том же компьютере и никогда не задавали пароль, после обновления другие ваши устройства остаются без доступа. Прокси на том же компьютере обычно обращается к серверу, который слушает только loopback, поэтому сервер не печатает код настройки. Задайте вход на компьютере, где запущена Marinara.

Чтобы вернуться:

  1. Откройте Marinara на компьютере, где она запущена, по адресу http://localhost:7860 (или со своим PORT). Для локального доступа пароль не нужен. На сервере без монитора сначала выполните на своем компьютере ssh -L 7860:127.0.0.1:7860 user@server, затем откройте там http://localhost:7860. В Docker это работает, только пока не заданы ни вход, ни IP_ALLOWLIST. Иначе введите код настройки из журнала сервера (docker logs <container> 2>&1 | grep "setup code") на странице, которая вас блокирует, или в Settings → Advanced → Access, либо воспользуйтесь браузером, в котором вход еще выполнен.
  2. Перейдите в Settings → Advanced → Access и задайте имя пользователя и пароль в разделе Remote login. Или откройте файл .env на этом компьютере и задайте BASIC_AUTH_USER и BASIC_AUTH_PASS. Если задан IP_ALLOWLIST, добавьте в него адрес другого устройства или уберите его: устройство, которого нет в списке, получает 403 даже со входом.
  3. Войдите с другого устройства с этим именем пользователя и паролем.

Поисковые системы

Marinara просит поисковые системы не индексировать его страницы (X-Robots-Tag: noindex, nofollow). Это не защищает вашу установку и не удаляет страницы, которые уже проиндексированы. Чтобы установка оставалась закрытой, используйте описанные выше средства контроля доступа.

Смежные руководства