Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
swift-nio-ssh — SwiftNIO SSH — это программная реализация SSH с использованием SwiftNIO | Kitploit
Инструменты/GitHubGitHub/apple/swift-nio-ssh
Инструменты шифрования/дешифрованияСетевая безопасностьУтилиты и фреймворкиАутентификацияИнструмент Удаленного Доступа
GitHubapple/swift-nio-ssh

swift-nio-ssh

SwiftNIO SSH — это программная реализация SSH с использованием SwiftNIO

Репозиторий
5137941 месяц назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

SwiftNIO SSH

Этот проект содержит поддержку SSH с использованием SwiftNIO.

Что такое SwiftNIO SSH?

SwiftNIO SSH — это программная реализация SSH: то есть набор API, позволяющих программистам создавать конечные точки, работающие по протоколу SSH. Важно отметить, что это скорее аналог libssh2, нежели openssh. SwiftNIO SSH не предоставляет готовых к использованию в продакшене SSH-клиентов и серверов, а вместо этого предлагает строительные блоки для создания таких клиентов и серверов.

Существует несколько причин для создания программной реализации SSH. Одна из них — уникальное отношение SSH к интерактивности пользователя. Технические пользователи привыкли взаимодействовать с SSH интерактивно: либо для выполнения команд на удалённых машинах, либо для запуска интерактивных оболочек. Возможность программно отвечать на такие запросы открывает интересные альтернативные способы взаимодействия. В качестве примеров можно привести Twisted's Manhole, который использует программную реализацию SSH под названием conch для предоставления интерактивного интерпретатора Python внутри работающего Python-сервера, или ssh-chat — SSH-сервер, который предоставляет чат-комнату вместо обычной функциональности SSH-оболочки. Также можно представить инновационные применения для пересылки TCP.

Ещё одна веская причина для создания программной реализации SSH — это то, что сервисам часто требуется взаимодействовать с другими сервисами путём выполнения команд. Хотя Process решает эту задачу для локального сценария, иногда команды нужно выполнять удалённо. Хотя Process может запустить клиент ssh как дочерний процесс для выполнения такого вызова, зачастую гораздо проще напрямую вызывать SSH. Это и является целевым сценарием использования libssh2. SwiftNIO SSH предоставляет эквивалент сетевого и криптографического уровня libssh2, позволяя мотивированным пользователям управлять SSH-сессиями напрямую из Swift-сервисов.

Последние версии SwiftNIO SSH поддерживают Swift 5.9 и новее. Минимальные поддерживаемые версии Swift для разных релизов SwiftNIO SSH указаны ниже:

Что поддерживает SwiftNIO SSH?

SwiftNIO SSH поддерживает SSHv2 со следующим набором функций:

  • Все возможности сессионных каналов, включая запросы shell и exec
  • Прямая и обратная пересылка TCP-портов
  • Только современные криптографические примитивы: Ed25519 и ECDSA по основным кривым NIST (P256, P384, P521) для асимметричной криптографии, AES-GCM для симметричной криптографии, x25519 для обмена ключами
  • Аутентификация пользователя по паролю и с помощью открытого ключа
  • Поддержка всех платформ, поддерживаемых SwiftNIO и Swift Crypto

Как использовать SwiftNIO SSH?

SwiftNIO SSH предоставляет обработчик канала SwiftNIO — NIOSSHHandler. Этот обработчик реализует основную часть протокола SSH напрямую. Ожидается, что пользователи не будут генерировать SSH-сообщения вручную: вместо этого они взаимодействуют с NIOSSHHandler через дочерние каналы и делегаты.

SSH — это мультиплексированный протокол: каждое SSH-соединение делится на несколько двунаправленных каналов связи, которые, как несложно догадаться, называются каналами. SwiftNIO SSH отражает такую структуру, используя абстракцию «дочернего канала». Когда удалённая сторона создаёт новый SSH-канал, SwiftNIO SSH создаёт новый NIO-канал (Channel), который используется для представления всего трафика на этом SSH-канале. Внутри этого дочернего Channel все события строго упорядочены относительно друг друга, однако события в разных Channel могут свободно чередоваться реализацией.

Активное SSH-соединение выглядит следующим образом:

root@kitploit:~
┌ ─ NIO Channel ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐

│     ┌────────────────────────────────┐    │
      │                                │
│     │                                │    │
      │                                │
│     │                                │    │
      │                                │
│     │         NIOSSHHandler          │───────────────────────┐
│     │                                │    │                  │
      │                                │                       │
│     │                                │    │                  │
      │                                │                       │
│     └────────────────────────────────┘    │                  │
                                                               │
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘                  │
                                                               │
                                                               │
                                                               │
                                                               │
                                                               ▼
                     ┌── SSH Child Channel ─────────────────────────────────────────────────────────────┐
                     │                                                                                  │
                     │   ┌────────────────────────────────┐      ┌────────────────────────────────┐     ├───┐
                     │   │                                │      │                                │     │   │
                     │   │                                │      │                                │     │   ├───┐
                     │   │                                │      │                                │     │   │   │
                     │   │                                │      │                                │     │   │   │
                     │   │          User Handler          │      │          User Handler          │     │   │   │
                     │   │                                │      │                                │     │   │   │
                     │   │                                │      │                                │     │   │   │
                     │   │                                │      │                                │     │   │   │
                     │   │                                │      │                                │     │   │   │
                     │   └────────────────────────────────┘      └────────────────────────────────┘     │   │   │
                     │                                                                                  │   │   │
                     └───┬──────────────────────────────────────────────────────────────────────────────┘   │   │
                         │                                                                                  │   │
                         └───┬──────────────────────────────────────────────────────────────────────────────┘   │
                             │                                                                                  │
                             └──────────────────────────────────────────────────────────────────────────────────┘

SSH-канал вызывается с указанием типа канала. NIOSSH поддерживает три типа: session, directTCPIP и forwardedTCPIP. Наиболее распространённый тип — session: он используется для представления вызова программы, будь то конкретная именованная программа или оболочка. Два других типа связаны с пересылкой TCP-портов и будут рассмотрены позже.

SSH-канал работает с единственным типом данных: SSHChannelData. Эта структура инкапсулирует тот факт, что SSH поддерживает как обычные, так и «расширенные» данные канала. Обычные данные канала (SSHChannelData.DataType.channel) используются для подавляющего большинства основных данных. В каналах session тип данных .channel используется для стандартного ввода и стандартного вывода: тип данных .stdErr — для стандартного вывода ошибок (естественно). В каналах пересылки TCP используется только тип .channel, который представляет пересылаемые данные.

События канала

Канал session представляет вызов команды. То, как именно работает канал, передаётся с помощью нескольких входящих пользовательских событий. Важны следующие события:

  • SSHChannelRequestEvent.PseudoTerminalRequest: Запрос на выделение псевдотерминала.
  • SSHChannelRequestEvent.EnvironmentRequest: Запрос одной переменной окружения для вызова команды. Всегда отправляется перед самой командой.
  • SSHChannelRequestEvent.ShellRequest: Запрос на запуск оболочки аутентифицированного пользователя в качестве команды.
  • SSHChannelRequestEvent.ExecRequest: Запрос на выполнение конкретной команды.
  • SSHChannelRequestEvent.ExitStatus: Используется для уведомления о завершении удалённой команды и передачи кода возврата.
  • SSHChannelRequestEvent.ExitSignal: Используется для указания, что удалённая команда была завершена в ответ на сигнал, и указания самого сигнала.
  • SSHChannelRequestEvent.SignalRequest: Используется для отправки сигнала удалённой команде.
  • SSHChannelRequestEvent.LocalFlowControlRequest: Используется для указания, способен ли клиент самостоятельно выполнять управление потоком с помощью Ctrl-Q/Ctrl-S.
  • SSHChannelRequestEvent.WindowChangeRequest: Используется для сообщения об изменении размера окна терминала на клиенте для выделенного псевдотерминала.

Эти события не используются в сообщениях пересылки портов. Реализации SSH, поддерживающие каналы типа .session, должны быть готовы обрабатывать большинство или все эти события различными способами.

Каждое из этих событий также имеет поле wantReply. Оно указывает, требуется ли ответ, подтверждающий успех или неудачу. Если да, используются следующие два события:

  • ChannelSuccessEvent — для сообщения об успехе.
  • ChannelFailureEvent — для сообщения о неудаче.

Полузакрытие

Сетевой протокол SSH повсеместно использует полузакрытие в дочерних каналах. По умолчанию полузакрытие в NIO-каналах (Channel) отключено, и SwiftNIO SSH соблюдает это значение по умолчанию и в своих дочерних каналах. Однако если оставить этот параметр по умолчанию, поведение дочерних SSH-каналов будет крайне неожиданным. По этой причине настоятельно рекомендуется включить поддержку полузакрытия во всех дочерних каналах:

root@kitploit:~
channel.setOption(ChannelOptions.allowRemoteHalfClosure, true)

После этого используется стандартная поддержка полузакрытия NIO. Отправка EOF удалённой стороной будет передана как входящее пользовательское событие ChannelEvent.inputClosed. Чтобы отправить EOF самостоятельно, вызовите close(mode: .output).

Аутентификация пользователя

Аутентификация пользователя — важнейшая часть SSH. Для управления ею SwiftNIO SSH использует пару протоколов делегата: NIOSSHClientUserAuthenticationDelegate и NIOSSHServerUserAuthenticationDelegate. Клиенты и серверы должны предоставить реализации этих протоколов делегата для управления аутентификацией пользователя.

Клиентский протокол прост: SwiftNIO SSH вызывает метод nextAuthenticationType(availableMethods:nextChallengePromise:) у делегата. Параметр availableMethods будет экземпляром NIOSSHAvailableUserAuthenticationMethods, который сообщает, какие методы аутентификации сервер счёл приемлемыми. Делегат может затем выполнить nextChallengePromise либо с новым запросом аутентификации, либо с nil, чтобы указать, что у клиента закончились варианты.

Серверный протокол сложнее. Делегат должен предоставить свойство supportedAuthenticationMethods, которое сообщает, какие методы аутентификации поддерживаются делегатом. Затем каждый раз, когда клиент отправляет запрос аутентификации пользователя, вызывается метод requestReceived(request:responsePromise:). Этот метод может вызываться несколько раз параллельно, так как клиентам разрешается отправлять запросы аутентификации параллельно. responsePromise должен быть выполнен с результатом аутентификации. Возможны три результата: .success и .failure очевидны, но в принципе сервер может требовать несколько проверок, используя .partialSuccess(remainingMethods:).

Прямая пересылка портов

Прямая пересылка портов — это пересылка портов от клиента к серверу. В традиционном режиме клиент прослушивает локальный порт и перенаправляет входящие соединения на сервер. Он просит сервер перенаправить эти соединения как исходящие к определённому хосту и порту.

Такие каналы могут быть напрямую открыты клиентом с использованием типа канала .directTCPIP.

Удалённая пересылка портов и глобальные запросы

Удалённая пересылка портов — менее распространённая ситуация, когда клиент просит сервер прослушивать конкретный адрес и порт и перенаправлять все входящие соединения клиенту. Поскольку клиенту нужно запросить такое поведение, он делает это с помощью глобальных запросов.

Глобальные запросы инициируются с помощью NIOSSHHandler.sendGlobalRequest, а принимаются и обрабатываются через GlobalRequestDelegate. На данный момент поддерживаются два глобальных запроса:

  • GlobalRequest.TCPForwardingRequest.listen(host:port:): запрос на прослушивание сервером заданного хоста и порта.
  • GlobalRequest.TCPForwardingRequest.cancel(host:port:): запрос на отмену прослушивания заданного хоста и порта.

Серверы могут быть уведомлены об этих запросах и отвечать на них с помощью GlobalRequestDelegate. Реализуемый метод — tcpForwardingRequest(_:handler:promise:). Этот метод делегата будет вызываться каждый раз, когда получен глобальный запрос. Ответ на запрос передаётся в promise.

Затем пересылаемые каналы отправляются от сервера к клиенту с использованием типа канала .forwardedTCPIP.

Скачать инструмент
SwiftNIO SSHМинимальная версия Swift
0.0.0 ..< 0.3.05.1
0.3.0 ..< 0.4.05.2
0.4.0 ..< 0.5.05.4
0.5.0 ..< 0.6.25.5.2
0.6.2 ..< 0.9.05.6
0.9.0 ..< 0.9.25.8
0.9.2 ..< 0.10.05.9
0.10.0 ... 0.12.05.10
0.12.0 ..< 0.13.06.0
0.13.0 ..<6.1
  • SSHChannelRequestEvent.SubsystemRequest: Используется для запроса вызова конкретной подсистемы. Смысл этого запроса зависит от конкретного сценария.