CF-Workers-WebSSH - Нативный WebSSH-терминал на Cloudflare Workers - 2026
Published: 2026-07-30
CF-Workers-WebSSH — это бессерверный WebSSH-клиент с открытым исходным кодом, работающий полностью на границе (Edge) сети Cloudflare. Проект реализует полноценный SSH 2.0 стек, криптографию (Web Crypto), фронтенд и SFTP-клиент на чистом TypeScript, развёртываемые в рамках одного Cloudflare Worker. Репозиторий проекта доступен на GitHub: github.com/cmliu/CF-Workers-WebSSH.
История и предпосылки создания
Традиционные WebSSH-решения требуют либо установки отдельного сервера-прокси (например, Apache Guacamole или GateOne), либо использования сторонних библиотек, реализующих SSH-протокол на серверной стороне. Это добавляет сложность в развёртывание, требует постоянного обслуживания инфраструктуры и увеличивает задержки.
С появлением Cloudflare Workers и, в особенности, Durable Objects (DO) и TCP Sockets API, стало возможным выполнение долгоживущих TCP-соединений непосредственно на границе сети CDN. CF-Workers-WebSSH использует эти возможности для создания полностью бессерверного SSH-клиента, который не требует никакой традиционной серверной инфраструктуры — ни виртуальных машин, ни контейнеров, ни выделенных серверов.
Проект был создан разработчиком под псевдонимом cmliu и опубликован на GitHub как open-source решение. Основная цель — предоставить простой, безопасный и эффективный способ доступа к SSH-серверам через веб-браузер без установки дополнительного программного обеспечения.
Архитектура
Архитектура CF-Workers-WebSSH основана на трёх ключевых компонентах:
Фронтенд (браузер)
Пользовательский интерфейс реализован на базе библиотеки xterm.js — эмулятора терминала, работающего непосредственно в браузере. Браузер подключается к Cloudflare Worker через HTTPS и WebSocket (WSS). Через WebSocket передаются все данные терминала: ввод с клавиатуры, вывод на экран, управляющие сообщения, а также данные SFTP по отдельному каналу.
Cloudflare Worker (шлюз)
Worker выступает в роли шлюза, который обрабатывает HTTP-запросы, выполняет проверку источника (same-origin check), генерирует одноразовые сессионные билеты (tickets), раздаёт статические ресурсы (фронтенд) и направляет WebSocket-соединения к соответствующему Durable Object.
Ключевые функции Worker: - Генерация одноразовых билетов для создания сессии - Проверка Content-Type и размера тела запроса - Валидация WebSocket-ориджина - Принудительное использование HTTPS - Установка защитных HTTP-заголовков - Обслуживание статических файлов фронтенда
Durable Object (изолятор сессии)
Каждый SSH-сеанс изолирован внутри отдельного объекта Durable Object, который поддерживает постоянное TCP-соединение с целевым сервером через Cloudflare TCP Sockets API. Durable Object реализует полный SSH 2.0 клиент, включая: - Ключевой обмен (Key Exchange) - Шифрование и дешифрование пакетов - Аутентификацию пользователя - Управление каналами (session, SFTP) - Keepalive-механизм
Схема работы:
Браузер (xterm.js)
│ HTTPS: запрос одноразового билета
│ WSS: ввод/вывод терминала, SFTP
▼
Cloudflare Worker
│ проверка источника, билеты, статика
▼
Durable Object (на сессию)
│ SSH 2.0 клиент, TCP Socket
▼
Целевой SSH-сервер (публичный IP)
Технический стек
SSH 2.0 протокол
Весь SSH 2.0 стек реализован с нуля на TypeScript с использованием Web Crypto API. Никакие сторонние SSH-библиотеки не используются во время выполнения. Реализованы следующие компоненты протокола:
- Протоколы: SSH 2.0 интерактивный Shell, PTY (псевдо-терминал), SFTP v3, синхронизация размеров окна, Keepalive
- Аутентификация: Password, однопарольный keyboard-interactive, OpenSSH Ed25519/RSA/ECDSA P-256/P-384/P-521 приватные ключи (незашифрованные)
- Ключевой обмен (KEX): curve25519-sha256, ecdh-sha2-nistp256
- Хост-ключи: Ed25519, ECDSA P-256/P-384/P-521, RSA SHA-2
- Шифрование: AES-128/256-GCM, AES-128/192/256-CTR
- MAC: HMAC-SHA2-256, HMAC-SHA2-512 (AES-GCM не использует отдельный MAC)
- Кодировки терминала: UTF-8, GB18030, Big5 (зависит от поддержки браузером TextDecoder)
Используемые технологии Cloudflare
Проект использует следующие возможности платформы Cloudflare:
- Cloudflare Workers — серверная среда выполнения на границе сети
- Durable Objects — изоляция состояния каждого SSH-сеанса с поддержкой WebSocket
- TCP Sockets API — установка TCP-соединений к целевым SSH-серверам (только публичные IP)
- Workers Assets — раздача статических файлов фронтенда (начиная с версии wrangler 4.x)
- Web Crypto API — криптографические операции на границе сети
Зависимости (npm)
Фронтенд использует минимальное количество зависимостей:
- @xterm/xterm (^6.0.0) — эмулятор терминала
- @xterm/addon-fit (^0.11.0) — адаптивное масштабирование
- @xterm/addon-web-links (^0.12.0) — кликабельные ссылки в терминале
Dev-зависимости:
- @cloudflare/workers-types (^5.20260727.1) — типы для Workers
- TypeScript (^5.9.2) — компилятор
- vite (^7.0.6) — сборщик фронтенда
- wrangler (^4.114.0) — CLI для деплоя
Развёртывание
Требования
Для развёртывания проекта необходим:
- Аккаунт Cloudflare с платным тарифом Workers Paid ($5/месяц) — из-за лимитов на Durable Objects и WebSocket-соединения
- Node.js версии 22.12.0 или выше
- GitHub аккаунт для форка репозитория
Пошаговая инструкция
1. Форкнуть репозиторий CF-Workers-WebSSH на GitHub 2. Перейти в панель Cloudflare → Workers и Pages → «Создать приложение» → «Connect to Git» 3. Выбрать форкнутый репозиторий 4. В поле «Build Command» указать:
npm run build:web
5. В поле «Deploy Command» указать:
npx wrangler deploy
6. Установить переменные окружения:
CONNECT_TIMEOUT_MS=10000
7. Создать Durable Object binding с именем SSH_SESSIONS и классом SSHSessionDO 8. Выполнить деплой
Либо через Wrangler CLI:
git clone https://github.com/cmliu/CF-Workers-WebSSH.git cd CF-Workers-WebSSH npm install npm run build:web npx wrangler deploy
Конфигурация
Основной файл конфигурации — wrangler.toml:
name = "cf-workers-webssh" main = "src/worker.ts" compatibility_date = "2026-07-01" workers_dev = true [build] command = "npm run build:web" [assets] directory = "./dist" binding = "ASSETS" not_found_handling = "single-page-application" run_worker_first = true [vars] CONNECT_TIMEOUT_MS = "10000" [[durable_objects.bindings]] name = "SSH_SESSIONS" class_name = "SSHSessionDO" [[migrations]] tag = "v1" new_sqlite_classes = ["SSHSessionDO"]
Функциональные возможности
Веб-терминал
Терминал на базе xterm.js обладает следующими возможностями:
- Адаптивный интерфейс, поддерживающий десктопные и мобильные устройства
- Автоматическое масштабирование под размер окна (через addon-fit)
- Полноэкранный режим
- Сохранение логов сессии в браузере
- Поддержка кликабельных URL-ссылок (через addon-web-links)
- Настраиваемая стартовая команда
SFTP-менеджер
Встроенный файловый менеджер позволяет:
- Просматривать содержимое удалённых каталогов
- Загружать файлы с локальной машины на сервер (до 64 МБ)
- Скачивать файлы с сервера на локальную машину (до 64 МБ)
- Создавать и удалять пустые каталоги
- Удалять файлы
- Переименовывать файлы и каталоги
SFTP реализован на уровне протокола SSH 2.0 как отдельный канал (subsystem sftp) с поддержкой версии 3 протокола SFTP.
Мониторинг ресурсов
Отдельный виджет процессов (аналог top) отображает в реальном времени:
- Загрузку CPU
- Использование RAM
- Использование Swap
- Системный Load Average
Мониторинг работает через изолированный WebSocket-канал и SSH exec channel, который выполняет команду top на удалённом сервере и парсит вывод.
Управление сессиями
- Одноразовые билеты: перед установкой SSH-соединения запрашивается одноразовый билет, который предотвращает повторное использование
- История подключений: после успешного подключения данные сессии сохраняются в LocalStorage браузера
- AES-256-GCM шифрование: пароли в истории шифруются с использованием AES-256-GCM; приватные ключи не сохраняются
- Проверка хостов: перед отправкой учётных данных соединение приостанавливается для подтверждения SHA-256 отпечатка (fingerprint) сервера
- Ссылки для шеринга: возможность генерировать ссылки для быстрого подключения; при парольной аутентификации ссылка содержит Base64-кодированный пароль
Кодировки
Терминал поддерживает три кодировки отображения:
- UTF-8 (стандартная)
- GB18030 (китайская)
- Big5 (традиционная китайская)
Выбор кодировки зависит от поддержки браузером интерфейса TextDecoder.
Безопасность
Проект реализует несколько уровней безопасности:
Отсутствие встроенной аутентификации
Важное предупреждение: по умолчанию проект не имеет встроенной авторизации для входа в сам WebSSH-интерфейс. Любой, кто знает URL развёрнутого Worker, может получить доступ к странице и инициировать SSH-соединение. При деплое на публичный доступ разработчик обязан:
- Использовать Cloudflare Access с интеграцией с провайдером идентификации (OIDC, One-time PIN, Google, GitHub и т.д.)
- Настроить WAF (Web Application Firewall) правила для ограничения доступа
- Включить Rate Limiting для предотвращения брутфорса
- Отключить ненужный публичный эндпоинт workers.dev
Защита на уровне HTTP
- Принудительное перенаправление на HTTPS
- Проверка источника (Origin) для WebSocket-соединений (same-origin check)
- Защитные HTTP-заголовки (Content-Security-Policy, X-Content-Type-Options, Strict-Transport-Security и др.)
- Проверка Content-Type и ограничение размера тела запроса (8 КБ)
SSH-безопасность
- Проверка SHA-256 отпечатка хоста перед аутентификацией
- Поддержка современных алгоритмов шифрования (AES-GCM, AES-CTR)
- Подтверждение fingerprint сервера — соединение приостанавливается до явного подтверждения пользователем
- Использование современных KEX алгоритмов (curve25519-sha256, ecdh-sha2-nistp256)
Сетевые ограничения
- Подключение возможно только к публичным IP-адресам (локальные/частные IP-адреса не поддерживаются)
- Запрещён исходящий трафик на TCP порт 25
- Доменные имена должны разрешаться только в публичные IP-адреса
Ограничения
Проект имеет ряд осознанных ограничений:
Протокольные ограничения
- Не поддерживаются зашифрованные приватные ключи
- Не поддерживаются ключи в формате PEM/PKCS#8
- Не поддерживается SSH Agent
- Не поддерживается многофакторная keyboard-interactive аутентификация (только однопарольная)
- Не поддерживается SCP (только SFTP)
- Не поддерживается порт-форвардинг (туннелирование)
- Не поддерживается ProxyJump
- Не поддерживается SSH-компрессия
- Не поддерживается rekey внутри сессии
Файловые ограничения
- Загрузка и скачивание файлов ограничены 64 МиБ на один файл
- Удаление каталогов поддерживается только для пустых каталогов
Сетевые ограничения
- Только публичные IP-адреса (без частных сетей и интрасетей)
- Запрещён порт 25 (SMTP) для предотвращения спама
- Требуется стабильное интернет-соединение
Инфраструктурные ограничения
- Требуется платный тариф Cloudflare Workers Paid ($5/мес)
- Производительность зависит от близости к граничным узлам Cloudflare
- Возможны таймауты при длительном бездействии (настраивается через CONNECT_TIMEOUT_MS)
Структура исходного кода
CF-Workers-WebSSH/ ├── src/ │ ├── worker.ts # Точка входа Worker │ ├── http-security.ts # HTTP-безопасность (CORS, HSTS, CSP) │ ├── types.ts # Типы и интерфейсы │ ├── backend/ │ │ ├── durable-object.ts # Durable Object с логикой SSH-сессии (23 КБ) │ │ ├── process-framing.ts # Фрейминг процессов для мониторинга │ │ └── sftp.ts # SFTP v3 серверная логика │ ├── ssh/ │ │ ├── algorithms.ts # Определения алгоритмов SSH │ │ ├── auth.ts # Базовая аутентификация │ │ ├── auth-password.ts # Password аутентификация │ │ ├── auth-key.ts # Public-key аутентификация │ │ ├── channel.ts # Управление SSH-каналами │ │ ├── cipher.ts # Шифрование/дешифрование (AES-GCM, AES-CTR) │ │ ├── client.ts # SSH 2.0 клиент │ │ ├── kex.ts # Ключевой обмен │ │ ├── mac.ts # Message Authentication Code │ │ ├── packet.ts # Пакетный уровень SSH │ │ └── server-host-key.ts # Проверка хост-ключей │ └── frontend/ │ ├── app.ts # Основной фронтенд │ ├── terminal.ts # Инициализация xterm.js │ ├── sftp-client.ts # SFTP клиент в браузере │ ├── process-view.ts # Виджет процессов (top) │ ├── storage.ts # LocalStorage с AES-256-GCM │ └── share.ts # Функции шеринга сессий ├── static/ # Статические ресурсы (CSS, favicon) ├── dist/ # Сборка фронтенда ├── package.json # NPM зависимости ├── wrangler.toml # Конфигурация Cloudflare Workers ├── vite.config.ts # Конфигурация Vite ├── tsconfig.worker.json # TypeScript для Worker ├── tsconfig.frontend.json # TypeScript для фронтенда └── README.md # Документация
Сравнение с альтернативами
| Функция | CF-Workers-WebSSH | Apache Guacamole | GateOne | ttyd |
|---|---|---|---|---|
| Развёртывание | Бессерверное (Edge) | Требует сервер (Tomcat) | Требует сервер (Python) | Требует сервер (C) |
| SSH-библиотеки | Собственная реализация на TypeScript | libssh2 | Python Paramiko | libwebsockets |
| WebSocket | Нативный | Через прокси | Нативный | Нативный |
| SFTP | Встроенный | Через расширения | Нет | Нет |
| Мониторинг top | Встроенный | Нет | Нет | Нет |
| Аутентификация | Password, key, keyboard-interactive | Password, key, TOTP, CAS, SAML, LDAP | Password, key | Password, key |
| Стоимость | $5/мес (Cloudflare) | Сервер + обслуживание | Сервер + обслуживание | Сервер + обслуживание |
| Масштабирование | Автоматическое (Edge) | Требует настройки | Требует настройки | Ограниченное |
| Поддержка кодировок | UTF-8, GB18030, Big5 | UTF-8 | UTF-8 | UTF-8 |
</source>
Применение и варианты использования
Администрирование серверов
CF-Workers-WebSSH позволяет системным администраторам получать доступ к SSH-серверам из любого браузера без установки SSH-клиента. Это особенно полезно при работе с:
- Chromebook и другими устройствами с ограниченными возможностями установки ПО
- Корпоративными сетями, где установка стороннего ПО ограничена политиками
- Общественными или арендованными компьютерами
Обучение и демонстрации
Благодаря возможности шеринга ссылок, инструмент удобен для:
- Проведения обучающих сессий и вебинаров
- Демонстрации работы с Linux-серверами
- Временного доступа для коллег или студентов
DevOps и CI/CD
Интеграция с Cloudflare Workers позволяет использовать инструмент в пайплайнах:
- Быстрый доступ к серверам для диагностики
- Выполнение команд через браузер без дополнительной аутентификации инфраструктуры
- Мониторинг серверов через встроенный виджет top
Резюме
CF-Workers-WebSSH представляет собой инновационное бессерверное решение для удалённого доступа к SSH-серверам, работающее полностью на границе сети Cloudflare. Проект демонстрирует, как современные возможности платформы Cloudflare Workers — Durable Objects, TCP Sockets и Web Crypto API — могут быть использованы для создания полноценного SSH 2.0 клиента с нуля, без зависимости от сторонних SSH-библиотек.
Ключевые преимущества проекта:
- Полностью бессерверная архитектура — не требует традиционной серверной инфраструктуры
- Изоляция сессий через Durable Objects
- Собственная реализация SSH 2.0 на TypeScript
- Встроенные SFTP-менеджер и мониторинг ресурсов
- Минимальные зависимости во время выполнения
- Современные алгоритмы шифрования
Основные недостатки и риски:
- Отсутствие встроенной аутентификации (требуется Cloudflare Access/WAF)
- Ограничение только публичными IP-адресами
- Требование платного тарифа Workers Paid
- Ограничение на размер SFTP-файлов (64 МБ)
- Отсутствие поддержки ряда SSH-возможностей (Agent, ProxyJump, порт-форвардинг)
Проект особенно ценен для разработчиков и администраторов, которые хотят иметь быстрый доступ к SSH-серверам из любого браузера без настройки дополнительной инфраструктуры. При правильной настройке безопасности (Cloudflare Access, WAF) он может стать удобным инструментом в арсенале DevOps-инженера.
