
Kit modular em Bash que fortalece sistemas Debian/Ubuntu para competições CyberPatriot, automatizando o endurecimento de contas, firewall, SSH, PAM e serviços com registro e backups.
Um toolkit modular em Bash para hardening de sistemas da família Debian/Ubuntu sob pressão de tempo de competição. Construído e refinado ao longo de várias temporadas da CyberPatriot National Youth Cyber Defense Competition, tendo mais recentemente alcançado o nível Platinum na divisão Linux na rodada semifinal de 2025.
Este não é um framework de conformidade de propósito geral. É um automatizador de checklist para um exercício cronometrado de seis horas: ele executa a maioria scriptável de uma passagem de hardening Linux de forma correta, rápida e idempotente, registra tudo o que tocou e deixa as decisões de julgamento para quem o executa.
As rodadas Linux do CyberPatriot pontuam uma imagem ativa contra uma rubrica que recompensa um conjunto bastante previsível de etapas de hardening -- higiene de contas, política de senhas, configuração de firewall, exposição de serviços, permissões de arquivos, nível de patches -- sob um limite de tempo rígido, geralmente sem aviso prévio de exatamente quais vulnerabilidades foram plantadas. Fazer esse checklist à mão, corretamente, sob contagem regressiva, é onde as equipes perdem pontos fáceis por erros de digitação e etapas esquecidas, não por conteúdo desconhecido.
Este toolkit começou como um único script monolítico escrito exatamente sob essa pressão. Este repositório é uma reescrita desse script: mesma cobertura de checklist, reestruturado em módulos pequenos e de propósito único que são mais fáceis de ler, testar e raciocinar de forma independente, com cada decisão não óbvia vinculada a uma seção específica do CIS Benchmark ou controle do NIST SP 800-53 (veja Controles de segurança e referências).
flowchart TD
A[bin/harden.sh] --> B[lib/common.sh<br/>logging, backups, run wrapper]
A --> C[Service-role prompts<br/>or --config file]
A --> D[lib/packages.sh<br/>updates, attack-tool removal]
A --> E[lib/firewall.sh<br/>default-deny + ufw]
A --> F[lib/ssh.sh]
A --> G[lib/services.sh<br/>samba/ftp/mail/http/mysql/dns]
A --> H[lib/users.sh<br/>account review, hidden UID 0]
A --> I[lib/kernel.sh<br/>sysctl hardening]
A --> J[lib/pam.sh<br/>password policy, lockout]
A --> K[lib/filesystem.sh<br/>permissions, cron, banners]
A --> L[lib/monitoring.sh<br/>fail2ban, auditd, rkhunter]
A --> M[lib/forensics.sh<br/>baseline snapshot]
D & E & F & G & H & I & J & K & L & M --> N[(~/hardening-run/<br/>log + backups + baseline)]Cada módulo é carregado por bin/harden.sh, que é responsável pela análise de
argumentos, pelo questionário de função do serviço e pela ordem de execução. Os
módulos não chamam uns aos outros diretamente, e todo comando que altera estado em
cada módulo passa pelo wrapper run() em lib/common.sh, o que dá ao projeto
inteiro um único lugar para implementar suporte a dry-run, logging consistente e
tratamento de erros não fatais.
git clone <this-repo>
cd cyberpatriot-linux-hardening
sudo ./bin/harden.sh
Serão feitas uma breve série de perguntas de sim/não sobre a função da máquina (se
ela precisa de Samba, FTP, SSH, um servidor web, e assim por diante), e então ele
executa de forma não assistida pelos módulos listados acima. Um log, um conjunto
completo de backups de configuração com timestamp e um snapshot de baseline do
sistema são gravados em ~/hardening-run/.
Em uma rodada real, pule os prompts de confirmação por pacote e responda às perguntas de função a partir de um arquivo de respostas preparado, em vez de digitá-las ao vivo:
cp examples/config.env.example my-machine.env
# edit my-machine.env for this box's actual role
sudo ./bin/harden.sh --config my-machine.env --auto-approve
Quer ver exatamente o que ele faria antes de tocar em qualquer coisa?
sudo ./bin/harden.sh --dry-run --config my-machine.env
| Módulo | Faz |
|---|---|
lib/packages.sh | Atualização completa do sistema; remove automaticamente quebradores de senha e ferramentas de exploração; revisa ferramentas de uso duplo (nmap, Wireshark, netcat) e serviços legados (VNC, NFS, telnet) antes de removê-los |
lib/firewall.sh | Default-deny para entrada / default-allow para saída via ufw, além de um bloqueio explícito em uma porta de backdoor comum conhecida |
lib/ssh.sh | Cifras/KEX/MACs modernos, sem login root, limites de conexão e sessão -- ou remove o SSH completamente se a função não precisar dele |
lib/services.sh | Samba, FTP, mail, impressão, MySQL, HTTP, DNS: cada um é instalado e minimamente endurecido se a função precisar dele, ou removido e bloqueado por firewall se não precisar |
lib/users.sh | Revisão interativa das contas existentes (direitos de admin, exclusão, redefinição de senha), detecção de contas ocultas com UID 0 e senhas vazias |
lib/kernel.sh | Configurações sysctl de pilha de rede e autoproteção do kernel (source routing, redirecionamentos ICMP, ASLR, escopo de ptrace, restrição de dmesg/kptr) |
lib/pam.sh | Complexidade e histórico de senhas via pam_pwquality/pam_pwhistory, bloqueio de conta via pam_faillock, expiração de senha em login.defs |
lib/filesystem.sh | Permissões de arquivos principais, restrição de cron/at, um rc.local mínimo, banners legais de login, varredura somente leitura de SUID/gravable por todos/arquivos sem dono |
lib/monitoring.sh | fail2ban e auditd por padrão; ClamAV e uma varredura completa de rkhunter/chkrootkit são opt-in (veja Notas de segurança para competição) |
lib/forensics.sh | Snapshot somente leitura de usuários, processos, portas em escuta e pacotes instalados para comparação posterior |
tools/find-port-owner.sh e tools/list-nonstandard-users.sh são pequenos
utilitários autônomos para o mesmo tipo de trabalho de triagem, utilizáveis
independentemente do script principal -- veja seus cabeçalhos para uso.
Um script de hardening que quebra a máquina que deveria proteger é pior que inútil em uma rodada cronometrada. Alguns padrões refletem isso e vale a pena entendê-los antes de executá-lo de forma não assistida:
SSH_PASSWORD_AUTH=no), mas o padrão aqui favorece não trancar uma equipe fora
de sua própria máquina quando ninguém provisionou chaves ainda.INSTALL_CLAMAV, RUN_BASELINE_SCAN), porque são as duas coisas mais lentas que
este script pode fazer e nenhuma delas altera o estado do sistema por conta própria.
Ative-as se seu checklist exigir ou se você tiver tempo de sobra.~/hardening-run/baseline/listening_ports.txt
de uma execução anterior se não tiver certeza do que está realmente escutando antes
de endurecer uma máquina pela primeira vez.docs/security-controls.md
para o procedimento manual.bin/harden.sh perguntará interativamente sobre a função de serviço da máquina se
você não responder antecipadamente. Para pular os prompts, copie
examples/config.env.example, preencha a função real e passe-o com --config.
Qualquer variável que você deixar de fora do arquivo recairá em um prompt interativo,
então um arquivo de configuração parcialmente preenchido é aceitável.
sudo ./bin/harden.sh --config my-machine.env
Flags:
| Flag | Efeito |
|---|---|
--config FILE | Carrega respostas de função/política de um arquivo env |
--dry-run | Registra toda ação que seria tomada; não altera nada |
--auto-approve | Pula os prompts de confirmação de remoção por pacote |
.
├── bin/harden.sh orchestrator: parses args, asks role questions, runs modules in order
├── lib/
│ ├── common.sh logging, backups, idempotent file edits, the run() wrapper
│ ├── packages.sh updates, attack-tool removal
│ ├── ssh.sh SSH install/removal and hardening
│ ├── services.sh samba/ftp/telnet/mail/printing/mysql/http/dns
│ ├── firewall.sh ufw default-deny posture
│ ├── users.sh account review, hidden UID 0 / empty password detection
│ ├── kernel.sh sysctl hardening
│ ├── pam.sh password policy, account lockout
│ ├── filesystem.sh permissions, cron, rc.local, banners, anomaly scan
│ ├── monitoring.sh fail2ban, auditd, rkhunter, chkrootkit, ClamAV
│ └── forensics.sh read-only system baseline snapshot
├── tools/
│ ├── find-port-owner.sh resolve a listening TCP port to a process path
│ └── list-nonstandard-users.sh flag UID >= 1000 accounts not on an expected list
├── docs/
│ ├── security-controls.md every hardening decision, mapped to its source standard
│ └── editor-cheatsheet.md small editor commands worth remembering under pressure
├── examples/config.env.example annotated template for non-interactive runs
└── .github/workflows/shellcheck.yml lint on every push/PR
Todo script passa por lint com ShellCheck em cada
push via GitHub Actions (.github/workflows/shellcheck.yml). Para verificar
localmente antes de abrir um PR:
shellcheck lib/*.sh bin/*.sh tools/*.sh
bin/harden.sh --dry-run também é, por si só, um teste: ele exercita o fluxo de
controle e o logging de cada módulo sem tocar no sistema de arquivos ou instalar
qualquer coisa, e é a maneira mais rápida de verificar uma mudança em uma VM
descartável antes de executá-la de verdade. Veja CONTRIBUTING.md para as
expectativas completas sobre novos módulos (idempotência, encaminhar ações
destrutivas por run() e citar uma fonte para qualquer nova etapa de hardening).
O comentário de cabeçalho de cada módulo e docs/security-controls.md citam a seção
específica do padrão por trás de cada decisão. Fontes primárias usadas em todo o
projeto:
| Padrão | Fonte |
|---|---|
| CIS Ubuntu Linux Benchmark | https://www.cisecurity.org/benchmark/ubuntu_linux |
| NIST SP 800-53 Rev. 5 | https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final |
| DISA STIG for Ubuntu | https://public.cyber.mil/stigs/downloads/ |
| Mozilla OpenSSH modern configuration guidelines | https://infosec.mozilla.org/guidelines/openssh |
| CyberPatriot National Youth Cyber Defense Competition | https://www.uscyberpatriot.org/ |
Ferramentas de detecção referenciadas (não embutidas, instaladas via apt):
fail2ban,
Linux Audit / auditd,
rkhunter,
chkrootkit. Lynis
e OpenSCAP são recomendados como uma auditoria
independente de acompanhamento e não são executados automaticamente por este projeto.
Veja docs/security-controls.md para o raciocínio completo por trás de cada uma
dessas decisões.
MIT. Veja LICENSE.