Juho Mäntysaari, 2011
Ohjelmointityötä tehdessä on tärkeää huolehtia, että kaikilla ohjelmoijilla on käytettävissään uusin versio jokaisesta lähdekooditiedostosta. Tähän käyttötarkoitukseen on käytettään versionhallintajärjestelmiä. Perinteisissä järjestelmissä on yksi tietovarasto, jossa säilytetään kaikkia tiedostoja ja niiden versiohistorioita. Nykyään suosiota ovat saavuttaneet niin sanotut hajautetut versiohallintajärjestelmät, jossa joka ohjelmoija pitää itsellään kopiota koko versiohistoriasta ja jossa käyttäjät pystyvät synkronoimaan kehitystyötään keskenään ilman sen lataamista koko projektin keskitettyyn järjestelmään. Hyvinä esimerkkinä hajautetuista järjestelmistä voidaan pitää suuren suosion saavuttaneita järjestelmiä Mercurial ja Git. (O'Sullivan, 2009)
Perinteiset keskitetyt järjestelmät ja niiden tietoturvaongelmat
Perinteisissä keskitetyissä versionhallintajärjestelmissä ohjelmistoprojektin koko versiohistoriaa säilytetään yhdellä keskitetyllä palvelimella. Käyttäjillä on omilla koneillaan vain yksi muokattavana oleva versio hallitusta lähdekoodista. He pystyvät versiohallinnan tarjoamilla komennoilla vertailemaan omaa versiotaan keskusvarastosta löytyviin versioihin, hakemaan muiden järjestelmään lataamia muuttuneita versioita itselleen, sekä lähettämään omia muokkauksiaan keskitettyyn tietovarastoon. (O'Sullivan, 2009)
Käytettäessä keskitettyä versiohallintaa voidaan ulkopuolisten pääsyä lukemaan tai kirjoittamaan estää järjestelmän tarjoamilla pääsynhallintatoiminnoilla. Useimmat keskitetyt versiohallintajärjestelmät tukevat pääsyn rajoittamista järjestelmän toimintoihin vain salasanalla autentikoituneille käyttäjille. Käyttämällä pääsynhallintaa saadaan ohjelmiston lähdekoodi pidettyä turvassa niin kauan, kuin yhdenkään käyttäjän salasana ei pääse julki tai versiohistoriaa säilyttävä palvelin ei joudu tietomurron kohteeksi. Mikäli yhden käyttäjän salasana vuotaa ei-toivotulle taholle, täytyy kaikki hänen tunnuksellaan salasanan leviämisen jälkeen tehdyt muutokset tarkistaa erikseen mahdollisten hyökkäysten varalta. Mikäli taas palvelimen turvallisuus joutuu vaarannetuksi, joudutaan käymään koko versiohistoria läpi, jotta voidaan varmistautua, ettei tietovarastoon ole ujutettu ei-toivottua materiaalia. Tosin useimmissa tilanteissa selvitään vähemmällä työmäärällä palauttamalla palvelin tietomurtoa edeltäneeseen tilaan varmuuskopiosta ja tekemällä kaikki varmuuskopioinnin jälkeen tehdyt muutokset uudelleen palvelimelle.
Hajautettujen järjestelmien etu: ei yhtä kriittistä pistettä
Käytettäessä hajautettuja järjestelmiä, jokainen käyttäjä säilyttää omalla koneellaan kopiota projektin koko versiohistoriasta. He kykenevät tekemään kaikkia versiohallinnan operaatioita, kuten selaamaan versiohistoriaa, luomaan uusia versioita tai vertailmaan tallennettuja versiota sekä muokkauksessa olevaa koodia, omalla koneellaan ilman yhteyttä keskitettyyn palvelimeen. (O'Sullivan, 2009) Koska järjestelmässä ei ole yhtä keskitettyä palvelinta, joka sisältäisi virallisen kopion kehitettävästä ohjelmasta, ei ole myöskään yhtä yksittäistä pistettä, jonka valtaamalla hyökkääjää pystyisi tekemään pahojaan koko projektille. Mikäli hyökkääjä saa pääsyn yhden käyttäjän koneella olevaan kopioon versiohistoriasta, pystyy hän tekemään pahojaan vain yhteen paikalliseen kopioon. Muiden kehittäjien koneilla olevat kopiot pysyvät koskemattomina, eikä pelkoa suuremmista tuhoista synny. Riittää, että kyseinen käyttäjä palauttaa kopionsa eheään versioon. Muiden käyttäjien toimintaan ja kehitystyöhön ei hyökkäyksellä ole minkäänlaista vaikutusta.
Versiohistorian kryptografinen varmennus
Koska hajautetut järjestelmät tallentavat käyttäjien muutokset keskitetyn järjestelmän sijasta käyttäjien koneille, käyttäjät pystyvät tekemään samanaikaisia muutoksia omiin kehitysversioihinsa. Tämän vuoksi järjestelmään tallennettua versioita ei kyetä tunnistamaan perinteisten versionumeroiden perusteella. Siinä missä keskitetyissä järjestelmissä versiot voitiin nimetä yksinkertaisesti niiden järjestysnumeron perusteella (1, 2, 3, 4, jne.), ei hajautettuja järjestelmien tapauksessa saada globaaleja nimiä yhtä helpolla. Erityisesti suuremmissa projekteissa tulisi hyvin nopeasta vastaan tilanne, missä Annan ja Mikon saman numeron sisältävät versiot olisivat kuitenkin sisällöltään täysin erilaisia. Kuitenkin yhtenäinen globaalisti toimiva versionumerointi saadaan käyttämällä versioiden niminä versioiden sisällöstä laskettuja riittävän pitkiä tiivisteitä.
Sekä Git että Mercurial laskevat version nimeksi tiivisteen uuden version tuoman muutoksen sisällöstä ja edeltäneen version tiivisteestä. Näin saadaan yhdellä tiivisteellä varmennettua niin muutoksen sisältö kuin sitä edeltävien versioiden sisältö. Tämä takaa sen, että jokainen versio kyetään nimeämään globaalisti yhtenäisellä tunnuksella, mutta myöskin huolehtii siitä, ettei kukaan pysty sorkkimaan jo jaettua versiohistoriaa. Sillä kaikilla käyttäjillä on oltava yhtenäiset historiatiedot, jotta versioiden välinen synkronointi onnistuisi. (O'Sullivan, 2009 & Chacon, 2011)
Vaikka tiivisteen laskeminen estää historian muokkaamisen muuttamatta muokkauksen jälkeisten versioiden tiivisteitä, eivät tiivisteet auta suojaamaan järjestelmää, silloin kun kaikki päivitykset tai ensimmäinen versio ladataan epäilyttävästä kohteesta. Tiiviste ei myöskään auta varmistamaan uusien versioiden tulevan luotettavilta tahoilta, sillä ladattaessa uusia muutoksia tiivisteen oletetaankin olevan tuntematon. Kuitenkin versio, ja samalla myös koko sitä edeltävä versiohistoria, pystytään varmentamaan allekirjoituksella. Sekä Git että Mercurial tukevat versioiden nimitiivisteiden allekirjoittamista PGP-tekniikalla ja näiden allekirjoitusten tarkastamista.
Versioiden jakaminen käyttäjien välillä
Siinä, missä perinteinen keskitetty versiohallintajärjestelmä pakottaa käyttäjät jakamaan tekemänsä muutokset yhden yhteisen keskusjärjestelmän kautta, jättävät hajautetut versionhallintajärjestelmät muutosten jakotavasta päättämisen käyttäjien vastuulle. Koska käyttäjät muokkaavat normaalisti vain omaa versiopuutaan, täytyy useamman ohjelmoijan projekteissa sopia tavoista, joilla tehdyt muutokset saadaan jaettua koko kehitysporukalle. Yksinkertaisimmassa, ja pienillä porukoilla usein myös hyvin toimivassa, mallissa käyttäjät lataavat muutokset suoraan toisiltaan. Kuitenkin malli, jossa jokainen synkronoi jokaisen kanssa, tuottaa merkittäviä ongelmia projektin, jos osanottajien määrä, ja näin ollen tarvittavien synkronointikohteiden määrä, kasvaa suureksi. (O'Sullivan, 2009)
Yksinkertainen tapa vähentää tarvittavien synkronointien määrää on luoda yksi keskitetty keskusvarasto, johon kaikki voivat ladata tekemiään muutoksia ja josta muut voivat sitten ladata näitä muutoksia (O'Sullivan, 2009). Vaikka hajautettu versionhallintajärjestelmä muistuttaa tässä käyttötavassa keskitettyä järjestelmää, on eroavaisuuksia kuitenkin merkittävästi. Tietoturvan ja saatavuuden kannalta kokoversiohistorian täydellisen kopion säilyttäminen jokaisen projektin jäsenen omalla koneella antaa edelleenkin merkittäviä hyötyjä. Täydellisen versiohistorian avulla käyttäjät pystyvät vähäisellä työllä varmistamaan muiden käyttäjien tekemät muutokset tiivisteiden ja allekirjoitusten avulla. Käyttäjät eivät myöskään ole yhtä riippuvaisia keskitetystä palvelimesta, vaan pystyvät jatkamaan työtään ja selaamaan koko aikaisempaa historiaa myös keskitetyn palvelimen ollessa alhaalla. Tärkeimpänä etuna keskitettyihin versionhallintajärjestelmiin on kuitenkin mahdollisuus tarvittaessa poiketa keskitetystä jakomallista ja esimerkiksi siirtää tehtyjä muutoksia suoraan kahden ohjelmoijan välillä käyttämättä niitä keskusjärjestelmässä.
Yhdestä keskitetystä tietovarastosta kyetään nopeasti pääsemään malliin, jossa projektin jokaisella ryhmällä on oma keskusvarastonsa, joita sitten synkronoidaan keskenään yhteen vain tarvittaessa. Tämä mahdollistaa esimerkiksi käyttöliittymätiimiä tekemään omaa kehitystyötään erillään tietokantatiimistä ja heidän tekemistään muutoksista. Kun kaikki projektin aliprojektit ovat saaneet oman osansa toimivaksi voidaan nämä erilliset osa-alueet yhdistää pienellä työllä. Tämä useampaan keskusvarastoon pohjautuva kehitysmalli on luultavasti kaikista yleisin toimintamalli yhtään suurempia ohjelmistokokonaisuuksia kehittäessä hajautettua versiohallintaa käyttäen. (O'Sullivan, 2009)
Viimeisenä ja hieman harvinaisena mallina voidaan pitää Linux-ytimen kehityksessä käytettävää tekniikkaa. Linuxin kehitys on organisoitu niin, että koko projektin keskellä seisoo Linus Torvalds, joka kokoaa ytimen lähdekoodin virallisen kehityspuun henkilökohtaisesti lataamalla muutokset luottamiltaan pääkehittäjiltä. Jokainen voi kopioida Torvaldsin pääpuun itselleen, mutta koska kenelläkään muulla kuin Torvaldsilla itsellään ei ole oikeutta ladata siihen uutta materiaalia pystyy Torvalds pitämään sen kehityksen ja sisällön täysin omassa hallinnassaan. (O'Sullivan, 2009)
Nämä muutamat Torvaldsin luottamat pääkehittäjät vastaavat jokainen pienestä osasta koko Linux-ytimen kehityksessä. Heistä jokainen pitää omaa erillistä tekniikkaansa omaan osa-alueeseensa tulevien muutosten lataamisessa kehittäjiltä ja lataa muiden osa-alueiden muutokset itselleen suoraan Torvaldsin puusta. Näin ollen Linuxin kehitys on jaettu hierarkiseen järjestelmään, jonka keskipisteessä on koko kokonaisuutta hallinnoimaan pyrkivä Linus Torvalds, jonka alla taas on tyypillisesti aina pienemmistä ja pienemmistä osa-alueista vastaavia henkilöitä. Tämän mallin etuna on se, että koska muutokset siirtyvät puussa ylöspäin vain ylemmällä tasolla olevan henkilön toimesta, yksittäisten alimmalla tasolla olevien kehittäjien tekemien virheiden ei pitäisi koskaan päästä nousemaan aina Torvaldsin viralliseen puuhun saakka. (O'Sullivan, 2009)
Hajautettujen järjestelmien tuoma suoja työssä: Tapaus kernel.org
Hyvä esimerkki hajautettujen järjestelmien tuomasta tietoturvasta saatiin kesällä 2011, kun Linux-ytimen kehityksen koordinoinnista vastaavan kernel.org sivuston palvelimet joutuivat hyökkäyksen kohteeksi ja järjestelmään tunkeutuja sai käsiinsä järjestelmän pääkäyttäjän oikeudet. (Corber, 2011) Mikäli Linuxia olisi kehitetty käyttäen perinteistä keskitettyä versionhallintajärjestelmää, olisi murtautuja saanut myös täydellisen mahdollisuuden ujuttaa omaa tuotostaan Linuxin lähdekoodeihin.
Kuitenkin koska Linuxin kehityksessä käytetään hajautettuun kehitysmalliin pohjautuvaa Git-versiohallintajärjestelmää, ei murtautuja kyennyt vaikuttamaan ytimen lähdekoodeihin. Tämä sen takia, ettei kernel.org:in palvelimella pidetty kuin yhtä kopiota Linuxin lähdekoodin kehityshistoriasta. Jokaisella Linuxin kehittäjällä oli oma kopionsa. (Corber, 2011) Murtautuja ei olisi myöskään kyennyt julkaisemaan uusia versioita Linus Torvaldsin nimissä, koska näitä versioita ladanneet käyttäjät olisivat huomanneet heti, ettei kyseisiä muutoksia olisi ollut allekirjoitettu Torvaldsin henkilökohtaisella salaisella avaimella.
Lähteet
Chacon Scott, et al. 2011. Git Community Book: The open Git resource pulled together by the whole community. 156 pp. Saatavissa: https://github.s3.amazonaws.com/media/book.pdf
Corber, Jonathan 2011, The cracking of kernel.org [verkkodokumentti]. Julkaistu 2011, päivitetty 31.8.2011 [viitattu 3.11.2011]. Saatavissa: http://www.linuxfoundation.org/news-media/blogs/browse/2011/08/cracking-kernelorg
O'Sullivan, Bryan. 2009. Mercurial: The Definite Guide. O'Reilly Media, 250 p. ISBN 978-0-596-80067-3.