Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited
Tere Habr!

Kaasaegses reaalsuses ei ole konteineriseerimise rolli suurenemise tõttu arendusprotsessides tähtsus konteineritega seotud erinevate etappide ja üksuste turvalisuse tagamise küsimus. Käsitsi kontrollimine on aeganõudev, mistõttu oleks hea teha vähemalt esimesed sammud selle protsessi automatiseerimiseks.

Selles artiklis jagan valmis skripte mitme Dockeri turbeutiliiti juurutamiseks ja juhiseid selle protsessi testimiseks väikese demostendi juurutamiseks. Materjalide abil saate katsetada, kuidas korraldada Dockerfile'i piltide ja juhiste turvalisuse testimise protsessi. On selge, et igaühe arendus- ja juurutamisinfrastruktuur on erinev, seega pakun allpool mitmeid võimalikke valikuid.

Turvakontrolli kommunaalteenused

Dockeri infrastruktuuri erinevate aspektide kontrollimiseks on olemas suur hulk erinevaid abirakendusi ja skripte. Mõnda neist on juba eelmises artiklis kirjeldatud (https://habr.com/ru/company/swordfish_security/blog/518758/#docker-security) ja selles materjalis tahaksin keskenduda neist kolmele, mis katavad suurema osa arendusprotsessi käigus loodud Dockeri piltide turvanõuetest. Lisaks näitan ka näidet, kuidas need kolm kommunaalteenust turvakontrolli tegemiseks üheks torujuhtmeks ühendada.

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

Üsna lihtne konsooliutiliit, mis aitab esimese ligikaudsusena hinnata Dockerfile'i juhiste õigsust ja ohutust (näiteks kasutades ainult volitatud pildiregistreid või kasutades sudo).

Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

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

Konsooliutiliit, mis töötab pildiga (või pildi salvestatud tararhiiviga), mis kontrollib konkreetse pildi kui sellise õigsust ja turvalisust, analüüsib selle kihte ja konfiguratsiooni – millised kasutajad luuakse, milliseid juhiseid kasutatakse, milliseid köiteid on paigaldatud, tühja parooli olemasolu jne. d. Seni pole kontrollide arv kuigi suur ja põhineb mitmel meie enda kontrollimisel ja soovitusel CIS (Interneti-turvalisuse keskus) võrdlusalus Dockeri jaoks.
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

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

Selle utiliidi eesmärk on leida kahte tüüpi turvaauke – probleeme OS-i järgudega (toetavad Alpine, RedHat (EL), CentOS, Debian GNU, Ubuntu) ja sõltuvustega seotud probleeme (Gemfile.lock, Pipfile.lock, composer.lock, pakett -lock.json , lõng.lukk, lasti.lukk). Trivy saab skannida nii hoidlas olevat pilti kui ka kohalikku pilti ning samuti saab skannida edastatud .tar-faili alusel koos Dockeri kujutisega.

Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

Kommunaalteenuste juurutamise võimalused

Kirjeldatud rakenduste proovimiseks eraldatud keskkonnas annan juhised kõigi utiliitide installimiseks mõnevõrra lihtsustatud protsessis.

Põhiidee on näidata, kuidas saate rakendada arenduse käigus loodud Dockerfailide ja Dockeri piltide automaatset sisu kontrollimist.

Kontroll ise koosneb järgmistest sammudest:

  1. Dockerfile'i juhiste õigsuse ja ohutuse kontrollimine linteriutiliidi abil Hadolint
  2. Lõplike ja vahepiltide õigsuse ja ohutuse kontrollimine utiliidi abil Dockle
  3. Utiliidi abil avalikkusele teadaolevate haavatavuste (CVE) olemasolu kontrollimine põhipildis ja mitmed sõltuvused Trivy

Hiljem annan artiklis kolm võimalust nende sammude rakendamiseks:
Esimene on CI/CD konveieri konfigureerimine, kasutades näitena GitLabi (koos testeksemplari tõstmise protsessi kirjeldusega).
Teine kasutab shelliskripti.
Kolmas hõlmab Dockeri kujutise loomist Dockeri piltide skannimiseks.
Saate valida endale sobivaima variandi, kanda selle üle oma infrastruktuuri ja kohandada seda vastavalt oma vajadustele.

Kõik vajalikud failid ja lisajuhised asuvad samuti hoidlas: https://github.com/Swordfish-Security/docker_cicd

Integreerimine GitLabi CI/CD-sse

Esimeses variandis vaatleme, kuidas saate GitLabi hoidlasüsteemi näitel turvakontrolli rakendada. Siin käime läbi sammud ja mõtleme välja, kuidas installida GitLabiga testikeskkond nullist, luua skannimisprotsess ja käivitada utiliidid testitava Dockerfile'i ja juhusliku pildi kontrollimiseks - JuiceShopi rakendus.

GitLabi installimine
1. Installige Docker:

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

2. Lisage dockeri gruppi praegune kasutaja, et saaksite dockeriga töötada ilma sudot kasutamata:

sudo addgroup <username> docker

3. Leidke oma IP:

ip addr

4. Installige ja käivitage GitLab konteinerisse, asendades hostinimes oleva IP-aadressi enda omaga:

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

Ootame, kuni GitLab lõpetab kõik vajalikud installiprotseduurid (saate protsessi jälgida logifaili väljundi kaudu: docker logs -f gitlab).

5. Avage brauseris oma kohalik IP ja vaadake lehte, mis palub teil muuta juurkasutaja parooli:
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited
Määrake uus parool ja minge GitLabi.

6. Loo uus projekt, näiteks cicd-test ja initsialiseeri see stardifailiga README.md:
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited
7. Nüüd peame installima GitLab Runneri: agent, mis käivitab nõudmisel kõik vajalikud toimingud.
Laadige alla uusim versioon (antud juhul 64-bitise Linuxi jaoks):

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

8. Muutke see käivitatavaks:

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

9. Lisage Runnerile OS-i kasutaja ja käivitage teenus:

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

See peaks välja nägema umbes selline:

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. Nüüd registreerime Runneri, et see saaks suhelda meie GitLabi eksemplariga.
Selleks avage leht Settings-CI/CD (http://OUR_IP_ADDRESS/root/cicd-test/-/settings/ci_cd) ja leidke vahekaardilt Runners URL ja Registration token:
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited
11. Registreerige jooksja, asendades URL-i ja registreerimismärgi:

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"

Selle tulemusena saame valmis töötava GitLabi, millesse peame lisama juhised oma utiliitide käivitamiseks. Selles demos pole meil rakenduse koostamiseks ja konteinerisse paigutamiseks vajalikke samme, kuid reaalses keskkonnas eelneksid need skannimisetappidele ning genereeriksid analüüsimiseks pildid ja Docker-faili.

torujuhtme konfiguratsioon

1. Lisage hoidlasse failid mydockerfile.df (see on test Dockeri fail, mida me kontrollime) ja GitLabi CI / CD protsessi konfiguratsioonifail .gitlab-cicd.yml, mis loetleb skannerite juhised (märkige täpp failinimes).

YAML-i konfiguratsioonifail sisaldab juhiseid kolme utiliidi (Hadolint, Dockle ja Trivy) käitamiseks, mis analüüsivad valitud Dockerfile'i ja muutujas DOCKERFILE määratud pilti. Kõik vajalikud failid saab hoidlast võtta: https://github.com/Swordfish-Security/docker_cicd/

Väljavõte sellest mydockerfile.df (see on abstraktne fail, mis sisaldab meelevaldseid juhiseid ainult utiliidi toimimise demonstreerimiseks). Otselink failile: mydockerfile.df

Mydockerfile.df sisu

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

YAML-i seadistus näeb välja selline (faili enda leiate otselingi kaudu siit: .gitlab-ci.yml):

Faili .gitlab-ci.yml sisu

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

Vajadusel saate skannida ka salvestatud pilte .tar-arhiivi kujul (samas peate muutma YAML-failis olevate utiliitide sisendparameetreid)

NB: Trivy vajab installimist rpm и git. Vastasel juhul tekitab see tõrkeid RedHat-põhiste piltide skannimisel ja haavatavuse andmebaasi värskenduste saamisel.

2. Pärast failide hoidlasse lisamist alustab GitLab vastavalt meie konfiguratsioonifailis olevatele juhistele automaatselt koostamis- ja skannimisprotsessi. Vahekaardil CI/CD → Pipelines näete juhiste edenemist.

Selle tulemusena on meil neli ülesannet. Kolm neist tegelevad otseselt skaneerimisega ja viimane (Aruanne) kogub hajusatest failidest lihtsa aruande koos skaneerimise tulemustega.
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited
Vaikimisi peatab Trivy töötamise, kui pildil või sõltuvustes tuvastatakse KRIITILISED haavatavused. Samal ajal tagastab Hadolint alati edukoodi, kuna selle tulemuseks on alati kommentaarid, mille tõttu ehitamine peatub.

Sõltuvalt teie konkreetsetest nõudmistest saate konfigureerida väljumiskoodi nii, et kui need utiliidid tuvastavad teatud kriitilisuse probleemid, peatavad nad ka ehitusprotsessi. Meie puhul peatub ehitamine ainult siis, kui Trivy tuvastab haavatavuse, mille kriitilisus on määratletud muutujas SHOWSTOPPER .gitlab-ci.yml.
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

Iga utiliidi tulemust saab vaadata iga skannimistoimingu logis, otse artefaktide jaotises olevates json-failides või lihtsas HTML-aruandes (sellest leiate lähemalt allpool):
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

3. Kasulike aruannete esitamiseks inimesele veidi loetavamal kujul kasutatakse väikest Pythoni skripti kolme JSON-faili teisendamiseks üheks HTML-failiks koos defektide tabeliga.
See skript käivitatakse eraldi aruande ülesandega ja selle lõplik artefakt on aruandega HTML-fail. Skripti allikas on samuti hoidlas ja seda saab kohandada vastavalt teie vajadustele, värvidele jne.
Dockeri turvakontrolli utiliitide rakendamise meetodid ja näited

Shelli skript

Teine valik sobib juhtudel, kui peate kontrollima Dockeri pilte väljaspool CI/CD-süsteemi või teil peavad olema kõik juhised kujul, mida saab otse hostis täita. See valik on kaetud valmis shelliskriptiga, mida saab käivitada puhtas virtuaalses (või isegi reaalses) masinas. Skript täidab samu juhiseid nagu ülalkirjeldatud gitlab-runner.

Skripti edukaks käitamiseks peab Docker olema süsteemi installitud ja praegune kasutaja peab olema dokkerite rühmas.

Skripti enda leiab siit: docker_sec_check.sh

Faili alguses määravad muutujad, millist pilti tuleb skannida ja millised kriitilisuse vead põhjustavad Trivy utiliidi väljumise määratud veakoodiga.

Skripti täitmise ajal laaditakse kõik utiliidid kataloogi alla docker_tools, on nende töö tulemused kataloogis docker_tools/jsonja HTML koos aruandega on failis tulemused.html.

Skripti väljundi näide

~/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

Dockeri pilt koos kõigi utiliitidega

Kolmanda alternatiivina koostasin kaks lihtsat Docker-faili, et luua turvautiliitidega pilt. Üks Dockerfile aitab luua komplekti pildi hoidlast skannimiseks, teine ​​(Dockerfile_tar) aitab luua komplekti pildiga tar-faili skannimiseks.

1. Võtke hoidlast vastav Dockeri fail ja skriptid https://github.com/Swordfish-Security/docker_cicd/tree/master/Dockerfile.
2. Käivitame selle kokkupanekuks:

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

3. Pärast kokkupaneku lõpetamist loome pildist konteineri. Samal ajal edastame keskkonnamuutuja DOCKERIMAGE meid huvitava pildi nimega ja ühendame oma masinast faili Dockeri faili, mida tahame analüüsida /Dockerfile (pange tähele, et selle faili absoluutne tee on nõutav):

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

Järeldused

Vaatasime Dockeri artefaktide skannimiseks ainult ühte põhilist utiliitide komplekti, mis minu arvates katab väga tõhusalt korraliku osa pilditurbe nõuetest. Samuti on olemas suur hulk tasulisi ja tasuta tööriistu, millega saab teha samu kontrolle, koostada ilusaid aruandeid või töötada puhtalt konsoolirežiimis, katta konteinerihaldussüsteeme jne. Nende tööriistade ja nende integreerimise ülevaade võib ilmuda veidi hiljem .

Artiklis kirjeldatud tööriistakomplekti hea külg on see, et need kõik on üles ehitatud avatud lähtekoodile ning saate nende ja muude sarnaste tööriistadega katsetada, et leida oma nõudmistele ja infrastruktuuri funktsioonidele sobivaim. Loomulikult tuleks kõiki leitud haavatavusi konkreetsetes tingimustes rakendada, kuid see on tulevase suure artikli teema.

Loodan, et see juhend, skriptid ja utiliidid aitavad teid ja saavad lähtepunktiks turvalisema infrastruktuuri loomisel konteineritesse paigutamise valdkonnas.

Allikas: www.habr.com

Lisa kommentaar