Como trocar a porta SSH no Rocky Linux com SELinux
Veja a ordem segura para trocar a porta SSH no Rocky Linux e AlmaLinux: firewalld, semanage, SELinux e sshd_config, sem perder a sessão atual.
Por que alterar a porta SSH requer três etapas aqui
Para alterar a porta SSH no Rocky Linux, AlmaLinux, CentOS Stream ou Fedora, uma única edição não é suficiente. Três sistemas separados determinam se uma ligação à nova porta funciona. O firewalld decide se o pacote chega à máquina. O SELinux decide se sshd pode fazer bind a esse número de porta. sshd_config decide qual porta o daemon solicita. Se ignorar a etapa do SELinux, o daemon recusa-se a iniciar. Se ignorar a etapa do firewalld, ele inicia, fica à escuta e ninguém consegue aceder-lhe.
No Ubuntu, o mesmo trabalho requer uma edição e um reinício, porque o Ubuntu usa AppArmor em vez de SELinux e não inclui nenhum perfil que restrinja as portas às quais o sshd pode fazer bind. Se o ufw estiver ativo, adicione uma regra. Essa é toda a diferença. A família RHEL inclui o firewalld ativo e o SELinux em modo enforcing numa instalação nova, e ambos consideram os números das portas.
Faça o trabalho por esta ordem para manter a sessão atual ativa durante todas as etapas:
- Abra a nova porta no firewalld, mantendo a porta 22 aberta por enquanto.
- Adicione o rótulo SELinux para a nova porta com
semanage. - Defina a porta na configuração do sshd.
- Reinicie
sshde, em seguida, inicie sessão na nova porta a partir de um segundo terminal antes de fechar o primeiro.
Encontre a consola web do seu fornecedor (VNC ou série) antes de começar e confirme que consegue iniciar sessão através dela. Essa consola é a sua forma de recuperar o acesso se a alteração correr mal. A alteração de uma porta é uma das razões mais comuns para um tenant ficar bloqueado fora de um servidor pelo qual acabou de pagar.
Primeiro, instale o semanage
semanage é a ferramenta que edita as definições da política do SELinux, mas uma instalação mínima do Rocky Linux ou do AlmaLinux não a inclui. A ferramenta está no pacote policycoreutils-python-utils.
sudo dnf install -y policycoreutils-python-utilsExecutar o comando antes de instalar esse pacote produz sudo: semanage: command not found. É nesse ponto que muitos leitores concluem que o SELinux não está instalado e ignoram este passo. O SELinux está instalado. Apenas falta a ferramenta de gestão. Se a sintaxe dnf for nova para si, os equivalentes dos comandos dnf e apt permitem relacioná-la com o que já conhece.
Escolha uma porta e verifique se não está ocupada
Qualquer porta TCP livre entre 1024 e 65535 serve. Faça estas duas verificações antes de escolher uma:
sudo ss -tlnp | grep -w 2222
sudo semanage port -l | grep -w 2222A primeira mostra se já existe um processo escutando nessa porta. A segunda mostra se a política do SELinux já a atribui a outro tipo de serviço. Uma porta livre não retorna nada em nenhuma das verificações. Se a política já a tiver atribuído, o semanage port -a na etapa 2 falha com ValueError: Port tcp/2222 already defined. Nesse caso, escolha outro número.
2222 é usado como exemplo em todo este guia. Também é a primeira porta que um scanner tenta depois da 22. Em um servidor real, escolha uma porta menos óbvia.
Passo 1: abra a porta no firewalld
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports--permanent grava a regra no ficheiro da zona em disco e não altera o firewall em execução. --reload carrega a configuração em disco para o firewall em execução. Se ignorar o reload, a regra existe, mas não tem efeito até o firewalld reiniciar. Esta é uma das formas mais comuns de este procedimento parecer falhar sem motivo.
Por enquanto, não altere a entrada do serviço ssh. Essa entrada mantém a porta 22 aberta e é o seu recurso de fallback durante os testes.
Verifique também o painel de controlo do seu fornecedor. Muitos hosts executam um firewall de rede à frente do VPS, fora do sistema operativo. Por isso, uma porta aberta no firewalld ainda pode ser descartada a montante. O guia básico do firewalld para um VPS explica as zonas e a diferença entre a configuração em execução e a configuração permanente, caso este modelo seja novo para si.
Passo 2: rotule a porta para o SELinux
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -l | grep ssh_port_t-a adiciona uma nova atribuição de porta. -t ssh_port_t é o tipo associado às portas SSH. O segundo comando lista tudo o que ssh_port_t abrange agora, para confirmar que o seu número foi adicionado antes de alterar o daemon.
Por que o SELinux bloqueia a porta
O SELinux (security-enhanced Linux) atribui um rótulo a cada objeto do sistema, e os números das portas TCP são objetos como quaisquer outros. O daemon SSH é executado confinado num domínio chamado sshd_t. A política permite que sshd_t associe portas TCP rotuladas como ssh_port_t e, por padrão, a única porta com esse rótulo é 22. Se o daemon tentar associar a porta 2222, o kernel verifica o rótulo, identifica o tipo genérico que a política atribuiu a esse número e recusa a permissão name_bind no socket.
É por isso que esta falha não se parece com um problema de firewall. O kernel recusa a operação antes de existir um socket em escuta, por isso sshd comunica o erro e termina. Num problema de firewall, acontece o oposto: o daemon está em execução e saudável, mas os pacotes são descartados durante a entrada.
getenforce indica em que modo o sistema está. No modo Permissive, uma recusa é registada, mas não é aplicada. Por isso, a alteração da porta parece funcionar e só falha no dia em que alguém executa setenforce 1 ou o sistema reinicia no modo enforcing. Rotule a porta de qualquer forma. O guia básico de SELinux para um servidor explica corretamente os modos, os contextos e os booleanos.
Passo 3: definir a porta na configuração do sshd
No Rocky Linux 9 e 10, AlmaLinux 9 e 10 e Fedora atual, /etc/ssh/sshd_config começa com uma linha de inclusão. Por isso, o local adequado para a alteração é um ficheiro drop-in. As atualizações dos pacotes nunca entram em conflito com a sua alteração.
grep -n '^Include' /etc/ssh/sshd_config
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -tSe grep não encontrar nenhuma linha Include, como acontece no Rocky Linux 8 e noutras imagens mais antigas, coloque Port 2222 diretamente em /etc/ssh/sshd_config. sshd -t analisa toda a configuração, incluindo os ficheiros drop-in, e comunica erros de sintaxe. Corrija todos os erros comunicados antes de reiniciar, porque uma configuração que não pode ser analisada impede o daemon de voltar a arrancar.
Port pode aparecer mais do que uma vez, e o sshd escuta em todas as portas listadas. Manter Port 22 juntamente com Port 2222 durante o primeiro dia é uma medida de segurança simples, desde que se lembre de o remover.
O seu sshd é iniciado por uma unidade de socket?
Algumas imagens iniciam o SSH através da ativação de sockets do systemd, em vez de o executarem como um serviço de longa duração. Quando essa configuração está ativa, o systemd controla o socket de escuta e entrega as ligações ao sshd. Por isso, a linha Port em sshd_config é totalmente ignorada. Verifique antes de reiniciar qualquer serviço:
systemctl is-enabled sshd.socketUma resposta enabled significa que a porta está definida na unidade de socket, e não em sshd_config:
sudo systemctl edit sshd.socket[Socket]
ListenStream=
ListenStream=2222O ListenStream= sem valor é obrigatório. Os valores acumulam-se entre os ficheiros drop-in. Sem uma atribuição vazia para limpar primeiro a lista, o socket continua a escutar na porta 22 e também na 2222. Aplique a alteração com sudo systemctl daemon-reload e depois sudo systemctl restart sshd.socket. Se a unidade estiver desativada ou não existir no seu servidor, esta seção não se aplica a você.
Etapa 4: reinicie e teste a partir de um segundo terminal
sudo systemctl restart sshd
systemctl status sshd
sudo ss -tlnp | grep sshdMantenha este terminal aberto. Não termine a sessão. Abra um segundo terminal na sua própria máquina e ligue-se à nova porta:
ssh -p 2222 youruser@203.0.113.10Feche a primeira sessão apenas depois de o segundo início de sessão funcionar. Se não funcionar, ainda terá uma shell a partir da qual pode reverter todas as alterações. Este hábito pode evitar resolver um problema de cinco minutos na consola do fornecedor durante uma tarde inteira.
Firewall: bloqueio ou negação do SELinux? Como distingui-los
A partir do seu laptop, as duas falhas parecem quase idênticas. No servidor, não se parecem em nada.
- Se
systemctl status sshdindicar que a unidade falhou, o daemon nunca obteve o seu socket. Isto indica um erro de configuração ou uma negação do SELinux. - Se a unidade estiver ativa e
ss -tlnpindicar que o sshd está associado à nova porta, o daemon está correto e o problema está no caminho de rede: firewalld, a firewall separada do fornecedor ou o endereço e a porta utilizados na ligação.
No caso do SELinux, leia o registo de auditoria em vez de tentar adivinhar:
sudo ausearch -m AVC -ts recent
sudo journalctl -u sshd -n 50 --no-pagerUma negação name_bind na classe tcp_socket identifica o processo em comm="sshd", o número da porta em src= e o rótulo efetivamente atribuído à porta em tcontext=. Esse último campo contém a resposta. Qualquer valor diferente de ssh_port_t significa que o passo 2 não foi aplicado à porta utilizada, normalmente devido a um erro no número ou ao protocolo incorreto. Instale setroubleshoot-server se preferir que sealert transforme o registo numa frase.
A mensagem que o próprio sshd escreve quando o kernel recusa a associação da porta é semelhante a esta:
error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.Permission denied numa porta acima de 1024, onde não é necessário privilégio de root para fazer a associação, é a assinatura do SELinux. Address already in use nessa mesma linha indica uma falha diferente: outro processo está a ocupar a porta. Do lado do cliente, a diferença entre ligação recusada e ligação expirada permite distinguir os dois casos de rede, porque uma recusa significa que o pacote chegou ao host e não havia nada a escutar, enquanto um timeout significa que nada respondeu.
Feche a porta 22 e atualize os clientes
Depois de vários logins na nova porta terem funcionado, remova a porta 22:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-allNão altere o rótulo SELinux da porta 22. Ele vem da política base e não concede acesso quando o firewall deixa de aceitar pacotes nessa porta.
Depois, corrija os clientes, porque todas as ferramentas que assumiam a porta padrão precisam de receber essa informação. Configure isto uma vez em ~/.ssh/config na sua própria máquina, em vez de escrever -p sempre:
Host myvps
HostName 203.0.113.10
Port 2222
User youruserscp, sftp, rsync e Ansible leem esse ficheiro. As tarefas de backup, as verificações de monitorização e os scripts do cron que têm a porta 22 definida diretamente não leem esse ficheiro. Procure-os enquanto a alteração ainda está recente.
O que mudar a porta resolve e o que não resolve
Isto reduz o ruído nos logs. Scanners automatizados atacam constantemente a porta 22, e mudar o serviço para outra porta remove a maioria dessas linhas do journal, o que facilita a identificação de eventos reais. Isto não é um controlo de segurança. Qualquer scanner que percorra todo o intervalo de portas encontra o seu daemon e lê igualmente o banner da respetiva versão. Trate a alteração da porta como uma tarefa de manutenção e aplique a proteção efetiva através de autenticação apenas por chave, com os logins por palavra-passe desativados. O guia de reforço de segurança do SSH para um VPS explica este procedimento passo a passo.
Tudo o que foi apresentado acima funciona de forma idêntica nas duas principais reconstruções do RHEL, porque são compiladas a partir das mesmas fontes. Consulte Rocky Linux e AlmaLinux comparados se ainda estiver a escolher entre os dois. Confirme qual versão recebeu antes de seguir um guia antigo, com cat /etc/os-release. Os guias escritos para Rocky Linux 8 continuam bem posicionados, e os passos semanage e firewall-cmd continuam corretos. No entanto, o Rocky 8 não tem a linha de inclusão sshd_config.d nem uma socket unit a considerar. Por isso, a parte sobre sshd desses guias não corresponde a um sistema atual.
o fail2ban precisa ser configurado para usar a nova porta
O fail2ban não está nos repositórios base. Ele vem do EPEL (pacotes adicionais para Enterprise Linux):
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalldO subpacote fail2ban-firewalld faz o fail2ban aplicar os bans através do firewalld. É o que deve ser usado num servidor em que o firewalld gere o conjunto de regras.
A jail padrão sshd define port = ssh, e esse nome é resolvido através de /etc/services para a porta 22. Depois da alteração, a jail monitoriza uma porta que ninguém está a atacar. Por isso, não aplica bans, enquanto as tentativas de início de sessão falhadas se acumulam na porta 2222. Defina a porta pelo número em /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
bantime = 3600backend = systemd lê as falhas do journal em vez de /var/log/secure. Esta é a opção mais segura numa instalação mínima em que rsyslog pode não estar presente. Inicie-o com sudo systemctl enable --now fail2ban e consulte a jail com sudo fail2ban-client status sshd. A sintaxe da jail é a mesma usada em a configuração do fail2ban para SSH no Ubuntu 24.04. Apenas a origem do pacote e a ação de ban diferem.
A aplicação de patches é mais importante do que a porta
Um servidor com a porta SSH alterada e quatro meses de atualizações de segurança por aplicar está numa situação pior do que um servidor na porta 22 que instala patches todas as noites. Ative as atualizações automáticas na mesma sessão, enquanto já está como root: atualizações automáticas do dnf no Rocky Linux e no AlmaLinux explica a configuração do timer e a escolha entre descarregar as atualizações e aplicá-las.
FAQ
Por que o sshd falha ao iniciar depois de eu alterar a porta no Rocky Linux?
Quase sempre, falta o rótulo de porta do SELinux. sshd é executado confinado no domínio sshd_t, e a política só permite associá-lo a portas rotuladas como ssh_port_t, que, por padrão, inclui apenas a porta 22. O kernel recusa a associação, por isso o daemon termina em vez de escutar, e journalctl -u sshd contém uma linha no formato error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.. Execute sudo semanage port -a -t ssh_port_t -p tcp 2222 com o número da sua porta e reinicie o serviço. Se semanage não for encontrado, instale policycoreutils-python-utils primeiro.
Ainda preciso de semanage se o SELinux estiver no modo permissivo?
Sim. No modo permissivo, a negação é registada e a associação é permitida mesmo assim, por isso a alteração parece ter funcionado. O rótulo continua em falta. Assim que alguém executar setenforce 1, ou o servidor arrancar com SELINUX=enforcing em /etc/selinux/config, o sshd deixará de iniciar nessa porta. Adicionar o rótulo requer um comando e elimina uma falha que, de outro modo, só surgiria semanas depois, sem uma causa evidente.
A porta está rotulada e o sshd está em execução. Por que a minha ligação expira?
Um daemon em execução significa que o SELinux está satisfeito. Portanto, o pacote está a ser descartado no percurso de entrada. Verifique sudo firewall-cmd --list-ports relativamente à sua porta e confirme que executou firewall-cmd --reload depois da regra --permanent, porque uma regra permanente, por si só, nunca é aplicada à firewall em execução. Em seguida, verifique o painel de controlo do seu host para procurar uma firewall de rede separada à frente do VPS. Esse é o segundo ponto onde as ligações podem ser bloqueadas, e nada dentro do sistema operativo o indicará.
Que porta devo usar em vez da 22?
Qualquer porta TCP livre entre 1024 e 65535. Evite 2222 e 22222 num servidor real, porque os scanners tentam essas portas imediatamente depois da 22. Confirme que o número está livre com sudo ss -tlnp, confirme que a política do SELinux ainda não o atribuiu com sudo semanage port -l e não use uma porta atribuída a um serviço que possa instalar mais tarde. Um número alto e difícil de memorizar é adequado, porque irá registá-lo em ~/.ssh/config uma vez e nunca mais terá de o escrever.