Эй Хабр!
Қазіргі заманғы шындықта контейнерлендірудің даму процестеріндегі рөлінің өсуіне байланысты контейнерлерге байланысты әртүрлі кезеңдердің және субъектілердің қауіпсіздігін қамтамасыз ету мәселесі маңызды мәселе емес. Қолмен тексерулерді жүргізу көп уақытты қажет етеді, сондықтан бұл процесті автоматтандыру үшін ең болмағанда бастапқы қадамдарды жасаған дұрыс.
Бұл мақалада мен бірнеше Docker қауіпсіздік утилиталарын енгізуге арналған дайын сценарийлермен және осы процесті сынау үшін шағын демонстрацияны қалай орналастыру керектігі туралы нұсқаулармен бөлісемін. Сіз материалдарды Dockerfile кескіндері мен нұсқауларының қауіпсіздігін тексеру процесін ұйымдастыру әдісімен тәжірибе жасау үшін пайдалана аласыз. Әркімнің даму және іске асыру инфрақұрылымы әртүрлі екені анық, сондықтан төменде мен бірнеше ықтимал нұсқаларды беремін.
Қауіпсіздікті тексеру утилиталары
Docker инфрақұрылымының әртүрлі аспектілерін тексеруді жүзеге асыратын әртүрлі көмекші қолданбалар мен сценарийлердің үлкен саны бар. Олардың кейбіреулері алдыңғы мақалада сипатталған (
Хадолинт
Бірінші жуықтау ретінде Dockerfile нұсқауларының дұрыстығы мен қауіпсіздігін бағалауға көмектесетін өте қарапайым консольдік утилита (мысалы, тек рұқсат етілген кескін тізілімдерін пайдалану немесе sudo пайдалану).
Докл
Белгілі бір кескіннің дұрыстығы мен қауіпсіздігін тексеретін, оның қабаттары мен конфигурациясын талдайтын кескінмен (немесе кескіннің сақталған tar мұрағатымен) жұмыс істейтін консольдік утилита - қай пайдаланушылар жасалған, қандай нұсқаулар пайдаланылады, қай көлемдер орнатылған, бос құпия сөздің болуы және т.б. d. Әзірге тексерулер саны онша көп емес және біздің бірнеше тексерулеріміз бен ұсыныстарымызға негізделген.
Триви
Бұл утилита осалдықтардың екі түрін табуға бағытталған - ОЖ құрастыру проблемалары (Alpine, RedHat (EL), CentOS, Debian GNU, Ubuntu қолдау көрсетеді) және тәуелділік мәселелері (Gemfile.lock, Pipfile.lock, composer.lock, пакеті). -lock.json , yarn.lock, cargo.lock). Trivy репозиторийдегі кескінді де, жергілікті кескінді де сканерлей алады, сонымен қатар Docker кескіні бар тасымалданған .tar файлы негізінде сканерлей алады.
Утилиталарды енгізу нұсқалары
Сипатталған қолданбаларды оқшауланған ортада сынап көру үшін мен барлық утилиталарды біршама жеңілдетілген процесте орнату нұсқауларын беремін.
Негізгі идея - әзірлеу кезінде жасалған Dockerfiles және Docker кескіндерінің мазмұнын автоматты түрде тексеруді қалай жүзеге асыруға болатынын көрсету.
Тексерудің өзі келесі қадамдардан тұрады:
- Linter утилитасының көмегімен Dockerfile нұсқауларының дұрыстығы мен қауіпсіздігін тексеру Хадолинт
- Утилитаның көмегімен соңғы және аралық кескіндердің дұрыстығы мен қауіпсіздігін тексеру Докл
- Негізгі кескінде жалпыға белгілі осалдықтардың (CVE) және бірқатар тәуелділіктердің бар-жоғын - қызметтік бағдарламаны пайдалану арқылы тексеру Триви
Кейінірек мақалада мен осы қадамдарды жүзеге асырудың үш нұсқасын беремін:
Біріншісі, мысал ретінде GitLab көмегімен CI/CD конфигурациялау арқылы (сынақ данасын көтеру процесінің сипаттамасымен).
Екіншісі қабық сценарийін пайдалану.
Үшіншісі Docker кескіндерін сканерлеу үшін Docker кескінін құруды қамтиды.
Сіз өзіңізге ең қолайлы нұсқаны таңдай аласыз, оны инфрақұрылымыңызға тасымалдай аласыз және оны қажеттіліктеріңізге бейімдей аласыз.
Барлық қажетті файлдар мен қосымша нұсқаулар да репозиторийде орналасқан:
GitLab CI/CD жүйесіне интеграция
Бірінші нұсқада мысал ретінде GitLab репозиторий жүйесін пайдаланып қауіпсіздік тексерулерін қалай жүзеге асыруға болатынын қарастырамыз. Мұнда біз қадамдардан өтіп, GitLab көмегімен сынақ ортасын нөлден қалай орнату керектігін, сканерлеу процесін құруды және сынақ Dockerfile және кездейсоқ кескінді - JuiceShop қолданбасын тексеруге арналған утилиталарды іске қосуды анықтаймыз.
GitLab орнатылуда
1. Docker орнату:
sudo apt-get update && sudo apt-get install docker.io
2. Docker тобына ағымдағы пайдаланушыны қосыңыз, осылайша sudo қолданбасын қолданбай докермен жұмыс істей аласыз:
sudo addgroup <username> docker
3. IP мекенжайыңызды табыңыз:
ip addr
4. Контейнерге GitLab орнатып, іске қосыңыз, хост атауындағы IP мекенжайын өзіңіздікімен ауыстырыңыз:
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
GitLab барлық қажетті орнату процедураларын аяқтағанша күтеміз (процесті журнал файлының шығысы арқылы бақылауға болады: docker logs -f gitlab).
5. Браузерде жергілікті IP мекенжайын ашыңыз және түбірлік пайдаланушының құпия сөзін өзгертуді сұрайтын бетті қараңыз:
Жаңа құпия сөзді орнатыңыз және GitLab бөліміне өтіңіз.
6. Жаңа жоба жасаңыз, мысалы, cicd-test және оны бастау файлымен инициализациялаңыз README.md:
7. Енді бізге GitLab Runner орнату керек: сұраныс бойынша барлық қажетті операцияларды орындайтын агент.
Соңғы нұсқаны жүктеп алыңыз (бұл жағдайда, Linux 64-бит үшін):
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
8. Оны орындалатын етіп жасаңыз:
sudo chmod +x /usr/local/bin/gitlab-runner
9. Runner үшін ОЖ пайдаланушысын қосып, қызметті бастаңыз:
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
Ол келесідей көрінуі керек:
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. Енді біз Runner бағдарламасын GitLab данасымен әрекеттесе алатындай етіп тіркейміз.
Ол үшін Settings-CI/CD бетін (http://OUR_IP_ADDRESS/root/cicd-test/-/settings/ci_cd) ашыңыз және Жүгірушілер қойындысында URL мекенжайын және Тіркеу белгісін табыңыз:
11. URL мекенжайын және Тіркеу таңбалауышын ауыстыру арқылы жүгіргішті тіркеңіз:
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"
Нәтижесінде біз дайын жұмыс істейтін GitLab аламыз, оған утилиталарды іске қосу үшін нұсқауларды қосу керек. Бұл демонстрацияда бізде қолданбаны құру және оны контейнерлеу қадамдары жоқ, бірақ нақты ортада олар сканерлеу қадамдарынан бұрын болады және талдау үшін кескіндер мен Dockerfile жасайды.
құбыр конфигурациясы
1. Репозиторийге файлдарды қосыңыз mydockerfile.df (бұл біз тексеретін сынақ Dockerfile) және GitLab CI/CD процесінің конфигурация файлы .gitlab-cicd.yml, ол сканерлерге арналған нұсқауларды береді (файл атауындағы нүктеге назар аударыңыз).
YAML конфигурация файлында таңдалған Dockerfile және DOCKERFILE айнымалысында көрсетілген кескінді талдайтын үш қызметтік бағдарламаны (Hadolint, Dockle және Trivy) іске қосу нұсқаулары бар. Барлық қажетті файлдарды репозиторийден алуға болады:
үзінді mydockerfile.df (бұл тек қызметтік бағдарламаның жұмысын көрсету үшін ерікті нұсқаулар жиынтығы бар дерексіз файл). Файлға тікелей сілтеме:
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
YAML конфигурациясы келесідей көрінеді (файлдың өзін мына жерден тікелей сілтеме арқылы табуға болады:
.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
Қажет болса, .tar мұрағаты түрінде сақталған кескіндерді сканерлеуге де болады (бірақ YAML файлындағы утилиталар үшін енгізу параметрлерін өзгерту қажет болады)
Ескертпе: Trivy орнатуды қажет етеді айн / мин и Git. Әйтпесе, ол RedHat негізіндегі кескіндерді сканерлеу және осалдық дерекқорына жаңартуларды алу кезінде қателер жасайды.
2. Репозиторийге файлдарды қосқаннан кейін конфигурация файлындағы нұсқауларға сәйкес GitLab құрастыру және сканерлеу процесін автоматты түрде бастайды. CI/CD → Құбырлар қойындысында нұсқаулардың орындалу барысын көре аласыз.
Нәтижесінде төрт тапсырмамыз бар. Олардың үшеуі сканерлеумен тікелей айналысады, ал соңғысы (Есеп) сканерлеу нәтижелері бар шашыраңқы файлдардан қарапайым есеп жинайды.
Әдепкі бойынша, кескінде немесе тәуелділікте CRITICAL осалдықтары анықталса, Trivy жұмысын тоқтатады. Сонымен қатар, Hadolint әрқашан Сәттілік кодын қайтарады, себебі ол әрқашан түсініктемелерге әкеледі, бұл құрастыруды тоқтатуға әкеледі.
Арнайы талаптарға байланысты шығу кодын конфигурациялауға болады, осылайша бұл утилиталар белгілі бір маңыздылық мәселелерін анықтағанда, олар құрастыру процесін де тоқтатады. Біздің жағдайда, Trivy біз SHOWSTOPPER айнымалы мәнінде көрсеткен маңыздылығы бар осалдықты анықтаған жағдайда ғана құрастыру тоқтатылады. .gitlab-ci.yml.
Әрбір қызметтік бағдарламаның нәтижесін әрбір сканерлеу тапсырмасының журналында, тікелей артефактілер бөліміндегі json файлдарында немесе қарапайым HTML есебінде көруге болады (төменде бұл туралы толығырақ):
3. Утилита есептерін адам оқи алатындай етіп көрсету үшін үш JSON файлын ақаулар кестесі бар бір HTML файлына түрлендіру үшін шағын Python сценарийі пайдаланылады.
Бұл сценарий бөлек Есеп тапсырмасы арқылы іске қосылады және оның соңғы артефакті есебі бар HTML файлы болып табылады. Сценарий көзі де репозиторийде және сіздің қажеттіліктеріңізге, түстеріңізге және т.б. сәйкес келтіруге болады.
Shell сценарийі
Екінші опция Docker кескіндерін CI/CD жүйесінен тыс тексеру қажет немесе хостта тікелей орындалатын пішіндегі барлық нұсқауларды алу қажет болған жағдайларда қолайлы. Бұл опция таза виртуалды (тіпті нақты) машинада іске қосуға болатын дайын қабық сценарийімен қамтылған. Сценарий жоғарыда сипатталған gitlab-runner сияқты нұсқауларды орындайды.
Сценарий сәтті іске қосылуы үшін жүйеде Docker орнатылуы керек және ағымдағы пайдаланушы докер тобында болуы керек.
Сценарийдің өзін мына жерден табуға болады:
Файлдың басында айнымалы мәндер қандай кескінді сканерлеу керектігін және қандай маңыздылық ақаулары Trivy утилитасының көрсетілген қате кодымен шығуына себеп болатынын көрсетеді.
Сценарийді орындау кезінде барлық утилиталар каталогқа жүктеледі docker_tools, олардың жұмысының нәтижелері анықтамалықта docker_tools/json, және есебі бар HTML файлда болады нәтижелер.html.
Сценарий шығысының мысалы
~/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
Барлық утилиталары бар докер кескіні
Үшінші балама ретінде мен қауіпсіздік утилиталары бар кескін жасау үшін екі қарапайым Dockerfiles құрастырдым. Бір Dockerfile репозиторийден кескінді сканерлеуге арналған жиынды құруға көмектеседі, екіншісі (Dockerfile_tar) кескіні бар tar файлын сканерлеуге арналған жиынды құруға көмектеседі.
1. Репозиторийден сәйкес Docker файлы мен сценарийлерін алыңыз
2. Біз оны құрастыру үшін іске қосамыз:
docker build -t dscan:image -f docker_security.df .
3. Құрастыру аяқталғаннан кейін суреттен контейнер жасаймыз. Сонымен бірге, біз DOCKERIMAGE ортасының айнымалы мәнін бізді қызықтыратын кескіннің атымен өткіземіз және компьютерімізден талдағымыз келетін Docker файлын файлға орнатамыз. /Dockerfile (бұл файлға абсолютті жол қажет екенін ескеріңіз):
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
нәтижелері
Біз Docker артефактілерін сканерлеуге арналған утилиталардың бір ғана негізгі жинағын қарастырдық, бұл менің ойымша, кескін қауіпсіздік талаптарының лайықты бөлігін өте тиімді қамтиды. Сондай-ақ бірдей тексерулерді орындай алатын, әдемі есептерді шығара алатын немесе тек консоль режимінде жұмыс істей алатын, контейнерлерді басқару жүйелерін жабуға және т.б. көптеген ақылы және тегін құралдар бар. Бұл құралдарға шолу және оларды біріктіру жолы сәл кейінірек пайда болуы мүмкін. .
Осы мақалада сипатталған құралдар жиынтығының жақсы жағы - олардың барлығы ашық бастапқы коды және қажеттіліктеріңіз бен инфрақұрылымыңызға сәйкес келетін нәрсені табу үшін олармен және басқа ұқсас құралдармен тәжірибе жасай аласыз. Әрине, табылған барлық осалдықтарды белгілі бір жағдайларда қолдану мүмкіндігін зерттеу керек, бірақ бұл болашақ үлкен мақаланың тақырыбы.
Бұл нұсқаулық, сценарийлер мен утилиталар сізге көмектесіп, контейнерлеу аймағында қауіпсіз инфрақұрылымды құрудың бастапқы нүктесі болады деп үміттенемін.
Ақпарат көзі: www.habr.com