Sikkerhetsaspekter rundt objektlagring

Passordpolicy

Brukere med tilgang til webgrensesnittet (CMC) vil automatisk få varsel om å skifte passord når det nærmer seg et år siden sist. Vi oppfordrer brukere til å samtidig rotere sine nøkkelpar, både systembrukerens hovednøkkel og eventuelle opprettede IAM-nøkler.
Dette gjøres enkelt ved å opprette et nytt nøkkelpar, og slette det forrige.

For røde bøtter roterer vi rutinemessig nøklene tilhørende systembrukere som eier bøttene, men vi mangler system for rutinemessig rotering av IAM-nøklene som deles ut til sluttbruker.
Det vil komme en oppdatering her så snart det lar seg gjøre.

 

Databeskyttelse

Vi har tre alternativer for databeskyttelse:

  1. Versjonering av objekter
  2. Tradisjonell backup til annet lagringssystem
  3. Replikering til separat Cloudian-instans

Versjonering betyr at systemet beholder samtlige kopier av objekter med samme navn (key), slik at man i praksis får en endringshistorikk per objekt. Dette beskytter både mot uønskede overskrivelser, samt. sletting av filer. Dersom det kun finnes én versjon av et objekt, vil det dupliseres før det pålegges en slettemarkør på gjeldende versjon.

Brukerne kan selv bestemme om hvorvidt det skal være automatisk sletting av tidligere versjoner, og hvor ofte dette skal gjøres. Dessuten blir det ingen overraskelser mtp. kostnad da den ekstra kapasiteten som benyttes av eldre versjoner går på ordinær kvote.
For mange kan dette være god nok databeskyttelse i seg selv, men merk at versjonering ikke kan anses som god nok beskyttelse i seg selv for sårbare data som skal lagres over lang tid.

Tradisjonell backup lagrer en full kopi samt. inkrementelle endringer på bøtten én gang i døgnet, og har retensjonstid på 90 dager. Dette kan være nødvendig dersom man har kritiske data man vil ha kopi av på separat system og datasenter.
Påbeløper en ekstra kostnad.

Til slutt har vi en separat, virtuell Cloudian-instans som kan benyttes for å laste opp samme data til to separate steder. Denne instansen har derimot svært begrenset kapasitet, og er en tjeneste vi kun tilbyr for de aller mest kritiske dataene.

 

Sikring av aksessnøkler på klienten

Per default lagres konfigurerte nøkkelpar i klartekst under ~/.aws/credentials. I utgangspunktet er tilgangen til disse sperret ned til eieren av hjemmeområdet, men det anbefales å kryptere nøkkelfila slik at uvedkommede ikke også får tilgang til objektlagringen dersom maskinen blir hacket. Dette er spesielt viktig dersom det lagres sensitive data i bøttene.

I credentialsfila kan man i stedet for nøklene angi en parameter som vil peke på et skript som henter dem ut

[default] 
region = oslo 
credential_process = /sti/til/skript

credential_process forventer en JSON-output på følgende format:

{
  "Version": 1, 
  "AccessKeyId": "AKIA0123456787EXAMPLE",
  "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

På denne måten kan vi opprette et skript som enten dekrypterer en kryptert nøkkelfil, eller henter ned nøkler fra f.eks Vault, Enpass, eller annet passordhvelv. Se under.

 

1. Kryptering + dekrypteringsskript

Denne metoden krever kun at man har et standard krypteringsverktøy som OpenSSL, og et par linjer med shellkode. Derfor er det tilgjengelig ut av boksen på de aller fleste Unix-systemer.

Start med å opprette en JSON-fil med nøklene i formatet over, og krypter det med openssl med følgende opsjoner:

openssl enc -aes-256-cbc -md sha512 -pbkdf2 -in s3-creds.json -out s3-creds.enc

Du vil bli bedt om å skrive inn et passord, som du må også må tilføye når fila skal dekrypteres. Lagre gjerne dette i Vault e.l, slik du vanligvis oppbevarer delte passord.

Ekstra steg for Mac-brukere
Per default bruker MacOS LibreSSL for kryptering, som ikke supporterer pbkdf2-funksjonen i eksempelet over.
Så hvis du opplever at det feiler, sjekk versjonenav openssl. Hvis det refereres til LibreSSL, installer heller ordentlig OpenSSL (fra f.eks brew), og legg det til i din PATH:

# openssl version
LibreSSL 3.3.6

# brew update
# brew install openssl
# echo 'export PATH="/usr/local/opt/openssl@3/bin:$PATH"' >> ~/.bash_profile

# openssl version
OpenSSL 3.1.2 1 Aug 2023 (Library: OpenSSL 3.1.2 1 Aug 2023) 

 

Nå oppretter vi et kort dekrypteringsskript som skal pekes på i credential_process, slik at den krypterte JSON-fila med nøklene kan dekrypteres ved behov.
I sin simpleste form kan det se slik ut:

#!/bin/sh

openssl enc -d -aes-256-cbc -md sha512 -pbkdf2 -in $1 -pass env:S3_PW

Dekrypteringsskriptet over forventer en sti til kryptert fil når det kjøre (argument $1), og at passord på forhånd er satt som en environmentvariabel, S3_PW. Denne kan settes uten å vise input i terminalen slik:

read -s -r S3_PW && export S3_PW

Merk at når du lukker terminalen, så vil denne variabelen bli fjernet, og må settes på ny ved neste sesjon.

Til slutt, oppdatert ~/.aws/credentials til å bruke dekrypteringsskriptet:

[default]
region = oslo
credential_process = /sti/til/decrypt.sh /stil/til/s3-creds.enc

Når du nå forsøker å utføre et S3-kall mot lagringen via denne konfigurerte profilen, vil skriptet automatisk dekryptere s3-creds.enc og autorisere med de assosierte nøklene.
Husk å fjerne den ukryptere fila når det er bekreftet at oppsettet fungerer.

 

2. Uthenting av credentials fra passordhvelv

Guiden under tar utgangspunkt i HashiCorp Vault (som er mye brukt internt), men de fleste passordhvelv/managers har tilsvarende API'er som kan benyttes for å hente ut lagrede hemmeligheter.

For å bruke denne metoden trenger du å ha Vault-klienten installert. Start med å legge en hemmelighet på samme JSON-format på en foretrukket sti i passordhvelvet slik:På en foretrukket sti i tjenesten, lag en hemmelighet på følgende format In your prefered path, create the credential like this, where the name "system_user_testbucket" is the name of the key where you will be storing the JSON-data containing your access key and secret key.

vault kv put /secret/engine/sti/til/S3_credentials testbruker='{
  "Version": 1,
  "AccessKeyId": "AKIA0123456787EXAMPLE",
  "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}'

Så kan vi lage et bashskript som henter ut nøklene slik:

#!/bin/bash

vault kv get --field $1 /secret/engine/sti/til/S3_credentials

Når skriptet kjøres må du angi hvilken bruker du skal hente ut credentials fra, i eksempelet over = testbruker. Det vil si at du kan lagre flere brukere i samme hemmelighet, og dynamisk hente ut det du trenger slik:

$ ./retrieve_S3_vault.sh testbruker
{
  "Version": 1,
  "AccessKeyId": "AKIA0123456787EXAMPLE",
  "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

Når det er bekreftet å fungere, oppdatert .aws/credentials:

[default]
region = oslo
credential_process = /sti/til/retrieve_S3_vault.sh testbruker

Merk at hver gang du skal kommunisere med buckets må du først logge inn til Vault CLI i forkant for å ha en gyldig token (som vanligvis ekspirerer etter 1 time).

 

Server Side Encryption (SSE)

UiO S3-løsningen supporterer SSE, som i praksis betyr at dataene er kryptert på lagringen ("at rest"). Dette beskytter dataene dersom uvedkommede skulle få fysisk adgang til serverne.

Ulempen med SSE er at dataene dekrypteres ved requests, også om bøtten ved uhell har blitt gjort public. På sikt ønsker vi å sette opp støtte for KMS-kryptering som også håndterer dette issuet, men i mellomtiden kan man benytte en krypteringsnøkkel når data lastes opp for å unngå at sensitive data lekkes ved uhell. Dette kalles SSE-C (Server Side Encryption with Customer key).

Merk at når et objekt lastes opp med SSE-C benyttes det en krypteringsnøkkel, må samme nøkkel benyttes for nedlasting senere. Dette medfører en viss risiko;
hvis krypteringsnøkkele går tapt, er objektet også i praksis tapt.

For mer info referer vi til Amazons guide om SSE-C med PowerShell, men det vil bli skrevet eksempler som tar i bruk AWS CLI.

Vi mener imidlertid at alle former for kryptering "at rest" kan gi en form for falsk sikkerhet, da det ikke erstatter god håndtering av IAM-nøkler og eventuelle bøttepolicier, som i seg selv tilbyr vel så god beskyttelse fra brukersiden.

Emneord: S3, lagring, storage Av Markus Sørensen
Publisert 9. feb. 2024 14:28 - Sist endret 7. mai 2024 15:10