Wie Docker Container mit Volume laufen lassen?

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.651
Also ich bin leider noch ziemlicher Anfänger was Docker angeht. Ich weiß wie ich ein lokales Verzeichnis mounte beim Start von Docker aber ich habe folgendes Problem:

Ich möchte einen Container der ein Linux SSH Server bereitstellt laufen lassen. Hier gibt einen entsprechenden Container der noch so nette Dinge wie 2FA gleich mitbringt: https://github.com/cloudposse/bastion

Dort wird auch gezeigt wie ich das starten kann, z.B. mit diesem Befehl
Code:
$ docker run -it -p 1234:22 \
     -e MFA_PROVIDER=google-authenticator \
     -v ~/.ssh/authorized_keys:/root/.ssh/authorized_keys
     cloudposse/bastion

Problem an der Sache ist: Wenn ich den Container beende, wird nichts persistiert. Starte ich den Container später erneut, ist die Konfiguration des 2FA natürlich verschwunden. Ich vermute, dass diese Konfiguration unter /root/ abgelegt wird. Wie kann ich jetzt dieses Verzeichnis in ein statisches Volume auslagern ohne docker-compose zu benutzen. Ich muss einen Container bauen der später bei AWS läuft und dort mounte ich dann ein Filesystem auf dem persistent die Konfig abgelegt werden soll. Aber woher soll ich wissen wohin ich das mounten muss?
 
Du musst ein Volume mit Namen separat erstellen. Pass aber auf, wenn du das in /root mountest hast du in /root nur das leere volume. Falls in /root schon dateien drin sind, sind die im container nicht mehr verfügbar.

Wo genau die config abgelegt wird, hängt vom image ab. Ich habe aber in der github repo dokumentation keine infos zu genau deinem problem gesehen.
Du kannst auch einen container einfach mal interaktiv starten und nachschauen wo ggf. config dateien liegen.

Falls das nichts bringt musst du wohl auf github ein issue wegen unzureichender dokumentation erstellen.
 
  • Gefällt mir
Reaktionen: Nore Ply und Falc410
Ja das ist genau mein Problem. Ich kann zwar ein Image erstellen aber ich weiß nicht ob ich das einfach nach /root mounten kann - dann fehlen ja Sachen wie die authorized_keys und ich kann mich nicht einloggen. Habe in der Doku nichts gefunden auch bei den Issues nicht. Die gehen wohl davon aus, dass der Container einmal gestartet wird und für immer läuft. Ich benötige den aber nur ab und zu und möchte natürlich nicht jedesmal das MFA neu einrichten müssen. :(

Also wahrscheinlich werde ich nicht drumherum kommen mir selbst etwas zu basteln
 
Volumes gibst du mit -v an. Musst halt schauen wo die Dateien abgelegt werden und entsprechend alles mounten, was vorhanden bleiben soll. Geh also in den Container (docker exec -it) und sich dir die Daten zusammen. Wenn du weißt was genutzt wird, sollten auch die Dokus der entsprechenden Tools aushelfen.

Der Container nutzt nur das google-authenticator PAM Modul. Laut Doku scheint das in ~/.google_authenticator abgelegt zu werden. Also einfach die Datei mounten und gut.

Aber tu dir einen Gefallen und lager das in eine docker-compose.yml aus.
dasbene schrieb:
Du musst ein Volume mit Namen separat erstellen.
Quark, er muss nur ne Datei mounten. Zumal Named Volumes für einzelne Dateien afaik gar nicht möglich sind.
 
  • Gefällt mir
Reaktionen: Falc410
Yuuri schrieb:
Aber tu dir einen Gefallen und lager das in eine docker-compose.yml aus.
Das bringt mir leider nichts. Ich muss einen Container bauen in gitlab-ci der dann in AWS läuft. Mit docker-compose komme ich da nicht weiter.

Ich versuche mal nur den Ordner für den google_authenticator zu mounten, die SSH Keys werde ich direkt beim bauen des Containers injecten. Dann sollte hoffentlich die MFA Konfig persistent sein.

Alternativ baue ich mir gerade meinen eigenen Container mit sshd und schaue wie ich den absichern kann. Aber dieser Bastion Host sah halt auf den ersten Blick ganz nice aus.
 
Falc410 schrieb:
Das bringt mir leider nichts. Ich muss einen Container bauen in gitlab-ci der dann in AWS läuft. Mit docker-compose komme ich da nicht weiter.
Und wo in AWS läuft der container? In einer AWS Instanz? Du kannst docker-compose wunderbar mit gitlab-ci und einem gitlab runner verbinden. Wenn man schon nicht K8S oder Fargate nutzt, sollte man zumindest compose nutzen.
 
Falc410 schrieb:
...die SSH Keys werde ich direkt beim bauen des Containers injecten.
Ähm was? Die Keys haben im Image nichts zu suchen...
 
foo_1337 schrieb:
Kommt auf den use-case an.
Trotzdem packt man solche Daten nicht fest in ein Image, sondern arbeitet mit "Docker Secrets". Dann kennt die nur der Rechner, der den Container auf Basis des Images ausführt und jeder Rechner kann seine eigenen Secrets benutzen.

Selbst die Variante, den Ordner mit den SSH-Keys in den Container zu mounten wäre noch besser als die direkt ins Image zu kopieren.
 
mibbio schrieb:
Trotzdem packt man solche Daten nicht fest in ein Image, sondern arbeitet mit "Docker Secrets". Dann kennt die nur der Rechner, der den Container auf Basis des Images ausführt.
Ich selbst nutze hashicorp vault für secrets, aber in dem Fall geht es um die public keys, die eher nicht als secret anzusehen sind. Aber YMMV.
 
foo_1337 schrieb:
Wenn man schon nicht K8S oder Fargate nutzt, sollte man zumindest compose nutzen.
Wir nutzen ECS / Fargate
dasbene schrieb:
Ähm was? Die Keys haben im Image nichts zu suchen...
Ich kann den Public Key auch als env beim start des Containers einfügen und die Keys im AWS SecretManager hinterlegen. Das wäre flexibler, dann muss ich den Container nicht jedesmal neu bauen. Das stimmt natürlich.
Allerdings ändern sich die User die sich dort einloggen müssen nicht besonders oft und ich hätte die Public Keys jetzt mit ins Repo gehauen. Gitlab baut den Container automatisch bei einer Veränderung und der Containe wird automatisch über Terraform in AWS deployed.
 
Wie man die Keys (oder sonstige sensitive Daten) sichert, ist ja erstmal zweitrangig. Der Punkt ist der, dass solche Daten erst zur Laufzeit an den Container übergeben werden sollten. Ein Image gibt man ja ggf. weiter und damit würde man auch darin enthaltene Keys weitergeben.

Auch Public Keys würde ich nicht fest in ein Image integrieren, weil ich dann ja jedes Mal das Image neu bauen müsste, wenn ich die mal ändere/austausche.
 
mibbio schrieb:
Ein Image gibt man ja ggf. weiter und damit würde man auch darin enthaltene Keys weitergeben.
Auch Public Keys würde ich nicht fest in ein Image integrieren, weil ich dann ja jedes Mal das Image neu bauen müsste, wenn ich die mal ändere/austausche.
Daher schrieb ich ja: Es kommt auf den use case an. Und je nach dem wie das Deployment aussieht, ist es auch kein großes Problem, das Image einfach neu zu bauen und zu deployen, selbst wenn sich die keys öfter mal ändern sollten (z.B. Personalwechsel).

Man könnte die keys auch komplett rauslassen und anderweitig bereitstellen und dem sshd via AuthorizedKeysCommand sagen woher er sie sich holen soll. Dann wäre man voll dynamisch, was ggf. sinn macht falls es hoch volatil sein sollte.
 
An sich schon, nur würde ich mir von Anfang an diese Trennung angewöhnen. Sonst hat man irgendwann plötzlich doch aus Gewohnheit solche Daten in einem öffentlichen Image.
 
foo_1337 schrieb:
Ich hab schon mehrere Container, z.B. für Grafana in Fargate am laufen. Dort mounte ich ein EFS z.B. nach /var/lib/grafana und dort liegt dann die Datenbank (Konfiguration) von Grafana und ist persistent. Das war relativ einfach, da der Container von Grafana genau so gebaut ist.

Das Image bei uns ist nicht public und wird garantiert nicht weitergegeben und wie gesagt, das ganze Deployment ist automatisch. Aber ja ich gebe euch natürlich recht, dass es sinnvoller ist, die Keys zur Laufzeit einzupflegen (wobei ich die dann trotzdem über Terraform in AWS im Secretsmanager ablegen müsste). Ich muss mal schauen ob ich ein so großes "Secret" beim Container Start nach authorized_keys schreiben kann. Da gibts ja sicher eine Zeichenlimitierung.
@mibbio
Wir machen in Fargate im Prinzip so etwas wie docker run -e ENV_NAME=WERT

Wie würde ich so jetzt die Keys am einfachsten in die authorized_keys bekommen? Ich hätte pauschal jetzt noch ein Script geschrieben welches die Werte ausliest und rüber kopiert. Finde ich aber auch nicht schön.

Aktuell habe ich so ein Dockerfile gebaut. Der Host soll nicht durchgehend laufen, sondern nur bei Bedarf (automatisiert) gestartet werden für "Admintätigkeiten" innerhalb der VPC und danach sofort wieder beendet werden. Was trotzdem noch fehlt ist ein SSH Audit Log -> Cloudwatch. MFA ist nice to have aber fast overkill

Code:
FROM alpine:latest

RUN apk add --no-cache --upgrade curl openssh-server mysql-client python3 \
&& ln -sf python3 /usr/bin/python
RUN python3 -m ensurepip
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
RUN ssh-keygen -A

ADD falc.pub /root/.ssh/authorized_keys

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D", "-e"]
 
Runtime: Volumes, Secrets, Environment Variables
Compile Time: Build Args

Irgendwas fix hinterlegt ist immer falsch.
Falc410 schrieb:
Wie würde ich so jetzt die Keys am einfachsten in die authorized_keys bekommen? Ich hätte pauschal jetzt noch ein Script geschrieben welches die Werte ausliest und rüber kopiert. Finde ich aber auch nicht schön.
ENTRYPOINT
 
  • Gefällt mir
Reaktionen: mibbio
Das meine ich ja, ein shellscript welches über ENTRYPOINT aufgerufen wird und als Parameter die Keys übergeben bekommt und nichts anderes mal als ein echo $param > .ssh/authorized.keys
 
Man sollte einen Container eigentlich nicht per SSH erreichbar machen. Gibt dazu eigentlich keinen Grund
 
Zurück
Oben