# IP-adresse

## Hvad det er

En IP-adresse er det tal, som internetprotokollen skriver ind i hver eneste
pakke for at angive, hvor den skal hen, ved siden af en anden adresse, der
fortæller, hvor den kom fra. I daglig tale kaldes den ofte et IP-nummer. RFC
791, specifikationen af IP version 4 fra 1981, kalder den en internetadresse og
trækker grænsen i én sætning: »En adresse angiver, hvor den er.« Et navn, for
eksempel et domæne, siger, hvad man leder efter, og skal først oversættes til en
adresse, og det klarer [DNS](/da/glossary/#dns). Ruten, vejen mellem de to
adresser, overlades til routerne undervejs.

I IPv4 er adressen på 32 bit, fire oktetter, skrevet som fire decimaltal fra 0
til 255 adskilt af punktummer: 192.0.2.10. RFC 791 delte de bit i et
netværksnummer og en lokal del, og tre faste klasser afgjorde, hvor delingen
faldt. Klasserne passede dårligt til de fleste organisationer: et klasse
C-netværk rummede højst 254 værter, et klasse B op til 65.534, så klasse
B-numrene slap op, mens routingtabellerne voksede. I september 1993 erstattede
RFC 1519 klasserne med CIDR, som lader delingen falde efter en hvilken som helst
bit og skriver dens position efter en skråstreg. 192.0.2.0/24 er den blok, hvis
første 24 bit ligger fast: 256 adresser.

IPv6 udvider adressen til 128 bit. Den skrives som otte grupper med op til fire
hexadecimale cifre adskilt af koloner, og RFC 4291 tillader, at én række af
nulgrupper trækkes sammen til `::`, så 2001:db8:0:0:0:0:2:1 også kan skrives
2001:db8::2:1. Fordi den samme adresse dermed kunne staves på mange måder,
fastlagde RFC 5952 senere én anbefalet form: små bogstaver, ingen foranstillede
nuller i en gruppe og `::` brugt til den længste række af nulgrupper.

En adresse tilhører en netværksgrænseflade, ikke en maskine. Allerede RFC 791
sagde, at en enkelt vært skal kunne optræde som flere, med flere
internetadresser, og at nogle værter har flere fysiske grænseflader. RFC 4291
kræver, at hver IPv6-grænseflade har mindst én link-lokal adresse, der kun
gælder på dens eget netværkssegment, uanset hvilke andre adresser den har. En
vært på et netværk, der kører begge versioner, har derfor flere adresser på én
gang, foruden de loopback-adresser, den bruger til at nå sig selv: blokken
127.0.0.0/8 i IPv4 og `::1` i IPv6.

Ikke alle adresser kan nås fra alle steder. RFC 1918 afsætter tre IPv4-blokke
til private netværk, 10.0.0.0/8, 172.16.0.0/12 og 192.168.0.0/16, og siger, at
routinginformation om dem ikke må gives videre mellem organisationer. En enhed
med en af dem når derfor kun internettet gennem noget, der træder i stedet for
den, for eksempel NAT, som RFC 3022 beskriver som oversættelse af den private
adresse til en offentlig på vej ud. Tre andre blokke, 192.0.2.0/24,
198.51.100.0/24 og 203.0.113.0/24, er reserveret af RFC 5737 til dokumentation,
og RFC 3849 gør det samme for 2001:db8::/32 i IPv6. Alle eksempeladresser i
denne artikel kommer fra disse dokumentationsområder.

## Hvorfor det betyder noget

Adressen er den ene oplysning om en klient, som en server altid har, for uden
den ville svaret ikke have nogen steder at gå hen. Derfor er den standardnøglen
til mange beslutninger: regler i en [firewall](/da/glossary/#firewall) tillader
eller blokerer efter adresse, en rate limit tæller anmodninger pr. adresse, en
adgangslog skriver den på hver linje, og en misbrugsanmeldelse nævner den. Hver
af dem virker kun så godt, som adressen identificerer det, man tror, den
identificerer.

Den identificerer mindre, end det ser ud til. Bag NAT kan alle enheder på et
kontor eller i en husstand nå internettet fra den samme offentlige IPv4-adresse,
så en blokering eller en grænse rettet mod én af dem rammer dem alle. Bag en
proxy eller et [CDN](/da/glossary/#cdn) ser serveren proxyens adresse på hver
anmodning, og klientens egen adresse ankommer, hvis den overhovedet gør, i en
header, som en anden har skrevet. En regel skrevet mod en adresse er en regel om
en position i netværket, aldrig om en person.

Samtidig afslører den mere, end folk regner med. RFC 7239, der standardiserede
den `Forwarded`-header, som proxyer bruger til at give klientens adresse videre,
bemærker i sit afsnit om privatliv, at en IP-adresse kan identificere en klient
entydigt, vise hvilken operatør den bruger, og give et groft billede af, hvor
den befinder sig. En log fuld af adresser er derfor et ansvar lige så meget som
et værktøj, og en god grund til at beslutte, hvad man gemmer, før man begynder
at gemme det.

Og nu findes der to slags. Alt, der fortolker, gemmer eller sammenligner
adresser, skal tage lige godt imod IPv4 og IPv6, fordi en klient på et netværk,
der tilbyder begge, kan komme over den ene eller den anden. Kode skrevet
dengang, hvor hver adresse kunne være i femten tegn af cifre og punktummer, går
i stykker ved den første besøgende med IPv6, som regel et sted langt fra der,
hvor adressen blev læst.

## Sådan ser det ud i praksis

Pythons standardbibliotek har et `ipaddress`-modul, der fortolker begge
versioner og klarer regnestykkerne, så man aldrig behøver at splitte
tekststrenge i hånden. I en interaktiv session:

```text
>>> import ipaddress
>>> ipaddress.ip_address("203.0.113.57")
IPv4Address('203.0.113.57')
>>> ipaddress.ip_address("2001:0DB8:0000:0000:0000:0000:0002:0001")
IPv6Address('2001:db8::2:1')
>>> ipaddress.ip_network("203.0.113.57/24", strict=False)
IPv4Network('203.0.113.0/24')
>>> ipaddress.ip_network("2001:db8:42:7::5/48", strict=False)
IPv6Network('2001:db8:42::/48')
```

Det andet kald viser den normalisering, RFC 5952 beder om: den lange stavemåde
med store bogstaver og den korte med små er den samme adresse, og modulet
udskriver den kanoniske form. En streng som 192.0.2.300 afvises med en
`ValueError`, fordi 300 ikke kan være i en oktet. De to sidste kald gør en
adresse til netværket omkring den. Uden `strict=False` ville modulet også afvise
dem, fordi 203.0.113.57/24 har værtsbit sat; med det sættes værtsdelen til nul,
og tilbage står netværket alene.

Netop den nulstilling bruger dette site på sine besøgendes adresser. Dets
[side om privatliv](/da/privacy/) siger, at IP-adressen aldrig gemmes fuldt ud:
den forkortes i det øjeblik, loglinjen skrives, og den sidste del erstattes med
nuller, før noget som helst rammer disken, så det, der gemmes, peger på et groft
netværk, hvor et helt kontor og en hel gade kan se ens ud. Siden tilføjer, at
serveren skriver adressen i to felter og slører dem begge, og at de felter i
forespørgslen, der kan bære en adresse i sig selv, dem en virksomheds proxy
eller et indholdsnetværk sætter foran den besøgende, fjernes, før linjen
skrives. Den siger ikke, hvor mange bit der overlever; /24 og /48 ovenfor er
denne artikels illustration, ikke sitets indstillinger. Pointen holder uanset
hvad. En adresse, der aldrig skrives fuldt ud, kan ikke lække fuldt ud, og når
den forkortes på vej ind, afhænger det ikke af et oprydningsjob, der en dag kan
holde op med at køre.

## Hvor det går galt

**At stole på en header for klientens adresse.** `X-Forwarded-For` og den
standardiserede `Forwarded`-header er almindelige felter i forespørgslen, og RFC
7239 advarer om, at hver knude på vejen til serveren kan ændre
`Forwarded`-headeren, også klienten selv. Kode, der tager den første adresse på
listen, lader enhver klient vælge sin egen adresse og dermed sin egen rate limit
og sin egen plads på en tilladelsesliste. Brug adressen fra TCP-forbindelsen,
medmindre forespørgslen kom gennem en proxy, du selv driver, og læs i så fald
kun det, dine egne proxyer har tilføjet, talt fra højre.

**At behandle en adresse som en person.** Fordi mange brugere kan dele én
adresse, kan en udelukkelse af en adresse spærre et helt kontor ude, og en
grænse beregnet til én person kvæler en hel skole. Brug adresser til grove
beslutninger, sæt grænser med delte adresser i tankerne, og knyt alt personligt
til en konto, der er logget ind.

**At sammenligne adresser som tekst.** 2001:db8::2:1 og 2001:DB8:0:0:0:0:2:1 er
én adresse og to forskellige strenge, så en tilladelsesliste, der matcher på
tekst, godtager den ene og afviser den anden. Fortolk begge sider, før du
sammenligner, eller gem kun formen fra RFC 5952.

**At fortolke for IPv4 alene.** Et regulært udtryk for fire tal med punktummer,
en kolonne beregnet til femten tegn eller kode, der deler vært og port ved det
sidste kolon, fejler alle på IPv6. Brug en rigtig parser og en kolonnetype eller
-længde, der passer til begge versioner. Når en port skrives ved siden af en
IPv6-adresse, anbefaler RFC 5952 kantede parenteser, som i [2001:db8::1]:443,
fordi den sidste gruppe ellers kunne læses som en del af adressen.

**At gemme fulde adresser længere end nødvendigt.** Logs, analysetabeller og
backups samler adresser i årevis, hvis intet stopper dem. Beslut, hvilken
præcision du har brug for, forkort adressen, når den skrives, i stedet for
bagefter, og giv resten en udløbsdato.

**At bruge rigtige adresser i eksempler.** En eksempelkonfiguration, et sæt
testdata eller et skærmbillede med en andens rigtige adresse sender kopieret
trafik til en fremmed. RFC 5737 reserverer sine tre blokke netop for at mindske
den slags konflikter og forvirring; brug dem, og 2001:db8::/32 til IPv6.

## Læs mere

- [RFC 791: Internet Protocol](https://www.rfc-editor.org/rfc/rfc791.html) —
  specifikationen af IPv4 fra 1981, med dens adresse på 32 bit og skellet mellem
  navne, adresser og ruter.
- [RFC 4291: IP Version 6 Addressing Architecture](https://www.rfc-editor.org/rfc/rfc4291.html)
  — adressetyperne i IPv6, deres tekstformer og kravet om en link-lokal adresse.
- [RFC 5952: A Recommendation for IPv6 Address Text Representation](https://www.rfc-editor.org/rfc/rfc5952.html)
  — én kanonisk måde at skrive en IPv6-adresse på, og de problemer, frie
  stavemåder skaber.
- [RFC 7239: Forwarded HTTP Extension](https://www.rfc-editor.org/rfc/rfc7239.html)
  — hvordan proxyer giver en klients adresse videre, hvorfor man ikke bare kan
  stole på resultatet, og hvad det koster i privatliv.
- [RFC 5737: IPv4 Address Blocks Reserved for Documentation](https://www.rfc-editor.org/rfc/rfc5737.html)
  — de tre områder, der er beregnet til eksempler.
- [ipaddress: IPv4/IPv6 manipulation library](https://docs.python.org/3/library/ipaddress.html)
  — Pythons standardmodul til at fortolke, sammenligne og gruppere adresser.

<https://engineer.company/da/glossary/ip-address/>
