−25%

no Windows com pagamento anual, até 31/10. Ver planos

EQVPS
Começar

Como configurar um VPS com Alpine Linux: apk, doas, OpenRC e firewall

Primeiros passos num VPS novo com Alpine Linux 3.21: atualizar e reiniciar, criar um usuário com doas que consegue mesmo entrar, desligar o login SSH de root e por senha, instalar o ufw, ativar o cron e as atualizações diárias. Inclui a porta do Docker que o ufw não bloqueia.

O Alpine Linux é a menor imagem que oferecemos. Nos nossos servidores, um Alpine 3.21 recém-instalado usava em repouso 55 MB de RAM e 153 MB de disco, contra 313 MB e 2,7 GB do Ubuntu 24.04. Em troca, você abre mão das ferramentas de sempre. O Alpine usa apk em vez de apt, doas em vez de sudo, OpenRC em vez de systemd e musl em vez de glibc.

Os passos abaixo são os mesmos primeiros dez minutos do Debian ou do Ubuntu, traduzidos para o Alpine. Rodamos cada comando na nossa imagem do Alpine 3.21 antes de publicar, e dois deles nos pegaram na primeira vez. Entre como root com a senha do seu painel.

1. Atualize e reinicie uma vez

apk update && apk upgrade
uname -r
ls /lib/modules

Seu servidor já instalou as atualizações disponíveis no primeiro boot, então o apk upgrade costuma ter pouco a fazer. Olhe para as duas últimas linhas. Se essa primeira atualização trouxe um kernel novo, o kernel em execução (uname -r) não tem mais seus módulos no disco. Tudo o que carrega um módulo falha até você reiniciar. No nosso servidor de teste, a instalação do firewall mostrou ERROR: Couldn't determine iptables version. Se as duas versões forem diferentes, reinicie agora:

reboot

Nosso servidor de teste voltou em menos de um minuto.

2. Crie um usuário que consiga entrar

adduser -D deploy
passwd deploy
adduser deploy wheel

Não pule o passwd. O adduser -D cria a conta sem senha, o Alpine a marca como bloqueada e o sshd recusa uma conta bloqueada mesmo com a chave correta. No nosso teste, a única pista foi esta linha em /var/log/messages:

User deploy not allowed because account is locked

A senha também importa depois: é ela que o doas vai pedir.

Se você adicionou uma chave SSH ao pedir o servidor, ela está no authorized_keys do root. Copie-a para o novo usuário:

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys

Ainda não tem chave? Crie uma no seu computador e cole a parte pública em /home/deploy/.ssh/authorized_keys.

3. Faça o doas pedir a senha

O Alpine usa doas em vez de sudo, e a nossa imagem já o libera para o grupo wheel. A regra em /etc/doas.d/wheel.conf é permit nopass :wheel, ou seja, qualquer membro de wheel vira root sem digitar nada. Faça-o pedir a senha e lembrá-la por alguns minutos:

echo 'permit persist :wheel' > /etc/doas.d/wheel.conf

A partir de agora, doas apk add nano funciona como sudo apt install nano no Ubuntu.

4. SSH: só chaves, sem root

O sshd lê os arquivos de /etc/ssh/sshd_config.d/ em ordem de nome e fica com o primeiro valor que encontra para cada configuração. Na nossa imagem, o primeiro arquivo é 00-eqvps.conf, que libera root e senha para você conseguir entrar no primeiro dia. Substitua o conteúdo dele:

cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '

A terceira linha faz diferença no Alpine. A imagem usa a versão do OpenSSH com PAM, e só com as duas primeiras linhas nosso servidor de teste ainda oferecia login keyboard-interactive. Com as três, uma tentativa de login sem chave recebe:

Permission denied (publickey).

Mantenha a sessão de root aberta. Num segundo terminal, confira se ssh deploy@YOUR.SERVER.IP funciona (num plano NAT, acrescente -p e a porta pessoal do painel) e se doas id aceita a senha.

5. Firewall: ufw

O ufw está no repositório community, que já vem ativado na nossa imagem:

apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status

O limit deixa o SSH passar, mas freia quem abre muitas conexões seguidas. O rc-update importa aqui, porque o OpenRC não inicia o firewall após um reboot se você não o colocar no runlevel. Depois de reiniciar, nosso servidor voltou com Status: active. Num plano NAT, deixe o SSH na porta 22: sua porta externa pessoal é redirecionada para a 22 dentro do servidor. Num plano com IPv4 próprio, abra as portas web quando precisar (ufw allow 80/tcp, ufw allow 443/tcp). O guia do ufw cobre o resto.

6. Ative o cron e as atualizações diárias

Um Alpine recém-instalado não roda cron nenhum. Ative-o:

rc-update add crond default
rc-service crond start

O crontab do root no Alpine já roda tudo o que está em /etc/periodic/daily às 02:00. Coloque ali um script de atualização:

cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily

O último comando lista os scripts que o cron vai rodar, e o seu deve aparecer. Assim você recebe as correções da 3.21. Passar para a próxima versão do Alpine é um passo separado e manual. Atualizações de kernel ainda exigem reboot: repita de vez em quando a verificação uname -r / ls /lib/modules do passo 1.

7. OpenRC numa tabela

Se você conhece o systemd, é isto que muda, em resumo:

TarefasystemdAlpine (OpenRC)
Iniciar um serviçosystemctl start nginxrc-service nginx start
Iniciar no bootsystemctl enable nginxrc-update add nginx default
Statussystemctl status nginxrc-service nginx status
O que está rodandosystemctl list-unitsrc-status
Log do sistemajournalctl/var/log/messages

8. Docker, e a porta que o ufw não bloqueia

O Alpine é um bom host de Docker, porque o próprio sistema quase não atrapalha:

apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world

No nosso servidor isso levou 12 segundos, já com o download. Com o daemon do Docker rodando, a memória usada foi de 57 MB para 124 MB.

Uma armadilha que não é só do Alpine: o Docker escreve as próprias regras de firewall. Com o ufw liberando só o SSH, iniciamos o nginx com -p 8080:80 e o acessamos de fora do servidor na porta 8080. O ufw não bloqueou. Se um contêiner só deve ser acessado por um proxy reverso no mesmo servidor, publique-o em localhost:

docker run -d -p 127.0.0.1:8080:80 nginx:alpine

Qual plano

O Alpine deixa quase toda a RAM para o seu próprio software. O plano Nano (2 vCPU, 1 GB, 15 GB, $3/mês) basta para um serviço pequeno ou alguns contêineres. É um plano NAT, então o SSH entra por uma porta pessoal. Se precisar das portas 80 e 443 abertas para a internet, o Nano-IP tem IPv4 próprio por $8/mês. Para pilhas Docker mais pesadas, o Micro dá 2 GB por $5/mês.

O Alpine 3.21 está na página do Alpine VPS e disponível em todos os planos Linux em VPS. O pagamento é em USDT, USDC ou ETH nas redes Base, Ethereum ou Polygon, sem documento nem cartão.

Perguntas frequentes

Por que o Alpine é tão menor que o Ubuntu ou o Debian?

Ele usa musl em vez de glibc, BusyBox para os comandos básicos e OpenRC em vez de systemd. Nos nossos servidores, um Alpine 3.21 recém-instalado usava em repouso 55 MB de RAM e 153 MB de disco. O Ubuntu 24.04 usava 313 MB e 2,7 GB.

Por que meu novo usuário recebe "account is locked" mesmo com a chave certa?

O adduser -D cria a conta sem senha, o Alpine a marca como bloqueada e o sshd recusa esse usuário mesmo com uma chave válida. A linha no log é "User deploy not allowed because account is locked". Defina uma senha com passwd e o login por chave passa a funcionar.

Por que um túnel SSH não funciona no Alpine?

O /etc/ssh/sshd_config padrão do Alpine tem AllowTcpForwarding no, então os redirecionamentos ssh -L são recusados. Se precisar de túneis, mude para yes nesse arquivo e rode rc-service sshd restart.

Meu programa vai rodar no Alpine?

Tudo o que vem dos repositórios do Alpine roda, assim como contêineres Docker feitos sobre qualquer imagem base. Binários Linux prontos, compilados para glibc, muitas vezes não iniciam no musl. Procure uma versão para Alpine ou musl, ou rode o programa no Docker. O pacote gcompat ajuda com alguns binários glibc simples.

Qual plano basta para o Alpine?

O plano Nano de 1 GB por $3 por mês tem folga de sobra: o próprio sistema usa cerca de 55 MB. Se precisar das portas 80 e 443 abertas para a internet, escolha o Nano-IP por $8 por mês, que tem IPv4 próprio.

Comentários

Nenhum comentário ainda. Seja o primeiro.

Deixe um comentário

Os comentários são moderados antes de aparecerem.