SolarWinds-tietomurron jälkeen lähdekoodin vaarantaminen on osoittautunut toimivaksi ja erittäin tehokkaaksi tavaksi toteuttaa kyberhyökkäyksiä. Hyökkäys toimii, kun hyökkääjä hyödyntää murretun yrityksen herättämää luottamusta laajentaakseen vaikutuksensa useiden asiakkaiden ydinverkkoihin.
Sofus Albertsen
Sofus is a Continuous Delivery Trainer and Consultant in Copenhagen. Before joining Eficode Praqma he was assistant professor on an Applied Science Bachelor program. He flies kites and in the summer he escapes the modern world by spending two weeks in a beach hut without electricity or network coverage.
Lisäksi eilen paljastui, että myös PHP:n lähdekoodirepositorio on murrettu. Jos tätä ei olisi huomattu, kaikki PHP:tä käyttävät palvelimet olisivat voineet joutua kohteeksi, kun ne päivittivät PHP-version. Murretut commitit löydettiin kuitenkin ennen kuin ne päätyivät PHP:n tuotantoversioon, joten PHP-palvelimia käyttävien ei tarvitse huolestua. Tapaus havainnollistaa silti selvästi tietoturvan merkitystä ohjelmiston toimitusketjussa.
Molemmat tarinat korostavatkin sitä, että lähdekoodivuodot eivät ehkä enää ole ensisijainen tietoturvaloukkausten aiheemme.
Tietoturva on hyvin monimutkainen asia. Tämän blogin tavoitteena ei ole korjata kaikkea™ vaan keskittyä ohjelmiston toimitusketjumme riskeihin ja antaa esimerkkejä niiden pienentämisestä.
Toimitusketjun suojaaminen CIA-kolmiolla
CIA-kolmiota voidaan käyttää riskien arvioinnissa. CIA-kolmion kolme osa-aluetta ovat:
Luottamuksellisuus – tiedon suojaaminen ja salassapito. Tämä koskee ohjelmistoalgoritmeja, liiketoimintaprosesseja ja loppukäyttäjädataa. Salaisuuksien vuotaminen voi heikentää yrityksen kilpailuetua, vähentää loppukäyttäjien luottamusta tai johtaa jopa oikeustoimiin (esim. GDPR).
Eheys – tietomme suojaaminen muutoksilta. Tämä koskee sekä ohjelmistoartefakteja että dataa, myös loppukäyttäjädataa. Eheyden menetys voi altistaa ohjelmistoalustamme hakkereille ja johtaa samalla luottamuksellisuuden menetykseen laajemmassa mittakaavassa.
Saatavuus – ohjelmistomme palvelun käytettävyys. Tämä koskee sitä, miten infrastruktuurimme ja sovelluksemme on suunniteltu sekä miten ne kestävät haitallisia hyökkäyksiä. Se vaikuttaa myös prosesseihimme: käytämmekö esimerkiksi toimivia DevOps-prosesseja, jotka takaavat nopean palautumisen käyttökatkon jälkeen? Käyttökatko voi johtua meistä itsestämme (esim. ohjelmistopäivityksistä) tai ulkoisista tapahtumista (esim. katastrofipalautuksesta).
Ohjelmiston toimitusketjun suojaaminen
Havainnollistaaksemme tätä opasta käymme läpi virran kehittäjän commitista tuotannossa olevaan artefaktiin.
Tässä tilanteessa kehittäjä valmistelee commitin ja pushaa sen Git-repositorioon. Tämän jälkeen CI/CD-putki käynnistyy ja ottaa artefaktin uuden version käyttöön tuotannossa.
Yllä olevassa esimerkissä tiedonsiirto on suojattu SSH-tunneleilla, mutta haitallinen hyökkääjä voi silti lisätä committeja Git-repositorioon jäämättä huomaamatta, jos hänellä on pääsy repositorioon.
Tietoturvakerroksen lisääminen ohjelmiston toimitusketjuun
Tapa, jolla työskentelemme Gitin kanssa, vaikuttaa ohjelmiston toimitusketjun luottamuksellisuuteen ja eheyteen. Kehittäjät käyttävät Git-toimintojen suojaamiseen tyypillisesti seuraavia keinoja:
SSH-avainta käytetään 1) Git-palvelinyhteyden salaamiseen SSH-tunnelin avulla ja 2) Git-palvelimelle tunnistautumiseen sekä toimintojemme valtuuttamiseen.
HTTPS GitWeb-käyttöliittymässä. Vaikka HTTPS:n käyttämä TLS-protokolla on turvallinen, yritysten tietokoneissa on usein mukautettuja juurivarmentajia. Tämä tarkoittaa, että Git-käyttöliittymää suojaava HTTPS-salaus ei välttämättä ole päästä päähän -salattu, vaan yritys toimii välikätenä.
Voimme todeta, että luottamuksellisuus on suojattu, kun käytämme SSH-protokollaa Git-repositoriomme kanssa kommunikointiin. SSH-tunnelit tarjoavat vain paikallisen luottamuksellisuuden, koska niiden kattavuus ei ole päästä päähän, vaan ketjun pisteestä pisteeseen. Lähdekoodimme eheys ei kuitenkaan ole suojattu, joten tarvitsemme uuden vaiheen: committien kryptografisen allekirjoittamisen.
GPG-avaimia käytetään Git-committien ja -tagien allekirjoittamiseen. Allekirjoitettu Git-objekti todistaa, että commitin tai tagin on tehnyt henkilö, jolla on pääsy yksityiseen allekirjoitusavaimeen. Näin varmistetaan repositorion jokaisen commitin eheys.
Aloita GPG:n käyttö GitHubissa luomalla GPG-avain ja liittämällä se tiliisi. Ohjeet löytyvät github.comin dokumentaatiosta. Myös GitLab ja Bitbucket Server/DC tukevat GPG-avainten käyttöä. Bitbucket Cloud ei valitettavasti tue sitä.
Git-clientisi tukee jo GPG:n käyttöä. Lue ohjeet Git-clientin kotisivulta.
Kun olet luonut allekirjoittamiseen tarkoitetun GPG-avaimen, voit määrittää Gitin allekirjoittamaan kaikki tulevat commitit ja tagit automaattisesti liittämällä avaimesi Git-konfiguraatioon.
$git config --global user.signingkey 0A46826A
Git käyttää nyt avaintasi oletusarvoisesti tagien ja committien allekirjoittamiseen, jos haluat.
Huomautus: HTTPS:ää ei voida käyttää eheyden suojaamiseen. Käyttöliittymässä voimme tehdä useimmat Git-toiminnot, mutta emme allekirjoittaa committeja, koska sillä ei ole pääsyä yksityiseen allekirjoitusavaimeemme.
Uusi suojattu ohjelmiston toimitusketju
Tässä osiossa esittelemme työnkulun kehittäjälle, joka käyttää CI-putkea tuotantoympäristössä käytettävien kontti-imagien rakentamiseen. Oletamme, että kehittäjä allekirjoittaa commitit.
Tämä työnkulku havainnollistaa myös SSH-avainten käyttöä Gitin käyttämisessä: näemme SSH-tunneleita kehittäjän ja Gitin välillä sekä vastaavasti Gitin ja pipelinen välillä. Git-allekirjoitukset varmistavat vahvan päästä päähän -eheyden, mikä on tärkeää, sillä eheyden menetys voi johtaa myös luottamuksellisuuden menetykseen. Gitin SSH-avaimet Gitin käyttämiseen tarjoavat vain paikallisen luottamuksellisuuden.
CI-putki rakentaa kontti-imaget Git-lähdekoodista, ja sen tulisi validoida Git-allekirjoitukset luottamuksen muodostamiseksi kehittäjän ja pipelinen välille. CI-putken on myös allekirjoitettava rakennettu kontti-image, jotta eheys säilyy pipelinen ja tuotantoympäristön välillä kontti-imagerekisterin kautta (katso Docker Content Trust). CI/CD-järjestelmämme on siis luottamussilta lähdekoodin ja binääriartefaktin välillä.
Tässä työnkulussa CI-putki voi olla heikko kohta, sillä se suorittaa monimutkaisia toimintoja lähdesovelluksen ohjauksessa käyttäen mahdollisesti monenlaisia työkaluja. Tämä tarkoittaa, että CI-putken hyökkäyspinta on laaja. Heikkoutta korostaa se, että CI-putki siirtää luottamuksen kehittäjän allekirjoittamista comiteista tuotantoon validoituihin allekirjoitettuihin imageihin. Jos tämä luottamussilta vaarantuu – esimerkiksi huijaamalla CI-putki rakentamaan puutteellisesti allekirjoitetusta lähdekoodista – päästä päähän -eheys menetetään.
Tämän riskin pienentämiseksi kannattaa käyttää ulkoista agenttia Git-allekirjoitusten toissijaiseen varmentamiseen. Tarkistuksen tulisi tehdä agentti, joka ei ole suoraan yhteydessä CI-järjestelmään eikä CI-järjestelmä vaikuta siihen. Näin pidämme hyvin epätodennäköisenä, että se vaarantuisi samanaikaisesti CI-järjestelmän kanssa.
Ulkoisen allekirjoitustarkistajan arkkitehtuuri on esitetty alla:
Commitien varmentaminen
Michael on tehnyt Git-allekirjoitustarkistajan, jota voi käyttää sekä CI-putkissa että ulkoisena Git-allekirjoitustarkistajana. Se löytyy täältä, ja se on avoimen lähdekoodin ohjelmisto.
Tarkistaja tarvitsee hakemiston, joka sisältää luotettaviksi määritettyjen allekirjoitusavainten julkiset avaimet. Voit viedä julkisen Git GPG -avaimesi seuraavasti, mutta huomaa, että tarvitset kaikki julkiset avaimet, joita pidetään kelvollisina allekirjoitusavaimina:
$ gpg --armor --export user@example.com > user-pub-key.asc
Suorita seuraavaksi allekirjoitustarkistaja Git-repositorion ja luotettujen julkisten avainten luettelon kanssa seuraavasti:
$ docker run --rm -v $PWD/public-keys:/public-keys:ro -v $PWD/.git:/repo:ro michaelvl/git-signature-checker
Jos haluat vaihtoehtoisesti käyttää olemassa olevaa GPG-avainrengasta, johon avaimille on mahdollisesti määritetty luottamustaso, käytä seuraavaa:
$ docker run --rm -v $HOME/.gnupg:/gnupghome:ro -v $PWD/.git:/repo:ro michaelvl/git-signature-checker --git-dir /repo --keyring /gnupghome --minimum-trust ULTIMATE
Oletusarvoisesti tarkistaja validoi kaikki annetun repositorion nykyisen revision commitit. Käytä --revision-range-argumenttia vaihtoehtoisten viitteiden ja alipuujen tarkistamiseen.
Huomautus: kirjoitushetkellä GitHub näyttää repositorion commitit vahvistamattomina. Tämä johtuu siitä, että commitien allekirjoittamiseen käytetty avain on vanhentunut. Ikuisesti voimassa olevat avaimet ovat tietoturvan kannalta vaarallisia, mutta liian lyhytikäiset avaimet voivat johtaa kelvollisesti allekirjoitettujen commitien epäluotettavuuteen.
Samanlainen tilanne syntyy, kun työntekijät lähtevät: heidän allekirjoitusavaimensa tulisi mitätöidä, mutta heidän aiemmin tekemien allekirjoitustensa tulisi pysyä luotettuina. Yleisesti allekirjoituksen kelpoisuutta kannattaa arvioida avaimen tilan perusteella allekirjoitushetkellä.
Huomio julkisista avaimista
Tämä työkalu ei validoi --public-keys-parametrilla annetun polun kautta tuotuja julkisia avaimia. Avainten välinen luottamus ja vaadittu luottamustaso voidaan määrittää käyttämällä --keyring-parametria tietyn GPG-avainrenkaan käyttämiseen, jossa avaimille on määritetty luottamustaso. Parametrilla --minimum-trust voidaan määrittää onnistuneeseen allekirjoituksen validointiin vaadittu vähimmäisluottamustaso.
Huolellinen avainten hallinta on luonnollisesti edellytys Gitin eheyden validoimiselle allekirjoitusten avulla.
GitHub-mergien huomioitavat seikat Web UI:n kautta
Jos käytät GitHubin Web UI:ta PR:ien mergaukseen, mergesi allekirjoitetaan GitHubin julkisella avaimella, ei omalla avaimellasi. Tämä rikkoo päästä päähän -luottamuksen, sillä emme voi tietää, kuka UI:hin pääsi käsiksi – mahdollisesti joku vuotaneella käyttäjätunnuksella ja salasanalla. Käytä siksi Web UI:ssa aina kaksivaiheista tunnistautumista (2FA).
Voit harkita PR:ien mergeämistä itse. Tällöin GitHubin julkinen avain on lisättävä luotettujen allekirjoitusavainten luetteloon. Avain löytyy täältä:
curl https://github.com/web-flow.gpg
Tämä ongelma koskee myös muita Git-toimittajia, jotka mainitaan ”Tietoturvakerroksen lisääminen ohjelmistotoimitusketjuumme” -osiossa.
Huomautus: Jos tuot palvelimen avaimet luotettuina, et voi enää pitää Git-repositoriopalvelintasi vaarantumattomana. Yhdistämisten jäljitettävyys menetetään, ja palvelimen käyttöliittymän kautta lisätyt commitit katsotaan luotetuiksi.
Vain fast-forward-yhdistämisten salliminen voi tarjota molempien vaihtoehtojen parhaat puolet, sillä Git-palvelin ei tee vuorottelevia yhdistämisiä eikä lisää committeja. Tämä edellyttää, että pidät PR:si jatkuvasti ajan tasalla master-haaran kanssa.
Paras käytäntö
Suosittelemme käyttämään laitteistotunnistetta GPG-varmenteiden tallentamiseen. Näin voit pienentää avaimen varastamisen riskiä, vaikka tietokoneesi vaarantuisi. Yksi tällainen avain on YubiKey.
YubiKeylle tallennettuja avaimia ei voi viedä laitteelta (toisin kuin levylle tallennettuja tiedostopohjaisia avaimia), ja ne ovat käteviä päivittäisessä käytössä. SSH-/GPG-avainten avaamiseen tarvittavien salasanalauseiden muistamisen ja syöttämisen sijaan YubiKey vaatii PIN-koodilla avaamisen jälkeen vain fyysisen kosketuksen. Kaikki allekirjoitus- ja salausoperaatiot tehdään kortilla käyttöjärjestelmän muistin sijaan.
Löysimme perusteellisempaa ohjetta varten hyvin kirjoitetut kuvaukset tästä GitHub-repositoriosta. Lue ne huolellisesti, sillä emme ole tehneet toimitetuille tiedoille tietoturva-auditointia.
Loppuhuomautukset
Jos käytät GitOpsia ja Kubernetesia, infrastruktuuriin voi integroida eheyden tarkistuksen useilla tavoilla.
Jos esimerkiksi SRE allekirjoittaa kaikki commitit, GitOps-agentti voi tarkistaa Git-committien allekirjoitukset ennen muutosten käyttöönottoa Kubernetesissa. Tämä varmistaa infrastruktuurimuutosten toimituksen päästä päähän ulottuvan eheyden.
Imagejen validointiin voisi käyttää toistettavia buildeja. Käytännössä tämä on kuitenkin melko monimutkaista eikä ongelmatonta. Esimerkiksi toissijaisen buildin suorittava pipeline ei saa olla altis samoille hyökkäyksille kuin ensisijainen pipeline.
Turvallinen jäljitettävyys ohjelmistotoimitusketjussasi
Tietomurtojen yhteydessä keskitymme yleensä lähdekoodin muodossa olevan immateriaalioikeuden varastamiseen. Sen sijaan meidän on suunnattava huomiomme ohjelmistotoimitusketjun jäljitettävyyden turvaamiseen, jotta voimme välttää SolarWindsiin kohdistuneen kaltaisia hyökkäyksiä.
Jokaisen commitin allekirjoittaminen ja tarkistaminen pienentää riskiä, että pahantahtoinen hyökkääjä lisää ohjelmistoosi hyväksikäyttöjä tietämättäsi ja vaarantaa siten ohjelmistosi eheyden.
Tämän toteuttaminen oikein edellyttää uusia työkaluja ja luottamusta siihen, että kaikki osaavat käyttää niitä. Vaihtoehdon seuraukset ovat osoittautuneet niin tuhoisiksi, että meidän on kysyttävä itseltämme, olemmeko valmiita ottamaan tämän riskin.
- CI/CD
- Tietoturva
Subscribe to our newsletter
Related blogs