Kære EkstraBlad … glæd jer over at jeg i det hele taget gider besøge jeres hjemmeside!

Hvordan min browser er sat op skal jeg nok selv bestemme! Ekstra Bladet gav mig den her da jeg i en brandet kom til at klikke på et link til en artikel hos dem på Facebook:

Jeg “Blokerer for annoncer” … hvilket jeg ikke gør, jeg har intet imod at de viser mig annoncer … dem har jeg et mentalt filter for, næh det jeg blokerer er alle deres fucking trackere:

Og af den årsag får jeg ikke lov at læse deres sprøjt af en avis … det er noget fjolleri, og det gider jeg selvfølgelig ikke finde mig i … jeg har jo “betalt” … jeg vil netop gerne bruge min cpu-kraft og båndbrede på at se deres latterlige reklamer … jeg kan ikke gøre for at de vælger at bundle deres reklame-lort med trackere og at det hele derfor ryger i filteren.

Du gør således, i Chrome højreklikker du på det store sorte felt der skjuler siden og klikker “Undersøg”:

Derefter vil den forhåbentligt vise dig kode-examinatoren med det aktuelle element fremhævet.

Højreklik på blokken og vælg “Delete element”

og så læste jeg den, iøvrigt udemærkede, artikel.

Kære dagblade, aviser og generelle klassiske presse … i er ude og skide, i står i den silende regn udenfor døren mens en sulten Tyrannosaurus lurker rundt og så hjælper det altså ikke at skide på fyren med nøglen til bunkeren, våbendepotet eller helikopteren … så var det måske smartere at demonstrere sin værdi som uundværligt medlem af flokken og således gøre sig værdig til et sæde i helikopter, en seng i bunkeren eller som minimum en riffel …

I kommer ikke tilbage i varmen ved at overvåge os, forsøge at bestemme over os og spærre jeres til tider udmærkede artikler inde bag en paywall, internettet skal nok klare jer uden jer … ingen tvivl om det. Men kan i klare jer uden internettet? I don’t think so!

Webudvikling: Sikker håndtering as passwords

Der er mange webudviklere som reelt ikke har den fjerneste ide om hvordan et password skal behandles, selv store sites som f.eks. LinkedIn har for nyligt vist at de ikke har styr på det.

1. Opbevar altid passwords krypteret

Hvis du som website udvikler på noget tidspunkt kan læse en brugers password, så er det en fejl. Passwords skal altid gemmes på en sådan måde at de ikke kan læses igen når de først er indtastet, det kaldes populært for “krypteret” mén faktisk er det forkert, fordi kryptering er pr. definition two-vejs, du kan kryptere og du kan afkryptere.

One-way hashing kan ikke “afkrypteres” men tilgengæld ved vi at det samme password altid vil give den samme hash og vi kan derfor blot sammenligne hashen af det gemte password med hashen af det indtastede password.

Som en sidste kommenar skal du altid bruge en sikker hash-algoritme, world-wide vækst indenfor computerkraft er eksponentielt og algoritmer der var sikre i 90’erne er idag nemme at bryde og dem der var sikre i 70’erne er endnu nemmere. Det betyder at f.eks. den populære md5 hash-function er usikker og ikke bør bruges, brug istedet sha-256 eller sha-512 som f.eks. kan implementeres med Php’s hash() funktion, derudover skal du bruge en unik salt pr. bruger/password.

2. E-Mail er så sikker som et postkort

Når du sender en email til en person så skal du forvente at det bliver læst af mindst 20 andre mennesker, din chef,  systemadministrator, internet udbyder, din kone, dine børn og et par tilfældige efterretningstjenester, hackere og spyware produkter.

Så det er aldrig acceptabelt at sende et password i en email, for det første fordi du ikke må have kendskab til brugeres password ifht. punkt 1, derudover giver du resten af verden hovednøglen til din bruger konto – og andre konti hvor denne bruger samme password.

Det er selvfølgelig heller ikke iorden at sende Visa/Dankort detaljer eller andre personlige information via E-Mail – og hvis du har behov for at sende f.eks. et password til en kunde, så generer et one-time-password til kunden som kun kan bruges én gang.

3. Begræns ikke password og udnyt entropy

Passwords skal være unikke og de skal være komplekse, hvis brugeren indtaster mærkelige tegn eller mellemrum, samt store og små bogstaver så er det alt sammen med til at gøre password sværere at gætte og hvis brugeren selv vælger at bruge disse tegn har kunden  formodentligt også styr på at taste password rigtigt hver gang.

Der er nogle sider der fjerner store og små bogstaver og specialtegn fra passwords, eller som giver en fejl hvis man indtaster et password med mellemrum i eller hvis man bruger specialtegn.

Jeg føler lidt at det er spild af jeres tid og sige det her, men jeg har set det flere steder og det er hamrende uprofessionelt og der er INGEN undskyldning for at simplificere brugerens password og da slet ikke for at begrænse brugerens password.

Det eneste du bør gøre ved dine brugeres indtastninger i et password felt er at hashe det, og gemme hashen. Punktum!

4. Undgå Information leaks

Når dine brugere glemmer deres passwords, og det gør de. Så skal de kunne genetablere det, det foregår typisk ved at du indtaster din email adresse på hjemmesiden og modtager en email med en one-time-url til at ændre dit password.

Det er sådan set fint nok, med mindre at formularen kan bruges til at gætte brugernavne med. Hvis du kan indtaste bruger@domæne.com og få beskeden “Beklager meget, men den indtastede adresse findes ikke i vores system” eller hvis du kan indtaste brugernavn og password og få beskederne hhv. “Dit brugernavn er forkert” og “Dit password er forkert”.

Ovenstående giver en angriber mulighed for at gætte sig frem til et gyldigt brugernavn, og det er selvfølgelig noget der skal undgåes.

Enkelte steder har jeg enddog opdaget at jeg blot ved at taste min email adresse får adgang til mit navn, adresse, telefon og email samt ordrehistorik.

Dette er selvfølgelig en stor fejl og skal undgåes, sørg for at en bruger altid skal oplyse både email og password, eller email kombineret med modtagelse af en email for at opnå adgang til opbevaret information.

5. Undgå at bruge passwords

Jeg kom lidt ind på det før med modtagelse af emails, hvis vi kan bygge et system uden brug af passwords vil det øge sikkerheden væsentligt.

Hvis vi f.eks. kan bruge two-factor authentifiation i form af email, sms eller telefonopkald så øger vi sikkerheden eksponentielt. Forestil dig at blive ringet op af en person der kender dig og blive spurgt om du er ved at logge ind på din webmail, hvergang du logger på. Personen kender din stemme og kender en række detaljer om dig. Så hvis personen ikke er sikker på stemmen bliver du spurgt om ting som farven på din bil, eller antallet af børn – eller lign.

Det giver sig selv at gør det meget sværere at omgå sikkerheden, men samtidig er det også lidt kluntet at skulle blive ringet op 10 gange om dagen – så lige mht. webmail er det måske ikke det smarteste, med mindre selvfølgelig du lægger en cookie på brugerens computer og lader telefonopkaldet gælde for lige netop dén computer i et bestemt antal dage, og i denne periode kan brugeren logge ind kun med sit password.

Telefonopkald af en personlig bekendt er måske i overkanten til langt de fleste applikationer, men SMS Verifikation er idag let tilgængeligt og billigt at implementere.

6. Anvend autogenererede passwords

Enkelte steder er det upraktisk at skifte passwords hele tiden og samtidig er det praktisk at kunne oplyse brugeren om sit password, det er f.eks. tilfældet ifht. webhosting hvor du har databaser og email konti der er indtastet flere forskellige steder.

Det er bestemt ikke optimalt men i mange situationer er det den udvej man rent administrativt har valgt, og derfor kan det give mening af opbevare passwords.

Til den slags konti skal du bruge autogenererede passwords sådan at du ikke risikere at kunden selv bruger sin dankort kode eller password til sin netbank, det skal være et unikt genereret tokken som kun bruges til den ene ting, du kan f.eks. bruge http://www.sikkeradgangskode.dk

Derudover anbefaler jeg at kombinere den type adgang med en ekstra for for kontrol, f.eks. logning af tilgang, ip adresse blokering eller lign.

Epilog

Er vi i mål nu? Nej … på ingen måde, men vi er godt igang. Hvis alle ovenstående punkter er nye for dig, tillykke, så er du en af de få der laver tingene ordentligt første gang.

Jeg har selv været ude for at må tage genveje på grund af deadlines eller nærige chefer, og har også selv været den der måtte ryde op efter det var gået galt.

Det koster som regel mere at ryde op når det ér gået galt, end det ville have kostet at gøre det rigtigt fra starten af og jeg vil også gerne understrege at det langt fra altid er programmørens skyld. Ligeså ofte er det projektlederen, direktøren eller marketingsafdelingen der stiller krav om at det f.eks. skal være muligt at oplyse kunden sit password.

 

Hjælp … jeg er blevet populær.

Når dit website vokser dig overhovedet kommer det typisk bag på dig, det er ikke en situation du har forberedt dig og du har nu fået en mail fra dit webhotel med beskeden om din konto er suspenderet fordi du enten har brugt for meget trafik eller overbelastet serveren.

En anden mulighed er slet og ret at dit site begynder at blive så langsomt at dine brugere klager, og måske endda begynder at forlade siden. Det er selvfølgelig ikke rart, så hvad gør man for at løse problemet?

Den typisk fejl folk begår er at skifte til et andet, lidt større og måske lidt bedre webhotel hvorefter der går et par uger eller måneder indtil det hele gentager sig igen, som almindelig forbruger eller sågar som teknisk dygtig programmør kan det være svært for ikke at sige umuligt at vurdere kvaliteten på et tilfældigt webhotel.

En anden typisk fejl er at gå ud og leje den størst mulige server, og flytte din side derover. Det skal nok hjælpe i starten, primært fordi du pludselig har alle maskinens resourcer for dig selv, du vil opleve at størstedelen af din maskine slet ikke bruges eller at siden stadig er langsom selvom der er mange resourcer tilbage.

Det kan lidt sammenlignes med at købe en racerbil og så sætte din 7 årige søn til at køre i den, der er en ret go chance for at han ikke får den til at køre og hvis endelig han gør ødelægger han både sig selv og bilen.

Du bør selvfølgelig starte ud med at konsultere en person der har forstand på at køre racerbilen, og på samme måde skal du selvfølgelig også søge eksperthjælp når du skal have dit website til at bryde hastighedsgrænserne på internettet. En dårlig opsat dedikeret server eller virtuel server kan faktisk performe dårligere end et ganske almindeligt discount webhotel.

En anden observation man også er nødt til at gøre sig, hvad sker der den dag dit website kører på den størst mulige server med den størst mulige internet forbindelse med så meget ram som dit operativsystem kan håndtere … og du bliver ved med at få flere kunder og få højere og højere belastning på maskinen.

For at det hele ikke bare er metaforer vil jeg gennemgå nogle eksempler på hvad man rent praktisk kan gøre, og kort nævne et par fordele og ulemper:

  • Finjustering af serveren resourceforbrug, der er ikke nogen endelig løsning i din specifikke situation kan det være at din database kræver flere resourcer end din webserver, eller omvendt. Der er nødt til at foreligge en analyse af din applikation og dens resourceforbrug før der kan laves et brugbart estimat. Efterfølgende er man nødt til at finjustere løbende under drift.
  • Fordeling af roller til flere servere, det klassiske råd er at skille webserveren fra databasen og på den måde opnå flere resourcer end én fysisk maskine kan levere, men du rammer igen et problem når du så har brugt alle resourcer på begge maskiner og du ikke kan købe større maskiner.
  • Cluster setup med flere servere til hver rolle, en anden løsning er at sætte hhv. 2 eller flere database og webservere op, på den måde kan du skalere din løsning ved at tilføje flere maskiner af samme størrelse som din nuværende, du kan vælge at opgradere der hvor det giver mening og lade de dele som klarer sig fint være. Den største ulempe ved et cluster setup er at det er utroligt komplekst og typisk kræver en del tilpasning.
  • Flere forskellige former for cache, en cache er et midlertidigt lager hvor man opbevarer ting midlertidigt for hurtigt at kunne finde dem igen. Der findes flere forskellige caching teknikker og de har alle hver deres fordele og ulemper. Det er f.eks. muligt at sætte en række serveren foran webserverne som laver hjælper med at aflaste serverne, hvordan disse performer og generelt påvirker din applikation afhænger 100% af deres opsætningen.En anden mulighed er at installere en op-code cache som f.eks. APC, når webserveren udfører en PHP Fil skal den første fortolke alle kommandoerne i filen og oversætte dem til maskin-kode som serveren CPU kan forstå. Denne process foretages hvergang en PHP fil skal udføres, uanset om indholdet af filen er ændret eller ej. Dette er selvfølgelig et spild af resourcer og det er netop her en opcode cache kommer ind, den husker oversættelsen og genbruger den hvis der er behov for det. Det giver et enormt performanceboost på PHP tunge sider og det giver stort set ingen problemer.
  • Optimering af kildekoden og databasen, selv dygtige programmører laver dårlig kode, og dårlige programmører laver forfærdelig kode. Jo længere tid et projekt er under aktiv udvikling desto mere forværers koden og jævnlig oprydning er nødvendig. Tillæg dertil at de typiske iværksætter-projekter er startet eller udviklet af et par unge knægte, eller ihvertfald nogen som ikke er specialister indenfor deres felt. Det kan være ganske udemærket, men det kan sammenlignes lidt med at bygge et højhus på et fundament af halm og ler.Med andre ord er der næsten altid ydelse at hente i koden, og typisk vil der være behov for løbende at omskrive større eller mindre dele af koden, og det typiske tidspunkt at påbegynde dette arbejde er netop når den første opgradering, til f.eks. en virtuel server, er begyndt og man så småt begynder at øjne behovet for skallering i fremtiden.
  • Cloudløsninger og andre sky-basserede services, du har helt ret, det ligner ikke mig og bruge buzz-words, og pointen med det her punkt er også at afvise at “skyen” er svaret på alle dine bønner. For det første er sky ikke et fast defineret fagligt udtryk og det er derfor noget vrøvl at bruge det som sådan, det er derimod et buzzwork sælgere bruger for at lyde moderne. Alle steder du hører ordet “sky” eller “skyen” kan du sætte “internet” eller “internettet” ind i stedet, og på den måde afkode hvad din sælger forsøger at sælge dig.Lad mig slå det fast, Amazon, Microsoft Azure og den million af små private cloud-udbydere der skyder op verden over er direkte at sammenligne med en klassisk hosting udbyder der udlejer fysiske og virtuelle servere. Forskellen er 80% markedsføring og 20% smarte web-kontrolpaneler.Så ja, du kan sagtens bruge cloud til at løse dit problem, men det er kun en del af løsningen, alt ovenstående er stadig aktuelt uanset om du bruger en udbyder der kalder sit udstyr for en/flere serverpark(er) eller en/flere sky(er)

I min forretning har vi valgt at kombinere rådgivning og drift, således at vi kan designe en komplet hostingløsning og enten levere en projektplan eller slet og ret implementere den og servicere den for kunden, derudover har vi etableret professionel redundant hostingservice i Danmark, og hvis kunden har behov for hosting i udlandet har vi flere forskellige faste partnere vi trækker på. 

Det vigtige er altså ikke hvilken udbyder man vælger, men hvem man vælger til at administrere løsningen og hvordan man gør det.

Sådan bygger du skalerbare webapplikation

Du bliver ikke specialist af at læse denne artikel, men den almindelige gennemsnitslige webudvikler til at bygge “mindre håbløse” applikationer 🙂

Det der oftest sker er at en person får en ide til et spændende koncept, hyrer en handelsskoleelev, eller en middelmådig programmør – intet galt i det, jeg kender alt til at man som nyslået iværksætter ikke har råd til lukusmodellen fra dag 1. – problemet er bare, at for det meste ender den oprindelige model med at leve meget længere end først antaget, og virksomheden bliver længere henne i processen ofte tynget af dårlige beslutninger taget af den oprindelige udvikler … beslutninger som i sig selv kan virke ubetydelig, men om 3-4 år er vokset i en grad så det ikke er til at lave om.

Dette har affødt denne artikel, det er en række anbefalinger der er nemme at følge og som enhver der bare er marginalt kvalificeret til at udvikle en hjemmeside, bør kunne forstå og følge.

  1. Forbered siden på at køre fra et CDN, gem alle statiske filer, billeder, javascripts, css filer mv. på et seperat sub-domæne, det kunne f.eks. hedde filer.domæne.dk
  2. GemSESSIONS i databasen, når siden en gang får behov for at køre fra flere webservere vil det være nødvendigt at have centrale session-data, og databasen skal alligevel være delt så det vil typisk være det foretrukne valg.
  3. Lav så meget som muligt i Webbrowseren. Istedet for at reloade hele siden hvergang brugeren laver en lille ændring, så kør en javascript/JQuery funktion der sender en forespørgsel til webserveren og modtager f.eks. et json encoded svar, dette kan f.eks. indeholde nye chat-beskeder eller en reaktion på en bruger handling.Det er meget nemmere for serveren at betjene et enkelt json-kald end at reloade hele siden. Hvis dette gøres gennemført nok kan du faktisk lave hele siden så du loader al html og javascript én gang, og efterfølgende foregå al kommunikation med webserveren via json kald.
  4. Lav én PHP Klasse som står for al kommunikation med database. 
  5. Lav sådan at der kan laves read-write split på dine database queries.En måde at udvide en database applikation til to eller flere fysiske maskiner er at lave et såkaldt master-slave cluster, hvor én fysisk maskine tager sig af alle skrive opgaver mens en eller flere slaver håndterer læsninger.Det betyder principielt at alle ALTER, INSERT, CREATE, DELETE queries skal gå til f.eks. masterdb.domæne.dk mens alle SELECT skal gå til slave1.domæne.dk ELLER slave2.domæne.dk ELLER slave3.domæne.dk
  6. Brug kun InnoDB. Der er meget få gode undskyldninger for at bruge andet, det er ikke noget du bør bekymre dig om, bare vælg InnoDB som standard, i 95% af tilfældende er det dit bedste valg. Hvis du tror du er kommet ud for en af de sidste 5% bør du konsultere en database specialist.
  7. Design dine databaser med omhu. Du skal vide hvad et index er og hvordan man bruger dem, du skal bruge fornuftige typer – dvs. hvis et felt skal indeholde et tal, så må det ikke være en varchar. Alle tabeller skal have mindst én unik nøgle, hvis ikke tabellen har en naturlig nøgle så opfind en (jeg ved godt det strider imod normalformerne – beklager meget, skolen er slut, velkommen til virkeligheden) og når vi nu er ved normalformerne, så brug dem som reference.Undgå “tlf1″,”tlf2″,”tlf3” og undgå “tlf1,tlf2,tlf3” har du behov for mere end et telefonnummer er det yderst sansynligt at der findes scenarier hvor du har behov for ‘n telefonnumre. Lav derfor en seperat tabel til formålet.
  8. Ryd op i dine data, smid gamle data ud.Du bør kun gemme data du har behov for at gemme, der er ikke noget der hedder “vi gemmer det for en sikkerhedsskyld”. Hvis du gerne vil lave statistik, så beregn statistiken og smid de enkelte kliks ud bagefter.Lav en rutine der ved årsskiftet til 2020 trækker data for 2019 ud og gemmer dem i en seperat fil, og sletter dem i databasen.
  9. Hvis ting kan deles op, så del dem op for pokker. Hvis du laver en saas-applikation (eller som det hedder nu til dags, “cloud”) så vær opmærksom på at det ikke nødvendigvis er smart at rode alle dine kunders data sammen i én stor database. Måske kan man lave så alle kunder i f.eks. Danmark har deres egen database? Eller endnu bedre, sådan at hver enkelt kunde har sin egen database?
  10. Dan dig overblik, brug kode versionering og dokumenter din kode.Jeg ved godt der kom et par fy-ord der, men det er for det første noget du selv kan få gavn af, for det andet kan det være knald-eller-fald for virksomheden hvis du en dag ikke er der mere til at rede deres røv når lortet det går ned.Følg med i hvad systemet bruger af trafik, diskplads, cpu, ram osv. Hav styr på hvilke bibliokteker og pakker din kode gør brug af, strø kommentarer ud over koden alle steder hvor det giver mening.
  11. Lav et one-step-deploy script.
    Du skal med én kommando kunne rulle en given version af siden ud på en ny dev- eller produktionsserver. Det giver jeg hurtigere disaster recovery og det gør det nemmere at teste ny kode. Derudover kræver det at du har overblik over din applikation, det vil komme dig til glæde den dag du skal have de første eksterne folk ind over projektet.
  12. Lav pæn kode, jeg mener det, og ikke bare det du “syntes er pænt”.
    Dine variabler, klasser og metoder skal have sigende navne, det skal holdes i et bestemt sprog, typisk engelsk, men dansk kan også godt gå, bare det er konsistent hele vejen igennem. Ikke noget med at bruge bandeord, personer fra star-wars eller planeter, det er nemt at regne: DeployCustomerAppliance(); ud, men det er pænt umuligt at gætte hvad: Jupitor(); gør.
  13. Undgå så vidt som muligt at ændre i fil-træet,og hvis du gør det så sørg for at lave en abstraktionsklasse til det sådan at det i fremtiden nemt kan ændres til f.eks. at uploade evt. filændringer til et CDN eller til flere webservere.Mén billeder, video o.l. bør altid uploades til et CDN, eller ihvertfald en eller anden mekanisme til at håndtere den slags data, og alle andre dynamiske data bør ligge i databasen.
  14. Hold orden i dine filer. Jeg har engang haft en kunde der havde et webdir på 75GB, da vi var færdig med at ryde op og smide gamle database dumps og backup-tarballs ud fylde det pludselig kun 15GB.
  15. Lav fejltollerante applikationer. Tag stilling til hvad der skal se hvis din applikation ikke kan få fat i databasen, eller CDN’et. Hvad er nødløsningen? Skal data caches? Hvor? skal der sendes fejlbeskeder ud? Til hvem? Via hvilket medie? Hvad skal fejlbeskederne sige?
  16. Adskil webdesign og kode, defacto standarden for at gøre det i PHP hedder Smarty, der er simpelthen ingen unskyldning her … inline-kode medfører dødsstraf 😉

Bookmark denne artikel, jeg kommer nok til at udvide den løbende 🙂