Sådan udsendte vi 156.150 e-mails ved en fejl

Som beskrevet i en tidligere artikel kom vores system ved en fejl søndag aften til at udsende 10 gamle nyhedsbreve til alle abonnenter på Version2's nyhedsbrev.

Vi har nu fundet frem til årsagen, og jeg vil i dette indlæg kort redegøre for, hvordan det kunne lade sig gøre.

Siden relanceringen af Version2 i sommeren 2011 har vi benyttet tjenesten Mailchimp til at udsende nyhedsbreve. Mailchimp er formentlig verdens største på dette område, og firmaets interessante årsrapport for 2012 viser, at der i alt blev sendt 34.796.235.769 e-mails gennem systemet.

Mailchimp har et omfattende API, som vi benytter på Version2. Vi har bygget vores egen logik for dette baseret på det officielle Mailchimp-modul til Drupal.

Logikken er ret enkel. Nyhedsbreve er oprettet som indhold (i Drupal kaldet 'nodes') i vores system, så journalisterne selv kan styre disse som udgivelser. Hvert nyhedsbrev har et tidspunkt for udsendelse samt et interval for det indhold, nyhedsbrevet skal trække. Det har fungeret ret godt for os og været brugervenligt og effektivt for journalisterne at arbejde med.

Illustration: Privatfoto

Ved cron (som kører hvert minut) tjekkes på vores server for, om der er nyhedsbreve, hvis udsendelsesdato er overskredet. I så fald kalder vi Mailchimp gennem API'et og beder Mailchimp om at udsende disse til hele listen.

For Version2 kører vi mere end ét miljø - vi har forskellige lokale udviklingsmiljøer, et staging-miljø, test-miljøer og så videre. Her kan hurtigt opstå et problem, hvis udviklings-miljøer får et ældre database-dump fra live-miljøet, da de så vil tro, at de har en masse ikke-afsendte nyhedsbreve - og gå i gang med at sende dem, hvis cron bliver kaldt.

Derfor er det kun vores live-miljø, som har den rette API-nøgle til Mailchimp. Alle andre miljøer er låst ude fra at kunne kommunikere med Mailchimp.

Og det er så her, at problemet er opstået - i forbindelse med en række test af et nyt hosting-miljø, er live-konfigurationen og den rigtige API-nøgle for Mailchimp desværre blevet kopieret over i et test-miljø. Dette test-miljø har af endnu uforklarlige årsager kørt cron, og med den rette API-nøgle har det altså haft fri adgang til at sende (gamle) nyhedsbreve gennem Mailchimp.

Mailchimp er som en Ferrari - træder du speederen i bund, skal den nok følge med (ingen it-forklaring uden en bil-analogi). I vores tilfælde fik vi i løbet af et enkelt minut udsendt 156.150 e-mails.

Vi opdagede heldigvis fejlen hurtigt, og efter at have spærret alle API-nøgler i Mailchimp, måtte vi i gang med at forklare og undskylde på sitet og sociale medier, hvor det væltede ind med spørgsmål til, hvad vi egentlig havde gang i.

Her til formiddag er resultatet, at vi har fået 86 nyhedsbrevs-afmeldinger og 2 abuse complaints (spam-klager) som følge af de 10 fejludsendelser. Herudover har vi modtaget en stor mængde henvendelser fra folk, der er flinke at gøre os opmærksomme på problemet. Det er interessant at bemærke en generel høflig tone og forståelse for, at tekniske problemer kan opstå.

Vi har været i fuld gang med at udvikle en ny logik til vores mail-udsendelse, hvor der foruden API-spærring er en række 'failsafes' indbygget, så systemet først tjekker på dato, om der er udsendt noget inden for den sidste time - og en række andre tjek, som skulle forhindre, at dette kan ske igen. Denne kode er desværre ikke live endnu, men det er forståeligt nok noget, vi vil sætte ekstra fart på.

Er der yderligere spørgsmål til vores setup eller har du selv erfaring på dette område, du kan dele, hører vi det meget gerne i debatten herunder.

Og så er det selvfølgelig endnu engang på sin plads at sige: Undskyld.

Kommentarer (19)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Kasper Grubbe

Hvis i virkelig har behov for at køre cronjobs i test og staging-miljøer, ville det så ikke være hensigtsmæssigt at tjekke for hvilket environment koden som kører er i, før den begynder at sende noget så kritisk som e-mail udsendelser ud?

Hvad sker der iøvrigt hvis kaldet til Mailchimp tager længere end et minut?

Og tak for opklaringen og blogposten :-)

  • 4
  • 0
Johannes Ulfkjær Jensen

Det ser ud som om i tager det seriøst hvilket er dejligt at se. Jeg undrer mig blot over hvorfor denne konfiguration ligger i miljøet og ikke i er versionskontrolleret. Håber i laver et nyt indlæg over hvordan i håndterer det i fremtiden når i har fået det implementeret. Vidensdeling er godt.

Sidenote: Jeg fik ikke selv noget spam men undrer mig lidt over det da jeg plejer at melde mig til den slags. Måske bør i gøre mere opmærksom på nyhedsbrevet og eventuelt sælge det i højere grad på indhold end muligheden for at vinde en ipad. Rygtet siger at der er gode penge i nyhedsbreve.

  • 1
  • 0
Anders Pallisgaard

Jeg anvender Amazon Simple Email Service (SES) til udsendelse af masseemails. Når jeg laver et produktions-dump af databasen til et test-miljø, så har jeg en lille sql-update som ændrer alle email-adresser til et domæne jeg selv styrer med en catch-all mail-adresse tilknyttet. SQL'en ser således ud:

update system_users set email_address=CONCAT(ROUND(RAND()*100000000), '@foreninglet.dk')

Så gør det ikke noget hvis cron ved en fejl får sat gang i en masseudsendelse, da jeg selv modtager alle mails til en catch-all adresse som nemt kan tømmes.

  • 2
  • 0
Michael Mortensen

Har i overvejet en smarthost som kun tillader udsendelse af mail til forhåndsgodkendte domæner? Eks. kunne @version2.dk, @ing.dk m.fl. være godkendte hvor alle andre ville blive ignoreret - dvs. de vil aldrig nå udsendelse fra SMTP serveren og dermed aldrig kunne udsendes fra dev/stage miljø.

  • 1
  • 0
Andreas Krüger
  • 0
  • 0
Andreas Krüger
  • 0
  • 0
Rune Andersen

Det havde ikke nødvendigvis ikke hjulpet os at tjekke på hvilket miljø det drejede sig om, da problemet opstod på et nyt produktionsmiljø. Vi har nogle andre forholdsregler som i dette tilfælde ikke var nok.

Vores konfigurationsfiler er versions-styret, men ifm test på vores nye servere, blev der foretaget lokale ændringer som var medvirkende til problemet.

Cron kører ikke på dette miljø, men drupals indbyggede "poor mans cron" gør. Det vil ikke normalt være et problem, da serveren ikke bliver tilgået på produktions domænet, men i et tilfælde hvor dette er sket, er der blevet sendt besked til mailchimp om at sende en række mails, og hente disse mails fra vores rigtige produktions server.

Kaldet til mailchimp klares ret hurtigt, da den kun modtager få parametre, selve nyhedsbrevet bliver ikke generet med det samme, men mailchimp henter det efterfølgende. Drupals cron sørger som standard for at jobs der ikke er afsluttet ikke bliver kørt igen næste gang cron bliver kaldt.

mvh
Rune - Version2

  • 7
  • 0
Jacob Hansen

Min tid går med at sidde hjemme og stirre stift på skærmen. Så snart jeg får en nyheds-mail, som tydeligvis er lidt forkølet, så har jeg forberedt mig grundigt på, hvilke instanser jeg kan kontakte for at anklage sitet for SPAM. Sådanne amatøragtige sider skal ikke slide min mailbox op, med de få fejlsendte nyhedsbreve, jeg får!

Mine tænder er helt slidt ned af at sidde og skære tænder og knurre. Mit blodtryk holdes kun højt med RedBull og ved at hamre mine fingre i tastaturet, når jeg får en skinke-mail. Det er en fryd at se dem bukke under for min enorme harme og vrede mails, jeg kan formå at sende, for at stoppe det urimelige mailbox-krænkeri, der med fuldt overlæg hagler ned på os uskyldige, der helt uden at kende konsekvenserne har tilmeldt os et så underlødigt nyhedsbrev.

Mine øjne lyner! Dampen står ud af ørerne! Jeg er indbakkernes beskytter! Jeg er frihedens vogter! Jeg er root (på min maskine)!

Og/eller:
Tak for et super fint site, og mange tak for et rigtigt interessant og lærerigt nyhedsbrev, som jeg får helt gratis i min indbakke. Og så er det sku i orden, at mekanikken driller. Det sker jo selv for de bedste. :)

  • 3
  • 0
Tom Paamand

Hvis jeg sad med 150.000 modtagere til en mail, ville jeg ikke lade mekanikken styre udsendelserne alene. Systemet måtte pænt spørge en ansvarshavende, der så gav personligt gav lov til udsendelsen. Antallet af udsendelser er da ikke større, end at dette er det mest overskuelige - selv om mekanikken fortsat får lov til at stå for opsamling og udsendelse.

  • 0
  • 1
Klavs Klavsen

Jeg vil anbefale jer god praksis - at have skodder imellem test og produktion.

Her er mailchimps IP'er produktion (har de egentlig en test service?) - så dem bør der selvf. være spærret for.

Så lås jeres firewalls af - så ting ikke har adgange de ikke har behov for.
Ligeledes skal test servere, IKKE kunne forbinde sig til en produktions database - hvis den nu ved en fejl, fik en forkert config ind.

  • 0
  • 0
Casper Thomsen

Det indsatte billede viser 15.615 modtagere og gange 10 må det vel være 156.150 mails.

Ha, du har helt ret. Det gik lidt hurtigt, fordi vi gerne vil have forklaringen ud, men hvor jeg har fået det tal fra, aner jeg ikke. Godt set. (Jeg skal lige gøre opmærksom på, at jeg ikke har at noget at gøre med selve koden på vores site, så I kan være helt rolige).

Jeg har rettet artiklen, så tallet passer.

Mvh Casper

  • 0
  • 0
Søren Nielsen

Den måde vi alle kan blive bedre på, er ved at dele vores fejl, så andre ikke falder i. Det skal i have tak for- og må andre tage ved lære her af. Jo bedre fejlen er beskrevet, jo bedre bliver vi andre rustet. Det er det samme som med projekt evalueringer, der repræsenterer dyr viden, der skal deles -ikke hånes.

  • 1
  • 0
Log ind eller Opret konto for at kommentere