SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-26

Что значит http://127.0.0.1:3080 в DeepSeek Harness

Сообщение http://127.0.0.1:3080 означает, что веб-интерфейс привязан к локальному адресу. Используйте SSH-туннель для доступа к нему. Публикация порта 3080 в сеть небезопасна.

Что означает dsh web: http://127.0.0.1:3080

Когда вы запускаете веб-профиль DeepSeek Harness на VPS, он выводит две строки и переходит в режим ожидания:

dsh web: http://127.0.0.1:3080
Ready.

127.0.0.1 — это loopback-адрес. Это адрес, который машина использует для взаимодействия с самой собой. Сокет, привязанный к 127.0.0.1, принимает соединения только от процессов на этой же машине и ниоткуда больше. Таким образом, эта строка сообщает вам две вещи одновременно: где прослушивается веб-интерфейс и кому разрешено к нему обращаться. Только машине, на которой запущен dsh.

Именно поэтому URL не работает, когда вы вставляете его в браузер на своем ноутбуке. 127.0.0.1 вашего ноутбука — это сам ноутбук. Harness прослушивает 127.0.0.1 на VPS, а это другая машина с другим стеком loopback. Ничего не сломано. Вам нужно перенаправить соединение.

В официальном README значение по умолчанию указано прямо: "Команда запускает веб-интерфейс, который по умолчанию доступен по адресу http://127.0.0.1:3080". Адрес привязки берется из плагина веб-сервера @deepseek-ai/dsh-host-webserver, чей ключ host описан как "Хост для прослушивания; поддерживаются два значения: loopback и all-interfaces". Loopback используется, если вы не измените это значение. Если порты для вас в новинку, как работают порты в Linux описывает модель "адрес плюс порт", на которой всё это базируется.

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

dsh — это среда исполнения агента, то есть программа, управляющая моделью: она контролирует цикл работы, вызовы инструментов и права доступа, с которыми эти вызовы выполняются. Вкладка браузера служит панелью управления для процесса, который запускает shell-команды, читает и записывает файлы в выбранной вами рабочей директории, а также расходует ваш API-ключ модели. Любой, кто может открыть эту страницу, получает все эти возможности от имени пользователя, под которым запущен dsh. Сеть — не единственный вектор доступа: установленный вами плагин выполняется в том же процессе с теми же правами, поэтому проверка плагина dsh перед установкой требует такой же осторожности, как и выбор сетевого интерфейса для прослушивания.

Таким образом, порт 3080 — это не просто панель мониторинга для чтения. Загрузка этой страницы дает возможность выполнения команд на сервере.

При открытии веб-интерфейса вы сразу попадаете в список сессий. Запроса на вход нет, так как в developer preview не реализованы учетные записи пользователей и удаленная аутентификация. При работе через loopback это допустимо: операционная система выступает в роли контроля доступа, и доступ получают только локальные процессы. Если привязать этот же сервер к 0.0.0.0 на VPS с публичным IP-адресом, эта страница станет доступна всему интернету без какой-либо защиты. Автоматизированные сканеры постоянно проверяют нестандартные порты, поэтому считайте, что опубликованный порт 3080 будет обнаружен немедленно.

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

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

Как открыть веб-интерфейс dsh с моего ноутбука?

Существует три надежных способа, и каждый из них оставляет привязку harness к интерфейсу loopback.

  • SSH-туннель. Никакие новые службы не прослушивают публичный интерфейс, а учетные данные у вас уже есть. Это рекомендуемый способ.
  • Частная оверлейная сеть, благодаря которой интерфейс доступен с ваших устройств и скрыт от всех остальных.
  • Reverse proxy, который выполняет TLS termination (transport layer security) и требует пароль перед пересылкой любого запроса.

Разница между ними заключается в том, как именно ваш браузер получает доступ к loopback. Ни один из этих способов не требует переноса harness с интерфейса loopback.

Доступ через SSH-туннель

Выполните эту команду на своем ноутбуке, а не на VPS:

ssh -N -L 3080:127.0.0.1:3080 you@your-vps

Оставьте процесс запущенным, затем откройте http://127.0.0.1:3080 в локальном браузере. Веб-интерфейс загрузится.

Аргумент -L содержит три поля, разделенных двоеточиями. Первое — порт, который будет открыт на вашем ноутбуке. Второе и третье — адрес и порт, на которые будет перенаправлено каждое соединение. Важная деталь: 127.0.0.1 в среднем поле разрешается SSH-сервером на VPS уже после того, как трафик туда поступил. Это означает loopback-интерфейс VPS, а не ваш локальный. Именно этот адрес выводит dsh, поэтому туннель работает, в то время как прямое подключение из браузера — нет.

-N указывает SSH не выполнять удаленную команду, поэтому вы получаете только перенаправление портов без интерактивной оболочки. Для фонового туннеля, который завершается с ошибкой при сбое, используйте:

ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps

-f переводит процесс в фоновый режим после аутентификации. ExitOnForwardFailure=yes важнее, чем кажется: без этого флага SSH успешно установит соединение, даже если перенаправление настроить не удалось. В результате вы получите рабочую сессию, но неработающий туннель без каких-либо предупреждений. ServerAliveInterval=30 отправляет keepalive-пакеты каждые 30 секунд, чтобы простаивающий туннель не разрывался из-за таймаутов NAT (network address translation) в сетях кафе или отелей.

Что вы должны увидеть

На VPS проверьте, какой процесс прослушивает порт:

ss -ltnp | grep 3080

Корректный результат указывает на loopback-адрес:

LISTEN 0  511  127.0.0.1:3080  0.0.0.0:*  users:(("node",pid=1042,fd=21))

Если в столбце локального адреса указано 0.0.0.0:3080, значит, веб-интерфейс доступен на всех интерфейсах, включая публичный. Остановите его и исправьте привязку (bind), прежде чем продолжать. Если ss показывает сокет, но поле users: пустое, запустите команду с sudo, так как в противном случае имя процесса, принадлежащего другому пользователю, будет скрыто.

Если туннель не запускается

SSH выводит следующее сообщение и завершает работу:

bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080

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

ssh -N -L 3081:127.0.0.1:3080 you@your-vps

Изменилось только первое поле, теперь вы переходите по адресу http://127.0.0.1:3081, в то время как сервис продолжает прослушивать порт 3080. Эти два числа не обязаны совпадать.

Если туннель поднялся, но браузер сообщает об отказе в соединении или пустом ответе, значит, трафик дошел до VPS, но на той стороне ничего не ответило. Либо процесс dsh завершился, либо он привязан к другому порту. Проверьте это с помощью ss -ltnp | grep 3080 на сервере.

Есть еще один нюанс. Запущенный в интерактивном режиме npx @deepseek-ai/dsh web завершается при закрытии оболочки, поэтому туннель упадет, как только вы выйдете из системы. Запускайте его внутри tmux или как пользовательский systemd-юнит — это та же задача, что описана в поддержании работы агента на VPS. Пока вы занимаетесь настройкой SSH, стоит выполнить усиление безопасности SSH на VPS, так как туннель делает ваш SSH-вход единственной точкой доступа к агенту.

Доступ через частную оверлейную сеть

Оверлейная сеть предоставляет вашему VPS и ноутбуку адреса в частной сети, к которой подключаются только ваши устройства. Tailscale — популярный выбор, и его команда serve идеально подходит для этого случая: tailscaled запускается на VPS и подключается к localhost:3080 самостоятельно, поэтому обвязка остается на loopback, и вам не нужно менять конфигурацию dsh.

tailscale serve --bg localhost:3080
tailscale serve status

После этого веб-интерфейс становится доступен по имени вашего устройства внутри tailnet по протоколу HTTPS, при этом открывать порты на публичном интерфейсе не требуется. Для этого в вашей tailnet должны быть включены HTTPS-сертификаты, иначе serve не сможет предоставить сертификат. Чтобы отключить доступ, повторите команду с off:

tailscale serve --https=443 off

Используйте serve, никогда не используйте funnel. Funnel публикует ту же цель в публичный интернет, что возвращает вас к неаутентифицированной среде выполнения агента на открытом порту. Эти две команды выглядят почти одинаково, но выполняют противоположные действия, поэтому изучите разницу между Tailscale Serve и Funnel перед вводом любой из них. В статье Tailscale как частная сеть описан процесс настройки.

Доступ через обратный прокси с проверкой пароля

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

Инструмент работает на 127.0.0.1:3080. nginx запущен на том же узле, поэтому он может обратиться к loopback и слушает порт 443 с использованием сертификата и файла паролей.

server {
    listen 443 ssl;
    server_name dsh.example.com;

    ssl_certificate     /etc/letsencrypt/live/dsh.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dsh.example.com/privkey.pem;

    auth_basic           "dsh";
    auth_basic_user_file /etc/nginx/dsh.htpasswd;

    location / {
        proxy_pass http://127.0.0.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
        proxy_buffering off;
    }
}

Создайте файл паролей и перезагрузите конфигурацию:

sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginx

nginx -t должен вывести syntax is ok, а затем test is successful. Перезагрузка с поврежденным файлом завершится ошибкой и сохранит текущую конфигурацию, поэтому читайте текст ошибки, а не перезапускайте сервис вслепую.

Три строки проксирования здесь не для красоты. Заголовки Upgrade и Connection пропускают рукопожатие WebSocket; без них страница загрузится, но не будет обновляться. proxy_read_timeout 3600s заменяет стандартный таймаут в 60 секунд, который иначе прервет длительное выполнение агента в середине ответа и оставит интерфейс в «зависшем» состоянии. proxy_buffering off отправляет вывод модели в браузер по мере поступления, а не удерживает его до завершения ответа. Построчный разбор конфигурации обратного прокси nginx объясняет остальное, а выбор между nginx, Caddy и Traefik описывает реализацию того же решения с автоматическими сертификатами.

Держите порт 3080 закрытым в межсетевом экране независимо от выбранного прокси, чтобы единственный путь внутрь проходил через аутентифицированный прокси. Основы работы с ufw описывают настройку правил. Базовая аутентификация поверх TLS — это лишь минимальный уровень, а не законченная модель безопасности: тот, кто владеет паролем, получает доступ к командной оболочке на вашем сервере. По возможности отдавайте предпочтение туннелям.

Как изменить порт, на котором прослушивает запросы dsh web?

--port относится к веб-приложению, а не к программе запуска (launcher). В документации CLI приведен прямой пример:

dsh --profile web --port 8080

dsh web является псевдонимом --profile web, поэтому dsh web --port 8080 — это одна и та же команда. Программа запуска анализирует только свои собственные флаги, а всё, что идет после них, передает загружаемому профилю. Поэтому флаги программы запуска должны стоять первыми, а первый токен, который программа не распознает, начинает список аргументов приложения. Размещайте --port после профиля, но никогда не перед ним.

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

ssh -N -L 3080:127.0.0.1:8080 you@your-vps

Для постоянного изменения порт указывается в конфигурации профиля, а не в командной строке. Профили web и headless автоматически инициализируются при первом использовании на основе поставляемых шаблонов в ~/.dsh. В этой же директории хранятся ваш API-ключ и настройки конечных точек моделей, поэтому настройка ключей, моделей и конечных точек dsh — это сопутствующий материал, который стоит изучить, раз вы уже редактируете эти файлы. Чтобы увидеть, какие параметры фактически действуют после объединения всех уровней конфигурации:

dsh --dump-config

Плагин веб-сервера предоставляет ровно два ключа: host и port. Установка port в значение 0 запрашивает у операционной системы свободный порт; это задокументировано как «ноль запрашивает порт, назначенный ОС». Это гарантирует отсутствие конфликтов, но плохо подходит для туннеля, так как номер порта меняется при каждом перезапуске.

Почему dsh завершается с ошибкой address already in use?

Это происходит потому, что другой процесс уже занял этот адрес и порт, поэтому ядро отклоняет повторный вызов bind. Node сообщает об этом следующим образом:

Error: listen EADDRINUSE: address already in use 127.0.0.1:3080

Прежде чем что-либо менять, найдите процесс, удерживающий порт:

sudo ss -ltnp | grep 3080

Поле users:(("node",pid=1042,fd=21)) указывает имя процесса и его PID. Обычно это предыдущий экземпляр dsh, который, как вы полагали, был остановлен, но часто продолжает работать в отсоединённом окне tmux. Остановите его с помощью kill 1042 или запустите новый экземпляр на другом порту. Учтите, что 127.0.0.1:3080 и 0.0.0.0:3080 также конфликтуют друг с другом, так как привязка ко всем интерфейсам уже включает в себя loopback.

Зафиксируйте версию, так как это предварительная версия для разработчиков

В README прямо сказано: DeepSeek Harness находится на стадии предварительного просмотра для разработчиков и быстро развивается, поэтому возможны изменения, нарушающие обратную совместимость. Если именно этот темп вызывает у вас сомнения, сравнение dsh с Claude Code и Omnigent поможет сопоставить его с двумя другими инструментами, находящимися на разных этапах развития.

npx @deepseek-ai/dsh web при каждом запуске обращается к самой свежей опубликованной версии. Сервер, к которому вы не обращались неделю, при следующем запуске может запустить другой CLI с другими флагами. Зафиксируйте версию, чтобы перезапуск не приводил к обновлению:

npx @deepseek-ai/dsh@0.1.0-rc.7 web

По состоянию на август 2026 года опубликованная версия пакета — 0.1.0-rc.7. Проверьте, какую версию загрузит обычный npx, прежде чем подтверждать установку:

npm view @deepseek-ai/dsh version

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

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

dsh --profile web --help

Информацию об установке, настройке рабочего пространства и ключе модели см. в разделе установка DeepSeek Harness на VPS. Краткое руководство только по этапу доступа, подключение к веб-интерфейсу dsh на VPS, описывает настройку туннеля без лишних пояснений.

FAQ

Почему я не могу открыть http://127.0.0.1:3080 в браузере на своем ноутбуке?

Потому что 127.0.0.1 означает машину, за которой вы работаете. Веб-интерфейс DeepSeek Harness привязан к адресу loopback на VPS, поэтому к нему могут подключаться только процессы внутри этого VPS. У вашего ноутбука собственный loopback, и на порту 3080 там никто не слушает. Перенаправьте порт через SSH с помощью ssh -N -L 3080:127.0.0.1:3080 you@your-vps, а затем откройте http://127.0.0.1:3080 локально. Среднее поле аргумента -L разрешается на стороне сервера, именно поэтому оно указывает на harness.

Безопасно ли привязывать веб-интерфейс dsh к 0.0.0.0 на публичном VPS?

Нет. Веб-интерфейс является панелью управления агентом, который выполняет shell-команды и редактирует файлы от имени пользователя, запустившего dsh, а предварительная версия для разработчиков не имеет экрана авторизации. Привязка ко всем интерфейсам на публичном IP означает, что любой, кто обратится к порту 3080, получит возможность выполнять команды на вашем сервере. Оставьте привязку на 127.0.0.1, закройте порт 3080 на межсетевом экране и используйте SSH-туннель, частную оверлейную сеть или reverse proxy с обязательной аутентификацией.

Как оставить веб-интерфейс dsh запущенным после закрытия SSH-сессии?

Процесс npx @deepseek-ai/dsh web, запущенный в foreground, является дочерним для вашей оболочки входа, поэтому он завершается при выходе из неё. Запускайте его внутри сессии tmux и отключайтесь с помощью Ctrl-b d, либо используйте пользовательский systemd-сервис с включенным lingering. Туннель и harness независимы: вы можете разрывать и восстанавливать SSH-туннель сколько угодно раз, не затрагивая работающий harness, если у последнего есть родительский процесс, который продолжает работать после завершения вашей сессии.

Почему веб-интерфейс dsh зависает во время длительной работы агента при использовании nginx?

Потому что значение proxy_read_timeout по умолчанию в nginx составляет 60 секунд, поэтому он закрывает соединение, если в течение минуты не передаются данные, что часто случается при выполнении длительных шагов агента. Установите proxy_read_timeout 3600s; в блоке location. Добавьте proxy_buffering off;, чтобы вывод потоком передавался в браузер по мере поступления, и передавайте заголовки Upgrade и Connection с помощью proxy_http_version 1.1;, чтобы рукопожатие WebSocket завершилось успешно. Без этих заголовков страница загружается, но не получает обновлений.