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

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

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

Репозиторий
51379361 день назадПроверено Kitploit

Популярное

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

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

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

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

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

Этот проект содержит поддержку SSH с использованием [SwiftNIO](https://github.com/apple/swift-nio).

## Что такое SwiftNIO SSH?

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

Существует несколько причин для создания программной реализации SSH. Одна из них — уникальное отношение SSH к интерактивности пользователя. Технические пользователи привыкли взаимодействовать с SSH интерактивно: либо для выполнения команд на удалённых машинах, либо для запуска интерактивных оболочек. Возможность программно отвечать на такие запросы открывает интересные альтернативные способы взаимодействия. В качестве примеров можно привести Twisted's Manhole, который использует [программную реализацию SSH под названием `conch`](https://twistedmatrix.com/trac/wiki/TwistedConch) для предоставления интерактивного интерпретатора Python внутри работающего Python-сервера, или [ssh-chat](https://github.com/shazow/ssh-chat) — SSH-сервер, который предоставляет чат-комнату вместо обычной функциональности SSH-оболочки. Также можно представить инновационные применения для пересылки TCP.

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

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

SwiftNIO SSH        | Минимальная версия Swift
--------------------|--------------------------
`0.0.0  ..< 0.3.0`  | 5.1
`0.3.0  ..< 0.4.0`  | 5.2
`0.4.0  ..< 0.5.0`  | 5.4
`0.5.0  ..< 0.6.2`  | 5.5.2
`0.6.2  ..< 0.9.0`  | 5.6
`0.9.0  ..< 0.9.2`  | 5.8
`0.9.2  ..< 0.10.0` | 5.9
`0.10.0 ... 0.12.0` | 5.10
`0.12.0 ..< 0.13.0` | 6.0
`0.13.0 ..<`        | 6.1

## Что поддерживает 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-соединение выглядит следующим образом:

```
┌ ─ 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`: Используется для сообщения об изменении размера окна терминала на клиенте для выделенного псевдотерминала.
- `SSHChannelRequestEvent.SubsystemRequest`: Используется для запроса вызова конкретной подсистемы. Смысл этого запроса зависит от конкретного сценария.

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

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

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

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

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

```swift
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`.
Скачать инструмент