Hoe werken Linux poorten en actieve services?
Begrijp hoe een server netwerkverkeer sorteert via poorten. Leer met het ss commando controleren welke services luisteren en ontdek het verschil tussen lokale en publieke poorten.
Wat een poort precies is
Een poort is een nummer waarmee één server meerdere services tegelijk kan draaien zonder dat hun verkeer door elkaar loopt. Uw VPS heeft één IP-adres, maar kan tegelijkertijd een webserver, een SSH-server en een database draaien. Wanneer een pakket aankomt, moet het besturingssysteem weten voor welke service dit is. Het poortnummer is het antwoord. HTTPS-verkeer gaat normaal gesproken naar poort 443, SSH naar poort 22. Het IP-adres brengt het pakket bij uw server; de poort brengt het bij het juiste programma op die server.
Een poort is een 16-bit getal: 16 bits bieden 0 tot 65535, en 0 is gereserveerd, dus poorten lopen in de praktijk van 1 tot 65535. Poorten onder 1024 zijn de "well-known" poorten. Standaard staat Linux alleen de root-gebruiker (of een programma met de CAP_NET_BIND_SERVICE capability) toe om deze te openen. Daarom draaien standaard services daar: 22 voor SSH, 80 voor HTTP, 443 voor HTTPS, 53 voor DNS. De net.ipv4.ip_unprivileged_port_start sysctl kan die grens verplaatsen, maar de standaard is 1024. Alles vanaf 1024 is beschikbaar voor gewone programma's.
Er zijn twee soorten, TCP en UDP, en een poortnummer in de ene is gescheiden van hetzelfde nummer in de andere. TCP is het verbindingsgerichte protocol dat de meeste services gebruiken, zoals SSH, HTTP en databases. UDP is verbindingsloos en wordt gebruikt voor zaken als DNS en sommige VPN's. Wanneer u een firewall opent, specificeert u meestal welke van de twee, bijvoorbeeld 22/tcp.
Luisteren betekent dat een programma wacht op een poort
Een programma dat verbindingen wil ontvangen, vraagt de kernel om te "luisteren" op een poort. Vanaf dat moment is de poort open op de machine en beantwoordt het programma alles wat daar binnenkomt, afhankelijk van de firewall. Een poort waar niets op luistert, weigert simpelweg verbindingen. De eerste vraag bij elke beveiligingscontrole is daarom: wat luistert er, en waar.
Het commando om dit te beantwoorden is ss:
sudo ss -tlnpDe flags staan voor TCP (t), alleen luisterende sockets (l), numerieke poorten (n, zodat u 22 ziet in plaats van ssh), en het eigenaar-proces (p). Een typisch resultaat:
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 nginxDe kolom Process vertelt u welk programma de eigenaar is van elke poort. Hiermee kunt u achterhalen of er iets draait dat u niet had willen laten aanstaan.
De kolom Local Address is het relevante deel
Lees het adres voor elke poort zorgvuldig, want dit bepaalt wie de service kan bereiken. U zult constant drie gevallen tegenkomen.
0.0.0.0:22 betekent "luister op elk IPv4-adres dat deze machine heeft", inclusief het publieke adres. De service is bereikbaar vanaf het internet via IPv4, mits de firewall dit toestaat.
[::]:80 betekent hetzelfde voor IPv6: luister op elk IPv6-adres, inclusief publieke adressen. Veel programma's binden hier standaard aan, en op Linux accepteert een ::-socket vaak ook IPv4.
127.0.0.1:5432 betekent "luister alleen op loopback". 127.0.0.1 is het adres dat een machine gebruikt om met zichzelf te communiceren, en onder de standaardinstellingen van de kernel is dit vanaf geen enkele andere locatie routeerbaar. Een service die hieraan gebonden is, is alleen bereikbaar vanaf de server zelf, niet vanaf het internet, zelfs als uw firewall de poort zou toestaan. Die Postgres-regel hierboven is standaard veilig. De uitzondering is een kernelinstelling genaamd route_localnet: deze staat standaard uit, maar sommige tools schakelen deze in (zoals kube-proxy van Kubernetes). In combinatie met de juiste routing- of NAT-regels kan loopback-verkeer dan van buitenaf binnenkomen. sysctl -a | grep route_localnet zou op elke regel = 0 moeten tonen.
De praktische regel volgt hier direct uit: een database, een cache of een beheerpaneel dat alleen door uw eigen applicaties wordt gebruikt, moet binden aan 127.0.0.1, niet aan 0.0.0.0. Als het nooit op een publiek adres luistert, is er voor een aanvaller niets te bereiken.
Luisteren is niet hetzelfde als bereikbaar zijn
Eén extra onderscheid voorkomt veel verwarring. Een poort die openstaat op de machine, wat betekent dat een programma luistert, is iets anders dan die poort die bereikbaar is van buitenaf, wat betekent dat de firewall het toestaat. Beide moeten waar zijn voor een externe client om verbinding te maken. De twee fouten zien er vanaf de clientzijde zelfs anders uit: een verbinding die wordt geweigerd betekent meestal dat er niets luisterde, terwijl een verbinding die blijft hangen en vervolgens een time-out geeft, meestal betekent dat een firewall het pakket heeft gedropt, wat precies is wat die twee SSH-fouten u vertellen.
Er zijn dus twee controlelagen. U bepaalt wat luistert door het bind-adres van elke service in te stellen. En u bepaalt wat de buitenwereld kan bereiken met een firewall. Een goed beheerde server gebruikt beide: services binden alleen waar nodig, en een firewall weigert alles wat u niet expliciet heeft toegestaan. Lezen wat er luistert met ss is stap één; bepalen wat de firewall toestaat is stap twee, behandeld in firewalls 101 met UFW.
Er is een nuance die hier voor problemen zorgt. IPv4 en IPv6 zijn gescheiden, en een firewall die alleen IPv4 dekt, laat de [::]-services open op IPv6. Die specifieke valstrik heeft zijn eigen artikel: de IPv6-firewallvalstrik.
FAQ
Hoe zie ik welke poorten openstaan op mijn Linux-server?
Voer sudo ss -tlnp uit voor TCP of sudo ss -ulnp voor UDP. Dat geeft een lijst van elke luisterende socket, de poort, het lokale adres waaraan deze is gebonden en het proces dat de eigenaar is. Lees de kolom Local Address: 0.0.0.0 of [::] betekent dat de service is blootgesteld aan het netwerk, terwijl 127.0.0.1 betekent dat deze alleen op de machine zelf luistert.
Wat is het verschil tussen 0.0.0.0 en 127.0.0.1?
0.0.0.0 betekent "luister op alle IPv4-adressen", inclusief het publieke adres, zodat de service vanaf het netwerk bereikbaar is. 127.0.0.1 is loopback, het adres dat de machine gebruikt om met zichzelf te praten, en met de standaardinstellingen van de kernel is dit vanaf geen enkele andere locatie routeerbaar, dus een service die hieraan gebonden is, is alleen lokaal bereikbaar. Bind interne services aan 127.0.0.1 zodat ze buiten het netwerk blijven.
Moet ik een poort openen in de firewall om een service te laten werken?
Alleen voor services die vanaf andere machines bereikt moeten worden. Een service die gebonden is aan 127.0.0.1 heeft geen toelatingsregel nodig, omdat met de standaard kernelinstellingen niets externs deze toch kan bereiken. Een service op 0.0.0.0 of [::] heeft een toelatingsregel nodig zodra uw firewall inkomend verkeer standaard weigert, wat de aanbevolen werkwijze is. Als er geen firewall actief is, of als het beleid alles accepteert, is die service al bereikbaar zonder enige regel.
Wat is het verschil tussen een TCP-poort en een UDP-poort?
TCP is verbindingsgericht en wordt gebruikt door de meeste services, zoals SSH, webservers en databases. UDP is verbindingsloos en wordt gebruikt door DNS en sommige VPN's. Hetzelfde nummer in TCP en UDP zijn afzonderlijke poorten, dus 53/tcp en 53/udp zijn verschillend. Wanneer u firewallregels schrijft, specificeert u het protocol, bijvoorbeeld 22/tcp.