Mapa da aula
Aula 06 publicada. Mapa, exemplo, EX016.
flowchart TD
N0["6.1 Endurecimento como subtração"]
N1["6.2 Contas de serviço e menor privilégio"]
N2["6.3 Os arquivos de configuração são relevantes para"]
N3["6.4 Linhas de base de integridade de arquivos"]
N4["6.5 Virtualização"]
N5["6.7 Atividade prática: linha de base de integridade"]
N6["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6
N6 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX016"]
Desenho lógico
flowchart LR
N0["6.1 Endurecimento como subtração"]
N1["6.2 Contas de serviço e menor privilégio"]
N2["6.3 Os arquivos de configuração são relevantes para"]
N3["6.4 Linhas de base de integridade de arquivos"]
N4["6.5 Virtualização"]
N5["6.7 Atividade prática: linha de base de integridade"]
N6["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> Q["EX016"]
[6.1 Endurecimento como subtração]
|
v
[6.2 Contas de serviço e menor privilégio]
|
v
[6.3 Os arquivos de configuração são relevantes para]
|
v
[6.4 Linhas de base de integridade de arquivos]
|
v
[6.5 Virtualização]
|
v
[6.7 Atividade prática: linha de base de integridade]
|
v
[Síntese do capítulo]
|
v
[Exemplo resolvido] --> [Exercício EX016]
Objetivos de aprendizagem e conexão
Depois deste capítulo, você deve ser capaz de:
- endurecer um servidor removendo o que ele não precisa e restringindo o que ele precisa;
- executar um serviço sob uma conta dedicada e sem privilégios, com apenas os arquivos e as portas de que ele precisa;
- construir e usar uma linha de base de integridade de arquivos para detectar mudanças não aprovadas;
- explicar o que a virtualização muda para a segurança — e o que ela não muda.
Os relays e o historiador do LANTERN são servidores comuns. A maioria dos comprometimentos desses servidores, e muitas interrupções, não vêm de falhas exóticas, mas de coisas deixadas neles: um serviço não usado escutando em todas as interfaces, uma opção de depuração, um arquivo gravável por todos, uma conta antiga. Este capítulo trata de manter um servidor pequeno, conhecido e verificável.
6.1 Endurecimento como subtração
Endurecer (hardening) significa reduzir um sistema ao que a sua função exige e configurar com segurança o que sobra. O guia de segurança de servidores do NIST recomenda remover ou desabilitar serviços, aplicações e protocolos de rede desnecessários, configurar a autenticação e os controles de recursos, e manter o sistema com patches e monitorado (NIST SP 800-123). Para um relay, isso significa: nenhum ambiente de desktop, nenhum compilador, nenhum serviço de compartilhamento de arquivos, SSH escutando apenas na interface de gerenciamento, o processo do relay escutando apenas no seu endereço e porta declarados, e nada escutando em 0.0.0.0 sem um motivo registrado por escrito.
6.2 Contas de serviço e menor privilégio
Execute cada serviço com a sua própria conta sem privilégios (relay, e não root). Dê a essa conta acesso de leitura à sua configuração, acesso de escrita apenas aos seus próprios diretórios de dados e de logs, e nenhum login de shell. Use o gerenciador de serviços do sistema operacional para reiniciá-lo em caso de falha e para aplicar restrições adicionais (por exemplo, uma visão somente leitura da maior parte do sistema de arquivos). Se o processo do relay um dia for comprometido, essas escolhas determinam se o atacante fica com um serviço ou com o host inteiro.
No RLY-01, essa é a definição de serviço cujas permissões mudaram para 0666.
6.3 Os arquivos de configuração são relevantes para a segurança
Num relay, os arquivos mais relevantes para a segurança são a sua configuração (onde ele escuta, para onde encaminha, onde fica a sua chave), a sua allowlist de estações e a sua definição de serviço (com qual conta ele roda, com quais restrições). Uma mudança em qualquer um deles muda a segurança do serviço. As permissões dos arquivos importam tanto quanto o conteúdo: uma definição de serviço que passou a ser gravável por qualquer usuário permite que qualquer usuário local decida o que roda como o serviço.
O RLY-01 mostrou os dois tipos: uma mudança de conteúdo, debug_listen 0.0.0.0:9000, e uma mudança de permissão para 0666.
6.4 Linhas de base de integridade de arquivos
Uma linha de base de integridade de arquivos registra um hash criptográfico e as permissões de cada arquivo importante num momento sabidamente bom. Os retratos posteriores são comparados com ela; toda diferença ou é explicada por um registro de mudança aprovado, ou é investigada. O SHA-256, especificado na FIPS 180-4, é uma escolha padrão: qualquer mudança no conteúdo do arquivo muda o seu digest. A própria linha de base precisa ser protegida — guardada fora do host ou assinada —, porque um atacante que consegue mudar um arquivo e a linha de base consegue esconder a mudança.
6.5 Virtualização
A virtualização executa vários sistemas operacionais num único host físico por meio de um hipervisor. Ela ajuda a operação — snapshots, reconstruções rápidas, convidados separados para funções separadas — e cria coisas novas a proteger. O guia do NIST sobre virtualização completa observa que o hipervisor e as suas interfaces de gerenciamento se tornam alvos de alto valor, e que os convidados num mesmo host compartilham recursos físicos e podem afetar uns aos outros (NIST SP 800-125). Consequências práticas: a rede de gerenciamento do hipervisor é uma zona própria; quem administra o hipervisor administra, na prática, todos os convidados; os snapshots contêm segredos e precisam ser protegidos como backups; e colocar um relay voltado às estações e um servidor de relatórios voltado ao corporativo no mesmo host une duas zonas por meio de hardware compartilhado e de um administrador compartilhado.
6.6 Exemplo resolvido: uma linha de base pega um listener de depuração (sintético)
Você faz a linha de base dos três arquivos de configuração do RLY-01. Uma semana depois, a comparação mostra quatro diferenças. A allowlist ganhou PS-11 sob a mudança aprovada CHG-118 — explicada. A configuração do relay ganhou debug_listen 0.0.0.0:9000 sem registro de mudança: alguém habilitou uma porta de depuração em todas as interfaces, talvez durante uma resolução de problemas, e a deixou. As permissões da definição de serviço mudaram de 0640 para 0666: qualquer usuário local agora pode reescrevê-la. Um novo arquivo helper.sh apareceu no diretório de units. Três mudanças não aprovadas num host crítico são uma investigação, e não uma arrumação: antes de reverter qualquer coisa, preserve os arquivos atuais e a saída da comparação, e pergunte quem mudou o quê (Capítulo 20).
6.7 Atividade prática: linha de base de integridade de arquivos
Laboratório 6 (salve como lab06.py, execute com python3 lab06.py):
# Lab 6 - a file-integrity baseline for the relay host's configuration (offline, standard library only)
# Synthetic files are created in a temporary directory; nothing outside it is read or changed.
import hashlib, json, os, tempfile
def digest(path):
h = hashlib.sha256()
with open(path, "rb") as f:
for block in iter(lambda: f.read(65536), b""):
h.update(block)
return h.hexdigest()
def snapshot(root):
out = {}
for d, _, files in os.walk(root):
for name in sorted(files):
p = os.path.join(d, name)
st = os.stat(p)
out[os.path.relpath(p, root)] = {"sha256": digest(p), "mode": oct(st.st_mode & 0o777)}
return out
with tempfile.TemporaryDirectory() as root:
files = {"relay.conf": "listen 10.30.0.5:8443\nupstream hist-01:443\nhmac_key_file /etc/relay/key\n",
"allow.list": "PS-04\nPS-07\nPS-09\n", "units/relay.service": "[Service]\nUser=relay\n"}
for rel, text in files.items():
p = os.path.join(root, rel); os.makedirs(os.path.dirname(p), exist_ok=True)
with open(p, "w") as f: f.write(text)
os.chmod(p, 0o640)
base = snapshot(root)
print("baseline entries:", len(base), "| relay.conf", base["relay.conf"]["sha256"][:16])
# simulated changes: one approved (change ticket CHG-118), one not, one permission change, one new file
with open(os.path.join(root, "allow.list"), "a") as f: f.write("PS-11\n")
with open(os.path.join(root, "relay.conf"), "a") as f: f.write("debug_listen 0.0.0.0:9000\n")
os.chmod(os.path.join(root, "units/relay.service"), 0o666)
with open(os.path.join(root, "units/helper.sh"), "w") as f: f.write("#!/bin/sh\n")
approved = {"allow.list": "CHG-118"}
now = snapshot(root)
for rel in sorted(set(base) | set(now)):
b, n = base.get(rel), now.get(rel)
if b == n: continue
kind = "added" if b is None else "removed" if n is None else "content" if b["sha256"] != n["sha256"] else "mode " + b["mode"] + "->" + n["mode"]
print(f"{rel:<20} {kind:<16} {'approved ' + approved[rel] if rel in approved else 'UNAPPROVED - investigate'}")
print("baseline json bytes:", len(json.dumps(base, sort_keys=True)))
Saída esperada (Python 3.13.5):
baseline entries: 3 | relay.conf 1defd9289ede0120
allow.list content approved CHG-118
relay.conf content UNAPPROVED - investigate
units/helper.sh added UNAPPROVED - investigate
units/relay.service mode 0o640->0o666 UNAPPROVED - investigate
baseline json bytes: 342
O script cria os seus arquivos num diretório temporário, então você pode executá-lo em qualquer lugar. Note que o digest impresso para relay.conf depende apenas do conteúdo do arquivo: se você mudar um caractere do conteúdo sintético no script, o digest muda por completo.
Compare a saída com a semana do RLY-01 descrita acima: quatro diferenças, das quais apenas a entrada PS-11 da allowlist, sob a CHG-118, tem registro de mudança. Depois faça uma edição sua dentro do script, por exemplo acrescentar uma segunda linha de depuração ou mudar um modo de 0640 para 0644, execute-o de novo e confirme que a comparação relata exatamente essa diferença e nada mais. Uma linha de base que relata mais ou menos do que você mudou ainda não é confiável o bastante para servir de evidência numa investigação.
6.8 Erros comuns e limites
- Endurecer uma vez, na construção, e nunca mais conferir.
- Executar serviços como root "porque foi mais fácil fazer funcionar".
- Manter a linha de base de integridade no mesmo host, gravável pelos mesmos administradores.
- Alertar sobre toda mudança de arquivo num sistema movimentado, de modo que os alertas sejam ignorados; faça a linha de base dos arquivos que importam.
- Tratar um snapshot como backup sem testar a restauração, ou deixar desprotegidos snapshots com chaves dentro.
- Colocar convidados de zonas diferentes num mesmo hipervisor sem registrar que as zonas agora compartilham uma falha e um administrador.
A integridade de arquivos detecta mudanças; ela não diz se a mudança foi maliciosa, e nada diz sobre mudanças em memória ou em arquivos que você não incluiu na linha de base.
Exercícios — capítulo 6
EX016 — Revisão de endurecimento. Objetivo: aplicar o endurecimento como subtração. Entradas: uma listagem sintética do RLY-02: escutando em 0.0.0.0:22, 10.30.0.6:8443, 0.0.0.0:9000, 0.0.0.0:111; os pacotes instalados incluem um compilador e um ambiente de desktop; o relay roda como root. Restrições: apenas proponha mudanças; cada uma precisa de um motivo. Etapas: (1) liste todas as mudanças; (2) marque quais precisam de um ticket de mudança e quais podem ser feitas na próxima mudança padrão. Evidência esperada: tabela. Rubrica: 3 = SSH vinculado à interface de gerenciamento, depuração 9000 removida, porta 111 (RPC) desabilitada, compilador e desktop removidos, relay movido para uma conta sem privilégios com restrições; classificação sensata das mudanças; 2 = a maioria; 1 = genérico; 0 = nada.
EX017 — Proteja a linha de base. Objetivo: projetar o armazenamento da linha de base. Entradas: Laboratório 6. Restrições: dois projetos. Etapas: (1) descreva guardar a linha de base fora do host, num local de gravação única; (2) descreva assinar a linha de base com uma chave que não fica no relay; (3) compare contra o que cada um protege. Evidência esperada: meia página. Rubrica: 3 = os dois projetos corretos; observa que um atacante com root no relay consegue mudar arquivos, mas não consegue mudar sem ser detectado uma linha de base fora do host ou assinada; observa que a ferramenta de comparação no próprio host pode ser subvertida, então a comparação também deve rodar de fora; 2 = um projeto; 1 = vago; 0 = nada.
EX018 — Posicionamento no hipervisor. Objetivo: raciocinar sobre plataformas compartilhadas. Entradas: proposta de executar o RLY-01 (voltado às estações), o HIST-01 (voltado ao corporativo) e o gateway clínico do hospital como convidados num único hipervisor da FSTS, para economizar. Restrições: não rejeite automaticamente; declare condições. Etapas: (1) liste o que as zonas passariam a compartilhar; (2) liste as condições sob as quais você aceitaria; (3) nomeie o risco residual e o seu dono. Evidência esperada: uma página. Rubrica: 3 = hardware, administradores do hipervisor, rede de gerenciamento e armazenamento compartilhados, e um ponto único de falha atravessando dois setores; condições como zona de gerenciamento separada, grupo de administradores restrito com MFA, redes virtuais separadas sem ponte, folga de capacidade documentada e um plano para a perda do host; risco residual assumido por donos de serviço nomeados; 2 = parcial; 1 = sim/não seco; 0 = nada.
Síntese do capítulo
Mantenha os servidores pequenos e conhecidos: remova o que a função não precisa, execute os serviços sob contas dedicadas e sem privilégios, vincule os listeners a endereços declarados e trate os arquivos de configuração e as suas permissões como relevantes para a segurança. Faça a linha de base dos arquivos que importam com um hash criptográfico, proteja a linha de base e investigue toda diferença sem explicação. A virtualização simplifica a operação, mas concentra o controle no hipervisor e nos seus administradores; registre quais zonas compartilham um host.