# Firewall til webservere: Åbn kun nødvendige porte

> Firewall til webservere: kontrollér åbne porte, frigiv kun 80 og 443, begræns SSH, afgræns udgående forbindelser. Med nftables og ufw.

Kilde: https://phpsos.de/da/blog/firewall-fuer-webserver/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** En firewall til webservere tillader indgående kun TCP 80 og 443, ved HTTP/3 desuden UDP 443, og SSH kun fra kendte net. Alt andet kasseres: Databaser, caches, PHP-FPM og administrationsflader hører ikke hjemme på internettet. Kontrollér først med `ss -tulpn`, hvad der lytter, opbyg derefter et regelsæt med standarden "kassér", og test resultatet udefra. At begrænse udgående forbindelser begrænser desuden følgerne af et indbrud.

## De glemte døre ved siden af hoveddøren

Ved PHP2Shell rettedes blikket mod selve webserveren, mod portene 80 og 443. De skal være åbne, ellers findes der intet website. Ved beholdningsopgørelser efter sådanne sårbarheder falder man dog ofte over noget andet: Ved siden af hoveddøren står der flere døre åbne. En database lytter på alle netværksgrænseflader, en PHP-FPM-pool på port 9000, en cachetjeneste uden adgangskode, en administrationsflade fra opsætningsfasen.

Hver af disse døre er en egen angrebsflade med egne sårbarheder. En firewall, der kun tillader det nødvendige, lukker dem med få regler. Det er en af de mest virksomme foranstaltninger, når man afsikrer en egen server, som også siden [Afsikr root-server og vServer selv](https://phpsos.de/da/server/root-server-vserver/) beskriver.

## Hvad hører til åbent, og hvad ikke?

Grundsætningen er en tilladelsesliste: Alt er lukket, og kun bevidst frigivne tjenester kan nås. Oversigten nedenfor hjælper med indordningen.

| Tjeneste | Typisk port | Kan nås udefra? |
|---|---|---|
| HTTP og HTTPS | TCP 80, TCP 443 | ja |
| HTTP/3 (QUIC) | UDP 443 | kun hvis det bruges |
| SSH | TCP 22 | kun fra kendte net eller via VPN |
| Hostingpanel | afhængigt af produkt | kun fra kendte net |
| MySQL/MariaDB, PostgreSQL | TCP 3306, TCP 5432 | nej |
| Redis, Memcached | TCP 6379, TCP 11211 | nej |
| PHP-FPM | TCP 9000 eller Unix-socket | nej, helst kun socket |
| Mailserver | TCP 25, 465, 587, 993 | kun hvis serveren modtager eller stiller mails til rådighed |

En tjeneste, der ikke behøver at nås udefra, bør desuden kun lytte på `127.0.0.1` eller en Unix-socket. Så forbliver den også ved en fejl i firewallen utilgængelig. Til administrationsadgange egner sig IP-frigivelser eller en VPN; detaljer står i indlægget [Afskærm admin-områder via IP, VPN eller ekstra beskyttelse](https://phpsos.de/da/blog/admin-bereiche-abschirmen/).

## Skridt 1: Fastslå, hvad der lytter

Før I skriver regler, skaffer I jer overblik. De følgende kommandoer læser kun:

```bash
# Alle lyttende TCP- og UDP-porte med proces
sudo ss -tulpn
# Nftables' aktuelle regelsæt
sudo nft list ruleset
# Status for ufw, hvis det bruges
sudo ufw status verbose
```

Vær i outputtet fra `ss` opmærksom på adressen foran porten. `0.0.0.0` eller `[::]` betyder: Tjenesten lytter på alle grænseflader. `127.0.0.1` betyder: kun lokalt. Notér for hver tjeneste, om den skal kunne nås udefra. Denne liste er samtidig et stykke af jeres serverinventar.

## Firewall til webservere med nftables

nftables er det aktuelle pakkefilter under Linux. Det følgende regelsæt retter sig efter eksemplet i den officielle nftables-wiki og supplerer en frigivelse til SSH kun fra et administrationsnet. Adresserne er dokumentationseksempler og skal erstattes.

```nft
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    set verwaltung_v4 {
        type ipv4_addr
        flags interval
        elements = { 203.0.113.0/28 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        ct state vmap { established : accept, related : accept, invalid : drop }
        iifname lo accept

        # IPv6 kræver nabogenkendelse
        icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
        icmp type echo-request limit rate 5/second accept
        icmpv6 type echo-request limit rate 5/second accept

        # Website
        tcp dport { 80, 443 } accept
        # kun ved HTTP/3:
        # udp dport 443 accept

        # SSH kun fra administrationsnettet
        ip saddr @verwaltung_v4 tcp dport 22 accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }
}
```

Kontrollér regelsættet før indlæsningen med `nft -c -f /etc/nftables.conf`. Den første linje `flush ruleset` sletter alle eksisterende regler, også sådanne, som Docker eller Fail2ban har indført. På servere med Docker eller andre tjenester, der sætter egne regler, tilpasser I derfor regelsættet i stedet for at erstatte det generelt. Hvordan Fail2ban samarbejder med firewallen, står under [Opsæt Fail2ban til webservere](https://phpsos.de/da/blog/fail2ban-fuer-webserver/).

Den, der foretrækker det enklere, bruger under Ubuntu `ufw`. Vigtig er rækkefølgen: først SSH-frigivelsen, derefter slå til.

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow proto tcp from 203.0.113.0/28 to any port 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
```

> **Vigtigt:**
> Ændr kun firewallregler på fjernservere med en anden adgangsvej, f.eks. udbyderens konsol. En forkert SSH-regel låser jer ellers selv ude.

## Udgående forbindelser: den undervurderede halvdel

De fleste firewalls tillader alt udgående. For en webserver er det rundhåndet. Efter et indbrud bruger angribere udgående forbindelser til at indlæse værktøjer, trække data ud eller modtage kommandoer. Webserver- eller PHP-processer, der opbygger uventede forbindelser, gælder derfor som advarselstegn.

En begrænsning af udgående forbindelser er mere krævende, fordi hver legitim forbindelse skal være kendt: pakkekilder til opdateringer, betalingstjenester, grænseflader, mailafsendelse, tidsservere. En pragmatisk vej er først at protokollere udgående forbindelser, derefter at danne en tilladelsesliste og først derefter at spærre. Hvordan I kontrollerer eksisterende forbindelser, beskriver [Kontrollér en servers udgående forbindelser](https://phpsos.de/da/blog/ausgehende-verbindungen-pruefen/); hvilke spor der ellers tyder på et indbrud, står under [Er jeg allerede kompromitteret?](https://phpsos.de/da/php2shell/bin-ich-gehackt-anzeichen/).

Til sidst tester I udefra, fra en anden computer og kun mod jeres egne systemer, hvilke porte der faktisk kan nås. Først denne test viser, om Docker, udbyderens firewall og serverregler tilsammen giver det ønskede billede.

## Konklusion: Få regler, stor virkning

En webserver-firewall behøver ikke være kompliceret. Webporte åbne, administration kun fra kendte net, alt andet kasseret: Med disse grundregler forsvinder databaser, caches og glemte tjenester fra internettet. Det er en af foranstaltningerne med det bedste forhold mellem indsats og nytte.

Mod sårbarheder i webserveren eller i selve PHP hjælper firewallen ikke, for netop disse porte skal forblive åbne. Dens styrke ligger i at holde den øvrige angrebsflade lille og med en begrænsning af udgående forbindelser inddæmme følgerne af et indbrud.

Afgørende er plejen. Hver ny tjeneste, hver container og hver ændring hos udbyderen kan forskyde billedet. Gentag derfor kontrollen udefra efter hver større ændring og med faste mellemrum, f.eks. én gang i kvartalet.

## Hvordan hjælper PHP SOS konkret?

- **Opgør beholdningen:** Vi registrerer alle lyttende tjenester og kontrollerer udefra, hvad der faktisk kan nås.
- **Opbyg regelsættet:** Vi udarbejder en tilladelsesliste for indgående og, hvor det er fornuftigt, udgående forbindelser, afstemt med Docker, Fail2ban og udbyderens firewall.
- **Omstil sikkert:** Ændringer gennemfører vi med en anden adgangsvej og tilbagefaldsplan.
- **Dokumentér:** Porte, frigivelser og begrundelser fastholder vi inden for rammerne af [serverhærdningen](https://phpsos.de/da/leistungen/server-haertung/).


## Ofte stillede spørgsmål

**Hvilke porte har en webserver brug for?**  
Til besøgende som regel kun TCP 80 og 443, ved HTTP/3 desuden UDP 443. SSH og administrationsflader bør kun kunne nås fra kendte net eller via VPN. Database-, cache- og PHP-FPM-porte hører ikke hjemme på internettet.

**Beskytter en firewall mod PHP2Shell?**  
Nej. PHP2Shell udnyttes via webserveren, altså netop via de porte, der skal være åbne. Men firewallen formindsker den øvrige angrebsflade, og en begrænsning af udgående forbindelser kan inddæmme følgerne af et indbrud.

**Hvorfor viser ufw porte som lukkede, som alligevel kan nås?**  
Et kendt tilfælde er Docker-containere: Docker indfører publicerede porte direkte i pakkefilterreglerne, uden om ufw. Kontrollér derfor altid åbne porte desuden udefra.

**Er min hostingudbyders firewall nok?**  
En forudgående firewall hos udbyderen er et godt andet lag. Men den erstatter ikke firewallen på serveren, fordi den ikke virker ved en fejl i udbyderens konfiguration eller ved interne forbindelser. Bedst bruger I begge med de samme grundregler.

## Kilder

- [nftables-wiki: Enkelt regelsæt til en server](https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server)
- [Ubuntu Server: Firewall (ufw)](https://ubuntu.com/server/docs/how-to/security/firewalls/)
- [BSI IT-Grundschutz (tysk metodik til informationssikkerhed)](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks)
