Windows как устройство dix.su¶
Этот гайд покрывает запуск device_client на Windows, автозапуск через NSSM,
браузерный терминал (ttyd) и все подводные камни, включая кириллицу в имени
пользователя.
Требования¶
- Windows 10 22H2+ или Windows 11, 64-бит
- PowerShell 5+ (встроен)
- Аккаунт на dix.su с активным слагом
1. Скачать клиент¶
PowerShell:
New-Item -ItemType Directory -Force C:\dixsu
Invoke-WebRequest https://dix.su/downloads/device_client_windows_x86_64 `
-OutFile C:\dixsu\device_client_windows_x86_64.exe
При предупреждении SmartScreen: Подробнее → Выполнить в любом случае. Или: правой кнопкой на файл → Свойства → Разблокировать → ОК.
Почему
C:\dixsu\?
Если имя пользователя Windows содержит кириллицу (например «Александр»), путь%LOCALAPPDATA%тоже будет содержать кириллицу. Клиент (Burrito/Erlang) падает с ошибкойFailed to open arguments fileпри первом запуске.C:\dixsu\гарантированно ASCII.
2. Первый запуск¶
$env:DEVICE_CLIENT_INSTALL_DIR="C:\dixsu\install"
$env:SERVER_HOST="proxy.dix.su"
$env:SERVER_PORT="443"
C:\dixsu\device_client_windows_x86_64.exe мой-слаг мой-токен 8080
Переменные окружения:
| Переменная | Обязательна | Назначение |
|---|---|---|
DEVICE_CLIENT_INSTALL_DIR |
Если кириллица в логине | Путь кэша Erlang-рантайма — без кириллицы |
SERVER_HOST |
Нет (дефолт proxy.dix.su) |
Адрес прокси |
SERVER_PORT |
Нет (дефолт 443) |
Порт прокси |
В PowerShell синтаксис
VAR=value commandне работает — только$env:VAR="value".
Если туннель подключился — в выводе увидите Joined channel proxy:мой-слаг.
3. Автозапуск¶
Вариант А — Планировщик задач (рабочая станция)¶
Запускается после входа пользователя. Подходит если Windows используется интерактивно.
Создать скрипт C:\dixsu\start-tunnel.ps1:
$env:DEVICE_CLIENT_INSTALL_DIR="C:\dixsu\install"
$env:SERVER_HOST="proxy.dix.su"
$env:SERVER_PORT="443"
C:\dixsu\device_client_windows_x86_64.exe мой-слаг мой-токен 8080
Зарегистрировать задачу (PowerShell от администратора):
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-NonInteractive -File C:\dixsu\start-tunnel.ps1" `
-WorkingDirectory "C:\dixsu"
$trigger = New-ScheduledTaskTrigger -AtLogOn
$trigger.Delay = "PT1M"
$settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit 0 -RestartCount 999 `
-RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName "dixsu-tunnel" `
-Action $action -Trigger $trigger -Settings $settings `
-RunLevel Highest -Force
Start-ScheduledTask "dixsu-tunnel"
Управление:
Start-ScheduledTask "dixsu-tunnel"
Stop-ScheduledTask "dixsu-tunnel"
Unregister-ScheduledTask "dixsu-tunnel" -Confirm:$false
Вариант Б — NSSM (серверный режим)¶
NSSM (Non-Sucking Service Manager) — обёртка, превращающая любой .exe
в настоящий Windows-сервис. Преимущества перед Планировщиком:
- Запускается до входа пользователя (как системный демон)
- Автоматически перезапускает процесс при падении
- Управляется через
sc/services.msc
Установка:
Создать сервис для туннеля:
nssm install dixsu-tunnel "C:\dixsu\device_client_windows_x86_64.exe" "мой-слаг мой-токен 8080"
nssm set dixsu-tunnel AppEnvironmentExtra `
"DEVICE_CLIENT_INSTALL_DIR=C:\dixsu\install" `
"SERVER_HOST=proxy.dix.su" `
"SERVER_PORT=443"
nssm set dixsu-tunnel AppRestartDelay 5000
nssm set dixsu-tunnel Start SERVICE_AUTO_START
nssm start dixsu-tunnel
Управление:
nssm status dixsu-tunnel # статус
nssm start dixsu-tunnel # запустить
nssm stop dixsu-tunnel # остановить
nssm remove dixsu-tunnel confirm # удалить
nssm edit dixsu-tunnel # открыть GUI редактор
Для серверного сценария (ПК без монитора) дополнительно настрой автовход через Sysinternals Autologon и отключи сон:
4. Браузерный терминал (ttyd) на Windows¶
ttyd открывает cmd.exe или PowerShell в браузере на порту 7681.
Через mgmt-туннель dix.su это даёт доступ к Windows без SSH-клиента.
Установка¶
winget install tsl0922.ttyd
# Winget кладёт бинарник в профиль пользователя — скопировать в C:\dixsu\
Copy-Item (where.exe ttyd) C:\dixsu\ttyd.exe
Проверка¶
Открыть http://localhost:7681 — должна появиться командная строка.
Автозапуск через NSSM¶
nssm install ttyd "C:\dixsu\ttyd.exe" "--port 7681 --writable cmd"
nssm set ttyd Start SERVICE_AUTO_START
nssm start ttyd
Пароль на терминал (опционально)¶
nssm set ttyd AppParameters "--port 7681 --credential user:password --writable cmd"
nssm restart ttyd
Типичная ошибка: Unexpected status SERVICE_STOPPED¶
Процесс упал сразу после старта. Причины:
1. Неверный путь к бинарнику — проверить через nssm edit ttyd (GUI)
2. Путь с кириллицей — скопировать в C:\dixsu\ttyd.exe
3. Порт занят — сменить --port 7682
Проверить лог:
nssm set ttyd AppStdout C:\dixsu\ttyd.log
nssm set ttyd AppStderr C:\dixsu\ttyd.log
nssm restart ttyd
type C:\dixsu\ttyd.log
5. Несколько сервисов через NSSM¶
Пример: основной туннель + mgmt-туннель + ttyd:
# Основной туннель (сайт на порту 8080)
nssm install dixsu-tunnel "C:\dixsu\device_client_windows_x86_64.exe" "мой-слаг мой-токен 8080"
nssm set dixsu-tunnel AppEnvironmentExtra "DEVICE_CLIENT_INSTALL_DIR=C:\dixsu\install" "SERVER_HOST=proxy.dix.su" "SERVER_PORT=443"
nssm set dixsu-tunnel AppRestartDelay 5000
nssm set dixsu-tunnel Start SERVICE_AUTO_START
# ttyd на порту 7681
nssm install ttyd "C:\dixsu\ttyd.exe" "--port 7681 --writable cmd"
nssm set ttyd Start SERVICE_AUTO_START
# mgmt-туннель (указывает на ttyd, порт 7681)
nssm install dixsu-mgmt "C:\dixsu\device_client_windows_x86_64.exe" "мой-слаг-mgmt мой-mgmt-токен 7681"
nssm set dixsu-mgmt AppEnvironmentExtra "DEVICE_CLIENT_INSTALL_DIR=C:\dixsu\install" "SERVER_HOST=proxy.dix.su" "SERVER_PORT=443"
nssm set dixsu-mgmt AppRestartDelay 5000
nssm set dixsu-mgmt Start SERVICE_AUTO_START
# Запустить всё
nssm start ttyd
nssm start dixsu-tunnel
nssm start dixsu-mgmt
Важно:
мой-слаг-mgmt— это отдельный дополнительный слаг в личном кабинете dix.su. Создать: Личный кабинет → «Дополнительные слаги». Оба слага (мой-слагимой-слаг-mgmt) должны быть подключены с одного устройства — иначе в личном кабинете появится предупреждение о расхождении.
6. Машина как сервер¶
Если Windows используется как постоянный сервер (без монитора / headless):
Автовход (Autologon)¶
Docker Desktop стартует только после входа пользователя. Без автовхода после перезагрузки NSSM-сервисы поднимутся, но Docker и контейнеры — нет.
Invoke-WebRequest https://live.sysinternals.com/Autologon.exe -OutFile C:\dixsu\Autologon.exe
C:\dixsu\Autologon.exe
В открывшемся окне: введи имя пользователя и пароль → Enable → OK. Пароль хранится зашифрованным в реестре (не в открытом виде).
Что поднимается после перезагрузки¶
| Компонент | Когда | Условие |
|---|---|---|
NSSM-сервисы (dixsu-tunnel, ttyd, dixsu-mgmt) |
До входа пользователя | SERVICE_AUTO_START |
| Docker Desktop | После входа | «Start when you sign in» + Autologon |
Docker-контейнеры (restart: unless-stopped) |
Вместе с Docker Desktop | Autologon |
Без сна и гибернации¶
Windows Update¶
Задать «Период активности» (Параметры → Центр обновления → Дополнительные параметры), чтобы перезагрузки шли ночью.
7. Работа в ttyd¶
ttyd запускается через NSSM как Windows-сервис (пользователь SYSTEM).
Когда открываешь браузерный терминал — получаешь cmd.exe с правами SYSTEM.
PowerShell от администратора¶
Просто напечатай powershell в cmd — откроется PowerShell с полными
правами (SYSTEM выше обычного Admin, UAC не нужен).
Консоль WSL/Ubuntu¶
Важно: WSL 2 привязан к пользовательской сессии. wsl из ttyd
работает только если пользователь залогинен в Windows. Если Autologon
настроен — wsl работает нормально.
Неполадки¶
| Симптом | Причина / решение |
|---|---|
Failed to open arguments file |
Кириллица в %LOCALAPPDATA% — задать DEVICE_CLIENT_INSTALL_DIR=C:\dixsu\install |
The term 'SERVER_HOST=...' is not recognized |
Unix-синтаксис в PowerShell — использовать $env:SERVER_HOST="..." |
Unexpected status SERVICE_STOPPED (NSSM) |
Неверный путь к бинарнику или кириллица в пути — скопировать в C:\dixsu\ |
SmartScreen блокирует .exe |
Правой кнопкой → Свойства → Разблокировать |
| Туннель подключается, но сайт недоступен | LOCAL_PORT не совпадает с портом, на котором слушает приложение |
| После перезагрузки NSSM-сервис не запускается | Проверить nssm status имя — должен быть SERVICE_AUTO_START |
| После перезагрузки Docker-контейнеры не поднялись | Docker Desktop требует входа пользователя — настроить Autologon (раздел 6) |
nginx Exited (127), в docker inspect ошибка mount ... not a directory |
Docker Desktop не успел инициализировать bind-mount файла при старте — монтируй директорию вместо файла (./nginx/ вместо ./nginx/nginx.conf) |
wsl в ttyd не работает |
WSL 2 требует активной пользовательской сессии — настроить Autologon |