#!/bin/sh
set -eu

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'

say() { printf "${GREEN}✔${NC} %s\n" "$1"; }
info() { printf "${BLUE}ℹ${NC} %s\n" "$1"; }
warn() { printf "${YELLOW}⚠${NC} %s\n" "$1"; }
fail() { printf "${RED}✖${NC} %s\n" "$1"; exit 1; }

[ "$(id -u)" -eq 0 ] || fail "Este script precisa ser executado como root."

printf "\n${BLUE}=== Configuração inicial segura Debian/Ubuntu ===${NC}\n\n"

printf "Nome do novo usuário: "
read -r NEW_USER

[ -n "$NEW_USER" ] || fail "Nome de usuário vazio."
echo "$NEW_USER" | grep -Eq '^[a-z_][a-z0-9_-]*[$]?$' || fail "Nome de usuário inválido."

if id "$NEW_USER" >/dev/null 2>&1; then
  warn "Usuário '$NEW_USER' já existe. Vou reutilizá-lo."
else
  adduser --disabled-password --gecos "" "$NEW_USER"
  say "Usuário '$NEW_USER' criado."
fi

printf "\nCole a chave pública SSH abaixo.\n"
printf "Exemplo: ssh-ed25519 AAAAC3... usuario@maquina\n\n"
printf "Chave pública: "
read -r SSH_PUBKEY

printf "\n${YELLOW}Chave recebida:${NC}\n%s\n\n" "$SSH_PUBKEY"

echo "$SSH_PUBKEY" | grep -Eq '^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) [A-Za-z0-9+/=]+( .*)?$' \
  || fail "A chave pública SSH parece inválida."

USER_HOME=$(getent passwd "$NEW_USER" | cut -d: -f6)
SSH_DIR="$USER_HOME/.ssh"

mkdir -p "$SSH_DIR"
printf "%s\n" "$SSH_PUBKEY" > "$SSH_DIR/authorized_keys"

chown -R "$NEW_USER:$NEW_USER" "$SSH_DIR"
chmod 700 "$SSH_DIR"
chmod 600 "$SSH_DIR/authorized_keys"

say "Chave pública adicionada em $SSH_DIR/authorized_keys."

printf "\nBloco IPv4 permitido para SSH/input, exemplo 203.0.113.0/24.\n"
printf "Deixe vazio se não quiser liberar IPv4: "
read -r IPV4_BLOCK

printf "\nBloco IPv6 permitido para SSH/input, exemplo 2001:db8::/32.\n"
printf "Deixe vazio se não quiser liberar IPv6: "
read -r IPV6_BLOCK

[ -n "$IPV4_BLOCK$IPV6_BLOCK" ] || fail "Você precisa informar pelo menos um bloco IPv4 ou IPv6."

info "Instalando pacotes necessários..."
apt-get update
apt-get install -y openssh-server nftables

say "Pacotes instalados."

SSHD_CONFIG="/etc/ssh/sshd_config"
SSHD_DROPIN_DIR="/etc/ssh/sshd_config.d"
SSHD_DROPIN="$SSHD_DROPIN_DIR/99-hardening.conf"

mkdir -p "$SSHD_DROPIN_DIR"

cat > "$SSHD_DROPIN" <<EOF
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
PermitEmptyPasswords no
EOF

sshd -t || fail "Configuração do SSH inválida. Nada foi reiniciado."

systemctl enable ssh >/dev/null 2>&1 || true
systemctl restart ssh || systemctl restart sshd

say "SSH configurado para aceitar apenas chave e bloquear login root."

NFT_CONF="/etc/nftables.conf"

cat > "$NFT_CONF" <<EOF
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
  chain input {
    type filter hook input priority 0;
    policy drop;

    iif lo accept

    ct state established,related accept
    ct state invalid drop

    ip protocol icmp accept
    ip6 nexthdr ipv6-icmp accept

EOF

if [ -n "$IPV4_BLOCK" ]; then
cat >> "$NFT_CONF" <<EOF
    ip saddr $IPV4_BLOCK tcp dport 22 accept
EOF
fi

if [ -n "$IPV6_BLOCK" ]; then
cat >> "$NFT_CONF" <<EOF
    ip6 saddr $IPV6_BLOCK tcp dport 22 accept
EOF
fi

cat >> "$NFT_CONF" <<EOF
  }

  chain forward {
    type filter hook forward priority 0;
    policy drop;
  }

  chain output {
    type filter hook output priority 0;
    policy accept;
  }
}
EOF

nft -c -f "$NFT_CONF" || fail "Configuração do nftables inválida. Verifique os blocos de IP informados."

systemctl enable nftables
systemctl restart nftables

say "nftables configurado e ativado."

printf "\n${GREEN}=== Resumo final ===${NC}\n"
printf "Usuário criado/configurado: %s\n" "$NEW_USER"
printf "Chave SSH instalada em: %s\n" "$SSH_DIR/authorized_keys"
printf "Login SSH por senha: desabilitado\n"
printf "Login SSH como root: desabilitado\n"
printf "Firewall: nftables ativo\n"
printf "Política de INPUT: drop por padrão\n"
printf "Ping IPv4: liberado\n"
printf "Ping IPv6: liberado\n"

if [ -n "$IPV4_BLOCK" ]; then
  printf "SSH IPv4 liberado para: %s\n" "$IPV4_BLOCK"
else
  printf "SSH IPv4: não liberado\n"
fi

if [ -n "$IPV6_BLOCK" ]; then
  printf "SSH IPv6 liberado para: %s\n" "$IPV6_BLOCK"
else
  printf "SSH IPv6: não liberado\n"
fi

printf "\n${YELLOW}Importante:${NC} antes de fechar sua sessão atual, teste outro login SSH com:\n"
printf "ssh %s@SEU_SERVIDOR\n\n" "$NEW_USER"