Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere
Hej Habr!

U današnjoj stvarnosti, zbog sve veće uloge kontejnerizacije u razvojnim procesima, pitanje osiguranja sigurnosti različitih faza i entiteta povezanih s kontejnerima nije na posljednjem mjestu. Ručno obavljanje provjera je naporan zadatak, stoga bi bilo lijepo poduzeti barem početne korake prema automatizaciji ovog procesa.

U ovom ću članku podijeliti gotove skripte za implementaciju nekoliko Docker sigurnosnih uslužnih programa i upute o tome kako postaviti mali demo stalak za testiranje ovog procesa. Materijale možete koristiti za eksperimentiranje s načinom organiziranja procesa testiranja sigurnosti Dockerfile slika i uputa. Jasno je da je razvojna i implementacijska infrastruktura različita za svakoga, stoga ću u nastavku dati nekoliko mogućih opcija.

Uslužni programi sigurnosne provjere

Postoji veliki broj različitih pomoćnih aplikacija i skripti koje vrše provjere različitih aspekata Docker infrastrukture. Neki od njih već su opisani u prethodnom članku (https://habr.com/ru/company/swordfish_security/blog/518758/#docker-security), a u ovom bih se članku želio usredotočiti na tri od njih, koji pokrivaju većinu sigurnosnih zahtjeva za Docker slike koje se izgrađuju tijekom procesa razvoja. Osim toga, također ću pokazati primjer kako se ova tri pomoćna programa mogu kombinirati u jedan cjevovod za izvođenje sigurnosnih provjera.

Hadolint
https://github.com/hadolint/hadolint

Prilično jednostavan konzolni uslužni program koji pomaže prvo procijeniti ispravnost i sigurnost uputa Dockerfilea (na primjer, korištenje samo dopuštenih registara slika ili korištenje sudoa).

Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Dockle
https://github.com/goodwithtech/dockle

Konzolni uslužni program koji radi na slici (ili na spremljenoj arhivi slike) koja provjerava ispravnost i sigurnost određene slike kao takve analizirajući njezine slojeve i konfiguraciju - koji su korisnici stvoreni, koje se upute koriste, koji su volumeni montirani , prisutnost prazne lozinke itd. e. Dok broj provjera nije jako velik i temelji se na nekoliko vlastitih provjera i preporuka CIS (Centar za internetsku sigurnost) mjerilo za dokera.
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Trivy
https://github.com/aquasecurity/trivy

Ovaj uslužni program ima za cilj pronalaženje dvije vrste ranjivosti - probleme s verzijom OS-a (podržani su Alpine, RedHat (EL), CentOS, Debian GNU, Ubuntu) i probleme ovisnosti (Gemfile.lock, Pipfile.lock, composer.lock, package-lock .json, yarn.lock, Cargo.lock). Trivy može skenirati i sliku u repozitoriju i lokalnu sliku, a također skenirati na temelju prenesene .tar datoteke s Docker slikom.

Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Mogućnosti implementacije uslužnih programa

Kako bismo isprobali opisane aplikacije u izoliranim uvjetima, dat ću upute za instaliranje svih pomoćnih programa kao dio pojednostavljenog postupka.

Glavna ideja je pokazati kako možete implementirati automatsku provjeru sadržaja za Docker datoteke i Docker slike koje su stvorene tijekom razvoja.

Sama verifikacija se sastoji od sljedećih koraka:

  1. Provjera ispravnosti i sigurnosti uputa Dockerfilea pomoću uslužnog programa linter Hadolint
  2. Provjera ispravnosti i sigurnosti završne i međuslike - pomoćni program Dockle
  3. Provjera općepoznatih ranjivosti (CVE) u osnovnoj slici i brojnih ovisnosti - od strane uslužnog programa Trivy

Kasnije u članku dat ću tri opcije za provedbu ovih koraka:
Prvi je konfiguriranjem CI/CD cjevovoda na primjeru GitLaba (s opisom procesa podizanja testne instance).
Drugi je korištenje shell skripte.
Treći je izrada Docker slike za skeniranje Docker slika.
Možete odabrati opciju koja vam najviše odgovara, prenijeti je na svoju infrastrukturu i prilagoditi svojim potrebama.

Sve potrebne datoteke i dodatne upute također se nalaze u repozitoriju: https://github.com/Swordfish-Security/docker_cicd

GitLab CI/CD integracija

U prvoj opciji pogledat ćemo kako se sigurnosne provjere mogu implementirati koristeći GitLab sustav repozitorija kao primjer. Ovdje ćemo proći kroz korake i vidjeti kako postaviti testno okruženje s GitLabom ispočetka, stvoriti proces skeniranja i pokrenuti uslužne programe za testiranje testne Dockerfile i nasumične slike - aplikacije JuiceShop.

Instaliranje GitLaba
1. Instalirajte Docker:

sudo apt-get update && sudo apt-get install docker.io

2. Dodajte trenutnog korisnika u docker grupu tako da možete raditi s dockerom bez korištenja sudo:

sudo addgroup <username> docker

3. Pronađite svoj IP:

ip addr

4. Instalirajte i pokrenite GitLab u spremniku, zamjenjujući IP adresu u imenu hosta svojom:

docker run --detach 
--hostname 192.168.1.112 
--publish 443:443 --publish 80:80 
--name gitlab 
--restart always 
--volume /srv/gitlab/config:/etc/gitlab 
--volume /srv/gitlab/logs:/var/log/gitlab 
--volume /srv/gitlab/data:/var/opt/gitlab 
gitlab/gitlab-ce:latest

Čekamo da GitLab dovrši sve potrebne instalacijske procedure (proces možete pratiti kroz izlaz log datoteke: docker logs -f gitlab).

5. Otvorite svoj lokalni IP u pregledniku i pogledajte stranicu koja nudi promjenu lozinke za root korisnika:
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere
Postavite novu lozinku i idite na GitLab.

6. Napravite novi projekt, na primjer cicd-test i inicijalizirajte ga s početnom datotekom PROČITAJ ME.md:
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere
7. Sada moramo instalirati GitLab Runner: agent koji će pokrenuti sve potrebne operacije na zahtjev.
Preuzmite najnoviju verziju (u ovom slučaju pod 64-bitnim Linuxom):

sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

8. Učinite ga izvršnim:

sudo chmod +x /usr/local/bin/gitlab-runner

9. Dodajte OS korisnika za Runner i pokrenite uslugu:

sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start

Trebalo bi izgledati otprilike ovako:

local@osboxes:~$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
Runtime platform arch=amd64 os=linux pid=8438 revision=0e5417a3 version=12.0.1
local@osboxes:~$ sudo gitlab-runner start
Runtime platform arch=amd64 os=linux pid=8518 revision=0e5417a3 version=12.0.1

10. Sada registriramo Runner tako da može komunicirati s našom GitLab instancom.
Da biste to učinili, otvorite stranicu Settings-CI/CD (http://OUR_ IP_ADDRESS/root/cicd-test/-/settings/ci_cd) i na kartici Runners pronađite URL i registracijski token:
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere
11. Registrirajte trkača zamjenom URL-a i tokena za registraciju:

sudo gitlab-runner register 
--non-interactive 
--url "http://<URL>/" 
--registration-token "<Registration Token>" 
--executor "docker" 
--docker-privileged 
--docker-image alpine:latest 
--description "docker-runner" 
--tag-list "docker,privileged" 
--run-untagged="true" 
--locked="false" 
--access-level="not_protected"

Kao rezultat, dobivamo gotov radni GitLab, u koji moramo dodati upute za pokretanje naših uslužnih programa. U ovoj demonstraciji nemamo korake izrade aplikacije i kontejnerizacije, ali u stvarnom okruženju oni će prethoditi koracima skeniranja i generirati slike i Dockerfile za analizu.

konfiguracija cjevovoda

1. Dodajte datoteke u repozitorij mojadockerfile.df (ovo je testna Docker datoteka koju ćemo testirati) i konfiguracijska datoteka GitLab CI/CD procesa .gitlab-cicd.yml, koji navodi upute za skenere (obratite pažnju na točku u nazivu datoteke).

Konfiguracijska datoteka .yaml sadrži upute za pokretanje tri pomoćna programa (Hadolint, Dockle i Trivy) koji će analizirati odabranu Dockerfile i sliku navedenu u varijabli DOCKERFILE. Sve potrebne datoteke mogu se preuzeti iz repozitorija: https://github.com/Swordfish-Security/docker_cicd/

Izvadak iz mojadockerfile.df (ovo je apstraktna datoteka sa skupom proizvoljnih uputa samo da se pokaže kako uslužni program radi). Izravna poveznica na datoteku: mojadockerfile.df

Sadržaj mydockerfile.df

FROM amd64/node:10.16.0-alpine@sha256:f59303fb3248e5d992586c76cc83e1d3700f641cbcd7c0067bc7ad5bb2e5b489 AS tsbuild
COPY package.json .
COPY yarn.lock .
RUN yarn install
COPY lib lib
COPY tsconfig.json tsconfig.json
COPY tsconfig.app.json tsconfig.app.json
RUN yarn build
FROM amd64/ubuntu:18.04@sha256:eb70667a801686f914408558660da753cde27192cd036148e58258819b927395
LABEL maintainer="Rhys Arkins <[email protected]>"
LABEL name="renovate"
...
COPY php.ini /usr/local/etc/php/php.ini
RUN cp -a /tmp/piik/* /var/www/html/
RUN rm -rf /tmp/piwik
RUN chown -R www-data /var/www/html
ADD piwik-cli-setup /piwik-cli-setup
ADD reset.php /var/www/html/
## ENTRYPOINT ##
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
USER root

Konfiguracija YAML izgleda ovako (sama datoteka se može preuzeti s izravnog linka ovdje: .gitlab-ci.yml):

Sadržaj .gitlab-ci.yml

variables:
    DOCKER_HOST: "tcp://docker:2375/"
    DOCKERFILE: "mydockerfile.df" # name of the Dockerfile to analyse   
    DOCKERIMAGE: "bkimminich/juice-shop" # name of the Docker image to analyse
    # DOCKERIMAGE: "knqyf263/cve-2018-11235" # test Docker image with several CRITICAL CVE
    SHOWSTOPPER_PRIORITY: "CRITICAL" # what level of criticality will fail Trivy job
    TRIVYCACHE: "$CI_PROJECT_DIR/.cache" # where to cache Trivy database of vulnerabilities for faster reuse
    ARTIFACT_FOLDER: "$CI_PROJECT_DIR"
 
services:
    - docker:dind # to be able to build docker images inside the Runner
 
stages:
    - scan
    - report
    - publish
 
HadoLint:
    # Basic lint analysis of Dockerfile instructions
    stage: scan
    image: docker:git
 
    after_script:
    - cat $ARTIFACT_FOLDER/hadolint_results.json
 
    script:
    - export VERSION=$(wget -q -O - https://api.github.com/repos/hadolint/hadolint/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64 && chmod +x hadolint-Linux-x86_64
     
    # NB: hadolint will always exit with 0 exit code
    - ./hadolint-Linux-x86_64 -f json $DOCKERFILE > $ARTIFACT_FOLDER/hadolint_results.json || exit 0
 
    artifacts:
        when: always # return artifacts even after job failure       
        paths:
        - $ARTIFACT_FOLDER/hadolint_results.json
 
Dockle:
    # Analysing best practices about docker image (users permissions, instructions followed when image was built, etc.)
    stage: scan   
    image: docker:git
 
    after_script:
    - cat $ARTIFACT_FOLDER/dockle_results.json
 
    script:
    - export VERSION=$(wget -q -O - https://api.github.com/repos/goodwithtech/dockle/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz && tar zxf dockle_${VERSION}_Linux-64bit.tar.gz
    - ./dockle --exit-code 1 -f json --output $ARTIFACT_FOLDER/dockle_results.json $DOCKERIMAGE   
     
    artifacts:
        when: always # return artifacts even after job failure       
        paths:
        - $ARTIFACT_FOLDER/dockle_results.json
 
Trivy:
    # Analysing docker image and package dependencies against several CVE bases
    stage: scan   
    image: docker:git
 
    script:
    # getting the latest Trivy
    - apk add rpm
    - export VERSION=$(wget -q -O - https://api.github.com/repos/knqyf263/trivy/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/1/')
    - wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz && tar zxf trivy_${VERSION}_Linux-64bit.tar.gz
     
    # displaying all vulnerabilities w/o failing the build
    - ./trivy -d --cache-dir $TRIVYCACHE -f json -o $ARTIFACT_FOLDER/trivy_results.json --exit-code 0 $DOCKERIMAGE    
    
    # write vulnerabilities info to stdout in human readable format (reading pure json is not fun, eh?). You can remove this if you don't need this.
    - ./trivy -d --cache-dir $TRIVYCACHE --exit-code 0 $DOCKERIMAGE    
 
    # failing the build if the SHOWSTOPPER priority is found
    - ./trivy -d --cache-dir $TRIVYCACHE --exit-code 1 --severity $SHOWSTOPPER_PRIORITY --quiet $DOCKERIMAGE
         
    artifacts:
        when: always # return artifacts even after job failure
        paths:
        - $ARTIFACT_FOLDER/trivy_results.json
 
    cache:
        paths:
        - .cache
 
Report:
    # combining tools outputs into one HTML
    stage: report
    when: always
    image: python:3.5
     
    script:
    - mkdir json
    - cp $ARTIFACT_FOLDER/*.json ./json/
    - pip install json2html
    - wget https://raw.githubusercontent.com/shad0wrunner/docker_cicd/master/convert_json_results.py
    - python ./convert_json_results.py
     
    artifacts:
        paths:
        - results.html

Ako je potrebno, također možete skenirati spremljene slike kao .tar arhivu (međutim, morat ćete promijeniti ulazne parametre za pomoćne programe u YAML datoteci)

Napomena: Trivy zahtijeva instaliranje min и git. Inače će generirati pogreške prilikom skeniranja slika temeljenih na RedHatu i dobivanja ažuriranja baze podataka ranjivosti.

2. Nakon dodavanja datoteka u repozitorij, prema uputama u našoj konfiguracijskoj datoteci, GitLab će automatski pokrenuti proces izgradnje i skeniranja. Na kartici CI / CD → Cjevovodi možete vidjeti napredak uputa.

Kao rezultat toga, imamo četiri zadatka. Tri su izravno uključena u skeniranje, a posljednji (Izvješće) prikuplja jednostavno izvješće iz razbacanih datoteka s rezultatima skeniranja.
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere
Prema zadanim postavkama, Trivy zaustavlja svoje izvršenje ako se na slici ili ovisnostima pronađu KRITIČNE ranjivosti. U isto vrijeme, Hadolint uvijek vraća Success u izvršnom kodu, budući da njegovo izvršenje uvijek ima primjedbi, što uzrokuje zaustavljanje izgradnje.

Ovisno o vašim specifičnim zahtjevima, možete konfigurirati izlazni kod tako da ovi pomoćni programi također zaustave proces izgradnje kada se otkriju problemi određene kritičnosti. U našem slučaju, izgradnja će se zaustaviti samo ako Trivy otkrije ranjivost s ozbiljnošću koju smo naveli u varijabli SHOWSTOPPER u .gitlab-ci.yml.
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Rezultat rada svakog uslužnog programa može se vidjeti u zapisniku svakog zadatka skeniranja, izravno u json datotekama u odjeljku s artefaktima ili u jednostavnom HTML izvješću (više o tome u nastavku):
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

3. Za predstavljanje izvješća o komunalnim uslugama u malo čitljivijem obliku, koristi se mala Python skripta za pretvaranje tri json datoteke u jednu HTML datoteku s tablicom nedostataka.
Ovu skriptu pokreće zaseban zadatak izvješća, a njezin je konačni artefakt HTML datoteka s izvješćem. Izvor skripte je također u repozitoriju i može se prilagoditi vašim potrebama, bojama itd.
Metode i primjeri implementacije uslužnih programa Docker sigurnosne provjere

Shell skripta

Druga je opcija prikladna za slučajeve kada trebate provjeriti Docker slike koje nisu unutar CI/CD sustava ili trebate imati sve upute u obliku koji se može izvršiti izravno na hostu. Ovu opciju pokriva gotova skripta ljuske koja se može pokrenuti na čistom virtualnom (ili čak stvarnom) stroju. Skripta slijedi iste upute kao gornji gitlab-runner.

Da bi skripta uspješno radila, Docker mora biti instaliran na sustavu i trenutni korisnik mora biti u docker grupi.

Samu skriptu možete pronaći ovdje: docker_sec_check.sh

Na početku datoteke, varijable određuju koju sliku treba skenirati i koja će ozbiljnost nedostataka uzrokovati izlazak uslužnog programa Trivy s navedenim kodom pogreške.

Tijekom izvođenja skripte, svi pomoćni programi bit će preuzeti u direktorij docker_tools, rezultati njihovog rada - u imeniku docker_tools/json, a HTML s izvješćem bit će u datoteci rezultati.html.

Primjer izlaza skripte

~/docker_cicd$ ./docker_sec_check.sh

[+] Setting environment variables
[+] Installing required packages
[+] Preparing necessary directories
[+] Fetching sample Dockerfile
2020-10-20 10:40:00 (45.3 MB/s) - ‘Dockerfile’ saved [8071/8071]
[+] Pulling image to scan
latest: Pulling from bkimminich/juice-shop
[+] Running Hadolint
...
Dockerfile:205 DL3015 Avoid additional packages by specifying `--no-install-recommends`
Dockerfile:248 DL3002 Last USER should not be root
...
[+] Running Dockle
...
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
...
[+] Running Trivy
juice-shop/frontend/package-lock.json
=====================================
Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 2, CRITICAL: 0)

+---------------------+------------------+----------+---------+-------------------------+
|       LIBRARY       | VULNERABILITY ID | SEVERITY | VERSION |             TITLE       |
+---------------------+------------------+----------+---------+-------------------------+
| object-path         | CVE-2020-15256   | HIGH     | 0.11.4  | Prototype pollution in  |
|                     |                  |          |         | object-path             |
+---------------------+------------------+          +---------+-------------------------+
| tree-kill           | CVE-2019-15599   |          | 1.2.2   | Code Injection          |
+---------------------+------------------+----------+---------+-------------------------+
| webpack-subresource | CVE-2020-15262   | LOW      | 1.4.1   | Unprotected dynamically |
|                     |                  |          |         | loaded chunks           |
+---------------------+------------------+----------+---------+-------------------------+

juice-shop/package-lock.json
============================
Total: 20 (UNKNOWN: 0, LOW: 1, MEDIUM: 6, HIGH: 8, CRITICAL: 5)

...

juice-shop/package-lock.json
============================
Total: 5 (CRITICAL: 5)

...
[+] Removing left-overs
[+] Making the output look pretty
[+] Converting JSON results
[+] Writing results HTML
[+] Clean exit ============================================================
[+] Everything is done. Find the resulting HTML report in results.html

Docker slika sa svim pomoćnim programima

Kao treću alternativu, kompajlirao sam dvije jednostavne Docker datoteke za stvaranje slike sa sigurnosnim uslužnim programima. Jedan Dockerfile pomoći će u izradi skupa za skeniranje slike iz repozitorija, drugi (Dockerfile_tar) će izgraditi skup za skeniranje tar datoteke sa slikom.

1. Uzimamo odgovarajuću Docker datoteku i skripte iz repozitorija https://github.com/Swordfish-Security/docker_cicd/tree/master/Dockerfile.
2. Pokrenite ga za sastavljanje:

docker build -t dscan:image -f docker_security.df .

3. Nakon dovršetka izgradnje, stvorite spremnik iz slike. U isto vrijeme prosljeđujemo varijablu okruženja DOCKERIMAGE s nazivom slike koja nas zanima i montiramo Dockerfile koji želimo analizirati s našeg stroja na datoteku /dockerfile (imajte na umu da je potrebna apsolutna putanja do ove datoteke):

docker run --rm -v $(pwd)/results:/results -v $(pwd)/docker_security.df:/Dockerfile -e DOCKERIMAGE="bkimminich/juice-shop" dscan:image


[+] Setting environment variables
[+] Running Hadolint
/Dockerfile:3 DL3006 Always tag the version of an image explicitly
[+] Running Dockle
WARN    - DKL-DI-0006: Avoid latest tag
        * Avoid 'latest' tag
INFO    - CIS-DI-0005: Enable Content trust for Docker
        * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO    - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
        * not found HEALTHCHECK statement
INFO    - DKL-LI-0003: Only put necessary files
        * unnecessary file : juice-shop/node_modules/sqlite3/Dockerfile
        * unnecessary file : juice-shop/node_modules/sqlite3/tools/docker/architecture/linux-arm64/Dockerfile
        * unnecessary file : juice-shop/node_modules/sqlite3/tools/docker/architecture/linux-arm/Dockerfile
[+] Running Trivy
...
juice-shop/package-lock.json
============================
Total: 20 (UNKNOWN: 0, LOW: 1, MEDIUM: 6, HIGH: 8, CRITICAL: 5)
...
[+] Making the output look pretty
[+] Starting the main module ============================================================
[+] Converting JSON results
[+] Writing results HTML
[+] Clean exit ============================================================
[+] Everything is done. Find the resulting HTML report in results.html

Nalazi

Pokrili smo samo jedan osnovni skup Docker pomoćnih programa za skeniranje artefakata, za koje mislim da prilično učinkovito pokriva dobar dio sigurnosnih zahtjeva slike. Postoje mnogi drugi plaćeni i besplatni alati koji mogu obavljati iste provjere, crtati prekrasna izvješća ili raditi isključivo u konzolnom načinu rada, pokrivati ​​sustave upravljanja kontejnerima, itd. Pregled ovih alata i kako ih integrirati može se pojaviti nešto kasnije.

Pozitivna strana skupa alata opisanih u članku jest to što su svi izgrađeni na otvorenom kodu i možete eksperimentirati s njima i drugim sličnim alatima kako biste pronašli ono što točno odgovara vašim zahtjevima i značajkama infrastrukture. Naravno, sve ranjivosti koje se pronađu treba proučiti za primjenjivost u određenim uvjetima, ali to je tema za budući veliki članak.

Nadam se da će vam ove upute, skripte i uslužni programi pomoći i postati polazna točka za stvaranje sigurnije infrastrukture u području kontejnerizacije.

Izvor: www.habr.com

Dodajte komentar