# Brannmur

## Hva det er

Mellom en tjeneste og nettverket den lytter på, sitter ofte en brannmur: et filter på nettverksveien
som sammenligner hver pakke eller forbindelse med en liste regler og deretter lar den passere,
forkaster den eller svarer med en avvisning. Den kan være programvare på maskinen den beskytter, en
egen boks mellom to nettverk eller en tjeneste som en skyleverandør kjører foran en virtuell maskin.
Mange sier firewall også på norsk, Linux-administratorer sier gjerne pakkefilter om det samme, og
skyleverandører selger brannmurer under navn som sikkerhetsgruppe (security group). Brannmurer
kommer som regel i lag: én hos leverandøren og én på verten.

NISTs veiledning på området, SP 800-41 Rev. 1 fra september 2009, sorterer dem etter hvor mye av
trafikken de leser. Et pakkefilter ser på adresser, protokoll og portnumre, én pakke om gangen. En
tilstandsbasert brannmur (stateful firewall) husker i tillegg forbindelser, så svaret på en
forespørsel serveren selv sendte, slipper inn uten en egen regel. En applikasjonsproxy
(application-proxy gateway) avslutter forbindelsen og leser protokollen inne i den. En vertsbasert
brannmur kjører på serveren eller den bærbare maskinen den vokter, og vet hvilket program som eier
en socket.

På en Linux-server skjer filtreringen i netfilter, rammeverket for pakkefiltrering i kjernen. Siden
kjerneversjon 3.13 har nftables vært tilgjengelig som erstatning for de eldre iptables-verktøyene,
og grensesnitt som ufw skriver reglene for folk som heller vil si hva de ønsker, enn å skrive
kjeder. Uansett hva som skriver reglene, er modellen den samme: en ordnet liste som leses ovenfra,
der den første regelen som treffer, avgjør.

En brannmur blir ofte blandet sammen med verktøy i nærheten. En brannmur for webapplikasjoner (WAF)
leser HTTP-forespørsler og blokkerer angrepsmønstre i dem; en nettverksbrannmur ser aldri så dypt.
Et verktøy som utestenger inntrengere, leser logger og legger til midlertidige regler mot adresser
som oppfører seg dårlig, og er dermed avhengig av en brannmur under seg. Et VPN avgjør hvem som i
det hele tatt er på nettverket. Hvert av dem svarer på et annet spørsmål, og den enkle regellisten
blir ikke overflødig av noen av dem.

## Hvorfor det er viktig

Hver tjeneste som lytter på en offentlig adresse, er en dør, og brannmuren er fortegnelsen over
hvilke dører som finnes. Avgjørelsen et team faktisk står overfor, har tre deler: hvor brannmuren
skal ligge, hva den tillater som standard, og hvem som har lov til å endre den.

En brannmur i skyen hos leverandøren stopper trafikken før den når maskinen, fortsetter å virke selv
om noen får root på verten, og koster ikke serveren noe CPU-tid. Reglene ligger i en konsoll eller
bak et API, utenfor serverens egen konfigurasjon, så de glir ut av takt med alt annet med mindre de
er skrevet som kode. En brannmur på verten følger med maskinen, kan sette en hastighetsbegrensning
på én enkelt nettverksport og kan testes fra maskinen selv, men en kompromittert root-konto kan
skrive den om, og det kan også programvare som styrer sine egne regler. Å kjøre begge er vanlig og
fornuftig, til prisen av to lister som må holdes i takt: hver port som åpnes eller lukkes, er en
endring to steder.

Standardvalget er den andre delen. NIST anbefaler å avvise all trafikk som ikke uttrykkelig er
tillatt, og for innkommende trafikk er nesten alle enige. Utgående filtrering er der avveiningen
merkes: den begrenser hva en kompromittert tjeneste kan nå, og den stopper pakkeoppdateringer,
fornyelse av sertifikater og overvåking helt til hver destinasjon har fått sin regel.

Den tredje delen er eierskap. En brannmur som avviser alt som standard, er bare så riktig som listen
over porter noen har deklarert, så det nyttige dokumentet er nettopp den deklarerte listen, holdt
under versjonskontroll og sjekket mot reglene som faktisk er aktive. Programvaren er gratis på hver
vanlig Linux-distribusjon; det som koster, er oppmerksomheten det krever å holde deklarasjonen sann.
Og en brannmur er en andre forsvarslinje. En tjeneste som er bundet til loopback-adressen, kan ikke
nås utenfra uansett hva reglene sier, og det er en sterkere garanti enn en avvisningsregel foran en
tjeneste som lytter på alle adresser.

## Slik ser det ut i praksis

Tre deler av selskapets infrastrukturarbeid viser brannmuren fra tre sider: hvordan den sjekkes, når
den opprettes, og hva som kan gå rundt den.

På én vert sto en hastighetsbegrensning for SSH-porten i regellisten i et år uten at en eneste pakke
nådde den, fordi en bredere regel som tillot trafikken, sto over den og slo til først.
Statusverktøyene viste begrensningen hele året, og de hadde rett i det: den fantes.
[Sjekkene ble skrevet om for å lese plassering i stedet for tilstedeværelse](/nb/portfolio/verified-firewall-rules-by-position-113/):
de sammenligner nå rekkefølgen i den nummererte regellisten, og i kjeden kjernen faktisk filtrerer
med, mot det som var tenkt. Hver port får én regel, og hver regel navngir en protokoll; SSH har en
hastighetsbegrensning og ingen egen allow-regel. De fem offentlige portene er deklarert samlet og
sjekkes som en helhet, så en åpen port som deklarasjonen utelater, får sjekken til å feile, og
sikkerhetsrapporten viser reglene i den rekkefølgen nettverkspakkene møter dem, med en merknad om
hvordan rekkefølgen skal leses.

Den første serveren ble bygd for hånd og fikk brannmuren sin først senere, og det etterlot et vindu
der en fersk maskin kunne nås fra internett. For en server nummer to hos en annen leverandør
[opprettes brannmuren av sitt eget play før maskinen](/nb/portfolio/provisioned-a-second-server-from-code-123/),
så den nye maskinen møter internett med reglene allerede på plass. Den leverandøren knytter
brannmurer til maskiner gjennom tagger, så taggene opprettes først: en regel som retter seg mot en
tagg, trenger at taggen finnes. Brannmuren hos hver leverandør er skrevet direkte mot leverandørens
REST-API med en vanlig HTTP-oppgave. Oppgaven gjør ingenting i en tørrkjøring, så endringer øves på
selve brannmur-playet, siden en brannmur hos leverandøren ikke koster noe å opprette og kan slettes
igjen.

Den tredje gjelder containere. Docker skriver sine egne oppføringer i kjernens pakkefilter, og en
port Docker publiserer for en container, blir matchet før noe av det herdingsrollen på verten har
lagt inn, så en container kan nås utenfra uansett hva brannmuren har fått beskjed om.
[Containerne på denne plattformen kjører under systemd gjennom Podman og Quadlet](/nb/portfolio/deployed-a-container-plane-on-podman-and-quadlet-122/),
deler vertens nettverk og publiserer ingen porter, så det finnes ingen containerport som noe kan
bruke til å gå rundt reglene.

## Hvor det går galt

**En regel står i statusutskriften og slår aldri til.** Reglene evalueres i rekkefølge, og første
treff vinner, så en bred allow-regel plassert over en smalere begrensning eller avvisning skygger
helt for den. Listen viser fortsatt begge. Les reglene slik kjernen gjør, nummerert og i rekkefølge,
sett spesifikke regler over generelle, og test fra en maskin utenfor:

```sh
ufw status numbered
nft list ruleset
```

**En container svarer på en port brannmuren avviser.** Docker publiserer porter ved å omdirigere
trafikk i kjernens NAT-tabell, før den når kjedene ufw filtrerer, og Dockers egen dokumentasjon sier
at dette i praksis går utenom brannmurkonfigurasjonen. Publiser bare til loopback-adressen, sett en
brannmur hos leverandøren foran, eller kjør containere uten publiserte porter, slik det er beskrevet
ovenfor.

**IPv4 er låst ned, og IPv6 står vidt åpen.** De to adressefamiliene har hvert sitt regelsett i
iptables, og ufw skriver bare IPv6-regler når IPv6 er slått på i filen med standardinnstillinger. En
vert med en offentlig IPv6-adresse og et regelsett bare for IPv4 er eksponert på hver port den
lytter på. Bruk en nftables-tabell i familien `inet`, som ser begge, eller gå gjennom begge listene,
og skann vertens IPv6-adresse utenfra.

**SSH-økten fryser idet brannmuren slås på.** Standardavvisningen ble aktiv før regelen for SSH,
eller daemonen for SSH ble flyttet til en annen port mens regelen fortsatt nevner 22. Legg inn
SSH-regelen først, hold leverandørens konsoll åpen i et annet vindu, og planlegg en automatisk
tilbakerulling noen minutter fram i tid, som avbrytes så snart en ny økt kommer inn.

**En regel åpner mer enn den som skrev den, mente.** I ufw åpner en regel som navngir en port uten
protokoll, porten for både TCP og UDP. Navngi protokollen i hver regel, og deklarer den forventede
flaten som en helhet, slik at alt ekstra får en sjekk til å feile i stedet for å vente på en
revisjon.

## Les mer

- [Firewall](https://csrc.nist.gov/glossary/term/firewall)
  — definisjonene NIST-publikasjonene bruker, hver lenket til kildedokumentet sitt.
- [SP 800-41 Rev. 1: Guidelines on Firewalls and Firewall Policy](https://csrc.nist.gov/pubs/sp/800/41/r1/final)
  — typer brannmurer, en policy som avviser alt som ikke er tillatt, og forvaltning av regler, fra
  NIST.
- [ufw(8)](https://manpages.ubuntu.com/manpages/noble/man8/ufw.8.html)
  — brannmurgrensesnittet i Ubuntu, bl.a. rekkefølgen på reglene og regelen `limit`.
- [nftables wiki](https://wiki.nftables.org/wiki-nftables/index.php/Main_Page)
  — netfilter-prosjektets dokumentasjon av rammeverket som erstatter iptables.
- [Packet filtering and firewalls](https://docs.docker.com/engine/network/packet-filtering-firewalls/)
  — Dockers egen forklaring på hvordan publiserte porter går utenom vertens regler.

<https://engineer.company/nb/glossary/firewall/>
