Módulo 5 · 5.1
Portas e serviços à escuta
Módulo 5: Proteger a rede · Tempo de leitura: 10 minutos
Objetivo de aprendizagem: Depois desta lição, saberá ver que serviços estão à escuta no seu servidor e em que endereço, explicar a diferença entre 0.0.0.0 e 127.0.0.1 e verificar a partir do exterior o que qualquer pessoa na internet vê do seu servidor.
Conceitos-chave: porta, TCP e UDP, escutar, ss -tulpn, 0.0.0.0 e [::], 127.0.0.1 e [::1], bind-address, aberta, fechada e filtrada, superfície de ataque, scanners
Um endereço IP com 65.535 portas
O seu servidor tem um endereço IP, por exemplo 192.0.2.10 e 2001:db8::10. Nesse endereço podem estar acessíveis vários programas ao mesmo tempo, cada um numa porta própria: um número de 1 a 65.535. Um programa que aceita ligações escuta numa porta. Algumas portas conhecidas:
| Porta | Protocolo | Serviço |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (servidor web) |
| 443 | TCP e UDP | https (UDP para HTTP/3) |
| 25 | TCP | correio entre servidores de correio (SMTP) |
| 3306 | TCP | MySQL e MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP é o protocolo para ligações que têm de chegar de forma fiável (web, SSH, bases de dados). UDP serve para pacotes soltos e rápidos (DNS, VPN como o WireGuard, HTTP/3). Um serviço escuta em TCP, em UDP ou em ambos.
Cada porta à escuta é uma porta de entrada no seu servidor. Por trás de cada uma há software que pode conter erros. O conjunto das portas acessíveis a partir do exterior chama-se a sua superfície de ataque. Quanto menor, melhor: um servidor com um site só precisa de ter as portas 22, 80 e 443 acessíveis do exterior.
Ver o que está à escuta: ss
O comando ss (socket statistics) mostra o que está à escuta no seu servidor. Com as opções -t (TCP), -u (UDP), -l (apenas à escuta), -p (que programa) e -n (números, não nomes):
anna@web1:~$ sudo ss -tulpn
Netid State Local Address:Port Peer Address:Port Process
udp UNCONN 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=402,fd=16))
tcp LISTEN 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=611,fd=3))
tcp LISTEN 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=902,fd=6))
tcp LISTEN 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=902,fd=7))
tcp LISTEN 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=755,fd=21))
tcp LISTEN 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=780,fd=6))
tcp LISTEN [::]:22 [::]:* users:(("sshd",pid=611,fd=4))
tcp LISTEN [::]:80 [::]:* users:(("nginx",pid=902,fd=8))
tcp LISTEN [::]:443 [::]:* users:(("nginx",pid=902,fd=9))A coluna mais importante é Local Address: o endereço em que o programa está à escuta.
| Endereço | Significado |
|---|---|
0.0.0.0 | Todos os endereços IPv4 do servidor, incluindo o endereço público: acessível do exterior (a não ser que uma firewall o impeça) |
[::] | Todos os endereços IPv6: o mesmo, para IPv6 |
127.0.0.1 ou [::1] | Apenas o próprio servidor (loopback): nunca acessível do exterior |
127.0.0.53, 127.0.0.54 | Também loopback; aqui escuta o auxiliar de DNS local do systemd-resolved |
192.0.2.10 | Apenas esse endereço |
No exemplo acima, o MariaDB está correto: escuta em 127.0.0.1, pelo que só os programas no próprio servidor (o seu site) lhe conseguem aceder. Mas o Redis escuta em 0.0.0.0:6379. Se a firewall não estiver bem configurada, toda a internet lhe consegue aceder. É precisamente este tipo de erro que esta lição aborda.
Escutar no endereço certo
Uma base de dados, uma cache ou um painel de administração quase nunca deve estar acessível a partir do exterior. A primeira e melhor defesa é o serviço escutar apenas em loopback. Uma firewall (lição 5.2) é a segunda camada; pode estar desligada por engano ou não se aplicar (por exemplo, com o Docker, lição 9.3).
O local onde configura isto varia de programa para programa:
| Programa | Definição | Ficheiro (Debian/Ubuntu) |
|---|---|---|
| MariaDB/MySQL | bind-address = 127.0.0.1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
| PostgreSQL | listen_addresses = 'localhost' | /etc/postgresql/<versie>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 e protected-mode yes | /etc/redis/redis.conf |
Os pacotes do Debian e do Ubuntu já configuram estes serviços em localhost por predefinição. Normalmente, o problema surge quando alguém segue um guia que diz "defina bind-address como 0.0.0.0 para ligar a partir do exterior". Se quiser aceder à base de dados a partir do seu portátil, utilize um túnel SSH (lição 2.3): a porta continua fechada e só quem entra por SSH lhe consegue aceder.
Depois de uma alteração, reinicie o serviço e verifique novamente com ss -tulpn.
Aberta, fechada e filtrada
Vista do exterior, uma porta pode estar em três estados:
- Aberta (open): há algo à escuta e a ligação é estabelecida.
- Fechada (closed): não há nada à escuta, ou uma firewall recusa ativamente. O servidor devolve de imediato um "não" (em TCP, um pacote RST). A ligação falha de imediato com "Connection refused" (ligação recusada).
- Filtrada (filtered): uma firewall descarta o pacote silenciosamente. A ligação fica pendente até ocorrer um time-out.
Para a sua base de dados, fechada e filtrada são ambas boas: ninguém lhe consegue aceder. A diferença apenas lhe diz porquê: filtrada significa quase sempre que é a sua firewall a bloquear.
Verificar a partir do exterior
O ss mostra o que está à escuta no servidor, mas não o que está acessível a partir do exterior. Pelo meio há ainda uma firewall e, por vezes, também uma firewall de rede do seu fornecedor. Por isso, a única verificação real é: verificar a partir do exterior, a partir de outro computador.
A partir do seu próprio computador (não a partir do servidor, porque aí passa pelo loopback), pode fazê-lo com o nc (netcat) para uma porta:
anna@laptop:~$ nc -vz -w 3 192.0.2.10 6379
nc: connect to 192.0.2.10 port 6379 (tcp) failed: Connection refused
anna@laptop:~$ nc -vz -w 3 192.0.2.10 22
Connection to 192.0.2.10 22 port [tcp/ssh] succeeded!No Windows, o PowerShell faz o mesmo com Test-NetConnection 192.0.2.10 -Port 6379. Um scanner de portas como o nmap consegue verificar várias portas de uma vez; utilize um scanner destes apenas no seu próprio servidor.
Não se esqueça do IPv6. Um erro frequente é uma firewall que só tem regras para IPv4, enquanto o serviço também escuta em [::]. Teste, portanto, também o endereço IPv6: nc -6 -vz -w 3 2001:db8::10 6379.
Porque é que isto é tão importante
O seu servidor é analisado desde o primeiro minuto. Motores de pesquisa de dispositivos e serviços na internet, bem como bots de criminosos, percorrem continuamente todos os endereços IPv4 em portas conhecidas. Um Redis aberto sem palavra-passe, um cluster Elasticsearch ou um MongoDB sem controlo de acesso são encontrados em pouco tempo. Fugas de dados devido a bases de dados e clusters de pesquisa abertos surgem regularmente nas notícias, e trata-se quase sempre exatamente deste erro: um serviço destinado a uso interno estava à escuta em todos os endereços.
A porta do SSH também é sondada durante todo o dia. Isso é normal e, com chaves (lição 2.2) e fail2ban (lição 5.3), não constitui problema.
A verificação do curso
No exercício desta lição, o programa do curso verifica a partir do exterior cinco portas fixas de bases de dados do seu servidor: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) e 27017 (MongoDB). O programa apenas tenta estabelecer uma ligação, não envia dados e não inicia sessão em lado nenhum. Não analisa outras portas. As verificações vêm do endereço IP indicado no exercício, para que as possa reconhecer nos seus próprios registos. Um endereço só pode ser verificado algumas vezes por hora.
No AlmaLinux e no Rocky Linux
O ss funciona da mesma forma. Os ficheiros dos serviços estão noutros locais (por exemplo, /etc/my.cnf.d/ para o MariaDB, /var/lib/pgsql/data/postgresql.conf para o PostgreSQL). Além disso, o SELinux pode bloquear um serviço que pretenda escutar numa porta pouco habitual; nesse caso, vê isso em journalctl (lição 6.2) e não em ss.
Resumo
- Cada porta à escuta é uma porta de entrada; mantenha abertas ao exterior apenas as que são realmente necessárias (normalmente 22, 80 e 443).
sudo ss -tulpnmostra que programa está à escuta em que endereço e em que porta.0.0.0.0e[::]significam "todos os endereços",127.0.0.1e[::1]significam "apenas o próprio servidor". Bases de dados, caches e clusters de pesquisa devem estar em loopback.- Fechada e filtrada são ambas boas para uma base de dados; aberta é um erro.
- Verifique sempre a partir do exterior, para IPv4 e IPv6, porque o
ssnão vê a firewall.
Questionário
Exercício
Exercício Z5.1: Portas de bases de dados fechadas ao exterior. Execute sudo ss -tulpn no seu servidor e descubra em que endereços os seus serviços estão à escuta. Depois, peça ao programa do curso que verifique a partir do exterior que as portas 3306, 5432, 6379, 9200 e 27017 do seu servidor não estão acessíveis, para IPv4 e (se o seu servidor tiver um registo AAAA) IPv6. Indique também que serviços estão, no seu caso, à escuta em 0.0.0.0 ou [::]. O programa apenas estabelece uma ligação a essas cinco portas e não envia nada.
