
In una logica di sviluppo agile basata un ambiente containerizzato è importante verificare durante la pipeline CI/CD se il container che si sta rilasciando rispetta dei criteri di sicurezza ben definiti. Qualys ha già a disposizione dei plugin per effettuare queste verifiche, ma sono disponibili soltanto per Jenkins e Bamboo (almeno attualmente). Come fare a integrare il modulo di Container Security direttamente nel tool di CI/CD di Gitlab? Abbiamo affrontato il problema e ora vi daremo degli input utili per creare una integrazione diretta tra Qualys e GitLab!
Requisiti
- Modulo di Container Security attivo nella propria istanza Qualys.
- Modulo API attivo nella propria istanza Qualys
Deploy del sensore Container Security
La prima cosa da fare è effettuare il deploy del Container Security Sensor dedicato alla CI/CD. Consigliamo di installarlo direttamente nella macchina che si occupa della build dei container durante il processo CI/CD.
Scaricare il sensore “Build (CI/CD) e seguire il processo di installazione indicato da Qualys.
Come funziona il Sensore CI/CD?
Il Sensore in maniera automatica scansiona le immagini che vengono taggate con il tag “qualys_scan_target:” e successivamente, se più di un tag è presente, rimuove il tag. I dati vengono successivamente caricati alla Qualys Platform.
Integrazione con GitLab
1. Modificare la Pipeline per taggare il container che si sta costruendo
Il nostro esempio prevede 3 stage: una prima parte di build, una seconda che abbiamo chiamato “release” che consiste nel push dell’immagine docker nel nostro registry e, per finire, la parte di deploy dove l’applicazione viene rilasciata ufficialmente in ambiente Kubernetes. Il primo passo è modificare la fase di build in modo che:
a) il container venga taggato con il tag “qualys_scan_target:” in modo da comunicare al sensore che l’immagine deve essere analizzata e scansionata;
b) contattare la piattaforma Cloud di Qualys via API per ricavare i dati della scansione.
Il punto a) è facilmente realizzabile modificando la pipeline:
build-app-backend: stage: build script: - IMAGE_ID=$(docker build -q -t qualys_scan_target:test-app-$RELEASE.$CI_PIPELINE_ID -t test-app:$RELEASE.$CI_PIPELINE_ID -f Dockerfile-app . | cut -c8-19)
Lo script che viene lanciato effettua una build docker silente, taggando l’immagine con i seguenti tag:
- qualys_scan_target:test-app-$RELEASE.$CI_PIPELINE_ID
- test-app:$RELEASE.$CI_PIPELINE_ID
Il comando ritorna l’Image ID in formato non troncato. Di seguito l’esempio:
sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182
Su Qualys le immagini vengono indicizzate con l’image ID nel formato truncated. Tale image ID è ricavato dalla versione “completa”, eliminando la parte “sha256:” e selezionando i successivi 12 caratteri. Per ottenere questo risultato abbiamo applicato un -cut per ricavarci l’Image ID ridotto, necessario per effettuare delle chiamate API alla Qualys Cloud Platform.
2. Identificazione delle vulnerabilità via API
A questo punto sarà sufficiente far seguire il processo di build da uno script in grado di contattare la Qualys Cloud Platform per ricavarsi il numero di vulnerabilità una volta che la scansione dell’immagine ha completato il suo corso. Per contattare il cloud sarà necessario prima autenticarsi alla piattaforma per ottenere un token di accesso e, successivamente, interrogare le API per ottenere tutte le metriche desiderate. Il modo più semplice per testare il processo è quello di creare uno script BASH che prenda in input il Qualys Username e la Password necessari per effettuare il login, oltre che la image ID dell’immagine che si intende analizzare.
Lo username e la password potranno essere salvati come variabili di ambiente nelle impostazioni relative al processo CI/CD di GitLab.
Nel nostro caso abbiamo aggiunto lo script bash nella directory dedicata all’utente gitlab-runner (per semplicità), ma è possibile e consigliabile integrare lo script direttamente in un container dedicato alla parte di analisi delle vulnerabilità.
script: - IMAGE_ID=$(docker build -q -t qualys_scan_target:socialhive-app-$RELEASE.$CI_PIPELINE_ID -t socialhive-app:$RELEASE.$CI_PIPELINE_ID -f Dockerfile-app . | cut -c8-19) - sh /home/gitlab-runner/qualys_analysis.sh -u $qualys_username -p $qualys_password -I $IMAGE_ID
Esempio di script:
Nell’esempio si effettua una chiamata API che ritorna il numero di vulnerabilità per l’immagine che si sta analizzando. Sui dati ritornati si effettua un controllo solamente per le vulnerabilità ritenute più critiche (quelle con severity 4 e 5). Da queste viene calcolato un indice di rischio che pesa ciascuna vulnerabilità di criticità 5 con un fattore 3, mentre vulnerabilità con criticità 4 con fattore 1. Se il peso di rischio supera una soglia definita (nell’esempio 10), lo script esce con codice di errore 1. Tale processo blocca la pipeline impedendo di procedere agli stage successivi (release e deploy).
Ecco un esempio di comportamento:
Lo script è stato modificato bloccando la pipeline se la variabile $risk è maggiore di 0, ovvero se è presente almeno una vulnerabilità di criticità 4 o 5. Osservando i risultati dello stage build-app-backend si può notare che è presente una vulnerabilità di criticità 5 che ha irrimediabilmente bloccato la pipeline.
Al contrario lo stage build-app-cdn ha avuto successo, in quanto l’analisi dell’immagine ha evidenziato la presenza di 0 vulnerabilità.
Chiaramente lo script è solo d’esempio ed è piuttosto banale, ma dà l’idea di come è facile integrare il Container Sensor di Qualys con la pipeline di GitLab avendo accesso a tutte le informazioni via API. Ad esempio sarebbe possibile effettuare un controllo sul software installato nell’immagine, o controllare la presenza di specifiche vulnerabilità, ad esempio individuando se sono presenti vulnerabilità con un cvss3 score superiore ad un certo valore o se sono presenti vulnerabilità con exploit o malware associato.