3.7 KiB
Proposta Técnica: Mecanismo de Descoberta de Portas e Port-Hunting
Documento de Arquitetura e Especificação para o SDK Web
@cybercore/signer-sdk
1. Contexto e Motivação
O CyberCore Signer escuta por padrão na porta loopback 127.0.0.1:21325. No entanto, em cenários corporativos ou máquinas com múltiplos softwares e agentes instalados, podem ocorrer:
- Colisão de Porta: Outro serviço local ou instância em segundo plano do agente já está vinculado à porta
21325. - Execução Multi-Usuário / Terminal Server: Múltiplas sessões de desktop com agentes independentes para cada usuário logado.
- Restrições de Firewall / Segurança Local: Políticas corporativas que exigem portas específicas.
Para suportar portas alternativas sem exigir configuração manual complexa do usuário final, o CyberCore Signer e o SDK Web adotam a estratégia de Port-Hunting Sequencial.
2. Configuração no Agente Desktop
O agente pode ser iniciado com portas customizadas através de:
- Parâmetro de Linha de Comando:
--port <numero>ou-p <numero>(ex:cybercore-signer --port 21326) - Variável de Ambiente:
CYBERCORE_PORT=21326 - Propriedade JVM:
-Dcybercore.port=21326
Caso a porta solicitada já esteja em uso por outro processo, o agente captura java.net.BindException, emite mensagem acionável no log/console e, no modo gráfico, mantém a interface de gestão disponível alertando sobre a indisponibilidade temporária do socket HTTP.
3. Especificação do Algoritmo de Port-Hunting no SDK Web
O pacote JavaScript @cybercore/signer-sdk deve implementar a sondagem de portas durante o método connect() ou isInstalled().
Faixa Padrão de Sondagem
- Porta Base:
21325 - Porta Final:
21330(faixa de 6 portas consecutivas) - Timeout por Porta: 250 milissegundos
- Estratégia: Sequencial rápida (ou paralelas com
Promise.any)
Algoritmo
export interface SignerOptions {
basePort?: number;
maxPort?: number;
timeoutMs?: number;
}
export async function discoverActivePort(options: SignerOptions = {}): Promise<number> {
const basePort = options.basePort ?? 21325;
const maxPort = options.maxPort ?? 21330;
const timeoutMs = options.timeoutMs ?? 250;
for (let port = basePort; port <= maxPort; port++) {
try {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
const resp = await fetch(`http://127.0.0.1:${port}/ccsp/v1/status`, {
method: 'GET',
signal: controller.signal,
headers: { 'Accept': 'application/json' }
});
clearTimeout(timer);
if (resp.ok) {
const body = await resp.json();
if (body.status === 'ready' && body.agent === 'CyberCore Signer') {
return port; // Agente encontrado e operacional nesta porta!
}
}
} catch {
// Porta indisponível ou conexão recusada; continua para a próxima
}
}
throw new Error('CyberCore Signer não encontrado na faixa de portas 21325-21330. O agente está em execução?');
}
4. Segurança e Mitigações
- Host Header Restrito: Cada requisição deve sempre enviar
Host: 127.0.0.1:{port}ouHost: localhost:{port}. O agente rejeita qualquer Host externo com HTTP 403. - Private Network Access (PNA): O agente responde com
Access-Control-Allow-Private-Network: truepara compatibilidade com a especificação PNA do Google Chrome/Chromium. - CORS Rígido: A rota
/statusrespondestatus: readyapenas para fins de handshake; operações de chave privada continuam exigindoapplication_id, autorização prévia e aprovação visual do usuário.