Pular para o conteúdo
Novo

DeepSeek V4.1 Flash grátis por 7 dias: 10M tokens por dia após qualquer recarga. Até 30/11.

Como funciona

TCP/IP e portas: como os serviços escutam na sua máquina

Porta é uma entrada numerada na sua máquina. Entenda como TCP e UDP usam portas e teste um servidor local em 127.0.0.1.

Iniciante12 min de leituraPor NotHoly

Porta é um número que diz ao sistema operacional qual programa deve receber um pedaço de tráfego de rede. Sua máquina tem um endereço IP e pode rodar dezenas de programas de rede ao mesmo tempo: um navegador que busca páginas, um cliente de e-mail, um banco de dados, um servidor web local. O endereço IP leva o tráfego até o computador certo. A porta leva até o programa certo.

Se você leu o que é DNS, já sabe como um nome vira um endereço. Este artigo explica de onde vêm as portas, como os dois principais protocolos de transporte as usam e como descobrir em quais portas a sua própria máquina está escutando. O laboratório roda em 127.0.0.1, o endereço de loopback que sempre significa "esta máquina", então nada sai do seu computador.

O que é uma porta

Uma porta é um número de 16 bits, ou seja, vai de 0 a 65535. Os cabeçalhos de TCP e UDP carregam uma porta de origem e uma porta de destino. Quando um pacote chega ao seu computador, o sistema operacional lê a porta de destino e entrega os dados ao programa que pediu para receber naquele número.

Pense num prédio de apartamentos. O endereço da rua leva a entrega até o prédio. O número do apartamento diz ao entregador em qual porta bater. Nessa imagem, o IP é o prédio e a porta é o apartamento. Alguém decide qual número é de qual apartamento, e um morador pode sair e deixar o número para outro.

Uma porta em escuta é aquela em que um programa avisou o sistema operacional, na prática, "me mande as conexões deste número". Um programa nesse estado está escutando. Quando ele encerra, o sistema libera a porta e ninguém mais responde ali.

Por que isso importa

Todo serviço que você roda abre pelo menos uma porta. Isso inclui programas que você não iniciou de propósito: atualizadores, clientes de sincronização, servidores de desenvolvimento, plugins e softwares que se instalam como serviço em segundo plano. A lista de portas em escuta é a forma mais simples e fiel de ver o que a sua máquina oferece para a rede.

Se um dia você revisar um host que é seu, essa lista é a primeira coisa a anotar. Antes de perguntar se um serviço está atualizado ou bem configurado, você precisa saber que ele existe. O trabalho de segurança começa pelo inventário, e o inventário começa pelas portas.

As camadas em uma passada

TCP/IP é o conjunto de protocolos sobre o qual a internet funciona. Ele é organizado em camadas, e você não precisa de todas agora. Quatro camadas importam aqui:

  • Enlace: move quadros dentro de um mesmo segmento de rede local, como Wi-Fi ou Ethernet.
  • Internet: o IP move pacotes entre hosts por várias redes, usando endereços IP.
  • Transporte: TCP ou UDP levam dados entre programas, usando portas.
  • Aplicação: o protocolo que o programa fala, como HTTP, DNS ou SSH.

Cada camada envolve os dados da camada de cima com um cabeçalho próprio. O cabeçalho IP leva os endereços de origem e destino. O cabeçalho TCP ou UDP leva as portas de origem e destino. Os dados da aplicação ficam dentro. Quando o pacote chega, cada camada remove o seu cabeçalho e passa o resto para cima.

A porta vive na camada de transporte. O IP não sabe qual programa deve receber os dados. Essa tarefa é da camada de transporte, e é por isso que um único endereço IP pode servir uma página web na porta 443 e um banco de dados na porta 5432 ao mesmo tempo.

Como o TCP abre uma conexão

O TCP, especificado na RFC 9293, oferece a um programa um fluxo confiável e ordenado de bytes. Antes que qualquer dado da aplicação circule, as duas pontas combinam números de sequência iniciais e confirmam que cada lado consegue enviar e receber. Esse acordo é o three-way handshake, o aperto de mão em três etapas.

  1. O cliente envia um segmento SYN. Em termos simples, ele diz: quero me conectar à porta 8000, e meu número de sequência inicial é X.
  2. Se algum programa escuta na porta 8000, o servidor responde com SYN-ACK. Ele confirma X e envia o próprio número inicial.
  3. O cliente responde com ACK. A conexão está aberta, e o cliente pode enviar a requisição.

Quando nenhum programa escuta na porta, a máquina de destino não envia SYN-ACK. Ela envia um segmento RST (reset), e o cliente desiste na hora com uma mensagem como "conexão recusada". Essa resposta rápida é útil. Ela mostra que o host recebeu o seu pacote e que nada aceita conexões naquela porta.

Uma espera silenciosa que termina em timeout quer dizer outra coisa. Muitas vezes um firewall descartou os pacotes sem responder. Então "recusada" e "tempo esgotado" são pistas diferentes. Aprenda a lê-las.

As conexões em 127.0.0.1 usam a mesma lógica de TCP, mesmo que os pacotes nunca cheguem a uma placa de rede. O sistema operacional executa o handshake em software, o que torna o endereço de loopback um bom lugar para praticar.

Como o UDP é diferente

O UDP, especificado na RFC 768, é bem mais simples. O cabeçalho tem 8 bytes: porta de origem, porta de destino, tamanho e checksum. Não há handshake, não há confirmação, não há retransmissão e não há ordenação. O remetente envia um datagrama, e a rede o entrega ou não. O receptor não confirma nada, a menos que a própria aplicação implemente essa lógica.

Essa simplicidade tem utilidade. Consultas DNS costumam viajar por UDP na porta 53, porque uma pergunta curta e uma resposta curta cabem numa troca só, e um handshake acrescentaria idas e voltas. Voz e vídeo em tempo real também costumam usar UDP, e o mesmo vale para o QUIC, o transporte por baixo do HTTP/3. Cada um desses protocolos traz suas próprias regras para perda e reenvio.

As portas funcionam do mesmo jeito no UDP. A porta de destino escolhe o programa. A diferença é que uma porta UDP não guarda estado de conexão. Qualquer programa ligado a essa porta recebe o que chegar, de quem quer que envie. Um listener TCP só enxerga conexões que completaram o handshake. Nos dois casos, a pergunta é a mesma: qual programa deve receber este pacote.

Quem decide qual número significa o quê

A IANA (Internet Assigned Numbers Authority) mantém o Service Name and Transport Protocol Port Number Registry. O registro indica qual serviço é normalmente associado a cada número de porta, para TCP, UDP e alguns outros protocolos de transporte. Entre as entradas mais conhecidas estão 22 para ssh, 53 para domain (DNS), 80 para http e 443 para https.

A RFC 6335 divide o espaço de números em três faixas:

  • 0 a 1023: portas de sistema, também chamadas de portas bem conhecidas. Em muitos sistemas, só processos com privilégio podem ligar essas portas.
  • 1024 a 49151: portas de usuário, onde fornecedores registram muitos serviços.
  • 49152 a 65535: portas dinâmicas ou privadas. Clientes costumam usá-las como portas de origem temporárias.

O registro descreve atribuições e convenções. Nada no TCP ou no UDP as impõe. Qualquer programa com permissão pode ligar quase qualquer porta livre. O registro diz o que costuma rodar em um número, e pode estar errado sobre a sua máquina. Veja o que está de fato escutando antes de tirar conclusões.

Laboratório prático: um servidor web local em 127.0.0.1

Você precisa de um terminal e de Python 3. O laboratório usa o servidor HTTP que já vem com o Python, então não há nada extra para instalar.

Rodei os comandos do Windows abaixo no Windows 11 Pro, com Git Bash, Python 3.12.10 e curl 8.12.1. Não rodei os comandos de Linux e macOS nesta máquina, então a saída deles não aparece aqui. Sempre que aparece um bloco de saída, ele veio do comando logo acima.

Uma observação sobre o Python: na minha sessão do Git Bash, python3 não foi encontrado, enquanto python rodou o Python 3.12. Se python3 falhar no Windows, use python. O resto do comando continua igual.

Passo 1: crie uma pasta com um arquivo

O servidor publica o que estiver na pasta onde você o iniciar, então coloque algo pequeno lá primeiro.

bash
mkdir -p ~/port-lab && cd ~/port-lab
printf '<!doctype html><title>lab</title><h1>Port 8000 lab</h1>\n' > index.html

No PowerShell, crie a mesma pasta e escreva essas duas linhas em index.html com qualquer editor.

Passo 2: inicie o servidor e deixe-o rodando

Mantenha este terminal aberto. O servidor roda até você pará-lo.

bash
cd ~/port-lab
python3 -m http.server 8000 --bind 127.0.0.1

A opção --bind 127.0.0.1 diz ao Python para escutar apenas na interface de loopback. Sem ela, o Python escuta em todas as interfaces da máquina. Essa diferença aparece depois, na lista de portas em escuta.

Passo 3: encontre o socket em escuta

Escolha o comando do seu sistema operacional. Cada um lista os sockets em estado LISTEN que usam a porta 8000.

Linux:

bash
ss -tlnp | grep 8000

macOS:

bash
lsof -iTCP -sTCP:LISTEN -n -P | grep 8000

Windows PowerShell:

powershell
Get-NetTCPConnection -State Listen -LocalPort 8000

Esta é a saída que obtive com o comando do Windows na minha máquina, passada por Format-Table:

text
LocalAddress LocalPort  State OwningProcess
------------ ---------  ----- -------------
127.0.0.1         8000 Listen         45608

O número do processo vai ser diferente na sua máquina. Rode Get-Process -Id <OwningProcess> com o seu número para confirmar que o dono é o processo Python que você iniciou. Na minha execução era o python.

O que observar:

  • LocalAddress é 127.0.0.1. O socket aceita conexões só desta máquina. Se você tivesse omitido --bind, o esperado seria ver 0.0.0.0 aqui. Não testei essa variante nesta máquina, então trate isso como resultado esperado, não como observado.
  • State é Listen. O socket está esperando conexões.
  • OwningProcess aponta para o programa que você espera. Se apontar para algo que você não reconhece, pare e descubra o que é antes de seguir.

Passo 4: conecte-se a ele

Abra um segundo terminal e rode:

bash
curl -v http://127.0.0.1:8000/

Esta é a saída da minha execução, cortada nas linhas que importam:

text
* Trying 127.0.0.1:8000...
* Connected to 127.0.0.1 (127.0.0.1) port 8000
> GET / HTTP/1.1
> Host: 127.0.0.1:8000
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.12.10
< Content-type: text/html
<!doctype html><title>lab</title><h1>Port 8000 lab</h1>

Leia na ordem. Trying quer dizer que o curl está abrindo uma conexão TCP. O endereço já é um IP, então não há consulta DNS. Connected significa que o handshake terminou. GET / HTTP/1.1 é a camada de aplicação: o curl agora fala HTTP sobre essa conexão. 200 OK quer dizer que o servidor achou o arquivo e respondeu. A linha HTML no fim é o seu arquivo.

O servidor também escreve uma linha sobre a requisição no próprio terminal. A minha mostrou:

text
127.0.0.1 - - [08/Nov/2026 06:07:56] "GET / HTTP/1.1" 200 -

O endereço de origem é o mesmo de loopback, então a requisição veio desta máquina.

Passo 5: pare o servidor e tente de novo

Volte ao terminal do servidor e pressione Ctrl+C. Essa é a forma limpa de parar. Na minha máquina, parei o processo com Stop-Process -Force, que o encerra sem dar a chance de fechar direito. Em qualquer dos casos, o socket em escuta desaparece quando o processo termina.

Confirme que o socket sumiu:

powershell
Get-NetTCPConnection -State Listen -LocalPort 8000

Na minha execução, a saída ficou vazia. Depois rode o mesmo curl de novo:

bash
curl -v http://127.0.0.1:8000/

Esta é a saída da minha execução:

text
* Failed to connect to 127.0.0.1 port 8000 after 2048 ms: Could not connect to server
curl: (7) Failed to connect to 127.0.0.1 port 8000 after 2048 ms: Could not connect to server

O código de saída do curl foi 7, que significa que ele não conseguiu conectar.

O que aconteceu: o seu SYN chegou a 127.0.0.1 na porta 8000. Não havia nada escutando ali, então o sistema operacional respondeu com um reset. O curl reportou a recusa na hora, sem esperar timeout. Se você vir uma espera longa seguida de timeout, desconfie de um firewall ou de uma rota que descarta pacotes.

O que o laboratório mostra

O mesmo endereço e a mesma porta se comportaram de duas formas. Com um listener, o handshake se completou e o servidor respondeu. Sem ele, a recusa voltou em milissegundos. A lista de portas em escuta é o que separa os dois casos. Quando uma conexão te surpreender, verifique a lista primeiro.

Erros comuns

Ligar a todas as interfaces sem perceber. Muitos servidores rápidos escutam em todos os endereços por padrão. Num notebook conectado a uma rede de café, isso pode expor um servidor de desenvolvimento a outros dispositivos da mesma rede. Use um endereço de bind explícito quando precisar só de acesso local.

Tratar o número da porta como prova de identidade. A porta 80 costuma significar HTTP, mas nada obriga um programa a falar HTTP nela. Conecte-se e veja o que o serviço envia, ou confira qual processo é o dono do socket.

Esquecer o UDP. ss -tlnp mostra só listeners TCP. Use ss -ulnp para UDP, ou Get-NetUDPEndpoint no Windows. Uma máquina pode ter um serviço UDP ativo que nunca aparece na sua checagem de TCP.

Ler timeout como "não há serviço". Um timeout muitas vezes significa que um filtro fica entre você e a porta. Uma recusa significa que o host respondeu e que nada escuta ali. Eles pedem próximos passos diferentes.

Matar o processo errado. Confirme o nome e a linha de comando do processo dono antes de encerrá-lo. Um servidor esquecido de uma tentativa anterior pode continuar segurando a porta e responder com arquivos de uma pasta que você não queria publicar. Verifique o dono antes de presumir que a porta é sua.

Por que isso vem primeiro no trabalho de segurança

As portas em escuta descrevem o que a sua máquina oferece à rede, quer você tenha querido oferecer ou não. Antes de testar qualquer outra coisa num host que é seu, liste o que escuta, associe cada entrada a um programa que você conhece e feche o que não precisa. Um servidor de desenvolvimento esquecido é um bom exemplo de entrada que parece inofensiva e continua respondendo.

Os mesmos comandos podem ser usados em máquinas que você não controla, mas escanear ou sondar um sistema alheio exige permissão por escrito do dono. Mantenha a prática nas suas máquinas e no seu laboratório.

Como seguir em frente

Repita o exercício com UDP. Um listener Python simples em 127.0.0.1, porta 5399, recebeu um datagrama de um remetente na minha execução. O listener não fazia nada de especial:

python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("127.0.0.1", 5399))
data, addr = s.recvfrom(1024)
print("got", data, "from", addr)

Rode em um terminal e envie um datagrama de outro com socket.sendto. A saída que obtive foi got b'hello' from ('127.0.0.1', 63411). Repare que não houve handshake. O pacote simplesmente chegou. A porta 5353 já estava em uso na minha máquina, e a tentativa de ligá-la falhou com erro de permissão, então escolhi a 5399 para o teste.

Depois, leia a parte da RFC 9293 sobre o estabelecimento de conexão e compare com o fluxo de pacotes acima. Em seguida, passe para como o HTTP funciona, que mostra como o HTTP roda sobre o TCP e o que uma requisição e uma resposta contêm.

Fontes

RFC 9293, Transmission Control Protocol (TCP), IETF, agosto de 2022. https://www.rfc-editor.org/rfc/rfc9293

RFC 768, User Datagram Protocol, IETF, agosto de 1980. https://www.rfc-editor.org/rfc/rfc768

Service Name and Transport Protocol Port Number Registry, IANA. https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml

RFC 6335, Internet Assigned Numbers Authority (IANA) Procedures for the Management of the Service Name and Transport Protocol Port Number Registry, IETF, agosto de 2011. https://www.rfc-editor.org/rfc/rfc6335

Fontes

  1. RFC 9293: Transmission Control Protocol (TCP)
  2. RFC 768: User Datagram Protocol
  3. IANA: Service Name and Transport Protocol Port Number Registry
  4. RFC 6335: IANA Procedures for the Service Name and Port Number Registry

Mais em Redes e web

Redes e web

O que é TLS? Como o HTTPS protege o tráfego

TLS 1.3 dá ao HTTPS confidencialidade, integridade e autenticação do servidor. Veja o handshake, as cadeias de certificados e o que o cadeado não prova.

Iniciante12 min de leitura