Guides
Fundamentos ▾
Versionamento ▾
Deploy ▾

Servidor Ubuntu — Setup e SSL

Configuração inicial segura + HTTPS com Let's Encrypt/Certbot.

Ordem de Execução

1
Criar usuário + sudo
Nunca operar como root no dia a dia
2
Configurar SSH keys
Gerar ed25519 no local, copiar authorized_keys no servidor
3
Endurecer sshd_config
PermitRootLogin no + PasswordAuthentication no
4
UFW
Bloquear tudo, abrir só SSH + 80 + 443
5
fail2ban
Banir IPs com tentativas de force brute
6
Nginx
Instalar e habilitar o serviço
7
Timezone + hostname + NTP
Logs com horário certo, hostname identificável
8
Atualizações automáticas
unattended-upgrades para patches de segurança
9
SSL com Certbot
Depois que Nginx e DNS estão funcionando

1. Criar Usuário

# conectado como root
adduser alfredo
usermod -aG sudo alfredo
chown -R alfredo:alfredo /home/alfredo

# TESTAR sudo antes de fechar sessão root
su - alfredo
sudo whoami   # deve retornar: root
Não feche a sessão root antes de confirmar que o novo usuário tem sudo funcionando.

2. SSH Keys

No cliente local

ssh-keygen -t ed25519 -C "alfredo@servidor"
# salva em ~/.ssh/id_ed25519 + ~/.ssh/id_ed25519.pub

Copiar para o servidor

ssh-copy-id -i ~/.ssh/id_ed25519.pub alfredo@ip-do-servidor

~/.ssh/config (cliente)

Host meu-servidor
    HostName ip-ou-dominio
    User alfredo
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

3. Endurecer sshd_config

sudo nvim /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers alfredo
Protocol 2
sudo systemctl restart ssh
Testar nova sessão SSH antes de fechar a sessão atual. Se errar a config, fica sem acesso.

4. UFW

sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Ver firewall/firewall-guide.md para UFW + fail2ban detalhado.

5. fail2ban

sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nvim /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
banaction = ufw

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status sshd

6. Nginx

sudo apt install nginx -y
sudo systemctl enable nginx
sudo ufw allow 'Nginx Full'
curl http://localhost   # página padrão nginx

7. Sistema

Timezone

sudo timedatectl set-timezone America/Sao_Paulo
timedatectl status

Hostname

sudo hostnamectl set-hostname meu-servidor
sudo nvim /etc/hosts
# adicionar: 127.0.1.1  meu-servidor

NTP

sudo apt install systemd-timesyncd -y
sudo timedatectl set-ntp true
timedatectl show-timesync

8. Atualizações Automáticas

sudo apt update && sudo apt upgrade -y
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
# verificar em /etc/apt/apt.conf.d/20auto-upgrades:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

SSL/HTTPS com Certbot

1
DNS
domínio aponta para IP do servidor
2
Nginx Block
server_name configurado
3
Certbot
emite certificado via ACME
4
Auto-renovação
certbot.timer renova a cada 60 dias

Instalar Certbot

sudo apt install certbot python3-certbot-nginx -y

Server Block Nginx (pré-requisito)

Certbot precisa encontrar o domínio no Nginx antes de rodar. Criar o server block primeiro.
sudo nvim /etc/nginx/sites-available/meu-dominio.com
server {
    listen 80;
    listen [::]:80;
    server_name meu-dominio.com www.meu-dominio.com;

    root /var/www/meu-dominio.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
sudo ln -s /etc/nginx/sites-available/meu-dominio.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Certbot — Plugin Nginx (recomendado)

sudo certbot --nginx -d meu-dominio.com -d www.meu-dominio.com
# → email → concordar termos → redirect HTTP→HTTPS (opção 2)

Certbot modifica o server block automaticamente com as diretivas SSL.

Certbot — Modo Standalone

Quando Nginx não está rodando ou para isolar o processo:

sudo systemctl stop nginx
sudo certbot certonly --standalone -d meu-dominio.com
sudo systemctl start nginx

Certificados salvos em /etc/letsencrypt/live/meu-dominio.com/.

Renovação Automática

# Certbot instala timer systemd automaticamente
sudo systemctl status certbot.timer

# testar renovação (--dry-run não altera certificado)
sudo certbot renew --dry-run

# ver certificados instalados
sudo certbot certificates

Cloudflare DNS Challenge (wildcard)

Para *.dominio.com ou quando porta 80 não está acessível:

sudo apt install python3-certbot-dns-cloudflare -y

sudo mkdir -p /root/.secrets
sudo nvim /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = SEU_TOKEN_CLOUDFLARE
sudo chmod 600 /root/.secrets/cloudflare.ini

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d meu-dominio.com \
  -d "*.meu-dominio.com"
Token Cloudflare precisa da permissão: Zone:DNS:Edit para a zona do domínio. Criar em dash.cloudflare.com → My Profile → API Tokens.

Config Nginx com SSL (final)

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name meu-dominio.com www.meu-dominio.com;

    ssl_certificate /etc/letsencrypt/live/meu-dominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/meu-dominio.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/meu-dominio.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name meu-dominio.com www.meu-dominio.com;
    return 301 https://$host$request_uri;
}

Proxy Reverso para Node.js

server {
    listen 443 ssl;
    server_name app.meu-dominio.com;

    # ssl_certificate / ssl_certificate_key...

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Checklist de Segurança

SSH
Login root desabilitado: PermitRootLogin no
Senha desabilitada: PasswordAuthentication no
Acesso só por chave ed25519
AllowUsers configurado
Firewall
UFW ativo: sudo ufw status
Só portas 22, 80, 443 abertas
fail2ban ativo: sudo fail2ban-client status
Sistema
Atualizações automáticas ativas
Timezone correto: timedatectl status
NTP sincronizado
SSL
Certificado válido: sudo certbot certificates
Renovação automática: sudo certbot renew --dry-run
Redirect HTTP→HTTPS funcionando