Av Karl-Martin Skontorp
Noe av det beste som finnes er et teknisk problem man kan gruble på. Vel og bra med de vanlige utfordringene som skal løses i vårt yrke. Men en nøtt ubevisstheten kan gruble på når man tar en dusj, går en tur eller har lagt seg for kvelden - det er virkelig noe spesielt.
For en tid tilbake opplevde en av våre kunder noen veldig rare problemer. Denne kunden leverer en SaaS (SPA) til bedriftsmarkedet og hadde servere plassert i Oslo.
Plutselig begynte kundestøtte å få noen få, sporadiske henvendelser fra brukere som opplevde rar oppførsel i applikasjonen. Kanskje fikk de ikke åpnet innloggingssiden, andre ganger fikk de logget inn helt fint før det raskt surnet. Bilder og styling kunne mangle, menytrykk ble stående og vente. For de få brukerne som ble rammet var det i praksis helt umulig å bruke tjenesten, men for de aller fleste virket jo alt som normalt.
Henvendelsene til kundestøtte var ganske ulne i beskrivelsen av symptomene, slik det forståelig nok er med ikke-tekniske brukere. “Works for me” oppsummerer alle forsøk på reproduksjon av problemene. Nylige endringer i både kode og infrastruktur ble støvsugd for mulige ledetråder. Det var ikke før etter en grundig analyse av feilrapportene at vi begynte å se en fellesnevner - mens de fleste av brukerne befinner seg i Skandinavia, så kom feilrapportene hovedsakelig fra lenger sør på kontinentet!
Det betød at problemet kunne være relatert til rutingen ute på internett og vi koblet på vår hosting-leverandør for videre feilsøking. De har igjen sin leverandør av tilkobling til nettet, hvor de opprettet en sak, og vi håpet at problemet snart ville være ute av verden. Men dagene gikk og kundestøtte fortsatte å få inn rapporter.
Dermed var det behov for å forsøke å bidra ytterligere i feilsøkingen. Men hva kunne vi bidra med i et problem vi kunne anta lå langt borte og langt utenfor vår kontroll? Og det er akkurat slike veldig åpne, dypt tekniske nøtter jeg setter spesielt pris på!
Ganske raskt fant vi igjen forespørslene fra kundene med problemer i access-loggene, og her var det også en fellesnevner - noen av dem hadde responstid sammenfallende med tiden for tidsavbrudd. Noe støy var det selvsagt, men med litt manuell filtrering kunne vi lage lister med IP-er som var rammet og som ikke var det.
Deretter brukte vi traceroute fra servere i Oslo til å spore rutingen til klientene for å se etter fellesnevnere. Tanken var at det kunne være en linje mellom to rutere, eller en enkelt ruter, som hadde en eller annen form for feil. Ved å lage et tre over rutingen fant vi én bestemt sti nedover i vårt naboland som felles for problemene. Det må nevnes at traceroute ikke er helt nøyaktig da det ikke nødvendigvis viser alle fysiske hopp, det er flere underliggende lag. Den viser dessuten heller ikke såkalt asymmetrisk ruting hvor stien ikke er lik i begge retninger. Likevel et interessant og ikke minst morsomt verktøy.
Ledetrådene ble videreformidlet til vår leverandør, men dagene gikk uten resultater. Det var behov for å finne på noe lurt. Rask, enkel og stabil reproduksjon av et problem er ofte en viktig nøkkel for å komme videre. Og det ble det også her. En ansatt hos kunden vår hadde en privat konto hos en av disse VPN-leverandørene som er populære som YouTube-sponsorer. Ved å prøve seg gjennom en rekke av de valgbare utgangsnodene klarte han å reprodusere problemet ved å sende trafikken via enkelte europeiske byer.
Hvorfor hadde vi ikke tenkt på dette før?! Et kredittkort og litt utprøving senere, og vi hadde tcpdump/Wireshark-logger fra begge ender av kommunikasjonen. Der så vi raskt at enkelte TCP-strømmer gikk helt uten problemer, mens andre viste tegn til pakketap. Dette var jo veldig rart! Og igjen, kunne vi finne en fellesnevner?
I slike situasjoner gjelder det å ikke gi opp, men å være kreativ og ha et åpent sinn. Kunne det være et sporadisk problem hvor helt tilfeldige TCP-strømmer ble rammet - for eksempel vakkel i en kontakt, eller kunne det være et eller annet relatert til innholdet i pakkene. Sistnevnte var noe vi i stor grad kunne kontrollere og teste for, og dermed en mulig vei videre.
For å gjøre historien kort, vi fant etter hvert ut at avsender-porten i TCP-hodet hadde en påvirkning. Dette er et 16-bits felt som normalt blir tildelt av operativsystemet, en såkalt “ephemeral port”, men enkelte verktøy lar brukeren styre nummeret, og dette brukte vi for å teste.
Og igjen, kan vi finne et mønster? Litt tilfeldig utprøving i starten, deretter mer og mer systematisk, og det blir klart at visse områder med portnummer virker mens andre ikke virker. Kan vi grave oss enda dypere ned? Det er ikke så ofte man får muligheten til det, men her ble det aktuelt å se på de grunnleggende digitale byggeklossene: bitsene i portnummeret. Og dypt her nede lå mønsteret: når ett bestemt bit var satt høyt (1) var TCP-strømmen dømt til å feile!
Feilen var sannsynligvis altså en maskinvarefeil i en ruter langt der ute på internettet! Hvem skulle trodd noe sånt kunne skape så rare problemer for vår lille SaaS da de første feilrapportene tikket inn. Hva som var selve rotårsaken her, om det var en minnefeil i ruteren, eller om portnummeret ble brukt som en del av en algoritme for lastfordeling mellom flere linjer (hvorav én hadde feil), fikk vi aldri noe svar fra vår underleverandør på. Men problemet ble plutselig løst og det var slutten på den historien. God jul!