2015-11-10 32 views
21

W http://docs.docker.com/engine/reference/builder/#arg Zaleca, aby sekrety nie były przekazywane przez ARGS.Dlaczego ARG w pliku DOCKERFILE nie jest zalecane do przekazywania sekretów?

Uwaga: Nie zaleca się stosowania w czasie kompilacji zmiennych przekazywania sekretów jak klucze GitHub, poświadczeń użytkownika itp

W jakim punkcie są tajemnice przekazywane przez zmienne w czasie kompilacji w niebezpieczeństwie?

+1

Po wpisaniu ich w terminalu w postaci zwykłego tekstu? –

+0

Czy to też ma zastosowanie do zapisywania pliku w zmiennej środowiskowej i przekazywania jej przez zmienne env? –

+0

Myślę, że zapisanie pliku jest w porządku. Niektóre osoby umieszczają swoje klucze (takie jak AWS) w '.bashrc', więc są one ładowane w każdej sesji bash. Myślę, że ta uwaga odnosi się do 'budowania dockera --build-arg param = ...' –

Odpowiedz

26

Aktualizacja stycznia 2017:

Docker (rój) 1.13 ma docker secret.

Jednakże, jak commented przez Steve Hoffman (bacoboy):

[...] Sekret komenda pomaga tylko użytkownikom rój nie jest bardziej ogólne rozwiązanie (jak zrobili załączeniem uporczywe tomów).
Sposób zarządzania sekretami (czym one są i kto ma do nich dostęp) jest bardzo zależny od systemu i zależy od tego, które części płatnego i/lub OSS są ze sobą sklejane, aby utworzyć "platformę".
Z firmą Docker, która przenosi się na platformę, nie dziwi mnie, że ich pierwsza implementacja jest roju, tak jak Hashicorp integruje Vault w Atlasie - ma to sens.

Naprawdę, w jaki sposób przekazywane są sekrety, spoza obszaru docker run.
AWS robi tego rodzaju rzeczy z rolami i zasadami, aby nadać/odmówić uprawnienia oraz pakiet SDK.
Szef kuchni robi to za pomocą zaszyfrowanych databagów i "bootstrapu" krypto-uwierzytelniania.
K8S ma własną wersję tego, co właśnie wydano w wersji 1.13.
Jestem pewien, że mesos doda podobną implementację na czas.

Te wdrożenia wydają się należeć do 2 obozów.

  • przekazać tajemnicę poprzez objętości zamontować, że „platforma” przewiduje lub (Chef/doker tajne/K8S
  • poświadczenia przejścia rozmawiać z usługą zewnętrzną dostać rzeczy w bagażniku (IAM/credstash/etc)

oryginalny odpowiedź: Nov. 2015

ten został wprowadzony w commit 54240f8 (dokowanym 1.9, lis 2015) od PR 15182,

Środowisko kompilacji jest poprzedzone ciągiem poleceń pośredniej kontynentalnej, aby ułatwić wyszukiwanie w pamięci podręcznej.
Pomaga również w tworzeniu identyfikowalności. Ale powoduje to również, że funkcja jest mniej bezpieczna z punktu widzenia przekazywania tajemnic czasu budowy.

issue 13490 powtarza:

Build-time zmienne środowiskowe: Zmienne środowiskowe build-time nie zostały zaprojektowane do obsługi tajemnice. Z braku innych opcji ludzie planują wykorzystać je do tego. Aby nie sprawiać wrażenia, że ​​nadają się one do tajemnic, postanowiono celowo nie szyfrować tych zmiennych w procesie.

Jak wspomniano w 9176comments:

zmienne env są w niewłaściwy sposób przekazać tajemnice wokół. Nie powinniśmy próbować wymyślać koła od nowa i zapewnić porzucony mechanizm dystrybucji bezpieczeństwa natychmiast po wyjęciu z pudełka.

Podczas przechowywania tajnych kluczy w środowisku, są podatne na przypadkowo je odsłonić - dokładnie to, co chcemy, aby uniknąć:

  • Biorąc pod uwagę, że środowisko jest domyślnie dostępny do procesu, to jest bardzo trudne , jeśli nie jest to niemożliwe, śledzenie dostępu i sposobu wyświetlania zawartości
  • Jest to niezwykle powszechne, gdy aplikacje pobierają całe środowisko i drukują je, ponieważ mogą być przydatne do debugowania, a nawet wysłać je jako część raportu o błędzie . Tyle tajemnic przedostaje się do PagerDuty, że mają dobrze natłuszczony wewnętrzny proces, który usuwa je z ich infrastruktury.
  • Zmienne środowiskowe przekazywane są do procesów potomnych, co umożliwia niezamierzony dostęp i łamie zasadę najmniejszych uprawnień. Wyobraź sobie, że jako część twojej aplikacji nawołujesz do narzędzia innej firmy, aby wykonać pewne działanie, nagle narzędzie innej firmy ma dostęp do twojego środowiska, a Bóg wie, co z nim zrobi.
  • Bardzo często zdarza się, że aplikacje powodujące awarie przechowują zmienne środowiskowe w plikach dzienników w celu późniejszego debugowania. Oznacza to tajemnice zwykłego tekstu na dysku.
  • Umieszczenie tajemnic w zmiennych env szybko zmienia się w wiedzę plemienną. Nowi inżynierowie nie wiedzą, że tam są i nie są świadomi, że powinni zachować ostrożność podczas obsługi zmiennych środowiskowych (filtrowanie ich do podprocesów itp.).

Ogólnie rzecz biorąc, tajemnice zmiennych env łamią zasadę najmniejszego zdziwienia, są złą praktyką i prowadzą do ewentualnego wycieku tajemnic.

+7

Ta odpowiedź jest najlepsza, jaką widziałem, ale wiele z tych komentarzy odnosi się do ENV, a nie do ARG. Ponadto, nie ma żadnej wzmianki o zalecanym sposobie, w jaki zalecany sposób przekazywania sekretów do kompilacji jest ... – Shane

+0

Dalsze czytanie [wydanie 13490] pokazuje (https://github.com/docker/docker/issues/13490) pokazuje że w rzeczywistości nie ma jeszcze zalecanego rozwiązania, ale kilka (w tym przy użyciu skarbców haseł) jest badanych. – Shane

+2

Rozumiem, że na pytanie odpowiedziano uroczo przez VonC [respekt:]], ale wciąż pozostaje pytanie, jak powinniśmy zarządzać tajemnicami i przekazywać je do plików docker i/lub komponować ostatecznie ... –

7

Prostym powodem jest to, że wartość tajemnicy jest widoczna dla każdego z obrazem po prostu uruchamiając na niej history.

Weź ten przykładowy plik Döcker:

FROM alpine 

ARG secret 

RUN echo "${secret}" 

(ładne i proste, tak aby pokazać, jak można użyć w tajemnicy.)

następnie budujemy to $ docker build --build-arg secret=S3CR3T - < Dockerfile

Sending build context to Docker daemon 2.048 kB 
Step 1 : FROM alpine 
---> 13e1761bf172 
Step 2 : ARG secret 
---> Running in 695b7a931445 
---> 5414c15a1cb6 
Removing intermediate container 695b7a931445 
Step 3 : RUN echo "${secret}" 
---> Running in c90cf0d1414b 
s3cr3t 
---> f2bcff49ac09 
Removing intermediate container c90cf0d1414b 
Successfully built f2bcff49ac09 

a przykładem jak zdobyć "tajne" z powrotem (poszukaj |1 secret= w pierwszym wierszu):

$ docker history f2bcff49ac09 
IMAGE    CREATED    CREATED BY          SIZE    COMMENT 
f2bcff49ac09  8 seconds ago  |1 secret=S3CR3T /bin/sh -c echo "${secret}" 0 B 
5414c15a1cb6  8 seconds ago  /bin/sh -C#(nop) ARG secret     0 B 
13e1761bf172  6 months ago  /bin/sh -C#(nop) ADD file:614a9122187935fccf 4.797 MB 

ten ma miejsce w przypadku, gdy obraz został utworzony lokalnie lub pobrany z rejestru.

Jeśli twoim celem jest, aby zachować w tajemnicy build-time z pojemnika bieżącą następnie używając ARG ma pomóc - rozważ to:

$ docker run --rm -ti f2bcff49ac09 sh 
/# env 
HOSTNAME=7bc772fd0f56 
SHLVL=1 
HOME=/root 
TERM=xterm 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
PWD=/ 
$ # Note no secret in the above output 
1

Myślę, że nowy (17.05) funkcja doker Wielostopniowe Buduje (https://docs.docker.com/engine/userguide/eng-image/multistage-build/) łagodzi te (ważne) obawy dotyczące po prostu używania --build-arg.

FROM mybuildertools 
ADD my-git-creds /root/.ssh 
RUN git clone [email protected]:example/foo /src 
FROM mybuildertools 
COPY --from=0 /src /src 
RUN ...build /src with no git credentials ending up in final image... 

Niestety nie wydaje się być łatwym sposobem, aby umożliwić późniejsze przebudowy (np Zmiany do etapu budowy w Dockerfile), chyba że masz katalogu „My-git-creds”.

1

Napisałem https://github.com/abourget/secrets-bridge, aby rozwiązać problem z sekretami podczas budowania.

Tworzy konfigurację wyrzucania, którą można przekazać jako argument budowania, podczas procesu budowania łączy się z hostem i pobiera sekrety, używa ich, a następnie może zabić most hosta. Nawet jeśli argumenty build-args są gdzieś zapisane, stają się bezużyteczne w momencie wyjścia z serwera.

Serwer obsługuje przekazywanie agentów SSH, tunelowane przez komunikację sieciową TLS. Działa również w systemie Windows!

Mam nadzieję, że to pomoże.