O que são portas e como serviços Linux escutam
Entenda como portas encaminham tráfego para serviços no Linux e use ss para ver o que está escutando, distinguindo portas locais de portas públicas.
O que é efetivamente uma porta
Uma porta é um número que permite que um servidor execute vários serviços ao mesmo tempo sem misturar o respetivo tráfego. O seu VPS tem um endereço IP, mas pode executar simultaneamente um servidor Web, um servidor SSH e uma base de dados. Quando chega um pacote, o sistema operativo precisa de saber a qual desses serviços se destina. O número da porta fornece essa informação. O tráfego HTTPS vai normalmente para a porta 443 e o SSH para a porta 22. O endereço IP entrega o pacote ao servidor; a porta entrega-o ao programa correto nesse servidor.
Uma porta é um número de 16 bits: 16 bits permitem os valores de 0 a 65535, e o valor 0 está reservado, por isso, na prática, as portas vão de 1 a 65535. As portas abaixo de 1024 são as portas "well-known" e, por predefinição, o Linux permite que apenas o root (ou um programa ao qual tenha sido concedida a capability CAP_NET_BIND_SERVICE) as abra. É por isso que os serviços padrão usam essas portas: 22 para SSH, 80 para HTTP, 443 para HTTPS e 53 para DNS. O sysctl net.ipv4.ip_unprivileged_port_start pode alterar esse limite, mas o valor predefinido é 1024. Qualquer porta a partir de 1024 pode ser usada por programas comuns.
Existem dois tipos, TCP e UDP, e o número de uma porta num protocolo é separado do mesmo número no outro. TCP é o protocolo orientado para ligações que a maioria dos serviços usa, incluindo SSH, HTTP e bases de dados. UDP não é orientado para ligações e é usado em serviços como DNS e algumas VPNs. Ao abrir uma porta na firewall, normalmente indica qual dos protocolos está a autorizar, por exemplo 22/tcp.
Escutar significa que um programa está à espera numa porta
Um programa que quer receber ligações pede ao kernel para "escutar" numa porta. A partir desse momento, a porta fica aberta na máquina e o programa responde a tudo o que chega nessa porta, de acordo com a firewall. Uma porta sem nenhum processo a escutar simplesmente recusa as ligações. Por isso, a primeira pergunta em qualquer verificação de segurança é: o que está a escutar e onde.
O comando para responder a essa pergunta é ss:
sudo ss -tlnpAs opções indicam TCP (t), apenas sockets em estado de escuta (l), portas numéricas (n, para ver 22 em vez de ssh) e o processo proprietário (p). Um resultado típico:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxA coluna Process indica qual programa é proprietário de cada porta. É assim que identifica algo que não pretendia deixar em execução.
A coluna Local Address é a parte relevante
Leia atentamente o endereço apresentado antes de cada porta, porque ele determina quem pode aceder ao serviço. Existem três casos que encontrará constantemente.
0.0.0.0:22 significa "escutar em todos os endereços IPv4 que esta máquina possui", incluindo o endereço público. O serviço fica acessível a partir da Internet por IPv4, desde que a firewall o permita.
[::]:80 significa o mesmo para IPv6: escutar em todos os endereços IPv6, incluindo os públicos. Muitos programas fazem bind aqui por predefinição e, no Linux, um socket :: também aceita frequentemente IPv4.
127.0.0.1:5432 significa "escutar apenas no loopback". 127.0.0.1 é o endereço que uma máquina usa para comunicar consigo própria e, com as definições predefinidas do kernel, não é encaminhável a partir de outro local. Um serviço associado a este endereço só pode ser acedido a partir do mesmo servidor, não a partir da Internet, mesmo que a firewall permita a porta. A linha do Postgres apresentada acima é segura por predefinição. A exceção é uma definição do kernel chamada route_localnet: está desativada por predefinição, mas algumas ferramentas ativam-na (o kube-proxy do Kubernetes faz isso) e, com essa definição e as regras de encaminhamento ou NAT corretas, o tráfego destinado ao loopback pode chegar do exterior. sysctl -a | grep route_localnet deve apresentar = 0 em todas as linhas.
A regra prática resulta diretamente daqui: uma base de dados, uma cache ou um painel de administração usado apenas pelas suas próprias aplicações deve fazer bind a 127.0.0.1, não a 0.0.0.0. Se nunca escutar num endereço público, não existe nenhum serviço acessível que um atacante possa atingir.
Escutar não é o mesmo que estar acessível
Existe ainda uma distinção que evita muita confusão. Uma porta estar aberta na máquina, ou seja, existir um programa a escutar, é diferente de essa porta estar acessível a partir do exterior, ou seja, de a firewall permitir o tráfego. Ambas as condições têm de ser verdadeiras para que um cliente remoto consiga estabelecer ligação. As duas falhas também têm comportamentos diferentes no lado do cliente: uma ligação recusada normalmente significa que não havia nenhum processo a escutar, enquanto uma ligação que fica pendurada e termina por timeout normalmente significa que a firewall descartou o pacote. É exatamente isso que esses dois erros de SSH estão a indicar.
Existem, portanto, duas camadas de controlo. Decide o que fica a escutar através do endereço de bind definido em cada serviço. E decide o que o exterior pode alcançar através de uma firewall. Um servidor bem administrado usa ambas: os serviços fazem bind apenas nos endereços de que precisam e a firewall bloqueia tudo o que não tenha sido explicitamente permitido. Consultar o que está a escutar com ss é o primeiro passo; decidir o que a firewall permite é o segundo, conforme explicado em firewalls 101 com UFW.
Existe uma particularidade que causa problemas. IPv4 e IPv6 são separados e uma firewall que cubra apenas IPv4 deixa os serviços [::] acessíveis através de IPv6. Essa armadilha específica é explicada no artigo a armadilha da firewall IPv6.
FAQ
Como vejo que portas estão abertas no meu servidor Linux?
Execute sudo ss -tlnp para TCP ou sudo ss -ulnp para UDP. Esse comando apresenta todos os sockets em escuta, a porta, o endereço local ao qual estão associados e o processo que os possui. Leia a coluna Local Address: 0.0.0.0 ou [::] significa que o serviço está exposto à rede, enquanto 127.0.0.1 significa que escuta apenas na própria máquina.
Qual é a diferença entre 0.0.0.0 e 127.0.0.1?
0.0.0.0 significa "escutar em todos os endereços IPv4", incluindo o endereço público, pelo que o serviço pode ser acedido a partir da rede. 127.0.0.1 é o loopback, o endereço que a máquina usa para comunicar consigo própria. Com as definições predefinidas do kernel, não é encaminhável a partir de outro local, pelo que um serviço associado a esse endereço só pode ser acedido localmente. Faça bind dos serviços internos a 127.0.0.1 para os manter fora da rede.
Preciso de abrir uma porta na firewall para um serviço funcionar?
Apenas para os serviços que têm de ser acedidos a partir de outras máquinas. Um serviço associado a 127.0.0.1 não precisa de uma regra de permissão, porque, com as definições predefinidas do kernel, nada externo lhe pode aceder. Um serviço em 0.0.0.0 ou [::] precisa de uma regra de permissão quando a firewall bloquear por predefinição o tráfego de entrada, como deve acontecer. Se não existir uma firewall ativa, ou se a política aceitar tudo, esse serviço já estará acessível sem qualquer regra.
Qual é a diferença entre uma porta TCP e uma porta UDP?
TCP é orientado para ligações e é usado pela maioria dos serviços, incluindo SSH, servidores Web e bases de dados. UDP não é orientado para ligações e é usado por DNS e algumas VPNs. O mesmo número em TCP e UDP corresponde a portas separadas, por isso 53/tcp e 53/udp são diferentes. Ao escrever regras de firewall, indique o protocolo, por exemplo 22/tcp.