Manual de operações do RoamSwitch Server Edition
Instalação oficial, implantação e referência operacional para Cloud VPS (AWS, GCP, Azure, Linode, DigitalOcean), data centers bare-metal e hosts de contêineres.
1. Visão geral e requisitos
RoamSwitch Server Edition é um conjunto autônomo de defesa e monitoramento de integridade headless (zero dependências de GUI) projetado para servidores Linux expostos à Internet pública.
Ao contrário da edição cliente, que alterna perfis dinamicamente com base no estado do Wi-Fi, a edição servidor impõe Inbound Default Drop, monitoramento de integridade de arquivos de caminho crítico (FIM), mitigação preventiva de LPE do kernel (Frag Gap), detecção de ameaças em tempo de execução eBPF, prevenção de bloqueio SSH e alertas de emergência multicanais automatizados (Telegram / LINE / Webhook).
cve_kernel_map_updates_enabled, ativada por predefinição). São os dados de CVE do kernel, as regras web e, em servidores Ubuntu, os dados de CVE de pacotes do Ubuntu usados pela verificação de CVE dos pacotes do sistema. o roamswitch-updater recebe, por HTTPS GET a partir do lafine.net, dados com assinatura Ed25519 (o manifesto assinado é verificado todos os dias, os dados de CVE em si cerca de uma vez a cada 30 dias e as regras web só quando o manifesto tem uma versão mais recente), sem query string nem cookies, com um User-Agent: RoamSwitch-Updater fixo como único cabeçalho que nomeia o software, e não envia nada sobre este anfitrião. Pode ser desativada com roamswitch server config set cve_kernel_map_updates_enabled false (ou com o assistente de configuração ou a TUI do servidor), e a auditoria continua a funcionar com a linha de base incorporada, embora a verificação de CVE dos pacotes do sistema num servidor Ubuntu indique então «sem dados de CVE locais». Todo o restante tráfego que sai do anfitrião limita-se ao seguinte, ativado explicitamente pelo operador: notificações (Telegram / LINE / webhook), a verificação de assinaturas npm (npm_audit_signatures_enabled, apenas quando o comando é executado) e o reencaminhamento de eventos (forward_enabled, desativado por predefinição; §16). O reencaminhamento de eventos vai apenas para destinos que indicar (um SIEM, syslog, um webhook); o syslog TLS é enviado através do openssl do sistema e o webhook estruturado através de um subprocesso curl. Além disso, o emparelhamento do Sensor (sensor_pairing_enabled, desativado por predefinição) e a integração com LLM da ferramenta independente incluída accessscope (desativada por predefinição; na linha de comandos, só quando se indica --llm) só se ligam ao exterior quando o operador os ativa. A lista de exceções está na secção Zero Telemetry do Livro Branco de Segurança da Server Edition.Requisitos do sistema
- Distribuições suportadas: Ubuntu 22.04 / 24.04 LTS, Debian 12+, AlmaLinux / Rocky Linux / RHEL 9+, Fedora 39+, openSUSE Leap 15.5+, Raspberry Pi OS (64 bits)
- Arquiteturas:
x86_64(amd64) ouaarch64(arm64) - Kernel: Linux 5.10+ (
nftables,cgroups v2, eBPF BTF recomendado) - Footprint: 20–30 MB de memória residente, <0,1% da CPU durante cargas de trabalho normais/inativas
2. Procedimentos de instalação
O uso dos repositórios assinados oficiais garante a resolução automática de dependências e atualizações contínuas por meio do gerenciador de pacotes do sistema padrão.
2.1 APT (sistema operacional Ubuntu/Debian/Raspberry Pi)
# 1. Registrar a chave de assinatura do repositório
curl -fsSL https://lafine.net/apt/roamswitch-archive-keyring.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/roamswitch-archive-keyring.gpg
# 2. Adicionar o repositório
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/roamswitch-archive-keyring.gpg] https://lafine.net/apt stable main" \
| sudo tee /etc/apt/sources.list.d/roamswitch.list
# 3. Instalar
sudo apt update && sudo apt install roamswitch-server
2.2 DNF/RPM (Fedora/RHEL/AlmaLinux/Rocky Linux)
# 1. Importar a chave GPG
sudo rpm --import https://lafine.net/rpm/RPM-GPG-KEY-roamswitch
# 2. Adicionar o arquivo de configuração do repositório
sudo curl -fsSL -o /etc/yum.repos.d/roamswitch.repo https://lafine.net/rpm/fedora/roamswitch.repo
# 3. Instalar
sudo dnf install roamswitch-server
2.3 openSUSE (zypper)
sudo rpm --import https://lafine.net/rpm/RPM-GPG-KEY-roamswitch
sudo zypper addrepo https://lafine.net/rpm/opensuse/roamswitch.repo
sudo zypper refresh && sudo zypper install roamswitch-server
roamswitch) e a Server Edition (roamswitch-server) declaram conflitos recíprocos de pacotes. Sempre selecione roamswitch-server em ambientes de servidor headless.3. Configuração inicial e verificação de serviço
3.1 Status do Serviço
Após a instalação, roamswitch-server.service inicia imediatamente e é ativado na inicialização do sistema.
sudo systemctl status roamswitch-server.service
3.2 Assistente de configuração interativo
Execute o assistente de configuração interativo com o comando abaixo para configurar portas, IPs de origem de manutenção, canais de notificação e a ação de contenção de forma interativa (pressione Enter para aceitar cada valor padrão).
sudo roamswitch server setup
- Portas: insira as portas de manutenção SSH (padrão
22) e as portas de serviço públicas (padrão80,443), separadas por vírgulas. - IPs de origem de manutenção: IPs ou CIDRs de um bastião SSH ou da monitorização (p. ex.
203.0.113.50/32). O assistente exige uma resposta e não aceita um valor vazio. Para permitir SSH de qualquer origem, escrevaANYWHERE(nesse caso o caminho SSH de administração fica aberto ao mundo inteiro, também durante o isolamento). - Canais de notificação: ative o bot do Telegram, a API de mensagens do LINE e/ou um webhook genérico (Slack / Discord / Teams).
- Resposta a um evento crítico do eBPF: escolha
isolate(isolar o host),freeze(congelar o processo) oualert_only(apenas notificar). Após salvar, você será solicitado a enviar uma notificação de teste e reiniciar o serviço. - Atualizações automáticas dos dados de CVE (predefinição
y): escolha se a base de dados de CVE do kernel usada pela auditoria de isolamento de contentores, as regras web e, em servidores Ubuntu, os dados de CVE de pacotes do Ubuntu usados pela verificação de CVE dos pacotes do sistema são obtidos anonimamente do lafine.net (o manifesto assinado é verificado todos os dias, os dados de CVE em si cerca de uma vez a cada 30 dias e as regras web só quando o manifesto tem uma versão mais recente; apenas HTTPS GET, sem query string nem cookies, com umUser-Agent: RoamSwitch-Updaterfixo como único cabeçalho que nomeia o software, com a assinatura Ed25519 verificada). Nada sobre este anfitrião é enviado. É a única comunicação externa ativada por predefinição na Server Edition; respondernpara-a (a própria auditoria continua a funcionar com a linha de base incorporada, mas a verificação de CVE dos pacotes do sistema num servidor Ubuntu indica então «sem dados de CVE locais»). Se já estiver desativada numserver.confexistente, a resposta predefinida continua a sern. - Configurações do File Scan Guard: escolha se deseja ativar a verificação de vírus para relés de e-mail, pastas compartilhadas e destinos de upload (§13), e defina os diretórios de destino. Opcional, desativado por padrão.
- Configurações do Resource Guard: ative a proteção contra esgotamento de recursos que detecta crescimento sustentado de RSS (vazamentos de memória/DoS) ou loops de falha em serviços expostos à rede.
- Visão geral das proteções principais sempre ativas: exibe as defesas principais que funcionam o tempo todo, independentemente do assistente — rejeição padrão de entrada, FIM, integração com eBPF etc. (nenhuma entrada necessária).
- Configurações de delegação ao agente de investigação (investigation): escolha se deseja delegar automaticamente a investigação inicial — para eventos críticos de eBPF, ou detecções de adulteração de FIM de caminho crítico/arquivos de bloqueio de dependências, quando classificados apenas como notificação — a uma CLI de agente de IA externo (Claude Code / agy / Codex CLI / OpenCode, ou um comando personalizado) (§10.1). Desativado por padrão.
-100 (ex.: -1001234567890). Confirme o valor correto no campo "chat":{"id":...} da resposta de curl -s "https://api.telegram.org/bot<token>/getUpdates".3.3 Auditoria de segurança de servidor de 34 itens
sudo roamswitch status --server
Executa uma auditoria instantânea de 34 verificações de regras de firewall, mitigação de Frag Gap, restrições Yama LSM, permissões e exposição de porta Docker, produzindo uma pontuação e nota de segurança de 0 a 100 (S a C).
Cada item de verificação é agora também etiquetado, para efeitos de relatórios de conformidade, com uma função/categoria NIST CSF 2.0 (sempre presente quando aplicável) e, apenas quando existe um mapeamento fiável, com um número de controlo CIS Controls v8.
4. Regras de firewall e porta
O arquivo de configuração /etc/roamswitch/server.conf exige permissões 0600 (leitura/gravação somente para root) para proteger informações sensíveis. O formato é chave=valor simples; cabeçalhos de seção como [network] são ignorados.
# --- Firewall ---
ssh_ports=22 # Porta de gerenciamento SSH (mantida mesmo durante o isolamento de emergência)
allowed_ports=80,443 # Portas de serviço públicas
whitelist_ips=203.0.113.10/32 # IP/CIDR de origem de manutenção (vazio = permitir tudo, antigo nome admin_source_ips)
protect_docker_ports=true # Proteção DOCKER-USER (impede que contêineres contornem o firewall)
preserve_ssh_on_isolation=true # Preserva o caminho de gerenciamento SSH mesmo durante o isolamento de emergência (false = corte total)
# --- Guarda de runtime eBPF ---
action_on_critical=isolate # isolate | freeze (SIGSTOP+corte de rede) | alert_only
ebpf_socket_path=/run/roamswitch/events.sock
# --- Bloqueio de Egress/C2 e sinkhole de DNS ---
egress_ip_blocklist_enabled=true # Padrão true. A semente incluída no pacote contém apenas os três servidores de ataque publicados pelo JPCERT/CC; nada mais é bloqueado até que um feed seja instalado
metadata_watch_enabled=true # Padrão true. Avisa quando um programa que não seja root/contentor contacta os metadados da nuvem (apenas registo, não bloqueia; deteta SSRF)
metadata_watch_allow_users= # Contas que usam legitimamente o serviço de metadados (nomes ou ids numéricos, separados por vírgulas; root está sempre isento)
dns_sinkhole_enabled=false # Padrão false (para não quebrar o DNS interno/configurações split-horizon)
dns_sinkhole_provider=quad9 # quad9 | cloudflare | adguard | cleanbrowsing
# --- Dados de CVE de isolamento de contêineres (ativados por padrão) ---
cve_kernel_map_updates_enabled=true # Padrão true. A única comunicação externa ativada por padrão (dados de CVE do kernel assinados, regras web e, em servidores Ubuntu, dados de CVE de pacotes do Ubuntu; manifesto todos os dias, dados de CVE cerca de uma vez a cada 30 dias; anônima, só receção, assinatura verificada). false interrompe-a
# --- Notificações ---
telegram_enabled=false
telegram_bot_token=
telegram_chat_id=
line_enabled=false
webhook_enabled=false
webhook_url=
webhook_block_private_addresses=false # opt-in SSRF guard
webhook_allow_addresses=
# --- Sistema ---
language=ja
fim_check_interval_secs=300 # Antigo nome scan_interval
isolation_hard_cap_secs=3600 # Segundos até um isolamento de alta confiança passar ao modo DEGRADED (0 = manter até ser libertado)
Depois de editar o arquivo diretamente, reinicie o serviço para aplicar as alterações (roamswitch-server não suporta recarregamento):
sudo roamswitch server restart
4.1 Política por nível de severidade (guard.yaml, opcional)
Se somente action_on_critical não oferecer granularidade suficiente, crie /etc/roamswitch/guard.yaml (um modelo é fornecido em /etc/roamswitch/guard.yaml.example). Se ausente, uma política equivalente é sintetizada automaticamente a partir de action_on_critical em server.conf, sem afetar implantações existentes.
policies:
on_warning:
action: log_and_notify
on_critical:
server_action: isolate_process
kill_process: true
fallback_to_host_isolation_after_retries: 3 # Escala automaticamente para isolamento do host se o mesmo processo recorrer
on_emergency:
action: isolate_host_all
kill_process: true
server_safeguards:
maintenance_ssh_ports: [22]
safety_timer_secs: 300 # Segundos até um isolamento de baixa confiança ser restaurado automaticamente (0 desativa). Não se aplica aos isolamentos de alta confiança (ver abaixo)
Libertação automática de um isolamento (por confiança): libertar apenas com um temporizador fixo permite que um atacante paciente simplesmente espere, pelo que o desencadeador de cada isolamento é classificado por confiança. (1) Baixa confiança (eBPF Error / Warning e inferiores, anomalias genéricas de portas): totalmente restaurado após um temporizador curto (safety_timer_secs, 300 s por predefinição). (2) Alta confiança (adulteração de canary, reescrita em massa ao estilo ransomware, eBPF Critical / Emergency / Alert, escalada repetida da mesma regra): nunca é restaurado em silêncio. Após o temporizador curto, a causa continua a ser reverificada e o isolamento só é libertado, com uma notificação, quando a causa é verificada como eliminada. Se isso não puder ser confirmado, ninguém o tiver reconhecido e o limite máximo for atingido (isolation_hard_cap_secs em server.conf, 3600 s por predefinição, 0 = sem limite), passa para o modo DEGRADED. (3) O modo DEGRADED continua a bloquear o novo tráfego que não seja dos caminhos de gestão (as portas SSH de manutenção e os IPs da lista de permissões) e nunca abre por temporizador. Só é libertado por uma reverificação que confirme a eliminação, por um reconhecimento explícito (um ack durante o DEGRADED significa libertar) ou por sudo roamswitch emergency-restore. Em todos os isolamentos, as ligações estabelecidas que não sejam dos caminhos de gestão (um canal C2 ou uma reverse shell que o atacante já tenha aberto) são cortadas. Cada transição fica registada na cronologia de incidentes e é notificada em 10 idiomas.
sudo roamswitch server ack
roamswitch server ack reconhece um isolamento FULL mantendo-o estrito (o operador assumiu a responsabilidade, pelo que não há passagem a DEGRADED nem libertação automática) e liberta um isolamento DEGRADED.
4.2 Bloqueio de Egress/C2 e sinkhole de DNS
Com egress_ip_blocklist_enabled=true (padrão), as ligações de saída para IP maliciosos conhecidos são bloqueadas com nftables. O feed é /var/lib/roamswitch/threatfeed/malicious_ips.txt (gerido pelo mecanismo de atualização) se existir; caso contrário, a semente incluída no pacote (/usr/share/roamswitch/threatfeed/); usa-se um em vez do outro, não são combinados. A semente contém apenas os três endereços de servidores de ataque que o JPCERT/CC publicou no seu relatório de 15/10/2026 sobre ataques a serviços web e APIs (210.149.87.120, 118.26.36.16, 69.10.51.162). Os endereços de servidores alugados podem ser reatribuídos a outras pessoas; se um destino legítimo deixar de funcionar, verifique a linha correspondente nesse ficheiro.
Definir dns_sinkhole_enabled=true força a resolução por meio de um resolvedor DNS de filtragem (Quad9 / Cloudflare / AdGuard / CleanBrowsing), bloqueando a resolução de domínios conhecidos como maliciosos. O padrão é false, pois isso pode quebrar o DNS interno ou configurações split-horizon.
Com metadata_watch_enabled ativo (predefinição), a tabela nftables inet roamswitch_metadata_watch só escreve uma linha no registo do kernel quando um programa que não seja root ou um contentor abre uma nova ligação a um endereço de metadados da nuvem (169.254.169.254, 169.254.170.2, 100.100.100.200, fd00:ec2::254); o daemon do servidor avisa uma vez por dia por conta (por endereço de origem no caso de um contentor). Apenas regista e avisa, nunca bloqueia. Quando um atacante entrega à aplicação o URL do seu próprio servidor, que redireciona (302) para um endereço interno, o registo de acesso mostra só o URL externo; só este tráfego de saída revela o segundo salto. Uma aplicação que usa legitimamente a sua função na nuvem também é reportada: adicione a sua conta a metadata_watch_allow_users para a isentar (um contentor não pode ser isento).
4.3 Proteção de detecção de varredura de portas de entrada
Detecta IPs de origem que se conectaram a muitas portas distintas em pouco tempo, correlacionando regras de log do nftables com o journald (ativado por padrão). Fontes de varredura de alta confiança podem ser bloqueadas automaticamente por um período definido. Ao usar em conjunto com o RoamSwitch Sensor (um recurso diferente da §10.1 — sondas de auditoria de todas as portas de um Sensor emparelhado são excluídas como mitigação de falsos positivos), o próprio IP do Sensor é excluído automaticamente.
# --- Detecção de varredura de portas de entrada (ativado por padrão) ---
port_scan_detect_enabled=true # false para desativar
port_scan_detect_min_distinct_ports=15 # Considerado uma varredura quando as conexões atingem esse número de portas distintas
port_scan_detect_window_secs=300 # Janela de agregação para a detecção (segundos)
port_scan_block_enabled=true # Bloqueia automaticamente o IP de origem da varredura detectada
port_scan_block_duration_secs=600 # Duração do bloqueio automático (segundos)
Você pode consultar o histórico de detecção com o comando roamswitch port-scan.
4.4 Proteção de deteção de túneis DNS
Inspeciona apenas o tráfego DNS de saída deste anfitrião (porta UDP/TCP 53) através de um consumidor NFQUEUE dedicado. Uma consulta é considerada de forma suspeita se o comprimento do rótulo exceder 40 bytes E a sua entropia de Shannon exceder 3,8, ou se o seu qtype for TXT/NULL; um alerta é emitido assim que são detetadas 10 ou mais consultas deste tipo nos últimos 60 segundos (um período de arrefecimento de 300 segundos evita alertas repetidos para a mesma condição). O objetivo é detetar os padrões de consulta característicos de ferramentas de tunelamento/exfiltração DNS como o iodine e o dnscat2. A regra nftables subjacente tem a mesma flag bypass que as outras proteções DNS deste daemon, pelo que a resolução de nomes DNS nunca é interrompida mesmo que esta proteção esteja parada ou sem resposta. É uma funcionalidade apenas de notificação — nunca bloqueia automaticamente. Tal como qualquer outra definição, uma alteração a dns_tunnel_detect_enabled só produz efeito após reiniciar o serviço.
# --- Deteção de túneis DNS (ativada por predefinição) ---
dns_tunnel_detect_enabled=true # false para desativar
4.5 Guarda contra força bruta SSH
A guarda lê as falhas de início de sessão do sshd no instante em que são escritas no registo e conta-as por endereço de origem (ativa por predefinição). Para uma origem que atinge o número de falhas configurado (por predefinição 6 em 600 segundos), a tabela nftables inet roamswitch_sshguard descarta apenas as novas ligações às portas SSH. O primeiro bloqueio dura 1 hora, quadruplica de cada vez que a mesma origem reincide e tem um limite de 7 dias. No momento do bloqueio, são também cortadas as ligações que essa origem já tinha abertas para o SSH (as entradas do conntrack são apagadas e uma regra descarta os pacotes do sentido de resposta). Só é bloqueada uma origem sem sessão autenticada, sem início de sessão por chave pública registado e sem isenção, e isto é verificado de novo mesmo antes de cortar; uma sessão autenticada e uma origem isenta nunca são cortadas. Nada é enviado para o exterior; apenas são executados localmente comandos como journalctl, nft e loginctl.
O registo é seguido com journalctl -f. O journald guarda qual o processo que escreveu cada linha, pelo que as linhas escritas por algo que não seja o sshd são ignoradas. Sem journald, a guarda segue /var/log/auth.log ou /var/log/secure, mas qualquer utilizador local autorizado a usar o syslog pode forjar linhas nesses ficheiros e levar ao bloqueio de um terceiro; onde existir journald, deixe ssh_guard_log_source no valor predefinido auto. As falhas contadas são palavra-passe errada, utilizador inexistente, desligação antes da autenticação depois de indicado um nome de utilizador, excesso de tentativas e falhas de autenticação PAM. Uma falha de chave pública (Failed publickey) não é contada, porque um cliente legítimo com várias chaves produz uma em cada ligação. O endereço de origem é lido do fim da linha, em from <IP> port <N>. Um atacante pode pôr qualquer texto no nome de utilizador, mas um endereço de origem falso escrito aí não faz com que um terceiro seja bloqueado. O IPv6 é contado por /64 e o bloqueio também é por /64 (apenas o endereço de origem, se esse /64 contiver um endereço que tem de continuar acessível, como o gateway).
Nunca são bloqueados: o gateway, os resolvedores DNS, o próprio servidor, o loopback, whitelist_ips, ssh_guard_allow, a origem de uma sessão SSH aberta e já autenticada, qualquer endereço que tenha iniciado sessão com chave pública nos últimos 30 dias (ssh_guard_trust_key_days; um início de sessão com palavra-passe não conta) e um Sensor emparelhado. Se uma destas origens acumular falhas, a guarda limita-se a registá-lo. Os endereços privados não estão isentos, porque um equipamento comprometido dentro da rede também pode ser a origem de um ataque de força bruta. Uma origem que apenas mantém uma ligação aberta antes da autenticação também não está isenta.
Quando o fail2ban (com uma jail sshd ativa) ou o CrowdSec (com um firewall bouncer em execução) já protege o sshd, a guarda cede-lhe o bloqueio para não bloquear duas vezes o mesmo endereço e limita-se a detetar e notificar (ssh_guard_yield_to_fail2ban, true por predefinição). Com ssh_guard_block_enabled=false também só deteta e notifica. Notifica quando bloqueia (em modo só de deteção, quando o limiar é atingido) e quando um início de sessão tem êxito a partir de uma origem que tinha acumulado falhas (crítico: um ataque de força bruta pode ter tido êxito; a sessão não é cortada). Não notifica cada falha, e as origens que excedam 10 por hora são agrupadas numa única notificação.
A lista de bloqueios vê-se com roamswitch server bans (aceita --json; a lista só pode ser lida por root, por isso use sudo) e levanta-se um bloqueio com sudo roamswitch server unban <IP | /64 IPv6 | --all>; ao levantar um bloqueio, o contador de falhas dessa origem também é apagado. Os bloqueios são restaurados com o tempo que lhes resta depois de o servidor reiniciar. O roamswitch emergency-restore não levanta os bloqueios SSH (repor a rede não é motivo para readmitir quem andava a adivinhar palavras-passe); o menu de recuperação (roamswitch recover) e a desinstalação removem a tabela inteira. A ferramenta MCP get_ssh_guard_incidents é só de leitura e não existe nenhuma ferramenta para levantar um bloqueio. Na TUI do Server, a secção «Força bruta SSH» do ecrã de incidentes lista os bloqueios e permite levantá-los (quando iniciada como root; §17).
roamswitch server bans
sudo roamswitch server unban 203.0.113.9
sudo roamswitch server unban --all
Há 10 definições, todas com o prefixo ssh_guard_ (§18.1). Altera-se uma, por exemplo, com sudo roamswitch server config set ssh_guard_max_failures 10 e aplica-se com sudo roamswitch server restart. Defina ssh_guard_enabled=false para parar a guarda por completo, ou ssh_guard_block_enabled=false para que apenas detete e notifique. O item «Proteção de força bruta SSH» do diagnóstico de 34 itens também passa enquanto esta guarda estiver em execução e a bloquear.
Limites: as tentativas que só falham com chave pública não são contadas. Um ataque de força bruta distribuído por muitas origens é contado por origem, pelo que só é travado quando uma origem atinge o limiar. O remédio de fundo é desativar a autenticação por palavra-passe e permitir apenas chaves públicas.
5. Prevenção contra falhas de bloqueio SSH
O bloqueio acidental por configuração incorreta do firewall é um desastre operacional intolerável. RoamSwitch Server Edition incorpora proteções em vários níveis:
- ESTABELECIDO/RELACIONADO Passagem incondicional: sessões ativas nunca são descartadas durante recarregamentos de regras.
- SSH mantido durante o isolamento Air-Gap: mesmo quando uma anomalia desencadeia um isolamento de emergência,
preserve_ssh_on_isolation = truemantém o tráfego novo e estabelecido apenas nos caminhos de gestão — as portas SSH de manutenção e os IPs de origem de administração (whitelist_ips) — para que possa investigar e recuperar sem se deslocar ao local. Todas as outras ligações estabelecidas (C2, exfiltração de dados ou uma reverse shell que o atacante já tenha aberto) são cortadas. Se não for indicada nenhuma origem de administração (whitelist_ipse os endereços permitidos do guard.yaml estão vazios), as portas SSH de manutenção continuam a aceitar novas ligações de qualquer origem durante o isolamento, e o servidor emite um aviso no arranque. Compreserve_ssh_on_isolation=false, o isolamento corta também o SSH. A edição de servidor até à 1.10.4 tinha um defeito. As regras de isolamento descartavam as respostas SSH, pelo que o SSH do operador não funcionava durante o isolamento. Foi corrigido na 1.10.5. - Atomic nftables carregando com rollback: Erros de sintaxe de regra acionam instantaneamente uma reversão com tempo de inatividade zero para o conjunto de regras verificado anterior.
6. Proteção de contêineres (Docker/Podman)
O comportamento padrão do Docker cria regras de iptables personalizadas que ignoram firewalls de host padrão, expondo portas de contêiner (por exemplo, -p 8080:8080) diretamente à Internet.
Com protect_docker_ports=true (a predefinição), o RoamSwitch adapta-se ao back-end de firewall do Docker para que o tráfego para os contentores também seja inalcançável a partir do exterior, a menos que se destine a uma porta listada em ssh_ports ou allowed_ports. Com o back-end iptables / iptables-nft, insere uma regra de inspeção no topo da cadeia DOCKER-USER (para IPv4, e também através de ip6tables quando o IPv6 do Docker está ativado). Com o back-end nftables nativo do Docker (Docker 29 e posteriores, onde DOCKER-USER não existe), cria a sua própria tabela inet roamswitch_docker_guard no hook forward, antes das cadeias do Docker (uma tabela inet cobre IPv4 e IPv6). A decisão usa a porta de destino original anterior ao DNAT (ctorigdstport) e aplica-se apenas ao tráfego que chega pela interface externa, pelo que o tráfego de saída dos contentores e o tráfego entre contentores não são afetados. Impede a exposição acidental de, por exemplo, um contentor de base de dados de desenvolvimento.
A proteção é idempotente e autorrecupera-se a cada minuto: se o dockerd arrancar depois do RoamSwitch, se um reinício ou recarregamento do Docker reescrever as regras, ou após um nft flush manual ou a perda da tabela nftables, é reaplicada, enquanto uma proteção que já esteja atualizada é deixada intacta.
Uma proteção em tempo real que vigia docker events também deteta contentores iniciados com --privileged ou com /var/run/docker.sock montado (risco de fuga do contentor) logo após arrancarem e notifica-o. Além disso, a proteção de execução em contentores (container_exec_guard_enabled, ativada por predefinição) inspeciona com YARA os binários executados dentro dos contentores (uma evasão que apaga o ficheiro depois de o executar continua a ser inspecionada, porque o conteúdo é lido a partir do descritor de ficheiro já aberto). A proteção também assinala os contentores que já estão em execução no arranque e acompanha automaticamente os novos contentores. Ambas são apenas de notificação e nunca bloqueiam automaticamente. Funciona também com o Docker 29 (desde a 1.11.1). Quando a subscrição de eventos continua a falhar, o intervalo de religação aumenta de 5 segundos até um máximo de 5 minutos.
7. Monitoramento de integridade de arquivos de caminho crítico (FIM)
Mais de 150 ficheiros críticos — binários críticos como /bin/login, /usr/bin/sudo e /usr/sbin/sshd, configuração de autenticação como /etc/shadow e /etc/sudoers, e unidades systemd — são monitorizados por SHA-256.
O âmbito não se limita a ficheiros individuais. Nos diretórios críticos (/etc/pam.d, /etc/sudoers.d, /etc/ssh/sshd_config.d, /etc/cron.*, /etc/systemd/system, /etc/ld.so.conf.d, /etc/profile.d e /root/.ssh (exceto known_hosts)) o aparecimento de um novo ficheiro também é detetado, e ficam igualmente cobertos os authorized_keys de todas as contas que podem iniciar sessão, o /etc/ld.so.preload (normalmente não existe; o seu aparecimento é sinal de um rootkit local) e os binários do próprio RoamSwitch. As unidades temporárias que o snapd gera (snap-*.mount e afins) são excluídas. A deteção de novos ficheiros só funciona com uma linha de base que inclua este âmbito, por isso execute sudo roamswitch fim update uma vez após a atualização. Os ficheiros que fim verify não consegue ler quando executado sem root são comunicados como «ignorados, ilegíveis», e não como adulteração.
7.1 Verificação manual de hash
sudo roamswitch fim verify
7.2 Detecção orientada a eventos (instantânea)
Os arquivos monitorados são observados individualmente via fanotify (FAN_CLASS_NOTIF, eventos de conclusão de gravação), de modo que uma adulteração é reverificada e detectada no instante em que ocorre, sem esperar a próxima varredura periódica. A varredura periódica (padrão fim_check_interval_secs=300 segundos) permanece como uma proteção de reserva para eventos perdidos. Também são detetadas as edições que colocam um ficheiro novo sob o mesmo nome (install, sed -i e semelhantes), e a notificação indica o processo que fez a alteração e o seu início de sessão SSH (§7.5).
7.3 Sincronização automática de linha de base em atualizações do sistema operacional
No Debian/Ubuntu, a instalação de pacotes configura automaticamente o gancho DPkg::Post-Invoke em /etc/apt/apt.conf.d/99roamswitch-fim. No Fedora/RHEL/Rocky/AlmaLinux/openSUSE, uma unidade systemd.path (roamswitch-fim-update.path) que monitora /var/lib/rpm desempenha o mesmo papel.
No Debian/Ubuntu, /etc/apt/apt.conf.d/99roamswitch-fim anexa um gancho DPkg::Post-Invoke. Atualizações legítimas de pacotes via sudo apt upgrade atualizam automaticamente a linha de base do FIM, eliminando alertas falsos positivos.
sudo roamswitch fim update
Quando o daemon inicia pela primeira vez e cria a linha de base, se um gerenciador de pacotes (apt/dpkg, dnf/rpm, zypper ou pacman) estiver trabalhando, ele espera até 120 segundos para que termine antes de criá-la. Mesmo instalando no mesmo apt install do Apache ou de outro pacote, os arquivos temporários em que o dpkg está trabalhando (como *.dpkg-new) não entram mais na linha de base nem parecem adulteração na verificação seguinte (a partir da 1.11.18). Se ainda estiver ocupado após 120 segundos, um aviso é registrado e a linha de base é criada mesmo assim.
7.4 Honeytokens (iscos de credenciais)
No arranque, aproveitando o facto de correr como root, o daemon implanta de forma idempotente três ficheiros de credenciais isco sob /root: .aws/credentials, .ssh/id_rsa e .docker/config.json (coletivamente, honeytokens). Nunca substitui um ficheiro real já existente nesses caminhos. Um processo de vigilância em segundo plano usa o inotify para detetar qualquer acesso de leitura a estes ficheiros e trata-o como reconhecimento de credenciais pós-comprometimento (MITRE ATT&CK T1552: Unsecured Credentials), enviando de imediato uma notificação de gravidade Critical e registando-o na linha temporal de incidentes. A funcionalidade está ativada por predefinição e ajusta-se com as chaves honeytokens_enabled (false pára a colocação e a vigilância; os iscos já colocados ficam) e honeytokens_home (onde os iscos são colocados; predefinição /root). Os pacotes até à 1.10.4 não incluíam roamswitch-honeytokens, necessário para esta funcionalidade, pelo que não era executada nas instalações a partir dos pacotes. Está incluído desde a 1.10.5, e o problema de a sandbox do systemd bloquear as escritas em /root na edição de servidor foi corrigido na 1.10.10. Desde a 1.11.1, os comandos docker que o próprio RoamSwitch executa são iniciados com um diretório dedicado vazio (/run/roamswitch/docker-config como root) como DOCKER_CONFIG, pelo que não acionam o isco .docker/config.json (antes disso, a monitorização do daemon e o roamswitch status --server podiam ler o isco e gerar uma deteção falsa). A leitura por qualquer outro programa continua a ser detetada como antes.
Se for detetado um acesso real a um honeytoken, antecipando que o atacante continuará a explorar, o RoamSwitch implanta até dois iscos adicionais tematicamente relacionados por cada acionamento (por exemplo, ao aceder a .aws/credentials também implanta .aws/config; ao aceder a .ssh/id_rsa, implanta .ssh/config; ao aceder a .docker/config.json, implanta .kube/config), com um máximo total de seis entre todos os acionamentos. Se notar uma acumulação destes ficheiros desconhecidos sob /root durante uma investigação de incidente, trata-se de um comportamento esperado.
7.5 Via de intrusão (quem fez a alteração e através de que início de sessão SSH)
As notificações sobre um ficheiro alterado (FIM de caminhos críticos e FIM de ficheiros de bloqueio) passam a indicar o processo que fez a alteração (conta, executável, comando) e o início de sessão SSH a que pertence (IP e porta de origem, hora do início de sessão, método de autenticação e impressão digital da chave pública). Vem ativado por predefinição (fim_intrusion_context_enabled). No momento em que um evento é lido, o daemon tira um instantâneo de /proc/<pid> do processo que escreve (executável, utilizador, loginuid, sessionid, cgroup, cadeia de pais), porque um processo como tee ou sed desaparece um milissegundo depois. Um processo que já tinha terminado é completado pelo gravador de execuções (se estiver ativado). A associação a um início de sessão usa primeiro a tabela de sessões da guarda SSH e, na falta dela, as linhas Accepted do logind e do journald. Funciona mesmo com a guarda SSH desativada. Não é enviado nada para o exterior.
Só se confia nos valores que o kernel comunica: o executável vem de /proc/<pid>/exe (e não de argv[0]), o início de sessão de loginuid (definido uma única vez no início de sessão e herdado através de sudo e su) e do session-N.scope do cgroup, e o resto da cadeia de pais. Os valores que um processo pode alterar por si, como comm, a linha de comandos e o ambiente, são mostrados mas nunca usados para decidir; um processo que apenas se chama sshd não é tomado por um início de sessão SSH. Uma notificação distingue três respostas: encontrado (origem, hora, método, chave); «Não foi encontrado nenhum início de sessão SSH» (a verificação mostrou um serviço do systemd, um contentor, uma sessão de início local ou um processo sem sessão de início); e «Não foi possível determinar o caminho de acesso» (o processo já não existia e não consta do gravador de execuções, o logind não respondeu, a alteração foi encontrada pela verificação periódica e o processo é desconhecido, etc.). O que não pôde ser verificado nunca é apresentado como «não é um início de sessão». A notificação sai mesmo que a consulta falhe.
/etc/ssh/sshd_config: modified
Processo: root (iniciou sessão como admin) / /usr/bin/tee / comando: tee /etc/ssh/sshd_config (pid 4121)
Início de sessão SSH: a sessão que admin abriu a partir de 203.0.113.25:51544 às 2026-10-17 03:12:08 (autenticação: publickey, chave SHA256:AbCdEf0123456789)
/etc/sudoers: modified
Não foi possível determinar o caminho de acesso (a alteração foi encontrada pela verificação periódica, por isso não se sabe que processo a fez)
Passam também a ser detetadas as edições que colocam um ficheiro novo sob o mesmo nome: install, sed -i e cp seguido de mv no mesmo diretório. A marca por ficheiro fica no inode, pelo que este tipo de edição antes não gerava nenhum evento. Agora o daemon marca também os diretórios que contêm ficheiros vigiados e, quando um ficheiro com outro nome é fechado no mesmo diretório, volta a consultar o nome alguns milissegundos depois. Limite: um ficheiro escrito noutro diretório e movido com mv só é encontrado pela verificação periódica (fim_check_interval_secs). Nesse caso o processo que escreveu não é conhecido, e a notificação di-lo.
Além da notificação, o achado fica guardado na cronologia de incidentes (tipo fim) e em /var/lib/roamswitch/fim_intrusions.json (apenas root, os últimos 100). A ferramenta MCP verify_fim devolve-o num campo adicionado, recentIntrusionContext (apenas quando executada como root). O veredicto sobre se um ficheiro foi adulterado não muda. Limites: com o gravador de execuções desativado e um processo escritor que vive apenas um instante, o executável é desconhecido, e são mostrados o executável e a linha de comandos do processo pai. As notificações da vigilância de persistência (persistence_watch) não trazem informação de processo e por isso não recebem via de intrusão. A via mostra o processo que fez a alteração e o seu início de sessão, e nada mais: a porta de entrada em si (a vulnerabilidade explorada ou a forma como uma chave foi roubada) não é mostrada. Para desativar, defina fim_intrusion_context_enabled=false.
8. eBPF Runtime Guard e Integração Falco
Conecta-se a eventos eBPF do espaço do kernel (Falco/Tetragon) para detectar escalonamento de privilégios do kernel Frag Gap, escapes de contêiner e shells reversos não autorizados.
8.1 Arquitetura Anti-Inchaço
Para evitar o «inchaço do syslog» e a pressão sobre o disco que afetam as ferramentas de segurança convencionais, o RoamSwitch liga-se ao Falco diretamente através do socket de domínio UNIX /run/roamswitch/events.sock. O socket é criado apenas para root (0600), pelo que só o Falco em execução como root lhe pode escrever (não é necessária nenhuma configuração adicional de permissões).
- O pacote
/etc/falco/config.d/99-roamswitch-optimized.yamltransmite eventos diretamente para o daemon com zero E/S de disco. A saída do Falco é passada ao socket comsocatdentro dessa configuração, pelo que os pacotes deb / rpm da edição Server instalam osocatcomo pacote recomendado (Recommends); não é necessário se não usar o Falco. /etc/logrotate.d/roamswitch-falcogarante rotação diária limpa para qualquer saída de arquivo substituto.
8.2 Contenção Autônoma
Ao detectar um ataque crítico, o RoamSwitch emite imediatamente SIGSTOP para congelar o PID do processo agressor e aplica o isolamento Air-Gap nftables.
8.3 Preservação automática de provas forenses (Forensic Evidence Capture)
Um pacote de provas é criado automaticamente sempre que a Proteção de runtime eBPF executa uma ação de contenção por processo (congelamento via SIGSTOP mais corte de rede). Segundo a política predefinida da §4.1, os eventos de gravidade Critical seguem este caminho; os eventos de gravidade Emergency, que isolam todo o anfitrião, atualmente não produzem um pacote. Um pacote contém uma captura de pacotes limitada, em regime de melhor esforço, de cerca de 30 segundos na interface de encaminhamento predefinida (é ignorada silenciosamente, com o facto registado, se o tshark não estiver instalado) e, quando o PID responsável é conhecido, um snapshot de /proc/<pid>: status, cmdline, maps, environ (os valores cujo nome contém KEY/TOKEN/SECRET/PASSWORD são substituídos por [REDACTED]), uma lista dos destinos dos descritores de ficheiro abertos e a cadeia de processos antecessores até ao PID 1. Um manifest.json que regista o hash SHA-256 de cada ficheiro capturado é incluído para verificação de adulteração posterior.
Os pacotes são armazenados em /var/lib/roamswitch/incident-evidence/<timestamp>-<ID>/. Nunca são eliminados automaticamente. Para libertar espaço em disco, remova explicitamente os pacotes mais antigos do que o período de retenção (30 dias por predefinição) com:
sudo roamswitch-incident-capture prune [--keep-days N]
Também pode capturar um snapshot manual a qualquer momento, sem esperar por uma ação de contenção, com:
sudo roamswitch-incident-capture snapshot [--pid PID] [--reason TEXT] [--json]
8.4 Medição da rapidez do isolamento e heartbeat do caminho de alertas
A precisão e a rapidez do isolamento eBPF dependem das regras do sensor (Falco ou Tetragon). De facto, as regras padrão do Falco 0.45.0 (29 no total) não incluem nenhuma que detete um reverse shell no anfitrião: as regras de reverse shell são só para contentores, e algumas são descartadas pela condição priority: warning do RoamSwitch. O RoamSwitch não parte do princípio de que as regras são boas; compensa de três maneiras: mede quanto demora o isolamento, verifica regularmente que o caminho dos alertas está vivo e deteta por si os reverse shells.
Medição da latência do isolamento: por cada incidente eBPF o daemon regista o tempo desde a deteção do Falco até ler o alerta (detect_to_receive_ms), desde que o lê até a resposta terminar (receive_to_action_ms, medido depois de a chamada de isolamento regressar; no Air-Gap do anfitrião, até o conjunto de regras ser carregado) e a soma dos dois (detect_to_action_ms). Os valores surgem como campos adicionados em ebpf_incidents.json e na ferramenta MCP get_ebpf_incidents. A notificação de um processo isolado inclui uma linha «da deteção à resposta: N ms». Medido numa VM com Ubuntu 24.04 (Falco 0.45.0, modern eBPF): de 1 a 2 ms da deteção à receção, de 41 a 62 ms da receção ao isolamento do processo mais SIGKILL (42 a 64 ms no total) e 109 ms no total para o Air-Gap do anfitrião (dentro do objetivo de 150 ms). Os valores são dessa VM. O Tetragon marca a hora na receção, pelo que não tem detect_to_receive_ms.
Heartbeat (ebpf_heartbeat_interval_secs; 600 segundos por predefinição, 0 desativa-o, caso contrário de 60 a 86400): o pacote inclui uma regra do Falco própria do RoamSwitch, 96-roamswitch-heartbeat.yaml. Em cada intervalo o daemon abre um caminho descartável que só o root pode usar (um nome aleatório em /run/roamswitch/heartbeat/) e mede quanto tempo o alerta dessa regra demora a regressar pela saída do Falco. Uma única ida e volta mostra de uma vez que a regra está carregada, que o Falco está a funcionar e que o caminho de saída está vivo. Só quando duas verificações seguidas não regressam (a segunda um minuto depois da primeira) avisa: «as regras não estão carregadas ou a saída não está a chegar», no máximo uma vez em 24 horas. Uma linha de heartbeat é descartada sem chegar ao isolamento, à notificação, à lista de permitidos nem ao registo de incidentes. Não é enviado nada para o exterior. As idas e voltas medidas foram de 2 a 6 ms; ao retirar a regra o aviso chegou ao fim de cerca de 164 segundos e, ao restaurá-la, o estado voltou ao normal em cerca de 75 segundos.
O estado fica em /var/lib/roamswitch/ebpf_heartbeat.json e é lido pelo campo heartbeat da ferramenta MCP get_ebpf_incidents e pelo diagnóstico K-04 (agente de execução eBPF; o número de itens de diagnóstico continua a ser 34). Mesmo que o Falco esteja a funcionar, o K-04 reprova se o heartbeat não regressar. Limites: verifica-se uma única ida e volta de uma só regra (as chamadas de sistema da família open); não se consegue saber se outra regra está avariada por si. O que se avaria entre duas verificações (10 minutos por predefinição) só se vê na seguinte. Não é feito para o Tetragon. Num anfitrião em que o Falco não está em execução ou falta o ficheiro da regra, não se verifica nada nem se avisa de nada (disso trata a notificação existente de «guarda parada»). O Falco escreve uma linha de aviso no syslog por cada verificação (144 linhas por dia com o valor predefinido).
8.5 Deteção de reverse shell (própria do RoamSwitch)
Sem depender das regras do Falco, o RoamSwitch lê por si /proc de 2 em 2 segundos e procura uma shell ou um interpretador (sh, bash, python, perl, ruby, php, node e semelhantes) cuja entrada e saída padrão sejam uma única ligação TCP que este anfitrião abriu para um endereço externo. São abrangidos bash -i >& /dev/tcp/…, python, perl, nc -e e socat exec:. Só se comunica o que é visto duas vezes seguidas, uma vez por processo. Por predefinição só contam os endereços externos públicos; os privados (RFC 1918, CGNAT, link-local) só contam com reverse_shell_watch_include_private=true, porque o ProxyCommand do ssh, os contentores e o desenvolvimento local os tornam comuns e legítimos. O loopback nunca é vigiado. As ligações que o anfitrião aceitou (por inetd ou socat TCP-LISTEN) também não são abrangidas. Medido numa VM com Ubuntu 24.04, bash /dev/tcp, python, perl, nc -e e socat exec: foram detetados cada um cerca de 2,4 segundos após a ligação. Não são detetados ssh, ssh com ProxyCommand, git sobre ssh nem um cliente nc.
Uma deteção segue o mesmo caminho de um alerta do Falco (lista de permitidos, arrefecimento das notificações, ações por gravidade do guard.yaml, registo de incidentes) como um evento eBPF Critical chamado RoamSwitch Reverse Shell. Por predefinição isola o processo e termina-o (kill). Um reverse shell pertencente ao root não pode ser isolado por processo; tal como em qualquer evento Critical, segue-se então para o Air-Gap de todo o anfitrião. Há duas saídas se houver receio de que um programa legítimo seja assinalado por engano: reverse_shell_watch_notify_only=true (um Warning só com notificação; nada é isolado nem terminado; false por predefinição) e uma entrada na lista de permitidos, sudo roamswitch server allowlist add "RoamSwitch Reverse Shell" <nome do processo>. As três chaves de configuração são reverse_shell_watch_enabled (true por predefinição), reverse_shell_watch_include_private (false) e reverse_shell_watch_notify_only (false).
Limites: o filtro faz-se por nome (nome do processo e do executável), pelo que um binário caseiro com um nome diferente do de uma shell ou de um interpretador que ligue a sua entrada e saída padrão a um socket não é encontrado. As ligações por loopback (como o retorno de ssh -R) e as de menos de 2 segundos não são vistas, nem os processos que não sejam visíveis a partir do espaço de processos do anfitrião. Esta deteção existe apenas na Server Edition; o Mac e o cliente Linux não a têm.
9. Alertas de Emergência (Telegram/LINE/Webhook)
Envia alertas imediatos para canais de notificação externos quando ocorrem anomalias nas portas, adulteração de FIM ou eventos de contenção de eBPF:
[notifications]
language = ja
# Telegram: token do bot e ID do chat
telegram_bot_token = "123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
telegram_chat_id = "-1001234567890"
# LINE: token de acesso ao canal Messaging API e ID do usuário
line_channel_access_token = "YOUR_LINE_ACCESS_TOKEN"
line_user_id = "U1234567890abcdef1234567890abcdef"
# Webhook genérico (Slack, Discord, Teams, sua própria plataforma de monitoramento)
webhook_url = "https://hooks.slack.com/services/T00/B00/XXXXX"
Mesmo sem configurar estes canais externos, cada alerta enviado também é guardado localmente durante os últimos 7 dias. Consulte-o com roamswitch notifications.
Recusar destinos de webhook internos (opt-in): com webhook_block_private_addresses=true (predefinição false = sem alteração), um webhook de notificação é recusado se o seu destino — num nome de host basta um único endereço resolvido — for loopback, privado (10/8, 172.16/12, 192.168/16), link-local (169.254/16, incluindo o endpoint de metadados cloud 169.254.169.254), ULA (fc00::/7) ou CGNAT (100.64/10). O motivo vai para o log e para o erro de roamswitch notify-test. Grafias alternativas como 2130706433 ou 0x7f.1 e IPv6 IPv4-mapped também são classificadas, e os endereços verificados são fixados no curl, para que o DNS rebinding não troque o alvo. Destinos internos legítimos, como um SIEM interno, são permitidos com webhook_allow_addresses=10.20.0.0/16,fd00::/8 (CIDRs separados por vírgulas). Os webhooks de encaminhamento de eventos têm o mesmo par: forward_webhook_block_private_addresses e forward_webhook_allow_addresses. Mesmo com a opção em false, se o destino for um endereço de metadados cloud é registado um aviso (o envio não é interrompido). Se uma variável de ambiente de proxy HTTP estiver definida, a resolução e a ligação são feitas no proxy e ficam fora desta verificação.
10. Integração Agente AI/MCP (Protocolo de Contexto do Modelo)
O RoamSwitch Server Edition inclui roamswitch-mcp, permitindo que agentes de IA (Claude, Gemini, Cursor) monitorem a integridade e a postura da infraestrutura.
Exemplo de configuração (`claude_desktop_config.json`)
{
"mcpServers": {
"roamswitch": {
"command": "/usr/bin/roamswitch-mcp",
"args": []
}
}
}
10.1 Delegação ao agente de investigação (investigation — delegação da investigação automatizada inicial a um agente de IA)
Enquanto o roamswitch-mcp da §10 atende consultas do cliente de IA de um humano, a delegação investigation é um mecanismo separado em que o próprio daemon inicia de forma autônoma uma CLI de agente de IA externo, acionada por um evento de detecção. Ela visa eventos críticos de eBPF classificados como apenas notificação (que não desencadearam isolamento automático ou congelamento de processo), além de detecções de adulteração de FIM de caminho crítico e arquivos de bloqueio de dependências. Quando ativado, o daemon primeiro gera um relatório de triagem inicial heurístico local (probabilidade de falso positivo, raciocínio, próximos passos sugeridos) e, em seguida, inicia a CLI de agente de IA configurada como subprocesso com esse relatório anexado, delegando investigação e resumo adicionais. Desativado por padrão.
# Adicionar a /etc/roamswitch/guard.yaml (um arquivo separado de server.conf)
investigation:
enabled: true
command: "claude" # "claude" | "agy" | "codex" | "opencode" | qualquer comando personalizado
args: ["-p"] # O prompt é adicionado automaticamente como o último argumento
timeout_secs: 180
As mesmas configurações também podem ser definidas no assistente interativo de sudo roamswitch server setup (§3.2, etapa final). Escolha entre predefinições para Claude Code (claude -p), agy (agy -p --dangerously-skip-permissions), Codex CLI (codex exec), OpenCode (opencode run), ou um comando personalizado. Ao executar novamente, a predefinição correspondente é selecionada automaticamente com base na configuração salva.
run_as não é guardada pelo assistente (CLI e TUI) e o daemon não a inicia. Lançar a ferramenta num modo que ignora as confirmações de permissões, como --dangerously-skip-permissions, aumenta o risco de uma entrada maliciosa levar o agente a ações não pretendidas. O assistente mostra este aviso ao escolher agy. Onde existam caminhos de entrada de registos não fiáveis, recomenda-se uma configuração de ferramenta que não ignore as confirmações de permissões.A delegação investigation nunca é chamada enquanto a rede está isolada (por exemplo, durante um Air-Gap ativo, ou qualquer estado equivalente a isolate_host_all).
11. Folha de referências do comando CLI
| Comando | Privilégios | Descrição |
|---|---|---|
sudo roamswitch status --server |
root | Mostrar a pontuação de segurança do servidor de 34 itens e o estado (--json imprime o mesmo relatório em JSON) |
sudo roamswitch ports |
root | Auditar portas de escuta abertas e processos vinculados |
sudo roamswitch fim verify |
root | Verifique a integridade SHA-256 dos arquivos do sistema de caminho crítico |
roamswitch notifications |
Usuário | Mostrar o histórico de notificações da última semana (todos os alertas enviados); são suportados --json e --export FILE |
sudo roamswitch server setup |
root | Iniciar assistente de configuração inicial interativo |
sudo roamswitch fim update |
root | Atualizar banco de dados de linha de base FIM SHA-256 |
sudo roamswitch server config set <key> <value> |
root | Altera e salva uma única chave de configuração (lista no §18) |
sudo roamswitch emergency-restore |
Raiz | Desarma todo o isolamento de eBPF/firewall e restaura a linha de base inicial |
roamswitch port-scan |
Usuário | Mostra o histórico de detecção da proteção de detecção de varredura de portas de entrada (§4.3) (IP de origem, se foi bloqueado automaticamente e a duração do bloqueio) |
roamswitch sensor [key|list|pair|unpair|request-audit|results] |
Usuário/root | Confiança mútua com um RoamSwitch Sensor através de códigos de emparelhamento. pair --addr <IP> --code <code> --fingerprint <SHA-256> emparelha (a impressão digital é o valor apresentado no ecrã do Sensor), repin atualiza a fixação depois de o Sensor ter regenerado o seu certificado e request-audit pede uma auditoria ativa de vulnerabilidades (obtenha o resultado com results). Requer sensor_pairing_enabled: true (desativado por predefinição). Consulte o Manual de Operações do Sensor para mais detalhes |
roamswitch server tui |
Usuário/root | Iniciar a TUI que cobre todas as funções (só de leitura para utilizadores comuns, controlo total como root; §17) |
sudo roamswitch server ack |
root | Reconhecer o isolamento de emergência atual (mantém um isolamento FULL estrito, liberta um DEGRADED; §4.1) |
roamswitch server ebpf |
Usuário | Mostrar o estado atual de contenção da proteção de runtime eBPF e o histórico de incidentes detetados |
roamswitch server bans [--json] |
Usuário/root | Mostra a guarda contra força bruta SSH (§4.5): o seu estado e as origens bloqueadas neste momento com o tempo restante. Aceita --json. A lista de bloqueios só pode ser lida por root |
sudo roamswitch server unban <IP | IPv6 /64 | --all> |
root | Levanta um bloqueio da guarda SSH e apaga o contador de falhas dessa origem (indique uma origem IPv6 pelo seu /64; --all levanta todos os bloqueios) |
sudo roamswitch server allowlist [list|add <rule> <process> [--exe <path>]|remove <rule> <process>] |
root | Gerir a lista de permissões permanente de falsos positivos. Com --exe, a entrada fica associada ao caminho real do executável, para que um processo renomeado não a possa usar (uma entrada só com o nome pode ser falsificada, e é impresso um aviso) |
roamswitch frozen [list|resume <PID>|resume all] |
Usuário/root | Listar os processos que as proteções mantêm em SIGSTOP e libertar um que tenha sido um falso positivo (SIGCONT); resume all liberta todos |
sudo roamswitch events search|tree|export|verify|status |
root | Pesquisar o gravador de execuções (--since 2h --pid --exe --user --parent --text --json), imprimir uma árvore de processos, exportar, verificar a cadeia de hashes e mostrar o estado (§15) |
sudo roamswitch forward status|test|queue |
root | Mostrar o estado do reencaminhamento de eventos, enviar um evento de teste e listar a fila de repetição (§16) |
roamswitch timeline / notifications [--json] [--export FILE] |
Usuário | Mostrar a cronologia unificada de incidentes (experimental) ou o histórico de notificações; --json imprime um array JSON e --export FILE grava JSON Lines |
roamswitch audit-agent-setup [--json] |
Usuário | Verificação só de leitura dos ficheiros de instruções, skills e definições do OpenClaw dados a agentes de IA em busca de conteúdo de risco (só a pasta pessoal, sem rede; --json imprime JSON). Disponível também em «Ferramentas» do Server TUI |
12. Solução de problemas e perguntas frequentes
Q1. O RoamSwitch desconectará inesperadamente minha sessão SSH?
Não. Em funcionamento normal, o RoamSwitch permite incondicionalmente os estados de ligação established/related e ssh_ports (22 por predefinição). Mesmo quando um ataque grave desencadeia um isolamento de emergência Air-Gap, preserve_ssh_on_isolation=true (a predefinição) mantém as sessões de gestão nas portas SSH de manutenção e nos IPs de administração (todas as outras ligações estabelecidas são cortadas). A edição de servidor até à 1.10.4 tinha um defeito. As regras de isolamento descartavam as respostas SSH, pelo que o SSH do operador não funcionava durante o isolamento. Foi corrigido na 1.10.5.
Q2. Como posso recuperar o acesso se for bloqueado acidentalmente?
Faça login pelo console web do seu provedor de nuvem (VNC / console serial) e execute sudo roamswitch emergency-restore para desarmar o isolamento, ou sudo systemctl stop roamswitch-server para parar o serviço.
Q3. Como exponho portas para serviços da Web recém-adicionados (por exemplo, Nginx)?
Execute sudo roamswitch server config set allowed_ports 80,443,3000 (ou edite diretamente /etc/roamswitch/server.conf) e depois execute sudo roamswitch server restart.
13. File Scan Guard (protegendo relés de e-mail, pastas compartilhadas e pontos de upload)
Um recurso opcional relevante apenas se este host tiver um diretório que armazena arquivos para terceiros — um relé de e-mail, um compartilhamento Samba/NFS, um ponto de upload de arquivos. O mecanismo YARA integrado sempre varre clamav_scan_dirs sem dependência externa; definir clamav_enabled=true adiciona o ClamAV como uma segunda opinião. Ameaças confirmadas são automaticamente colocadas em quarentena em /var/lib/roamswitch/quarantine e o operador é notificado.
# --- File Scan Guard (ClamAV, opt-in) ---
# O mecanismo YARA integrado sempre varre clamav_scan_dirs incondicionalmente.
clamav_enabled=false # true habilita a inspeção adicional via clamdscan
clamav_scan_dirs= # Caminhos absolutos para verificar (separados por vírgula)
clamav_scan_interval_secs=86400 # Intervalo de verificação (segundos, mínimo 3600)
clamav_freshclam_interval_secs=7200 # Intervalo de atualização automática do banco de assinaturas (segundos, mínimo 1800)
Também configurável pelo assistente interativo sudo roamswitch server setup; verifique a configuração e o status da quarentena pela ferramenta MCP get_file_scan_guard_status.
14. Log Audit (deteção e notificação de anomalias de padrões de registo)
Uma verificação periódica do journalctl transforma as mensagens de registo em modelos para detetar padrões novos (formas de registo nunca vistas) e anomalias de frequência (um pico estatístico, Z-score > 3.0). É um mecanismo leve que não requer nenhum daemon adicional nem dependência externa, pelo que está ativado por predefinição. As deteções são enviadas através dos mesmos canais de notificação que o File Scan Guard e o FIM (Telegram / LINE / Webhook). Quaisquer chaves API ou tokens que possam aparecer numa linha de registo são automaticamente mascarados antes de serem incluídos na notificação.
# --- Log Audit (ativado por predefinição) ---
log_audit_enabled=true # false para desativar
log_audit_interval_secs=1800 # Intervalo de verificação em segundos (mínimo 300)
Também pode ser configurado a partir do assistente interativo sudo roamswitch server setup, e os resultados de deteção mais recentes podem ser consultados através do comando CLI roamswitch audit-logs ou da ferramenta MCP audit_security_logs.
AccessScope, uma ferramenta de diagnóstico de registos de acesso (ferramenta independente): o deb / rpm da Server Edition inclui o comando accessscope de uma ferramenta independente que diagnostica os registos de acesso de servidores web e de SSH (a aplicação com janela não está incluída). É só de leitura, e a sua análise não usa nem um LLM nem a rede. A análise por um LLM é opcional e está desativada por predefinição (quando ativada, também pode correr como root, mas o LLM corre então com os privilégios de root; recomenda-se um utilizador sem privilégios). accessscope scan --auto diagnostica os registos deste anfitrião e accessscope discover lista onde estão os registos. Consulte a página do AccessScope para mais detalhes. Os deb / rpm da Server Edition incluem também os comandos personalsoc e pathscope de duas outras ferramentas separadas, PersonalSOC (verifica os registos e as defesas deste anfitrião) e PathScope (analisa caminhos de escalada de privilégios); as aplicações com janela não estão incluídas. Os próprios comandos não fazem comunicação de rede. A análise por LLM do PersonalSOC só é executada se indicar --llm.
15. Gravador de execuções e regras de correlação (local, apenas notificação)
As execuções de processos (exec) são registadas através do proc connector do netlink: executável, argumentos, linhagem de processos pai, UID, cwd, ID do contentor e SHA-256. Está ativado por predefinição, e os registos são guardados no diretório /var/lib/roamswitch/exec_log, acessível apenas a root, neste anfitrião, como JSON Lines segmentado e com cadeia de hashes (0600, 200 MB / 14 dias por predefinição), e nunca são enviados para lado nenhum. O registo é evidente quanto a adulteração (events verify), não à prova de adulteração. Se não for possível abrir o proc connector, degrada para uma análise de /proc a baixa frequência. O registo corre em threads próprias, separadas do ciclo de eventos de permissão do fanotify, e mantém o seu próprio consumo de CPU dentro de um orçamento (3% por predefinição).
Pesquise e exporte localmente (o registo é acessível apenas a root, por isso normalmente é necessário sudo).
sudo roamswitch events status
sudo roamswitch events search --since 2h --exe curl
sudo roamswitch events tree 4242
sudo roamswitch events export --since 1d > exec-events.jsonl
sudo roamswitch events verify
Regras de correlação EXR-001 a EXR-007 (apenas notificação, cada uma com um ID de técnica MITRE ATT&CK): EXR-001 uma shell criada por um serviço web / EXR-002 execução a partir de /tmp, de um ficheiro apagado ou de memfd / EXR-003 execução logo após uma transferência / EXR-004 um one-liner de interpretador que usa base64 ou eval / EXR-005 obtenção de uid 0 sem setuid / EXR-006 execução de um binário acabado de colocar pelo cron ou pelo systemd / EXR-007 execução depois de ld.so.preload ter sido alterado. Cada regra tem uma predefinição deliberadamente discreta e nunca isola por si só. Silencie regras individuais com exec_rules_disabled (por exemplo EXR-003,EXR-004) e ajuste os utilizadores que a EXR-001 vigia com exec_rule_service_users.
Só se definir explicitamente exec_rules_isolation_optin (predefinição false) como true é que as regras de gravidade alta são tratadas como desencadeador de isolamento de alta confiança (§4.1). Por predefinição, as regras apenas notificam. Os registos também podem ser lidos através das ferramentas MCP de leitura search_exec_events e get_process_tree.
16. Reencaminhamento de eventos (SIEM / syslog / Webhook, opcional)
Os eventos de deteção podem ser reencaminhados para destinos que especificar na sua própria organização. Está desativado por predefinição: nada é enviado até definir forward_enabled=true e configurar pelo menos um destino, e não existe nenhum destino do fabricante incorporado. O que é reencaminhado são a cronologia de incidentes, o histórico de notificações, a proteção eBPF, as transições de estado de isolamento e os alertas de FIM, canary e regras de exec; o registo bruto de exec em si não é reencaminhado. Existem três tipos de destino.
- syslog (
forward_syslog_url:udp://host:514/tcp://host:port/tls://host:port): RFC 5424 ou CEF (forward_syslog_format). O enquadramento TCP / TLS éoctet(RFC 6587, a predefinição) oulf. Pode indicar uma CA para a verificação TLS comforward_tls_ca_file, e a ligação é delegada noopenssl s_clientdo sistema. - Ficheiro JSON Lines (
forward_file_path): um evento por linha, com rotação porforward_file_max_mb(50 por predefinição) eforward_file_keep(5 por predefinição). - Webhook estruturado (
forward_webhook_url): um POST JSON assinado com HMAC-SHA256 usando um segredo partilhado (forward_webhook_secret, ouforward_webhook_secret_filea apontar para um ficheiro0600), transportado no cabeçalhoX-RoamSwitch-Signature. O envio é feito por um subprocessocurl, e o segredo nunca é colocado na linha de comandos.
Os eventos que não puderam ser entregues (TCP / TLS / webhook) são colocados numa fila de repetição em disco (0600, limitada por forward_queue_max_mb, 20 por predefinição, e forward_queue_max_age_hours, 72 por predefinição) e repetidos com recuo exponencial, também após um reinício. forward_min_severity (predefinição low) define a gravidade mínima que é enviada. O envio corre numa thread dedicada, para que nenhum caminho crítico seja bloqueado, e quando a fila transborda os itens mais antigos são descartados primeiro.
Verifique o estado, teste a conectividade e inspecione a fila de repetição com os comandos seguintes (reinicie o serviço depois de alterar as definições).
# /etc/roamswitch/server.conf
forward_enabled=true
forward_syslog_url=tls://siem.example.org:6514
forward_syslog_format=rfc5424
forward_tls_ca_file=/etc/ssl/certs/corp-ca.pem
forward_min_severity=medium
sudo roamswitch server restart
sudo roamswitch forward status
sudo roamswitch forward test
sudo roamswitch forward queue
17. TUI do servidor (uma interface de terminal para todas as funções)
roamswitch-server-tui (também iniciada por roamswitch server tui) é uma TUI que dá acesso a todas as funções da Server Edition — repartidas pelos verbos da CLI e pelos dois ficheiros de configuração (server.conf e guard.yaml) — apenas com o teclado, por SSH (funciona em 80x24, em 10 idiomas). Os testes de desenvolvimento falham sempre que um verbo da CLI ou uma chave de configuração fica sem correspondente na TUI.
- Modo de permissões: iniciada como utilizador comum, fica em só de leitura (as alterações e as ações privilegiadas estão desativadas, e em vez disso é mostrado o comando
sudo roamswitch …de que precisaria). Iniciada como root, pode atuar; as operações de grande impacto mostram primeiro o que vão fazer, e as mais perigosas exigem que escrevayes. Nunca inicia o daemon e não abre nenhum socket de rede próprio. - Ecrãs (alterne com as teclas numéricas):
1Painel (saúde, estado de isolamento) /2Proteção (isolamento eBPF, canary, FIM, Docker, egress e DNS, gravador de execuções, regras e pesquisa de eventos, feeds, XDP gate) /3Incidentes (todos os tipos de incidente, incluindo a lista de bloqueios SSH e o seu levantamento, cronologia, histórico de notificações, processos congelados, cofre de quarentena, lista de permissões) /4Notificações e reencaminhamento /5Sensor /6Configuração /7Serviço /8Ferramentas /9Auditoria de registos /0Acerca de e ajuda.?mostra as teclas do ecrã atual,Lpercorre os 10 idiomas,rrecarrega eqsai (perguntando antes se há alterações de configuração por guardar). - Editor de configuração: gerado a partir de um esquema, edita as 146 chaves de
server.confeguard.yaml(§18) com validação do tipo, do intervalo e dos valores permitidos. Revê um diff (com os segredos mascarados) antes de guardar, e ao guardar é feita uma cópia de segurança com marca temporal e a escrita é atómica. As chaves que exigem reinício, e as chaves em que um valor errado pode cortar-lhe o acesso ou enfraquecer a proteção, estão assinaladas. A configuração do agente de investigação (§10.1) também pode ser escrita, depois de escolher uma predefinição e de a pré-visualizar.
Inicie-a com:
sudo roamswitch-server-tui # full control
roamswitch-server-tui # read-only
roamswitch server tui # same as roamswitch-server-tui
18. Referência das chaves de configuração (server.conf / guard.yaml)
O roamswitch-server não suporta o recarregamento da configuração: todas as chaves exigem um reinício do serviço para entrarem em vigor (sudo roamswitch server restart). Altere as chaves de server.conf com roamswitch server config set <key> <value> ou com o editor da §17; altere o guard.yaml com o editor ou editando-o à mão.
18.1 server.conf (109 chaves)
| Chave | Tipo / valores | Predefinição | Reinício |
|---|---|---|---|
language | system | ja | en | zh-hans | zh-hant | ko | de | fr | es | it | pt | ja | Sim |
ssh_ports | port list | 22 | Sim |
allowed_ports | port list | 80,443 | Sim |
whitelist_ips | list | — | Sim |
preserve_ssh_on_isolation | bool | true | Sim |
telegram_enabled | bool | false | Sim |
telegram_bot_token | string | — | Sim |
telegram_chat_id | string | — | Sim |
line_enabled | bool | false | Sim |
line_channel_access_token | string | — | Sim |
line_user_id | string | — | Sim |
webhook_enabled | bool | false | Sim |
webhook_url | URL | — | Sim |
webhook_block_private_addresses | bool | false | Sim |
webhook_allow_addresses | CIDR list | — | Sim |
action_on_critical | isolate | freeze | alert_only | isolate | Sim |
ebpf_socket_path | abs path | /run/roamswitch/events.sock | Sim |
ebpf_heartbeat_interval_secs | 0 (off) | int 60–86400 | 600 | Sim |
isolation_hard_cap_secs | int ≥ 0 | 3600 | Sim |
fim_check_interval_secs | int ≥ 10 | 300 | Sim |
fim_intrusion_context_enabled | bool | true | Sim |
protect_docker_ports | bool | true | Sim |
dns_sinkhole_enabled | bool | false | Sim |
dns_sinkhole_provider | quad9 | cloudflare | adguard | cleanbrowsing | quad9 | Sim |
egress_ip_blocklist_enabled | bool | true | Sim |
metadata_watch_enabled | bool | true | Sim |
metadata_watch_allow_users | list | — | Sim |
cve_kernel_map_updates_enabled | bool | true | Sim |
clamav_enabled | bool | false | Sim |
clamav_scan_dirs | abs path list | — | Sim |
clamav_scan_interval_secs | int ≥ 3600 | 86400 | Sim |
clamav_freshclam_interval_secs | int ≥ 1800 | 7200 | Sim |
lockfile_watch_dirs | abs path list | — | Sim |
npm_audit_signatures_enabled | bool | false | Sim |
log_audit_enabled | bool | true | Sim |
log_audit_interval_secs | int ≥ 300 | 1800 | Sim |
resource_guard_enabled | bool | true | Sim |
resource_guard_rss_sample_interval_secs | int ≥ 10 | 60 | Sim |
resource_guard_rss_window_secs | int ≥ 300 | 1800 | Sim |
resource_guard_rss_min_samples | int ≥ 3 | 10 | Sim |
resource_guard_rss_min_growth_pct | int ≥ 10 | 50 | Sim |
resource_guard_rss_recovery_drop_pct | int ≥ 1 | 10 | Sim |
resource_guard_rss_min_kb | int ≥ 0 | 20000 | Sim |
resource_guard_crash_loop_window_secs | int ≥ 60 | 300 | Sim |
resource_guard_crash_loop_min_restarts | int ≥ 2 | 3 | Sim |
resource_guard_correlation_window_secs | int ≥ 60 | 600 | Sim |
resource_guard_zombie_min_count | int ≥ 0 | 20 | Sim |
resource_guard_load_min_normalized | float ≥ 0.0 | 0.5 | Sim |
resource_guard_load_enabled | bool | true | Sim |
resource_guard_cpu_enabled | bool | true | Sim |
resource_guard_cpu_sample_interval_secs | int ≥ 0 | 60 | Sim |
resource_guard_cpu_window_secs | int ≥ 0 | 600 | Sim |
resource_guard_cpu_min_samples | int ≥ 0 | 8 | Sim |
resource_guard_cpu_pct_threshold | float 0.0–1000.0 | 80.0 | Sim |
container_exec_guard_enabled | bool | true | Sim |
port_scan_detect_enabled | bool | true | Sim |
port_scan_detect_min_distinct_ports | int ≥ 0 | 15 | Sim |
port_scan_detect_window_secs | int ≥ 0 | 300 | Sim |
port_scan_block_enabled | bool | true | Sim |
port_scan_block_duration_secs | int ≥ 0 | 600 | Sim |
ssh_guard_enabled | bool | true | Sim |
ssh_guard_block_enabled | bool | true | Sim |
ssh_guard_max_failures | int 2–1000 | 6 | Sim |
ssh_guard_window_secs | int 10–86400 | 600 | Sim |
ssh_guard_ban_secs | int 60–2592000 | 3600 | Sim |
ssh_guard_ban_max_secs | int 60–31536000 | 604800 | Sim |
ssh_guard_allow | IP/CIDR list | — | Sim |
ssh_guard_log_source | auto | journal | abs path | auto | Sim |
ssh_guard_yield_to_fail2ban | bool | true | Sim |
ssh_guard_trust_key_days | int 0–3650 | 30 | Sim |
dns_tunnel_detect_enabled | bool | true | Sim |
reverse_shell_watch_enabled | bool | true | Sim |
reverse_shell_watch_include_private | bool | false | Sim |
reverse_shell_watch_notify_only | bool | false | Sim |
sensor_pairing_enabled | bool | false | Sim |
sensor_colocated | bool | false | Sim |
forward_enabled | bool | false | Sim |
forward_syslog_url | URL | — | Sim |
forward_syslog_format | rfc5424 | cef | rfc5424 | Sim |
forward_syslog_framing | octet | lf | octet | Sim |
forward_tls_ca_file | abs path | — | Sim |
forward_file_path | abs path | — | Sim |
forward_file_max_mb | int 1–10000 | 50 | Sim |
forward_file_keep | int 1–100 | 5 | Sim |
forward_webhook_url | URL | — | Sim |
forward_webhook_secret | string | — | Sim |
forward_webhook_secret_file | abs path | — | Sim |
forward_webhook_block_private_addresses | bool | false | Sim |
forward_webhook_allow_addresses | CIDR list | — | Sim |
forward_min_severity | info | low | medium | high | critical | low | Sim |
forward_queue_max_mb | int 1–10000 | 20 | Sim |
forward_queue_max_age_hours | int 1–8760 | 72 | Sim |
exec_recorder_enabled | bool | true | Sim |
exec_recorder_retention_mb | int 1–100000 | 200 | Sim |
exec_recorder_retention_days | int 1–3650 | 14 | Sim |
exec_recorder_hash_chain | bool | true | Sim |
exec_recorder_hash_exe | bool | true | Sim |
exec_recorder_cpu_budget_pct | int 1–50 | 3 | Sim |
exec_rules_enabled | bool | true | Sim |
exec_rules_disabled | string | — | Sim |
exec_rule_service_users | string | — | Sim |
exec_rule_window_secs | int 5–3600 | 120 | Sim |
exec_rules_isolation_optin | bool | false | Sim |
honeytokens_enabled | bool | true | Sim |
honeytokens_home | abs path | /root | Sim |
harden_userns_enabled | bool | true | Sim |
dns_tunnel_entropy_allowlist | list | — | Sim |
fleet_forwarding_allowed_hosts | list | — | Sim |
fleet_forwarding_allow_plaintext | bool | false | Sim |
18.2 guard.yaml (37 chaves)
| Chave | Tipo / valores | Predefinição | Reinício |
|---|---|---|---|
sensor.type | falco | tetragon | falco | Sim |
sensor.transport | string | unix_socket | Sim |
sensor.socket_path | abs path | /run/roamswitch/events.sock | Sim |
sensor.reconnect_interval_ms | int 100–3600000 | 1000 | Sim |
policies.on_warning.action | log_and_notify | isolate_process | isolate_host_all | log_and_notify | Sim |
policies.on_warning.server_action | log_and_notify | isolate_process | isolate_host_all | — | Sim |
policies.on_warning.kill_process | bool | false | Sim |
policies.on_warning.freeze_process | bool | false | Sim |
policies.on_warning.fallback_to_host_isolation_after_retries | int 0–1000 | — | Sim |
policies.on_error.action | log_and_notify | isolate_process | isolate_host_all | isolate_process | Sim |
policies.on_error.server_action | log_and_notify | isolate_process | isolate_host_all | — | Sim |
policies.on_error.kill_process | bool | false | Sim |
policies.on_error.freeze_process | bool | false | Sim |
policies.on_error.fallback_to_host_isolation_after_retries | int 0–1000 | — | Sim |
policies.on_critical.action | log_and_notify | isolate_process | isolate_host_all | isolate_process | Sim |
policies.on_critical.server_action | log_and_notify | isolate_process | isolate_host_all | — | Sim |
policies.on_critical.kill_process | bool | true | Sim |
policies.on_critical.freeze_process | bool | false | Sim |
policies.on_critical.fallback_to_host_isolation_after_retries | int 0–1000 | 3 | Sim |
policies.on_emergency.action | log_and_notify | isolate_process | isolate_host_all | isolate_host_all | Sim |
policies.on_emergency.server_action | log_and_notify | isolate_process | isolate_host_all | — | Sim |
policies.on_emergency.kill_process | bool | true | Sim |
policies.on_emergency.freeze_process | bool | false | Sim |
policies.on_emergency.fallback_to_host_isolation_after_retries | int 0–1000 | — | Sim |
server_safeguards.allow_established_connections | bool | true | Sim |
server_safeguards.maintenance_ssh_ports | port list | 22 | Sim |
server_safeguards.whitelist_cidrs | list | — | Sim |
server_safeguards.whitelist_dns_servers | list | — | Sim |
server_safeguards.safety_timer_secs | int ≥ 0 | 300 | Sim |
adaptive_security.enabled | bool | true | Sim |
adaptive_security.untrusted_network_actions.elevate_falco_profile | string | — | Sim |
adaptive_security.untrusted_network_actions.auto_enable_userns_restriction | bool | false | Sim |
investigation.enabled | bool | false | Sim |
investigation.command | abs path | — | Sim |
investigation.args | list | — | Sim |
investigation.run_as | string | — | Sim |
investigation.timeout_secs | int 1–86400 | 180 | Sim |
19. Deteção de web shells e código injetado (Web Rules)
Esta função deteta web shells PHP, JavaScript, JSP e ASP e código injetado que correm no seu servidor web, PHP escondido em imagens e abusos de .htaccess (a partir do Linux 1.11.23). Não é preciso configurar nada: encontra as raízes de documentos na configuração do Apache, nginx e Caddy e verifica um ficheiro logo após ser escrito e fechado (com fanotify só de notificação, que nunca pode bloquear outro processo). Uma análise periódica de 6 em 6 horas cobre os eventos perdidos e os ficheiros anteriores ao arranque. O ClamAV não é necessário.
O comportamento define-se em /etc/roamswitch/web_rules.conf (dono root, modo 0644; um ficheiro que outros possam escrever é ignorado). Aplique uma alteração com sudo roamswitch server restart. Um modelo imprime-se com roamswitch web-rules example conf.
| Chave | Significado (predefinição) |
|---|---|
quarantine | Nível de quarentena automática. off nunca põe em quarentena, critical só critical, high critical e high (predefinição: critical). Um resultado high com o nível critical só notifica e aciona o hook; o ficheiro não é tocado. |
account_action | Indica se se revoga a shell de início de sessão do dono de um ficheiro detetado. off / revoke_shell (predefinição: off). Só contam os resultados critical ou high postos em quarentena. Nunca se toca em root, em UID abaixo de account_min_uid, em utilizadores com sessão iniciada nem no utilizador do daemon. A shell anterior é registada e sudo roamswitch web-rules unlock-account <utilizador> repõe-na. |
account_min_uid | account_min_uid: o UID mais baixo sobre o qual a resposta sobre contas pode atuar (1000 por predefinição; não pode descer abaixo de 100). |
scan_dirs, auto_docroots, watch, scan_interval_secs | scan_dirs (caminhos absolutos separados por vírgulas), auto_docroots (predefinição true; false pára a descoberta automática a partir da configuração do servidor web), watch (predefinição true; false desliga a vigilância de escritas e deixa só a análise periódica) e scan_interval_secs (predefinição 21600, mínimo 3600). |
# /etc/roamswitch/web_rules.conf
quarantine=critical
account_action=off
account_min_uid=1000
#scan_dirs=/srv/sites/a,/srv/sites/b
auto_docroots=true
watch=true
scan_interval_secs=21600
Uma deteção envia uma notificação (Telegram, LINE, webhook) que nomeia a regra e indica se o ficheiro foi posto em quarentena ou deixado. Para ver sem mover nada, use sudo roamswitch web-scan <pasta> (só consulta; --quarantine para quarentena) ou o ecrã Ferramentas da TUI do servidor. As suas regras ficam em /etc/roamswitch/rules.d/*.json. Para chamar o seu script após uma deteção, coloque-o em /etc/roamswitch/hooks/post-detection (o resultado chega como JSON na entrada padrão; só é executado um ficheiro pertencente a root, não escrevível por outros e num diretório seguro; sem shell e com paragem aos 30 segundos). As atualizações das regras vão na atualização diária só de receção. Com cve_kernel_map_updates_enabled desativado não há qualquer contacto de rede e usam-se as regras integradas.