Pular para o conteúdo

Abre uma sessão de VPN até a IPMI

POST /cloud/servers/{id}/ipmi-vpn

Escopo do token: servers:console. Recurso: VPN da IPMI.

Com o servidor em repouso (ativo, sem sistema ou falho) e na região com VPN (422 cloud.vpn_unavailable); indisponível enquanto uma operação nossa roda (deploy, reinstalação, limpeza, exclusão) e enquanto o servidor está desligado por falta de pagamento (409 cloud.server_suspended; o desligamento encerra as sessões abertas antes de desligar). public_key é a chave pública WireGuard gerada no dispositivo do cliente: a chave privada nunca chega à plataforma. A sessão nasce opening com o endereço do túnel e a conta da IPMI (usuário e senha gerados, papel Operator); o job cloud-ipmi-vpn cria a conta na IPMI e o peer no OPNsense (active, com a chave pública do OPNsense e o arquivo do WireGuard) e tira tudo ao vencer. Uma sessão viva por servidor (409 cloud.vpn_session_open) e 5 por conta (422 cloud.quota_exceeded). Por token de API só com o escopo servers:console, e pelo servidor MCP só depois da aprovação da pessoa no portal; a senha da IPMI nunca volta ao MCP (a pessoa a lê no portal).

Os exemplos leem o token da variável de ambiente HALVER_API_TOKEN (um token sc_live_… criado em Desenvolvedores › Tokens de API). Nunca escreva o token no código.

Janela do terminal
curl -X POST "https://dash.halver.com.br/api/v1/cloud/servers/307d7f63-0f00-4d4b-bc28-839d359e13a3/ipmi-vpn" \
-H "Authorization: Bearer $HALVER_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"duration_minutes": 60,
"public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExemploDeChavePublicaNaoUseEm0123456789 ana@notebook"
}'
  • id string (uuid) obrigatório

    Exemplo: 307d7f63-0f00-4d4b-bc28-839d359e13a3.

application/json, obrigatório.

  • duration_minutes integer obrigatório

    Um de: 60, 240, 480.

  • public_key string obrigatório

    Chave pública WireGuard do cliente (base64 de 32 bytes, como a saída de wg pubkey).

Exemplo de corpo
{
"duration_minutes": 60,
"public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExemploDeChavePublicaNaoUseEm0123456789 ana@notebook"
}

Sessão abrindo.

Campos da resposta
  • activated_at string (date-time) obrigatório pode ser nulo
  • apply_error string obrigatório

    Última resposta da IPMI ou do OPNsense a uma mudança que não passou (“” quando não há).

  • bmc object obrigatório
    • address string obrigatório

      IP da IPMI, alcançável só pelo túnel.

    • password string obrigatório

      Só enquanto a sessão está viva e só para o cliente que opera os servidores (responsável); “” nos outros casos, inclusive para o usuário de consulta.

    • url string obrigatório
    • username string obrigatório

      Conta da IPMI criada para a sessão (papel Operator).

  • close_reason string obrigatório

    Por que encerrou (ou está encerrando). operation = uma operação nossa (deploy, reinstalação, limpeza ou exclusão) começou no servidor; suspended = o servidor foi desligado por falta de pagamento. Um de: "" (vazio), ended, staff, expired, server_gone, failed, operation, suspended.

  • closed_at string (date-time) obrigatório pode ser nulo
  • created_at string (date-time) obrigatório
  • duration_minutes integer obrigatório
  • expires_at string (date-time) obrigatório
  • hostname string obrigatório
  • id string (uuid) obrigatório
  • server_id string (uuid) obrigatório
  • status string obrigatório

    opening = conta da IPMI e peer sendo criados; closing = peer, regras e conta sendo removidos. Um de: opening, active, closing, closed.

  • wireguard object obrigatório
    • address string obrigatório

      Endereço do cliente no túnel (/32).

    • allowed_ips string obrigatório

      Só a IPMI do servidor (/32).

    • config string obrigatório

      Arquivo do wg-quick com <SUA_CHAVE_PRIVADA> no lugar da chave privada (“” até ativa).

    • endpoint string obrigatório

      host:porta do WireGuard do OPNsense.

    • keepalive integer obrigatório
    • public_key string obrigatório

      Chave pública do cliente.

    • server_public_key string obrigatório

      Chave pública do OPNsense (“” até a sessão ficar ativa).

Exemplo de resposta
{
"activated_at": null,
"apply_error": "",
"bmc": {
"address": "198.51.100.20",
"password": "",
"url": "",
"username": "sc-7f3a"
},
"close_reason": "ended",
"closed_at": null,
"created_at": "2026-10-20T18:00:00Z",
"duration_minutes": 60,
"expires_at": "2026-10-20T18:00:00Z",
"hostname": "web-01",
"id": "f6ba3404-eb7b-4ebc-8d6b-7483c6c094b0",
"server_id": "307d7f63-0f00-4d4b-bc28-839d359e13a3",
"status": "opening",
"wireguard": {
"address": "198.51.100.20",
"allowed_ips": "10.250.0.0/24",
"config": "",
"endpoint": "198.51.100.1:51820",
"keepalive": 25,
"public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExemploDeChavePublicaNaoUseEm0123456789 ana@notebook",
"server_public_key": ""
}
}

Todo erro vem como application/problem+json (RFC 9457), com um code estável, a mensagem em português em detail, o motivo de cada campo em errors (nos erros de validação) e o request_id, que você informa ao suporte. Veja a lista completa de códigos.

Status Quando Códigos
400 Requisição inválida (JSON malformado, campo desconhecido, parâmetro inválido ou falha de validação). validation_failed, request.invalid_json
401 Não autenticado (token ausente, inválido ou expirado; credenciais inválidas). auth.unauthorized
403 Autenticado, mas sem permissão para a área ou a operação. api_token.insufficient_scope
404 Recurso não encontrado (ou fora do escopo do usuário). server.not_found
409 Conflito (unicidade ou operação concorrente em andamento). cloud.server_suspended, cloud.vpn_session_open
422 Entrada válida, mas viola uma regra de negócio. cloud.vpn_unavailable, cloud.quota_exceeded
Exemplo de erro
{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "o token não tem o escopo servers:console; crie um token com esse escopo em Desenvolvedores › Tokens de API",
"code": "api_token.insufficient_scope",
"request_id": "6f1c0b2a9e4d7c3b5a8f0e1d"
}