Ubuntu Segurança do Servidor

Um servidor ligado à internet começa a receber tentativas de invasão em minutos: robôs testam senhas no SSH o dia inteiro, em todos os endereços. Esta aula transforma um servidor recém-criado num servidor protegido, em um roteiro que leva uns 15 minutos.

Você vai aprender
  • Os princípios que guiam toda decisão de segurança.
  • O roteiro dos primeiros 15 minutos num servidor novo, passo a passo.
  • Como endurecer o SSH sem se trancar para fora.
  • Como o fail2ban bloqueia quem erra a senha muitas vezes.
  • Onde olhar para saber quem tentou entrar.

Antes, leia SSH, Firewall (ufw) e Usuários e Grupos. Nesta aula, a Ana acabou de criar uma máquina na nuvem chamada servidor, com IP 192.168.0.20. O provedor entregou acesso como root, com senha.


Os princípios

PrincípioNa prática
Menor privilégioCada pessoa e cada programa só tem o acesso de que precisa. Ninguém trabalha como root; usa-se sudo quando necessário.
Menos portas, menos riscoTodo serviço aberto é uma porta de entrada. Desinstale o que não usa e feche o resto no firewall.
Atualizado sempreA maioria das invasões explora falhas que já têm correção. Atualizações de segurança devem ser automáticas.
Defesa em camadasChave SSH + firewall + fail2ban. Se uma camada falhar, a próxima segura.
Registrar e revisarLogs mostram quem tentou entrar. Backups permitem voltar atrás (veja Backup).

Os primeiros 15 minutos num servidor novo

Siga na ordem. Os passos 1 e 2 são feitos como root, no acesso que o provedor entregou. Do passo 3 em diante, a Ana usa o próprio usuário.

Por que as mensagens estão em inglês?

Servidores criados a partir de imagens de nuvem costumam vir com o idioma C.UTF-8, que é inglês. É normal; os comandos são os mesmos.

  1. Atualize tudo. A imagem do provedor pode ter semanas de atraso. Conecte com ssh root@192.168.0.20 e rode:

    #> apt update && apt full-upgrade -y
    #> ls /var/run/reboot-required
    /var/run/reboot-required                            « o arquivo existe: reinicie
    #> reboot

    Se o arquivo /var/run/reboot-required existir, uma atualização (normalmente do kernel) só vale depois de reiniciar. Veja Atualizações.

  2. Crie um usuário administrador. Trabalhar como root é perigoso: um erro de digitação não tem nenhuma barreira.

    adduser
    Cria o usuário, a pasta pessoal e pede a senha.
    ana
    O nome do novo usuário.
    #> adduser ana
    info: Adding user `ana' ...
    info: Selecting UID/GID from range 1000 to 59999 ...
    info: Adding new group `ana' (1000) ...
    info: Adding new user `ana' (1000) with group `ana (1000)' ...
    info: Creating home directory `/home/ana' ...
    info: Copying files from `/etc/skel' ...
    New password:                                       « nada aparece enquanto você digita
    Retype new password:
    passwd: password updated successfully
    Changing the user information for ana
    Enter the new value, or press ENTER for the default
    	Full Name []: Ana
    	Room Number []:
    	Work Phone []:
    	Home Phone []:
    	Other []:
    Is the information correct? [Y/n] y
    info: Adding new user `ana' to supplemental / extra groups `users' ...
    info: Adding user `ana' to group `users' ...
    #> usermod -aG sudo ana
    #> groups ana
    ana : ana sudo users

    O usermod -aG sudo ana coloca a ana no grupo sudo, que pode administrar o sistema. O -a é essencial: sem ele, a ana sairia de todos os outros grupos (veja Usuários e Grupos).

  3. Entre com chave SSH. No seu computador (o notebook), crie uma chave e copie a parte pública para o servidor:

    $ ssh-keygen -t ed25519 -C "ana@notebook"
    $ ssh-copy-id ana@192.168.0.20
    $ ssh ana@192.168.0.20

    Se o último comando entrou sem pedir a senha da conta (no máximo a senha da chave), a chave funciona. Detalhes em SSH.

  4. Endureça o SSH. Vamos proibir o login do root e o login por senha. Mas não edite o arquivo principal: crie um arquivo seu em /etc/ssh/sshd_config.d/.

    # Configuração de segurança do SSH
    PermitRootLogin no
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    MaxAuthTries 3
    AllowUsers ana
    OpçãoO que faz
    PermitRootLogin noNinguém entra direto como root. Robôs sempre tentam "root".
    PasswordAuthentication noSó entra quem tem uma chave. Adivinhar senha deixa de funcionar.
    KbdInteractiveAuthentication noFecha outra forma de pedir senha (o "teclado interativo").
    MaxAuthTries 3Derruba a conexão após 3 tentativas erradas.
    AllowUsers anaSó a ana pode entrar por SSH, mesmo que existam outros usuários.
    $ sudo nano /etc/ssh/sshd_config.d/10-seguranca.conf
    $ sudo sshd -t
    $ sudo sshd -T | grep -E "^(permitrootlogin|passwordauthentication) "
    permitrootlogin no
    passwordauthentication no
    $ sudo systemctl restart ssh
    sshd -t
    test: confere se a configuração tem erro, sem aplicar nada. Sem saída = sem erros.
    sshd -T
    Mostra a configuração efetiva, já juntando todos os arquivos.
    systemctl restart ssh
    Aplica. Quem já está conectado continua conectado.
    Por que "10-" no nome do arquivo?

    No SSH, vale a primeira vez que uma opção aparece. Os arquivos de sshd_config.d são lidos em ordem alfabética, antes do resto. Em servidores de nuvem, costuma existir um 50-cloud-init.conf com PasswordAuthentication yes. Com o nome começando por 10-, o seu arquivo é lido antes e vence. O sshd -T confirma qual valor ficou.

    Teste num segundo terminal antes de sair

    Mantenha a sessão atual aberta. Abra outro terminal no notebook e rode ssh ana@192.168.0.20. Só feche a primeira sessão quando a segunda entrar. Teste também que o root foi barrado: ssh root@192.168.0.20 deve responder Permission denied (publickey).

  5. Ligue o firewall, liberando o SSH primeiro (detalhes em Firewall (ufw)):

    $ sudo ufw allow OpenSSH
    Rules updated
    Rules updated (v6)
    $ sudo ufw enable
    Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
    Firewall is active and enabled on system startup
  6. Instale o fail2ban (explicado na próxima seção):

    $ sudo apt install fail2ban -y
    $ sudo systemctl enable --now fail2ban
  7. Confirme as atualizações automáticas de segurança. No Ubuntu Server, o unattended-upgrades já vem instalado. Confira se está ligado:

    $ cat /etc/apt/apt.conf.d/20auto-upgrades
    APT::Periodic::Update-Package-Lists "1";
    APT::Periodic::Unattended-Upgrade "1";              « 1 = ligado

    Se o arquivo não existir ou tiver "0", rode sudo dpkg-reconfigure -plow unattended-upgrades e responda Yes.

  8. Acerte o fuso horário, para os logs mostrarem a hora certa:

    $ sudo timedatectl set-timezone America/Sao_Paulo
    $ date
    Thu Oct 15 10:45:12 -03 2026
  9. Veja o que está aberto para a rede. Cada linha é um programa escutando uma porta:

    $ sudo ss -tulpn
    Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
    udp   UNCONN 0      0         127.0.0.54:53         0.0.0.0:*     users:(("systemd-resolve",pid=512,fd=16))
    udp   UNCONN 0      0      127.0.0.53%lo:53         0.0.0.0:*     users:(("systemd-resolve",pid=512,fd=14))
    tcp   LISTEN 0      4096   127.0.0.53%lo:53         0.0.0.0:*     users:(("systemd-resolve",pid=512,fd=15))
    tcp   LISTEN 0      4096         0.0.0.0:22         0.0.0.0:*     users:(("sshd",pid=1043,fd=3),("systemd",pid=1,fd=104))
    tcp   LISTEN 0      4096            [::]:22            [::]:*     users:(("sshd",pid=1043,fd=4),("systemd",pid=1,fd=105))

    Endereços 127.0.0.x só aceitam conexões do próprio servidor; 0.0.0.0 e [::] aceitam de qualquer lugar. Aqui, só o SSH está exposto, como deve ser. Se aparecer algo que você não reconhece, descubra o que é (veja ip, ping, ss) e desinstale se não precisar.


fail2ban: banir quem insiste

Mesmo com login só por chave, robôs continuam tentando, enchendo os logs. O fail2ban lê os registros, conta as falhas de cada IP e, quando passa do limite, cria uma regra de firewall que bloqueia aquele IP por um tempo.

TermoSignificado
jail ("cadeia")Uma proteção para um serviço. A jail sshd protege o SSH; o pacote do Ubuntu já a deixa ligada.
maxretryQuantas falhas são toleradas.
findtimeEm quanto tempo essas falhas são contadas.
bantimePor quanto tempo o IP fica bloqueado.
ignoreipEndereços que nunca são bloqueados (o seu, por exemplo).

Configurar

Nunca edite o jail.conf, que é substituído nas atualizações. Crie um jail.local, que tem prioridade:

[DEFAULT]
# 5 falhas em 10 minutos = 1 hora de bloqueio
maxretry = 5
findtime = 10m
bantime  = 1h
# nunca bloquear o próprio servidor nem a rede do escritório
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/24

[sshd]
enabled = true
$ sudo nano /etc/fail2ban/jail.local
$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:	sshd

Ver quem foi bloqueado

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	2
|  |- Total failed:	57
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	1                         « IPs bloqueados agora
   |- Total banned:	4
   `- Banned IP list:	203.0.113.45

Dependendo de onde o fail2ban lê os registros, a linha File list pode aparecer como Journal matches. O resultado é o mesmo.

Desbloquear um IP

$ sudo fail2ban-client set sshd unbanip 203.0.113.45
1                                                   « 1 IP desbloqueado

Quem tentou entrar?

Formas diferentes de investigar os acessos ao SSH:

PerguntaComando
Quem está conectado agora?who ou w
Últimos logins com sucessolast -n 10 (no 26.04, vem no pacote wtmpdb)
Tentativas que falharamsudo grep "Failed\|Invalid user" /var/log/auth.log | tail
Tudo do SSH desde ontemsudo journalctl -u ssh --since yesterday
IPs que mais tentaramveja abaixo
$ sudo grep "Invalid user" /var/log/auth.log | tail -2
2026-10-15T10:51:33.402871-03:00 servidor sshd-session[2231]: Invalid user admin from 203.0.113.45 port 40122
2026-10-15T10:51:35.118203-03:00 servidor sshd-session[2233]: Invalid user oracle from 203.0.113.45 port 40130
$ sudo grep "Invalid user" /var/log/auth.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -nr | head -3
     41 from 203.0.113.45
     12 from 198.51.100.7
      3 from 192.0.2.88

Robôs testam nomes comuns (admin, oracle, test). Com AllowUsers ana e login só por chave, todas essas tentativas falham. O segundo comando junta grep, sort e uniq para contar tentativas por IP.


AppArmor: limitar o que cada programa pode fazer

O AppArmor vem ligado no Ubuntu. Ele dá a programas como o navegador e o servidor web uma lista do que podem acessar. Mesmo que um programa seja invadido, ele não consegue sair dessa lista.

$ sudo aa-status | head -4
apparmor module is loaded.
119 profiles are loaded.
33 profiles are in enforce mode.                    « enforce = regras aplicadas
   /usr/bin/man

Você raramente precisa mexer nele. O importante é não desligá-lo quando um tutorial da internet mandar; prefira entender qual regra está bloqueando, em sudo journalctl -k | grep apparmor.


Boas práticas no dia a dia

  • Não rode scripts da internet sem ler. curl https://site/instalar.sh | sudo bash executa como root um código que você não viu. Baixe, leia, depois rode.
  • Proteja a chave privada com uma senha (o ssh-keygen pergunta) e nunca a copie para o servidor.
  • Um usuário por pessoa. Não compartilhe a conta da ana; crie outra e remova quando a pessoa sair.
  • Serviços como usuários próprios, nunca como root (veja Criar um Serviço).
  • Backup fora do servidor. Um invasor que apaga o servidor também apaga o backup que está nele.
  • Revise de tempos em tempos: sudo ss -tulpn, sudo ufw status, sudo fail2ban-client status sshd e as atualizações (veja Manutenção).

Quando não funciona

"Permission denied (publickey)" depois de desligar a senha
$ ssh ana@192.168.0.20
ana@192.168.0.20: Permission denied (publickey).

O que aconteceu: o servidor agora só aceita chave, e a sua chave não está em /home/ana/.ssh/authorized_keys, ou as permissões da pasta .ssh estão abertas demais.

Como resolver: se a primeira sessão ainda está aberta, use-a para conferir: ls -la ~/.ssh (a pasta deve ser drwx------ e o arquivo -rw-------). Se você se trancou para fora, entre pelo console web do provedor e, temporariamente, volte PasswordAuthentication yes no seu arquivo de configuração.

"Bad configuration option" ao testar
$ sudo sshd -t
/etc/ssh/sshd_config.d/10-seguranca.conf: line 2: Bad configuration option: PermitRotLogin
/etc/ssh/sshd_config.d/10-seguranca.conf: terminating, 1 bad configuration options

O que aconteceu: erro de digitação no nome da opção ("Rot" em vez de "Root").

Como resolver: corrija a linha indicada e rode sudo sshd -t de novo. Nunca reinicie o SSH antes de o teste passar.

O fail2ban bloqueou o seu próprio IP

O que aconteceu: você errou a senha (ou um script errou por você) mais vezes que o maxretry. A conexão fica tentando e não responde.

Como resolver: entre por outro IP (a rede do celular, por exemplo) ou pelo console do provedor e rode sudo fail2ban-client set sshd unbanip SEU_IP. Depois, coloque o seu IP fixo em ignoreip.

O root ainda consegue entrar com senha

O que aconteceu: outro arquivo de sshd_config.d, lido antes do seu, define o valor contrário. Ou o SSH não foi reiniciado.

Como resolver: sudo grep -ri "permitrootlogin\|passwordauthentication" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ mostra todos os lugares. Ajuste o nome do seu arquivo para ser lido primeiro e confira com sudo sshd -T.


Referência

ComandoPara quê
sudo adduser NOME + sudo usermod -aG sudo NOMECriar um administrador
ssh-keygen -t ed25519 + ssh-copy-idLogin por chave
sudo sshd -t / sudo sshd -TTestar / ver a configuração efetiva do SSH
sudo systemctl restart sshAplicar mudanças do SSH
sudo ufw allow OpenSSH + sudo ufw enableFirewall
sudo fail2ban-client status sshdIPs bloqueados
sudo fail2ban-client set sshd unbanip IPDesbloquear
sudo dpkg-reconfigure -plow unattended-upgradesLigar atualizações automáticas
sudo ss -tulpnPortas abertas
sudo aa-statusEstado do AppArmor
sudo journalctl -u ssh --since todayAcessos ao SSH

Exercícios

1. Proibir o root

Complete a linha de configuração do SSH:

PermitRootLogin

2. Testar antes de aplicar

Complete o comando que confere a configuração do SSH sem aplicá-la:

sudo sshd

3. Adicionar ao grupo sudo

Complete para colocar o usuário joao no grupo sudo sem tirá-lo dos outros grupos:

sudo usermod sudo joao

4. Por que o arquivo se chama 10-seguranca.conf e não seguranca.conf?

5. O que o fail2ban faz quando um IP passa do maxretry dentro do findtime?


Resumo

  • Servidor novo: atualize, crie um usuário com sudo, entre por chave, endureça o SSH, ligue o firewall e o fail2ban.
  • Configure o SSH num arquivo próprio em sshd_config.d; teste com sshd -t e confira com sshd -T.
  • Sempre teste o acesso num segundo terminal antes de fechar o primeiro.
  • O fail2ban bloqueia IPs que erram demais; configure-o no jail.local.
  • Revise portas abertas, bloqueios e logins com frequência.