
## SSH-данные

`GET /v1/infra/servers/:id/ssh`

Возвращает данные для SSH-подключения. Полноценный SSH-доступ (с паролем, приватным ключом и публичным ключом) возвращается только для серверов в режиме `OPEN`. Для `BLACKHOLE` все SSH-поля — `null`: сервер закрыт фаерволом iptables, и прямой SSH невозможен. Вместо SSH для BLACKHOLE используйте [Deploy API](/docs/infra/deploy) — `/exec`, `/upload`, `/logs`. Rate-limit: до 10 запросов в минуту на сервер.

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | да | ID сервера |

## Примеры

### curl — личный ключ

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/ssh
```

### curl — OAuth-приложение

```bash
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/ssh
```

### JavaScript — личный ключ

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/ssh`,
  { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const { data } = await res.json()

if (data.mode === 'OPEN') {
  console.log('Команда:', data.sshCommand)
  console.log('Пароль:', data.sshPassword)  // если выдавался
} else {
  console.log(data.note)  // BLACKHOLE — используйте Deploy API
}
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/ssh`,
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data.mode` | string | `OPEN` или `BLACKHOLE` |
| `data.ip` | string | Публичный IP сервера |
| `data.sshDirect` | boolean | `true` для `OPEN` (SSH работает по IP), `false` для `BLACKHOLE` (закрыт файрволом) |
| `data.sshUser` | string \| null | Пользователь SSH: `ubuntu` или `root`. `null` для BLACKHOLE |
| `data.sshPort` | number \| null | Порт SSH: `22`. `null` для BLACKHOLE |
| `data.sshPassword` | string \| null | Пароль. Для BLACKHOLE всегда `null`. Для OPEN — пароль если сервер сгенерил один при переходе в OPEN |
| `data.sshPrivateKey` | string \| null | Приватный ключ OpenSSH (ed25519). Возвращается для OPEN-сервера, когда платформа его сгенерировала |
| `data.sshPublicKey` | string \| null | Публичный ключ (ed25519) — соответствующая публичная часть к `sshPrivateKey` |
| `data.sshCommand` | string \| null | Готовая команда для копирования: `ssh ubuntu@IP`. Для BLACKHOLE — `null` |
| `data.appUrl` | string | HTTPS-адрес приложения (присутствует только для BLACKHOLE, где SSH недоступен) |
| `data.note` | string | Пояснение для BLACKHOLE: «BLACKHOLE servers do not expose SSH. Use the Deploy API…» |

## Пример ответа

OPEN-сервер:

```json
{
  "success": true,
  "data": {
    "mode": "OPEN",
    "ip": "111.88.251.211",
    "sshUser": "ubuntu",
    "sshPort": 22,
    "sshPassword": "Oi9owBO6zMbueGmM75J9hg",
    "sshPrivateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmU…\n-----END OPENSSH PRIVATE KEY-----\n",
    "sshPublicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM0JAP1EMGh0CkT7RkZ26pTSa4X1FsWXe61cB5Fiqqjz vibe-generated",
    "sshCommand": "ssh ubuntu@111.88.251.211",
    "sshDirect": true
  }
}
```

BLACKHOLE-сервер:

```json
{
  "success": true,
  "data": {
    "mode": "BLACKHOLE",
    "ip": "93.77.184.167",
    "sshDirect": false,
    "sshPassword": null,
    "sshPrivateKey": null,
    "sshPublicKey": null,
    "sshCommand": null,
    "appUrl": "https://app-abc12345.vibecode.bitrix24.tech",
    "note": "BLACKHOLE servers do not expose SSH. Use the Deploy API (exec/upload/logs) instead."
  }
}
```

## Пример ответа при ошибке

404 — сервер не существует:

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Server not found"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ |
| 403 | `SERVER_ROLE_FORBIDDEN` | Вы состоите в команде разработки этого сервера с ролью «Разработчик», а операция открыта роли «Администратор». В `error.hint` придут ваша роль, требуемый порог и перечень открытых вам вызовов. Разбор ролей — [Список серверов](/docs/infra/servers/list) |
| 404 | `NOT_FOUND` | Сервер не существует, удалён или привязан к другому API-ключу, и вы не состоите в его команде разработки |
| 429 | `RATE_LIMITED` | Превышен rate-limit (до 10 запросов в минуту на сервер) либо общий rate-limit платформы |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **Каждый BLACKHOLE → OPEN переход генерирует новый пароль.** Старые пароли (если они были) становятся недействительными. То же при обратном цикле BLACKHOLE → OPEN → BLACKHOLE → OPEN: на каждый вход в OPEN платформа генерирует свежий `sshPassword`. Пароль также возвращается в ответе на [`PATCH /mode`](./mode.md) — можно сохранить оттуда.
- **`sshPrivateKey` и `sshPublicKey` отдаются только для ключей, сгенерированных платформой.** Если при создании сервера через [`POST /v1/infra/servers`](/docs/infra/servers/create) вы передали свой `sshPublicKey`, платформа не генерировала приватный ключ — поле `sshPrivateKey` в ответе будет `null`. Используйте свой приватный ключ со стороны клиента.
- **`sshCommand` — готовая к копированию строка для AI-агентов и скриптов.** Это не отдельная команда запуска — просто `ssh ubuntu@IP`. Аутентификация через пароль или ключ — отдельный шаг на стороне SSH-клиента.
- **Отдельное ограничение — 10 запросов в минуту на сервер** существует именно из-за чувствительности возвращаемых данных. Общий лимит платформы выше, но `/ssh` ограничивается жёстче.

## Смотрите также

- [Переключить режим](./mode.md)
- [Выполнить команду](/docs/infra/deploy/exec)
- [Загрузить файл](/docs/infra/deploy/upload)
- [Политика доступа](./access-policy.md)
