Introduzione a Google Cloud Storage [GCP]

I

INTRODUZIONE

Se hai mai creato un’applicazione che comporta la memorizzazione di un’immagine, hai riscontrato il problema di decidere dove salvare le immagini.
È probabile che per mancanza di tempo hai risolto nella maniera più’ semplice: nel tuo database o sul tuo filesystem locale. Questa soluzione ha dei grossi limiti riguardo a scalabilità’ e HA. Tutti i cloud provider offrono come soluzione a questo problema l utilizzo di un object storage; Oggi parleremo di Google Cloud Storage  mostrando i concetti principali attorno a questo utilissimo servizio.

bucket e objects

I concetti chiave dietro a Cloud storage sono bucket e object. Puoi immaginare un bucket come un container per memorizzare i tuoi dati. Gli Object sono invece i files che salvi all’interno di  un bucket. Gli object hanno un nome univoco che li identifica all’ interno del bucket e possono essere organizzati all interno del bucket in folder.

bucket

Andiamo ad analizzare le caratteristiche fondamentali di un bucket analizzando il form di creazione bucket.

 

  • Name: l identificativo univoco globale del bucket.
  • Location: Come le VM di  Compute Engine, anche i bucket possono avere location.
    Anziché definire sempre una zona specifica (ad esempio, us-central1-a), e’ possibile specificare una regione (ad esempio, us-central1) o addirittura multi regionale (ad esempio, “Stati Uniti” o “Asia”). Se si sceglie una regione o multi regional i costi aumenteranno ma di conseguenza anche l HA e l utente potrà scaricare dal bucket geograficamente più’ vicino.
  • Storage Class: Proprio come esistono diversi tipi di dischi (ad esempio, SSD o magnetico) Cloud Storage offre diversi tipi di bucket. Queste storage class  presentano caratteristiche prestazionali diverse (entrambe latenza e disponibilità), nonché prezzi diversi.
  • Encryption: Se vogliamo gestire l encryption con nostre chiavi.
  • ACL Settings: E’ Specificare l’accesso a singoli oggetti utilizzando le autorizzazioni a livello di oggetto (ACL) oltre alle autorizzazioni a livello di bucket (IAM). Approfondiremo le ACL in una sezione successiva.

upload

A questo punto procediamo a creare il bucket e usando la cli iniziamo a salvare object all interno del bucket.

PS C:\Users\Dario\test> echo Ciao Mondo > test.txt
PS C:\Users\Dario\test> cat test.txt
Ciao
Mondo
PS C:\Users\Dario\test> gsutil ls
gs://demo-123-4/
gs://italiancoderstest/
gs://my-public-bucket-df/
gs://profile_pictures_itc/
PS C:\Users\Dario\test> gsutil cp .\test.txt gs://italiancoderstest
Copying file://.\test.txt [Content-Type=text/plain]...
- [1 files][   28.0 B/   28.0 B]
Operation completed over 1 objects/28.0 B.
PS C:\Users\Dario\test>

download

Andiamo a scaricare il file precedentemente caricato sul bucket.

PS C:\Users\Dario\test> gsutil ls gs://italiancoderstest/                                                               gs://italiancoderstest/test.txt
PS C:\Users\Dario\test> gsutil cp gs://italiancoderstest/test.txt download.txt                                          Copying gs://italiancoderstest/test.txt...
/ [1 files][   28.0 B/   28.0 B]
Operation completed over 1 objects/28.0 B.
PS C:\Users\Dario\test> cat .\download.txt                                                                              Ciao
Mondo
PS C:\Users\Dario\test>

limitare l aCCESSO CON LE ACL

Prima di entrare nel dettaglio, potrebbe essere utile dire che di default tutto quello che crei e’ accessibile solo da quelle persone che hanno accesso al tuo progetto. Quando aggiungi qualcun altro nel tuo progetto, anche loro avranno accesso ai tuoi dati nel Cloud Storage. Ad esempio, se aggiungi qualcuno come un altro proprietario del progetto, automaticamente sara’ in grado di controllare i dati del proprio Cloud Storage (bucket e oggetti).

Cloud Storage consente un controllo di accesso piu’ di dettaglio attraverso un meccanismo di sicurezza chiamato Access Control Lists (ACLs). Queste liste fanno
esattamente quello che ti aspetti lasciandoti dire quali account possono fare quali operazioni
(ad esempio, leggi o scrivi). Queste operazioni sono trasmesse da tre ruoli,  che hanno un significato diverso per bucket e oggetti.

READERS:

  • Bucket: I bucket reader possono vedere la lista di oggetti in un bucket
  • Object: object reader possono scaricare l oggetto

 

WRITERS:

  • Bucket: i Bucket Writers possono vedere la lista di oggetti, crearne nuovi e cancellare oggetti dal bucket.
  • Object:  –

 

OWNERS:

  • Bucket: i Bucket Owners possono fare tutto quello che possono fare gli writers con l aggiunta di aggiornare il bucket e quindi anche le ACL.
  • Object: I Object owners possono fare tutto quello che fa un reader con l aggiunta di modificare le ACL di un object

 

La domanda adesso sorge spontanea: cosa accade se sono Owner del bucket ma Reader di un oggetto ? La risposta è abbastanza semplice: ciascuna delle autorizzazioni trasmette attività specifiche che sono consentite, quindi non esiste una gerarchia di autorizzazioni che scendono verso il basso. Basandosi sulle specifiche dei ruoli appena riportate, in questo scenario potrò’ manipolare gli object del bucket ma non potrò modificare i metadata di quell object e quindi non potrò definire dei permessi custom ad hoc per quel object.

BUCKET ACL

Come prevedibile, puoi controllare l’accesso ai tuoi oggetti assegnando questi ruoli a diversi
attori (ad esempio un particolare utente). Cominciamo guardando l’ACL per
il  bucket appena creato nella Cloud Console.

Da quello che si evince, l accesso di default al bucket e’ basato sul project con i project editors e owners che hanno l owner access al bucket e i project viewers che hanno il Reader Access. E’possibile aggiungere altri utenti con specifici ruoli per il singolo bucket o usare degli user speciali come: allUsers, allAuthenticatedUsers o specificare un gruppo o dominio.

 

default object ACL

In aggiunta a definire permessi a Bucket e Object e’ possibile definire per un bucket una default ACL che farà’ si che ogni object che viene creato erediti quest ultima. Nota bene: la modifica di una una default object ACL  non e’ retroattiva.

acl predefinite

E’ possibile utilizzare delle ACL predefinite  che mette a disposizione Google per impostare velocemente il permesso di un object. Tornando al nostro esempio

PS C:\Users\Dario\test> gsutil acl get gs://italiancoderstest/test.txt                                                  [
  {
    "entity": "project-owners-677206649094",
    "projectTeam": {
      "projectNumber": "677206649094",
      "team": "owners"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-editors-677206649094",
    "projectTeam": {
      "projectNumber": "677206649094",
      "team": "editors"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-viewers-677206649094",
    "projectTeam": {
      "projectNumber": "677206649094",
      "team": "viewers"
    },
    "role": "READER"
  }
]

Proviamo con una curl a scaricare il file

PS C:\Users\Dario\test> curl https://italiancoderstest.storage.googleapis.com/test.txt                                  curl : AccessDeniedAccess denied.Anonymous caller does not have storage.objects.get access to the Google Cloud Storage
object.
At line:1 char:1
+ curl https://italiancoderstest.storage.googleapis.com/test.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
PS C:\Users\Dario\test>

Come era prevedibile non riusciamo a scaricare il file non essendo pubblico il bucket. A questo punto utilizzando una ACL predefinita: public potremmo settare velocemente i permessi pubblici in sola lettura per tale object e scaricare il file con una curl.

PS C:\Users\Dario\test> gsutil acl set public-read  gs://italiancoderstest/test.txt                                     Setting ACL on gs://italiancoderstest/test.txt...
/ [1 objects]
Operation completed over 1 objects.
PS C:\Users\Dario\test> gsutil acl get gs://italiancoderstest/test.txt                                                  [
  {
    "email": "dario.frongillo@gmail.com",
    "entity": "user-dario.frongillo@gmail.com",
    "role": "OWNER"
  },
  {
    "entity": "allUsers",
    "role": "READER"
  }
]
PS C:\Users\Dario\test> curl https://italiancoderstest.storage.googleapis.com/test.txt                                  

StatusCode        : 200
StatusDescription : OK
Content           : ÿþC i a o
                     M o n d o

RawContent        : HTTP/1.1 200 OK
                    X-GUploader-UploadID:
                    AAANsUkv7_5DzZMtKTc6gbcT3xc-cSMY-WeUCAvLZjL4knV6AUWBy52esGc5viEL678bjJFNu2_TdQWzItWsafU3ow
                    x-goog-generation: 1591690976898840
                    x-goog-metageneration: 3
                    x-goog...
Forms             : {}
Headers           : {[X-GUploader-UploadID,
                    AAANsUkv7_5DzZMtKTc6gbcT3xc-cSMY-WeUCAvLZjL4knV6AUWBy52esGc5viEL678bjJFNu2_TdQWzItWsafU3ow],
                    [x-goog-generation, 1591690976898840], [x-goog-metageneration, 3],
                    [x-goog-stored-content-encoding, identity]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 28

 

acl best practices

Ora che sappiamo in grosso modo cosa sono le ACL voglio suggerirvi alcune best practices per evitare brutte sorprese:

  • Quando sei in dubbio dai sempre il minimo accesso possibile ad un nuovo utente
  • Il permesso Owner e’ molto potente quindi fai attenzione a chi lo assegni
  • Fai attenzione alla tua ACL di default in quanto i nuovi object erediteranno tali permessi.

 

signed url

A volte siamo nelle situazioni in cui non si desidera aggiungere qualcuno alla ACL per sempre, ma piuttosto si vuole dare accesso per un determinato periodo di tempo ad un object. Situazione tipica in cui non ci preoccupiamo che l utente sia autenticato con i servizi google, in quanto magari abbiamo fatto autenticare l utente con la nostra piattaforma e vorremmo banalmente dire al sistema di controllo del Bucket:
“Questa persona ha accesso per visualizzare questi dati.”

Fortunatamente, Cloud Storage offre un modo semplice per farlo con i signed URL. Un  signed URL  è un URL che fornisce autorizzazioni e tempo limitati per effettuare una richiesta. Gli URL firmati contengono informazioni di autenticazione nella loro stringa di query, consentendo agli utenti senza credenziali di eseguire azioni specifiche su una risorsa. Quando si genera un URL firmato, si specifica un account utente o di servizio che deve disporre dell’autorizzazione sufficiente per effettuare la richiesta che verrà effettuata dall’URL firmato. Dopo aver generato un URL firmato, chiunque lo possiede può utilizzare l’URL firmato per eseguire azioni specifiche, come la lettura di un oggetto, entro un determinato periodo di tempo.

Andiamo a creare una signed URL per scaricare  un file  non pubblico del mio bucket

upload file

Andiamo a creare un object nel mio bucket che di default sara manipolabile solo dagli owner del progetto.

PS C:\Users\Dario\test> echo privatoooooooo > private.txt
PS C:\Users\Dario\test> cat .\private.txt
privatoooooooo
PS C:\Users\Dario\test> gsutil cp .\private.txt gs://italiancoderstest
Copying file://.\private.txt [Content-Type=text/plain]...
- [1 files][   34.0 B/   34.0 B]
Operation completed over 1 objects/34.0 B.
PS C:\Users\Dario\test> curl https://italiancoderstest.storage.googleapis.com/private.txt
curl : AccessDeniedAccess denied.Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
At line:1 char:1
+ curl https://italiancoderstest.storage.googleapis.com/private.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

creiamo service account

Andiamo a creare un service Account che vogliamo impersonare nel signed url. Creo quindi dalla consolle un service account Bucket Reader con il ruolo Storage Object Viewer in quanto nella signed Url vorro’ permettere di scaricare l object. Ricordatevi di generare la key Json del service account.

creiamo signed url

Una volta creato il service account e scaricata localmente la key procediamo alla creazione del signed url. Gli step che seguiremo sono:

  • modificare l ACL del mio object per permettere la lettura usando il service account
  • creazione di un signed URL utilizzando la key del nostro service account.
>> gsutil acl ch -u bucket-reader@italiancoders-demo.iam.gserviceaccount.com:R  gs://italiancoderstest/private.txt
Updated ACL on gs://italiancoderstest/private.txt
>> gsutil signurl -m GET -d 10m .\KEY.json gs://italiancoderstest/private.txt
URL     HTTP Method     Expiration      Signed URL
gs://italiancoderstest/private.txt      GET     2020-06-09 13:00:39     https://storage.googleapis.com/italiancoderstest/private.txt?x-goog-signature=cbd4bac5c8ca6e769d1a8b54438b5dd2cacfa1454d48683001f611cf16f825929a9a10bcebe2808dda1cd1ce2e06be560b360e2bdabde199c05f4f2e2de8d65680164f466812a89bba79a9a784db921b6eb62cd0df2f94c58e9fe210a137534210005a7e6020e4675fa2463459b4614600cb6ee464479317b739c47b8c77e4c5db8e9e2f2d90d1031a03681e97f4a23d6e6476c868ddee6ab8ef8081f2a2fa5661426c8a3ac36ccc01233797a34870c648776fff5947adf7ac9ba6f4d1f3cba9295d1d0de7f5ecc0d896c31cc8cdd5f446f6beecbaa7e5fc28b0b94eff63739b1b448c06f15c5a5278cd1f9b0cee9efef3c3619b79c433935b94f4c14bba7d03&x-goog-algorithm=GOOG4-RSA-SHA256&x-goog-credential=bucket-reader%40italiancoders-demo.iam.gserviceaccount.com%2F20200609%2Feurope-west2%2Fstorage%2Fgoog4_request&x-goog-date=20200609T105039Z&x-goog-expires=600&x-goog-signedheaders=host

Se proviamo ad accedere all URL creato riusciremo adesso a scaricare il file per 10 min.

 

A proposito di me

Dario Frongillo

Uno degli admin di Italiancoders e dell iniziativa devtalks.
Dario Frongillo è un software engineer e architect, specializzato in Web API, Middleware e Backend in ambito cloud native. Attualmente lavora presso NTT DATA, realtà di consulenza internazionale.
E' membro e contributor in diverse community italiane per developers; Nel 2017 fonda italiancoders.it, una community di blogger italiani che divulga articoli, video e contenuti per developers.

Gli articoli più letti

Articoli recenti

Commenti recenti