Capítulo 3 — Sistemas operacionais e identidades
Mapa da aula
Aula 03 publicada. Mapa, exemplo, EX009.
flowchart TD
N0["3.1 O que endurecimento significa no nível do técnic"]
N1["3.2 Ler corretamente a configuração do sshd"]
N2["3.3 Contas e identidades"]
N3["3.5 Atividade prática"]
N4["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX009"]
Desenho lógico
flowchart LR
N0["3.1 O que endurecimento significa no nível do técnic"]
N1["3.2 Ler corretamente a configuração do sshd"]
N2["3.3 Contas e identidades"]
N3["3.5 Atividade prática"]
N4["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX009"]
[3.1 O que endurecimento significa no nível do técnic]
|
v
[3.2 Ler corretamente a configuração do sshd]
|
v
[3.3 Contas e identidades]
|
v
[3.5 Atividade prática]
|
v
[Síntese do capítulo]
|
v
[Exemplo resolvido] --> [Exercício EX009]
Objetivos de aprendizagem e conexão
Ao final deste capítulo, você deverá ser capaz de:
- auditar um host Linux que dá suporte a um serviço de controle: serviços em escuta, configurações do daemon SSH, contas locais e grupos privilegiados;
- explicar por que o
sshdadota o primeiro valor que lê para a maioria das palavras-chave, e como isso derrota edições descuidadas; - identificar contas equivalentes a root, contas de serviço com shells interativos e contas que nenhuma pessoa atual possui;
- transformar as constatações numa mudança de endurecimento priorizada que não tranque os operadores do lado de fora.
Os Capítulos 1–2 descreveram o serviço e o seu tráfego. Os servidores do centro de controle — historiador, servidor SCADA, host de salto — executam sistemas operacionais comuns; este capítulo torna a configuração deles algo que você pode verificar, e não presumir.
3.1 O que endurecimento significa no nível do técnico
Endurecer é remover o que não é necessário e restringir o que é. Para um servidor num ambiente de controle, isso significa: serviços escutando apenas nas interfaces de que precisam; acesso administrativo apenas pelo caminho de gerência; nenhuma conta compartilhada ou órfã; contas de serviço que não conseguem fazer login interativo; e uma configuração registrada, para que a deriva possa ser detectada (Capítulo 14). O guia geral de servidores do NIST dá a lista de verificação mais ampla (SP 800-123); as Cross-Sector Cybersecurity Performance Goals da CISA resumem as práticas de contas e credenciais que mais costumam faltar (CISA CPGs).
3.2 Ler corretamente a configuração do sshd
O daemon do OpenSSH lê o sshd_config de cima para baixo e, para a maioria das palavras-chave, o primeiro valor obtido é o usado; as linhas posteriores para a mesma palavra-chave são ignoradas (sshd_config(5)). Os comentários começam com #. Assim, um arquivo que tem PasswordAuthentication yes perto do topo e a correção posterior de alguém, PasswordAuthentication no, no final continua permitindo senhas. A verificação confiável é a configuração efetiva: num host real, sshd -T a imprime; no Laboratório 3, o analisador guarda o primeiro valor, como faz o daemon.
Configurações que importam num host do centro de controle: ListenAddress restrito à interface de gerência; PermitRootLogin no; PasswordAuthentication no assim que chaves ou certificados funcionarem; X11Forwarding no; um MaxAuthTries baixo; e AllowGroups nomeando um grupo cujos membros você também revisa.
3.3 Contas e identidades
No Linux, privilégio é um número: UID 0 é root, seja qual for o nome da conta. Uma conta extra com UID 0 ("backup2", "support") é uma segunda senha de root que ninguém troca. Contas de serviço (UIDs abaixo de 1000 por convenção em muitas distribuições) executam daemons; devem ter um shell não interativo como /usr/sbin/nologin, para que uma credencial de serviço roubada não possa ser usada para fazer login. Contas de pessoas devem corresponder a alguém da lista atual de autorizações; uma conta de fornecedor que fica permanentemente no sudo é um privilégio permanente que deveria ter prazo (Capítulo 10). A participação em grupos faz parte da identidade: estar no sudo ou no ops-admins muitas vezes importa mais do que a própria conta.
3.4 Exemplo resolvido: auditoria do HIST-02 (sintético)
O hist-02 armazena as séries temporais da Kestrel Water. Política do KVROC: SSH apenas no endereço de gerência 10.90.0.21; nenhum login de root; apenas chaves; no máximo três tentativas; apenas J. Tan e R. Kaur autorizados.
Laboratório 3 (salve como lab03.py e execute com python3 lab03.py):
# Lab 3 - audit a host configuration and its local accounts (offline, standard library only)
# Synthetic files from historian host HIST-02 at the Kestrel Vale operations centre.
sshd_config = """
Port 22
ListenAddress 0.0.0.0
PermitRootLogin yes
PasswordAuthentication yes
# PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding yes
MaxAuthTries 6
AllowGroups ops-admins
"""
passwd = """root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
histsvc:x:998:998:historian service:/opt/hist:/bin/bash
jtan:x:1001:1001:J. Tan:/home/jtan:/bin/bash
rkaur:x:1002:1002:R. Kaur:/home/rkaur:/bin/bash
backup2:x:0:0:temp backup:/root:/bin/bash
vendor:x:1003:1003:vendor support:/home/vendor:/bin/bash"""
group = """ops-admins:x:1100:jtan,vendor
sudo:x:27:jtan,rkaur,vendor"""
policy = {"PermitRootLogin": "no", "PasswordAuthentication": "no", "X11Forwarding": "no",
"ListenAddress": "10.90.0.21", "MaxAuthTries": "3"}
roster = {"jtan", "rkaur"} # people currently authorized on HIST-02
eff = {}
for line in sshd_config.splitlines():
line = line.split("#", 1)[0].strip()
if not line: continue
key, val = line.split(None, 1)
eff.setdefault(key, val) # sshd uses the FIRST value it reads for a keyword
findings = []
for k, want in policy.items():
if eff.get(k) != want: findings.append(f"sshd {k} is {eff.get(k)!r}, policy {want!r}")
for line in passwd.splitlines():
name, _, uid, gid, gecos, home, shell = line.split(":")
if uid == "0" and name != "root": findings.append(f"account {name} has UID 0 (root equivalent)")
if 0 < int(uid) < 1000 and shell.endswith("sh") and not shell.endswith("nologin"):
findings.append(f"service account {name} has interactive shell {shell}")
if int(uid) >= 1000 and name not in roster: findings.append(f"person account {name} not on roster")
for line in group.splitlines():
g, _, _, members = line.split(":")
for m in members.split(","):
if m and m not in roster: findings.append(f"group {g} contains {m} (not on roster)")
for f in findings: print(f)
print("findings:", len(findings))
Saída esperada (Python 3.13.5):
sshd PermitRootLogin is 'yes', policy 'no'
sshd PasswordAuthentication is 'yes', policy 'no'
sshd X11Forwarding is 'yes', policy 'no'
sshd ListenAddress is '0.0.0.0', policy '10.90.0.21'
sshd MaxAuthTries is '6', policy '3'
service account histsvc has interactive shell /bin/bash
account backup2 has UID 0 (root equivalent)
person account vendor not on roster
group ops-admins contains vendor (not on roster)
group sudo contains vendor (not on roster)
findings: 10
Dez constatações. Repare na linha PasswordAuthentication: o arquivo contém um no comentado, que alguns revisores leem como "já corrigido". É um comentário, e o valor efetivo é yes. As constatações mais perigosas são backup2 com UID 0 (um segundo root não gerenciado) e vendor no sudo (acesso privilegiado permanente de fornecedor). A conta de serviço do historiador com /bin/bash importa porque as credenciais do serviço ficam armazenadas em disco para o historiador usá-las.
Uma ordem segura de endurecimento: (1) confirmar um login funcional por chave para J. Tan e R. Kaur a partir do jump-01; (2) restringir ListenAddress, PermitRootLogin e PasswordAuthentication numa única mudança, mantendo uma sessão existente aberta enquanto testa uma nova; (3) remover backup2 depois de preservar o seu histórico de logins; (4) remover vendor do sudo e passar o acesso do fornecedor para um procedimento com prazo; (5) definir o shell da conta de serviço como nologin depois de verificar que nenhum script de manutenção faz login com ela.
3.5 Atividade prática
Numa máquina virtual sua, execute sshd -T | sort e compare a saída com o arquivo. Acrescente uma palavra-chave duplicada mais abaixo no arquivo, recarregue e confirme que o primeiro valor vence. Registre a versão exata do OpenSSH, porque o comportamento dos blocos Include e Match varia conforme a versão.
Registre a versão do OpenSSH e o caminho de cada arquivo que o sshd -T mostra como incluído. Depois de recarregar, abra uma segunda sessão antes de fechar a primeira, para que uma mudança ruim em ListenAddress ou AllowGroups não possa trancá-lo do lado de fora. Compare os valores efetivos com a tabela de política do Laboratório 3 e anote qualquer palavra-chave que apareça duas vezes no arquivo.
3.6 Erros comuns e limites
- Ler o arquivo em vez da configuração efetiva.
- Corrigir as configurações do SSH a partir da única sessão aberta e trancar todos do lado de fora; sempre teste antes uma segunda sessão.
- Verificar nomes de contas em vez de UIDs.
- Remover o shell de uma conta de serviço sem verificar os scripts que dependem dele.
-
O Laboratório 3 não trata arquivos
Includenem blocosMatch; auditorias reais precisam tratar. -
Editar PasswordAuthentication no final do arquivo enquanto um yes anterior continua vencendo.
- Remover vendor do sudo sem um procedimento com prazo para a próxima visita de suporte.
- Verificar nomes de contas em vez de UIDs, de modo que um segundo root chamado backup2 passa despercebido.
Exercícios — capítulo 3
EX009 — O primeiro valor vence. Objetivo: raciocinar sobre a configuração efetiva. Insumos: o sshd_config do Laboratório 3. Passos: (1) prever o PasswordAuthentication efetivo se a linha comentada for descomentada e deixada onde está; (2) dizer onde a correção precisa ficar. Evidência esperada: previsão e posição. Rubrica: 3 = continua yes, porque a linha anterior vence; a correção substitui a primeira ocorrência (ou a linha anterior é apagada), verificada com sshd -T; 2 = resposta certa, sem verificação; 1 = prevê no; 0 = nada.
EX010 — Priorize as constatações do HIST-02. Objetivo: ordenar as mudanças por risco e segurança. Insumos: a saída do Laboratório 3. Passos: agrupar as dez constatações em hoje / esta semana / próxima janela de manutenção, com justificativas de uma linha e uma etapa de preservação onde necessário. Evidência esperada: uma lista em três grupos. Rubrica: 3 = backup2 com UID 0 e vendor no sudo hoje, com o histórico de logins preservado antes; vinculação do SSH e configurações de root/senha como uma única mudança testada; shell do serviço depois da verificação dos scripts; 2 = sensata, mas sem preservação; 1 = sem ordem; 0 = nada.
EX011 — Estenda a auditoria. Objetivo: acrescentar uma verificação. Insumos: Laboratório 3. Passos: acrescentar uma verificação que sinalize qualquer conta diferente de root cujo shell seja interativo e cujo diretório pessoal seja /root ou /. Relatar a nova saída. Evidência esperada: código e saída. Rubrica: 3 = sinaliza backup2 (diretório /root) e somente ela; explica por que diretórios pessoais compartilhados escondem a responsabilização; 2 = funciona, sem explicação; 1 = tentativa; 0 = nada.
EX012 — Desenho de conta de serviço. Objetivo: desenhar uma identidade não interativa. Insumos: o serviço do historiador precisa ler arquivos em /opt/hist e escrever no seu banco de dados. Passos: especificar a faixa de UID, o shell, o diretório pessoal, o grupo, as permissões de arquivo e como sua credencial é armazenada e trocada. Evidência esperada: uma especificação curta. Rubrica: 3 = UID de sistema, shell nologin, grupo dedicado, modos de arquivo de privilégio mínimo, credencial legível apenas pelo serviço, responsável e intervalo de troca; 2 = uma lacuna; 1 = genérica; 0 = nada.
Síntese do capítulo
O endurecimento do sistema operacional é verificável: configurações efetivas, UIDs, shells e participação em grupos podem ser lidos e comparados com uma política escrita. Saiba como o daemon realmente lê o seu arquivo, olhe os números em vez dos nomes e ordene as mudanças de modo a nunca trancar do lado de fora as pessoas que operam o serviço.
Continue estudando — capítulo 03 de 18
← Capítulo 02 · Índice de capítulos do curso · Capítulo 04 →
Siga para a próxima lição escrita.