Files
container.training/slides/swarm/secrets.md
Jérôme Petazzoni b56e54eaec ♻️ s/exercise/lab/
Now that we have a good number of longer exercises, it makes
sense to rename the shorter demos/labs into 'labs' to avoid
confusion between the two.
2021-12-29 17:18:07 +01:00

4.0 KiB

class: secrets

Secret management

  • Docker has a "secret safe" (secure key→value store)

  • You can create as many secrets as you like

  • You can associate secrets to services

  • Secrets are exposed as plain text files, but kept in memory only (using tmpfs)

  • Secrets are immutable (at least in Engine 1.13)

  • Secrets have a max size of 500 KB


class: secrets

Creating secrets

  • Must specify a name for the secret; and the secret itself

.lab[

]

If the secret is in a file, you can simply pass the path to the file.

(The special path - indicates to read from the standard input.)


class: secrets

Creating better secrets

  • Picking lousy passwords always leads to security breaches

.lab[

  • Let's craft a better password, and assign it to another secret:
    base64 /dev/urandom | head -c16 | docker secret create arewesecureyet -
    

]

Note: in the latter case, we don't even know the secret at this point. But Swarm does.


class: secrets

Using secrets

  • Secrets must be handed explicitly to services

.lab[

  • Create a dummy service with both secrets:
      docker service create \
             --secret hackme --secret arewesecureyet \
             --name dummyservice \
             --constraint node.hostname==$HOSTNAME \
             alpine sleep 1000000000
    

]

We constrain the container to be on the local node for convenience.
(We are going to use docker exec in just a moment!)


class: secrets

Accessing secrets

  • Secrets are materialized on /run/secrets (which is an in-memory filesystem)

.lab[

  • Find the ID of the container for the dummy service:

    CID=$(docker ps -q --filter label=com.docker.swarm.service.name=dummyservice)
    
  • Enter the container:

    docker exec -ti $CID sh
    
  • Check the files in /run/secrets

]


class: secrets

Rotating secrets

  • You can't change a secret

    (Sounds annoying at first; but allows clean rollbacks if a secret update goes wrong)

  • You can add a secret to a service with docker service update --secret-add

    (This will redeploy the service; it won't add the secret on the fly)

  • You can remove a secret with docker service update --secret-rm

  • Secrets can be mapped to different names by expressing them with a micro-format:

    docker service create --secret source=secretname,target=filename
    

class: secrets

Changing our insecure password

  • We want to replace our hackme secret with a better one

.lab[

  • Remove the insecure hackme secret:

    docker service update dummyservice --secret-rm hackme
    
  • Add our better secret instead:

    docker service update dummyservice \
           --secret-add source=arewesecureyet,target=hackme
    

]

Wait for the service to be fully updated with e.g. watch docker service ps dummyservice.
(With Docker Engine 17.10 and later, the CLI will wait for you!)


class: secrets

Checking that our password is now stronger

  • We will use the power of docker exec!

.lab[

  • Get the ID of the new container:

    CID=$(docker ps -q --filter label=com.docker.swarm.service.name=dummyservice)
    
  • Check the contents of the secret files:

    docker exec $CID grep -r . /run/secrets
    

]


class: secrets

Secrets in practice

  • Can be (ab)used to hold whole configuration files if needed

  • If you intend to rotate secret foo, call it foo.N instead, and map it to foo

    (N can be a serial, a timestamp...)

    docker service create --secret source=foo.N,target=foo ...
    
  • You can update (remove+add) a secret in a single command:

    docker service update ... --secret-rm foo.M --secret-add source=foo.N,target=foo
    
  • For more details and examples, check the documentation