Firewalld instellen op Rocky of AlmaLinux VPS
Leer hoe u poorten opent, SSH beveiligt en zones beheert in firewalld. Voorkom fouten met de --permanent vlag en zorg dat uw firewallconfiguratie een reboot overleeft.
Wat firewalld is en waarom Rocky en AlmaLinux dit meeleveren
firewalld is de firewall-beheerder die standaard is geïnstalleerd op Rocky Linux, AlmaLinux en de andere rebuilds van Red Hat Enterprise Linux (RHEL). Het inspecteert zelf geen pakketten. Het onderhoudt een opgeslagen configuratie en zet deze configuratie om in nftables-regels. Eén commando, firewall-cmd, wijzigt deze configuratie terwijl de server online blijft.
Als u al weet hoe ufw werkt op een Ubuntu VPS, dan kent u de werking. firewalld voegt twee concepten toe die ufw niet heeft. Het eerste zijn zones: een benoemd beleid waarin pakketten worden ingedeeld. Het tweede is een splitsing tussen de actieve regels en de opgeslagen regels, wat de --permanent-vlag is en de grootste bron van verwarring bij deze tool.
Alles hieronder is een commando dat u op uw eigen server uitvoert. Test elke wijziging vanaf een tweede machine, omdat een regel die op de server zelf correct lijkt, vanaf het internet alsnog onjuist kan zijn.
Open SSH voordat u iets anders doet
De meeste installaties van Rocky en AlmaLinux hebben firewalld al geïnstalleerd en actief, waarbij de standaardconfiguratie SSH toestaat. Sommige minimale cloud-images bevatten dit niet. Controleer dit in plaats van ervan uit te gaan.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --statefirewall-cmd --state geeft running weer. Als de service is gestopt, antwoordt elke andere firewall-cmd-aanroep met FirewallD is not running en wordt deze afgesloten met een non-zero exitcode. Dit is het eerste wat u moet controleren wanneer een commando schijnbaar niets doet.
Lees nu wat er momenteel is toegestaan.
sudo firewall-cmd --list-allDe werkelijke uitvoer bevat enkele regels meer. Dit zijn de regels die ertoe doen:
public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
rich rules:ssh in de services:-regel is de reden waarom uw sessie nog steeds werkt. Als deze ontbreekt, voeg deze dan toe voordat u iets anders wijzigt; het starten van een firewall zonder SSH-regel beëindigt uw sessie en blokkeert de toegang.
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadtarget: default betekent dat een pakket dat nergens mee overeenkomt, wordt geweigerd met een ICMP (internet control message protocol) host-prohibited-bericht, waardoor een client die een gesloten poort probeert te bereiken direct No route to host ziet. Door het doel in te stellen op DROP, reageert de server in plaats daarvan niet, waardoor scanners moeten wachten op een timeout.
sudo firewall-cmd --permanent --zone=public --set-target=DROP
sudo firewall-cmd --reloadWees u bewust van de gevolgen voordat u dit uitvoert: DROP zorgt er ook voor dat de server niet meer reageert op ping, waardoor uw eigen monitoring ook stilvalt.
Waarom is mijn regel verdwenen? De --permanent vlag
firewalld hanteert tegelijkertijd twee configuraties. De runtime-configuratie is wat de kernel op dit moment afdwingt. De permanente configuratie is wat in /etc/firewalld/zones/public.xml staat en wat terugkeert na een herlaadactie of een herstart.
Een commando zonder --permanent wijzigt alleen de runtime. Het werkt onmiddellijk en is verdwenen bij de volgende herlaadactie of boot. Een commando met --permanent schrijft het bestand weg en wijzigt niets aan de actieve configuratie, waardoor de poort gesloten blijft totdat u een herlaadactie uitvoert. Geen van beide gedragingen is een bug. Beide verrassen gebruikers, omdat het commando in beide gevallen success weergeeft.
Voer de combinatie elke keer uit.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reloadU kunt beide configuraties uitlezen; dit is de snelste manier om te achterhalen welke van de twee fouten u heeft gemaakt.
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --list-servicesHet eerste commando toont de actieve set. Het tweede toont de opgeslagen set. Als de actieve set een service bevat die niet in de opgeslagen set staat, dan vervalt die regel bij de volgende herlaadactie. Als de opgeslagen set een regel bevat die niet in de actieve set staat, dan bent u de herlaadactie vergeten. sudo firewall-cmd --runtime-to-permanent kopieert alles wat actief is naar het opgeslagen bestand, wat nuttig is na een sessie vol experimenten.
--reload behoudt de status van de verbindingstracking, waardoor uw SSH-sessie actief blijft. --complete-reload herlaadt ook de kernelmodules en verliest die status, wat meestal elke open verbinding verbreekt, inclusief de uwe. Gebruik de standaard herlaadactie.
Er is een ingebouwd vangnet. Een runtime-regel kan vanzelf verlopen.
sudo firewall-cmd --add-service=http --timeout=5mDie regel verwijdert zichzelf na vijf minuten. Dit kan niet worden gecombineerd met --permanent, en dat is precies het punt: het is bedoeld voor het testen van een wijziging waar u niet zeker van bent. Het oudere vangnet is beter. Houd een tweede SSH-sessie open terwijl u regels bewerkt en sluit deze pas af nadat een nieuwe login bewijst dat de nieuwe regels werken.
Zones, en waarom alleen de default zone relevant is op een VPS
Een zone is een benoemde set permissies met een bijbehorend vertrouwensniveau. firewalld plaatst elk inkomend pakket in precies één zone. Het systeem vergelijkt het bronadres van het pakket eerst met de sources:-lijst van elke zone. Als er geen match is, wordt de zone gebruikt waaraan de inkomende interface is gekoppeld. Als de interface aan geen enkele zone is gekoppeld, gaat het pakket naar de default zone.
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zonesOp een VPS met één netwerkinterface is het antwoord bijna altijd public, en dat is de enige zone die u zult gebruiken. firewall-cmd zonder --zone=-argument werkt op de default zone; dit is de reden waarom elk kort commando in deze handleiding werkt zonder een zone te benoemen.
Dit is de fout die vaak een middag verspilt. Als de interface aan een andere zone is gekoppeld, komen uw regels terecht in public, terwijl het verkeer elders wordt afgehandeld. Hierdoor heeft alles wat u toevoegt geen effect en ontvangt u geen waarschuwing. --get-active-zones toont de koppeling:
public
interfaces: eth0Als de interface onder een andere zonenaam verschijnt, schrijf uw regels dan daar met --zone=, of verplaats de interface.
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
sudo firewall-cmd --reloadNetworkManager beheert interfaces op Rocky en AlmaLinux en dwingt de zone opnieuw af wanneer de verbinding tot stand komt. Stel de zone daar ook in, zodat een reboot uw werk niet ongedaan maakt. Gebruik de verbindingsnaam uit het eerste commando, aangezien deze zelden gelijk is aan de apparaatnaam.
sudo nmcli connection show
sudo nmcli connection modify "System eth0" connection.zone publicBron-matching heeft voorrang op interface-matching; dit is hoe één adres een afwijkend beleid krijgt. De ingebouwde trusted-zone accepteert alles.
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10/32
sudo firewall-cmd --reloadWees voorzichtig met die zone. Deze opent elke poort op de server voor dat adres, inclusief de database waarvan u dacht dat deze privé was. Gebruik een rich rule wanneer u één poort wilt openstellen, in plaats van één host.
Wat is een firewalld-service?
Een service is een benoemde bundel poorten die als XML-bestand wordt meegeleverd. --add-service=https opent 443/tcp omdat /usr/lib/firewalld/services/https.xml definieert wat https betekent.
sudo firewall-cmd --get-services
sudo firewall-cmd --info-service=https--info-service toont de poorten die achter de naam schuilgaan:
https
ports: 443/tcpGebruik de naam wanneer deze beschikbaar is. Dit leest na zes maanden nog steeds duidelijk in --list-all, en pakketten zoals Cockpit installeren hun eigen servicebestand. Gebruik --add-port voor alles waarvoor geen definitie bestaat.
Het aandachtspunt: de ssh-service betekent 22/tcp en niets anders. Als u SSH naar een andere poort heeft verplaatst tijdens het beveiligen van SSH-toegang op de server, dan opent --add-service=ssh niet de poort die u daadwerkelijk gebruikt.
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadBij een RHEL-rebuild is er een tweede slot op die deur. SELinux (security-enhanced Linux) labelt poortnummers, en sshd mag niet binden aan een poort buiten zijn labels. De service weigert dan te starten en het logbestand vermeldt error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. Label de poort eerst.
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222Hoe zie ik wat er op dit moment openstaat?
sudo firewall-cmd --list-all
sudo firewall-cmd --list-rich-rules
sudo nft list table inet firewalld | head -n 40De eerste twee commando's rapporteren wat firewalld als status beschouwt. Het derde commando leest de regels die de kernel daadwerkelijk hanteert in de tabel die door firewalld wordt beheerd. Deze zouden met elkaar overeen moeten stemmen.
Geen van deze methoden levert sluitend bewijs. Test vanaf een andere machine:
nc -zv 203.0.113.20 443Voer de test niet uit op de server zelf. firewalld accepteert al het verkeer dat binnenkomt via de loopback-interface, waardoor curl http://localhost:8080 slaagt ongeacht uw firewallregels. Deze test bevestigt enkel dat de service actief is. Het zegt niets over de configuratie van de firewall.
Een webpoort toestaan
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesHet laatste commando zou nu http https moeten weergeven naast wat er al stond. Als de site nog steeds niet reageert, ligt het probleem mogelijk niet bij de firewall. Een regel staat een pakket toe. Een proces moet er echter nog steeds op luisteren.
sudo ss -tlnpEen socket die wordt weergegeven als 0.0.0.0:443 of *:443 accepteert verbindingen vanaf elk adres. Een socket die als 127.0.0.1:443 wordt getoond, reageert alleen op loopback, en geen enkele firewallregel zal deze ooit van buitenaf bereikbaar maken. Poorten en listening sockets op Linux behandelt dat verschil in meer detail.
Hoe sluit ik een poort weer?
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reloadDe --permanent-regel is ook hier van toepassing, en deze is in deze richting strenger. Als u een service alleen uit de runtime verwijdert, lijkt de poort gesloten, maar bij de volgende herlaadactie of reboot wordt deze weer geopend vanuit het opgeslagen bestand. Dit is een beveiligingslek dat u niet opmerkt, omdat de controle die u uitvoerde slaagde.
Het verwijderen van iets dat nooit aanwezig was, geeft Warning: NOT_ENABLED: http weer en sluit nog steeds af met exitcode 0. Het tweemaal toevoegen van hetzelfde item geeft Warning: ALREADY_ENABLED: http weer. Beide acties zijn veilig. Een verkeerd gespelde naam is anders: Error: INVALID_SERVICE betekent dat firewalld geen definitie met die naam heeft en dat er niets is gewijzigd.
Als uw --list-all de waarde cockpit toont en u gebruikt de Cockpit webconsole op poort 9090 niet, verwijder deze dan. Elke open poort is een service die u moet blijven patchen.
Beperk een poort tot één bronadres
Rich rules zijn de uitgebreide vorm voor situaties waarin een standaard servicenaam niet volstaat. Het beperken van SSH tot één kantooradres vereist twee commando's; het tweede commando wordt vaak vergeten.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadEen zone is een verzameling permissies, geen genummerde lijst die stopt bij de eerste overeenkomst. De rich rule voegt een accept toe voor één adres. Het weigert niemand. Zolang ssh nog in de services:-regel staat, bereikt het hele internet poort 22 en verandert de rich rule niets wat u kunt meten. Verwijder de algemene regel, anders is de specifieke regel slechts decoratie.
Voor een poort zonder servicenaam specificeert u de poort zelf.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="5432" protocol="tcp" accept'Om een storend netwerk te blokkeren en een logboek bij te houden, plaatst u het log-element vóór de actie; dit is de volgorde die de rich rule-taal vereist.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" log prefix="fw-drop " level="info" limit value="3/m" drop'
sudo firewall-cmd --reload
sudo journalctl -k -g fw-dropDe waarde limit voorkomt dat een vloed aan pakketten het journal vult. Voordat u SSH vergrendelt tot één enkel adres, moet u er zeker van zijn dat dit adres stabiel is. Een thuisverbinding met een wisselend IP-adres sluit u buiten op de dag dat het adres wijzigt; zorg er daarom voor dat u de console-toegang van uw provider eerst heeft getest en dat deze werkt.
ufw-commando's en hun firewall-cmd-equivalenten
Dezelfde taken, ander gereedschap. Elke --permanent-regel heeft een sudo firewall-cmd --reload nodig, wat het enige is dat een lijst als deze niet kan weergeven.
sudo ufw enablewordtsudo systemctl enable --now firewalldsudo ufw disablewordtsudo systemctl disable --now firewalldsudo ufw status verbosewordtsudo firewall-cmd --list-allsudo ufw allow OpenSSHwordtsudo firewall-cmd --permanent --add-service=sshsudo ufw allow 443/tcpwordtsudo firewall-cmd --permanent --add-port=443/tcpsudo ufw delete allow 443/tcpwordtsudo firewall-cmd --permanent --remove-port=443/tcpsudo ufw allow from 203.0.113.10 to any port 22wordt de hierboven getoonde rich rulesudo ufw reloadwordtsudo firewall-cmd --reloadsudo ufw default deny incomingis al hoe depublic-zone zich gedraagt, en--set-target=DROPis de stille versie daarvansudo ufw logging onwordtsudo firewall-cmd --set-log-denied=all
Eén verschil is het vermelden waard. ufw houdt een genummerde lijst bij en u kunt een regel op positie 1 invoegen. firewalld heeft geen regelnummers, dus "plaats deze regel als eerste" heeft hier geen betekenis. Wanneer twee firewalld-vermeldingen elkaar lijken tegen te spreken, wint de brede acceptatie, omdat niets in de set expliciet weigert. U dient de brede vermelding zelf te verwijderen.
Waarom is mijn Docker-container bereikbaar terwijl de firewall gesloten lijkt?
Omdat een gepubliceerde containerpoort nooit het deel van de firewall bereikt dat door uw zone wordt beheerd. docker run -d -p 8080:80 nginx instrueert Docker om zijn eigen NAT (network address translation) en forwarding-regels te schrijven. Een pakket dat binnenkomt op 8080 wordt herschreven en doorgestuurd naar de container; het wordt dus geforward in plaats van afgeleverd bij de host. De services:- en ports:-regels in uw zone beheren pakketten die bij de host worden afgeleverd. De regels van Docker beheren het forward-pad en deze accepteren het verkeer.
Het resultaat is een server waar sudo firewall-cmd --list-all geen poort 8080 toont, terwijl een nc -zv 203.0.113.20 8080 vanaf een andere machine toch verbinding maakt. Bekijk wat Docker heeft geïnstalleerd:
sudo iptables -t nat -L DOCKER -nDe oplossing zit in de publish-vlag. Koppel de poort aan loopback en plaats er een reverse proxy voor.
docker run -d -p 127.0.0.1:8080:80 nginxDe container reageert nu op curl http://127.0.0.1:8080 op de server zelf en op niets van buitenaf. Gebruikers van Ubuntu lopen tegen hetzelfde probleem aan, zoals beschreven in waarom Docker-containers poorten publiceren die ufw omzeilen. Rootful Podman, dat Rocky en AlmaLinux standaard in de basisrepositories meeleveren, publiceert poorten met dezelfde NAT-methode. Test daarom vanaf een andere machine in plaats van te vertrouwen op de lijst in de zone.
Zorgen dat de configuratie een herstart overleeft, en de fouten die u zult zien
sudo systemctl is-enabled firewalld
sudo systemctl status firewalldenabled en active (running) zijn wat u nodig heeft. Een firewall die wel draait maar niet is ingeschakeld, beschermt u slechts tot de eerste herstart. Deze controle hoort thuis op de lijst die u doorloopt in de eerste tien minuten op een nieuwe VPS, naast SSH-sleutels en updates.
Raw nftables-commando's en firewalld gaan niet samen. firewalld beheert een tabel genaamd inet firewalld. sudo nft flush ruleset verwijdert deze, waarna de server voor alles openstaat, terwijl firewall-cmd --list-all nog steeds uw beoogde configuratie toont omdat firewalld rapporteert wat het denkt dat er actief is, in plaats van wat de kernel daadwerkelijk bevat. sudo firewall-cmd --reload installeert de regels opnieuw. Schrijf regels met firewall-cmd zodat ze na een herlaadactie behouden blijven.
Twee firewall-beheerders op één server. Het installeren van ufw of iptables-services naast firewalld levert twee programma's op die regels schrijven zonder van elkaar op de hoogte te zijn; de winnaar is afhankelijk van welke service als laatste is gestart. Kies er één. Op Rocky en AlmaLinux is firewalld de standaard die door de distributie wordt ondersteund.
De firewall van de provider voor de server. Veel VPS-panelen hebben een aparte netwerkfirewall. Als --list-all aangeeft dat een poort openstaat en een verbinding van buitenaf toch mislukt, controleer dan het paneel voordat u wijzigingen aanbrengt op de server. Het werkt ook andersom: een open regel in het paneel doet niets zolang firewalld het pakket afwijst.
firewall-cmd uitvoeren zonder sudo. Elke wijziging vereist root-rechten. Zonder deze rechten wordt het verzoek geweigerd door een autorisatiecontrole en wordt er niets aangepast, wat op het eerste gezicht lijkt op een commando dat simpelweg wordt genegeerd.
Zes commando's dekken de meeste dagelijkse taken: --list-all om de status te lezen, --permanent --add-service of --add-port om iets te openen, --permanent --remove-service om het te sluiten, --reload om het opgeslagen bestand toe te passen, en --runtime-to-permanent na een reeks experimenten. De zone is public, de vlag is --permanent, en de enige betrouwbare controle komt vanaf een andere machine.
FAQ
Waarom is mijn firewalld-regel na een herstart verdwenen?
De regel is alleen toegevoegd aan de runtime-configuratie. sudo firewall-cmd --add-service=http wordt direct toegepast, maar gaat verloren bij een herlaadactie of herstart, omdat de opgeslagen configuratie in /etc/firewalld/zones/public.xml niet is gewijzigd. Voeg --permanent toe en voer daarna sudo firewall-cmd --reload uit. Om regels die u handmatig heeft toegevoegd te behouden, voert u sudo firewall-cmd --runtime-to-permanent uit; hiermee wordt de actieve configuratie gekopieerd naar het opgeslagen bestand.
Waarom verandert er niets nadat ik een regel met --permanent heb toegevoegd?
Omdat --permanent alleen het bestand schrijft en de actieve firewall ongemoeid laat. De poort blijft gesloten totdat sudo firewall-cmd --reload de opgeslagen configuratie in de kernel laadt. Vergelijk sudo firewall-cmd --list-services met sudo firewall-cmd --permanent --list-services: als de opgeslagen lijst een item bevat dat niet in de actieve lijst staat, dan is een herlaadactie wat u mist.
Moet ik --add-service of --add-port gebruiken?
Gebruik --add-service wanneer er een naam bestaat voor de service die u draait. Dit geeft uw intentie aan en sudo firewall-cmd --info-service=https toont precies welke poorten onder die naam vallen. Gebruik --add-port wanneer er geen definitie voor uw service bestaat, of wanneer deze op een niet-standaard poort luistert. De ssh-service staat alleen 22/tcp toe; als SSH is verplaatst naar 2222, is --add-port=2222/tcp vereist, plus een SELinux-label voor die poort.
Waarom is mijn Docker-container bereikbaar terwijl firewall-cmd aangeeft dat de poort gesloten is?
Een gepubliceerde poort wordt door de eigen NAT-regels van Docker herschreven en doorgestuurd naar de container. Het pakket wordt daardoor nooit aan de host afgeleverd, terwijl de service- en poortlijsten van een zone alleen betrekking hebben op pakketten die voor de host bestemd zijn. De container reageert op verkeer vanaf internet terwijl --list-all niets toont. Publiceer in plaats daarvan naar de loopback-interface met docker run -d -p 127.0.0.1:8080:80 nginx en plaats er een reverse proxy voor.
Kan ik ufw op Rocky Linux installeren in plaats van firewalld?
Twee firewall-beheerders op één server schrijven regels zonder van elkaar op de hoogte te zijn; welke set actief blijft, hangt af van welke service als laatste is gestart. firewalld is de ondersteunde tool op Rocky Linux en AlmaLinux, is standaard geïnstalleerd en stuurt dezelfde nftables-backend aan die ufw zou gebruiken. Leer de standaardzone en de --permanent-vlag kennen en u beheerst de gehele tool.