USSH
USSH é um protocolo de shell e um par cliente/servidor construído sobre USTP-Secure.
Não é um túnel TCP e não encapsula SSH dentro de TCP.
Status: Beta
Licença: MIT
Nomes de cifras AEAD
chacha20 = CHACHA20_POLY1305
aes-256-gcm = AES_256_GCM
aes-128-gcm = AES_128_GCM
- Cifra AEAD padrão:
chacha20
Porta padrão
Servidor
python3 ussh_server.py \
--peer-ip <CLIENT_IP_OR_DOMAIN> \
--peer-port 0 \
--bind-ip 0.0.0.0 \
--bind-port 5322 \
--cipher chacha20 \
--congestion-control auto
Se --password for omitido, o servidor solicita a senha de login USSH na inicialização.
Na inicialização interativa, o servidor pergunta se deve se instalar como um serviço systemd. Responda n para executá-lo normalmente. Use --no-systemd-prompt para pular essa pergunta.
Cliente
python3 ussh_client.py \
--peer-ip <SERVER_IP_OR_DOMAIN> \
--peer-port 5322 \
--bind-ip 0.0.0.0 \
--bind-port 0 \
--cipher chacha20 \
--congestion-control off \
--cleartext off
O cliente solicita a senha interativamente, como o SSH.
O cliente armazena a primeira chave pública X25519 do servidor vista em ~/.ussh_known_hosts.json.
Se essa chave mudar posteriormente, o cliente aborta com um erro de incompatibilidade TOFU em vez de confiar silenciosamente na nova chave.
Se você rotacionou intencionalmente a chave de host do servidor, execute o cliente com --regen-key para permitir a substituição da chave TOFU armazenada após confirmação interativa.
Internet-Drafts
- Internet-Draft
USSH: https://datatracker.ietf.org/doc/draft-x1co-ussh/
Notas
- O transporte é USTP-Secure sobre UDP.
- USSH também suporta modo DATA em texto claro opcional com integridade HMAC por pacote:
- Lado do servidor:
--cleartext auto|on|off
- Lado do cliente:
--cleartext on|off
- Com servidor
auto, USSH segue a solicitação do cliente.
- Com servidor
on ou off, o servidor força o modo de texto claro final.
- Quando
--cleartext on é usado, USSH exibe um aviso de que texto claro é perigoso na internet real e só é recomendado em ambientes controlados, como uma rede local.
- Sob o USSH, o USTPS usa linhas de controle ASCII legíveis como
ACK: 10 MAC:<tag>, NACK: 42 MAC:<tag>, HELLO: ..., CLOSE:, além de quadros DATA binários UPACK (UPAK).
ACK e NACK permanecem em texto claro para facilitar a depuração, mas são autenticados com uma tag HMAC por sessão para prevenir ataques de controle ACK/NACK forjados.
- No modo normal, as cargas úteis DATA usam criptografia AEAD.
- No modo de texto claro, as cargas úteis DATA não são criptografadas, mas ainda carregam um HMAC para que terceiros não possam modificá-las sem detecção.
- USSH herda o teto de carga útil do transporte USTPS de
900 bytes por carga útil DATA UPACK.
- USSH não define uma segunda camada de fragmentação abaixo do USTPS.
- MTU em nível de transporte, PMTU, comportamento de nonce, tratamento de duplicatas e tratamento de pacotes obsoletos são herdados do USTPS.
- A migração automática de rede/caminho foi removida.
- Se o cliente mudar de rede e seu
IP:porta de origem mudar, espera-se que a sessão USSH atual seja encerrada e o usuário deve reconectar-se de forma limpa.
- A implementação de migração foi removida porque causava problemas práticos de confiabilidade e segurança:
- inundações de migração repetidas quando redes NAT ou móveis mudavam de caminho rapidamente
- sessões que pareciam recuperadas, mas paravam de entregar dados do terminal
- longos períodos de silêncio antes de o cliente perceber que o caminho estava morto
- ambiguidade entre um cliente real em roaming e pacotes falsificados reivindicando uma sessão existente
- estado de recuperação que podia deixar o terminal travado em vez de reconectar de forma limpa
- O comportamento atual é intencionalmente mais simples: validar o cliente no
IP:porta atual, vincular a sessão a esse endpoint e reconectar se o endpoint mudar.
- USSH herda o
USTPS Congestion opcional do transporte.
- Lado do servidor:
--congestion-control auto|on|off
- Lado do cliente:
--congestion-control on|off
- Com servidor
auto, USSH segue a solicitação do cliente. Com servidor on ou off, o servidor força o modo final.
- O próprio USTP-Secure permanece sem ordenação.
- USSH não transforma o transporte em um canal ordenado semelhante a TCP.
- USSH apenas remonta o fluxo de bytes lógico de
stdout antes de escrever no terminal.
- USSH também pode manter a ordenação em nível de aplicação para blocos de entrada/saída do shell onde um PTY espera um comportamento coerente de fluxo de bytes.
- Essa remontagem existe porque a saída de um shell interativo é um fluxo contínuo de bytes, e renderizar bytes do terminal na ordem bruta de chegada pode corromper saídas grandes, como
ls, find ou logs de compilador.
- Isso significa que o USTP-Secure ainda evita bloqueio de Head-of-Line em nível de transporte, enquanto o USSH restaura apenas a ordem em nível de aplicação necessária para a renderização do terminal.
- As cargas úteis são criptografadas por pacote com AEAD.
- Nenhum PSK estático é usado.
- Cada cliente recebe uma chave de sessão AEAD efêmera separada através de X25519.
- A senha é usada para autenticação USSH após o estabelecimento da sessão segura.
- O servidor inicia um shell real com suporte a PTY na máquina que executa
ussh_server.py.
- O cliente envia bytes de stdin e renderiza bytes de stdout.
- O servidor suporta múltiplos clientes, com um shell/sessão por cliente.
- Se
--cipher for definido no servidor, o servidor usa exatamente essa cifra.
- Se
--cipher for omitido ou definido como auto, o servidor usa a cifra solicitada pelo cliente.
- Clientes rejeitam negociação de cifra inesperada.
- TOFU (Trust On First Use) está habilitado no cliente para detectar mudanças inesperadas na chave do servidor após a primeira conexão.
- O servidor mantém uma chave de host X25519 persistente em
~/.ussh_host_key por padrão, para que o TOFU permaneça estável entre reconexões e reinicializações.
- Uma reinicialização normal do servidor não altera a chave de host.
- Use
--regen-key no servidor apenas quando você quiser intencionalmente rotacionar essa chave de host.
- As entradas TOFU são armazenadas por
<peer-ip-or-domain>:<peer-port>, portanto um servidor diferente em um endereço/porta diferente é tratado como uma identidade de host diferente.
Handshake de transporte
- USSH herda o mesmo handshake de token de repetição USTPS do USTP-Secure.
- O servidor primeiro desafia o cliente com um token de repetição e metadados de sessão.
- O cliente deve ecoar esse token de volta antes que a sessão USSH criptografada seja aceita.
- O mesmo handshake também negocia a cifra AEAD final e se o
USTPS Congestion está on ou off.
- O mesmo handshake também negocia se DATA usa criptografia AEAD ou texto claro mais HMAC.
- O token de repetição é apenas uma prova de alcançabilidade antes da criação da sessão.
- Não é a chave de sessão, não é um nonce de pacote e não substitui a chave de sessão AEAD derivada posteriormente.