August-27th-2020, 04:50 PM
(This post was last modified: October-15th-2020, 08:51 AM by Armin@netPI.)
This thread is dedicated to a Docker security feature named "Docker trusted content".
In simple words: a repository and hosted containers are both trusted and signing was executed by person(s) of trust. So the whole repo authenticity is guaranteed even during image pulling time.
"Docker trusted" relies on "Notary" which is an open source project. Here is written what Notary exactly is https://docs.docker.com/notary/getting_started/.
In sum there is an extra Notary server required that runs independently of the repository server and manages alongside the trusted collection of content generated.
Here is how to deploy a Notary server. Remark: A Notary server can only be installed on AMD CPU compatible hosts - hosting on a Raspberry Pi or a netPI is not possible (I haven't found any source how to do this, maybe you?). For the test I made all the following executions were executed in a Linux Ubuntu shell:
Install some basic tools/commands:
Install the Notary client tool:
Install and run the Notary server:
Please take notice that the code contains the call to the script "regenerateTestingCerts.sh". This is executed to create own certificates and to overwrite the existing ones coming with the Notary sources. For a productive operation you should of course generate/copy keys and certificates in accordance to your companies security policy and exchange them manually with the existing ones.
Test the Notary server:
Make the notary server certificate known on the local machine.
Generate an alias for the Notary client
Pull a test image "Hello-World" we want to sign for test:
Switch Docker to trusted mode and make the Notify server address known:
Generate a trusted person as a signer and a key pair for it. Example generates the person "hilscher":
In order to test it further you need an account on public Docker Hub registry and you get back a name for your [repository]. So replace the [respository] in the code sequence below with your repositorys name
Generate a repository key (auto-generated when not available) and then add the signer "Hilscher" to this repo. Only this person can modify the repo from now on
Login to Docker hub ... enter your credentials when asked:
Push the trusted container image. The meta data is uploaded to the Notary server automatically as well:
Inspect the image
Now if someone has a trusted Docker running using the command
Tell him first how to reach your Notify server as URL like https://[URL]:4443. Then hand him over also the certificate from here /notary/fixtures/intermediate-ca.crt to make it know on the machine that pulls the images and he will be able to pull any of the trusted image from your repository.
In simple words: a repository and hosted containers are both trusted and signing was executed by person(s) of trust. So the whole repo authenticity is guaranteed even during image pulling time.
"Docker trusted" relies on "Notary" which is an open source project. Here is written what Notary exactly is https://docs.docker.com/notary/getting_started/.
In sum there is an extra Notary server required that runs independently of the repository server and manages alongside the trusted collection of content generated.
Here is how to deploy a Notary server. Remark: A Notary server can only be installed on AMD CPU compatible hosts - hosting on a Raspberry Pi or a netPI is not possible (I haven't found any source how to do this, maybe you?). For the test I made all the following executions were executed in a Linux Ubuntu shell:
Install some basic tools/commands:
Code:
apt update &&
apt install gnupg2 pass &&
# install docker
apt install -y docker-ce docker-ce-cli containerd.io &&
mkdir -p ~/.docker/trust &&
# install docker-compose
apt install -y docker-compose &&
# install go language
cd /tmp &&
wget https://golang.org/dl/go1.15.linux-amd64.tar.gz &&
tar -xvf go1.15.linux-amd64.tar.gz &&
rm -r /usr/local/go &&
mv go /usr/local &&
export GOROOT=/usr/local/go &&
export GOPATH=$HOME/go &&
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH &&
source ~/.profile &&
# install cfssl tools
go get -u github.com/cloudflare/cfssl/cmd/cfssl &&
go get -u github.com/cloudflare/cfssl/cmd/cfssljson
Install the Notary client tool:
Code:
wget --no-check-certificate -O /usr/local/bin/notary https://github.com/docker/notary/releases/download/v0.6.1/notary-Linux-amd64 && chmod a+x /usr/local/bin/notary
Install and run the Notary server:
Code:
cd / &&
git clone https://github.com/theupdateframework/notary.git &&
# generate own certificates
cd /notary/fixtures &&
./regenerateTestingCerts.sh &&
# build and start the notary server
cd /notary/ &&
docker-compose build &&
docker-compose up -d &&
sh -c 'echo "127.0.0.1 notaryserver" >> /etc/hosts'
Please take notice that the code contains the call to the script "regenerateTestingCerts.sh". This is executed to create own certificates and to overwrite the existing ones coming with the Notary sources. For a productive operation you should of course generate/copy keys and certificates in accordance to your companies security policy and exchange them manually with the existing ones.
Test the Notary server:
Code:
openssl s_client -connect notaryserver:4443 -no_ssl3
Make the notary server certificate known on the local machine.
Code:
rm -f /etc/ssl/certs/root-ca.pem &&
cp /notary/fixtures/intermediate-ca.crt /usr/local/share/ca-certificates/intermediate-ca.crt &&
update-ca-certificates
Generate an alias for the Notary client
Code:
alias notary="notary -s https://notaryserver:4443 -d ~/.docker/trust --tlscacert /usr/local/share/ca-certificates/intermediate-ca.crt"
Pull a test image "Hello-World" we want to sign for test:
Code:
docker pull hello-world:latest
Switch Docker to trusted mode and make the Notify server address known:
Code:
export DOCKER_CONTENT_TRUST=1 &&
export DOCKER_CONTENT_TRUST_SERVER=https://notaryserver:4443
Generate a trusted person as a signer and a key pair for it. Example generates the person "hilscher":
Code:
docker trust key generate hilscher --dir ~/.docker/trust
In order to test it further you need an account on public Docker Hub registry and you get back a name for your [repository]. So replace the [respository] in the code sequence below with your repositorys name
Code:
docker tag hello-world:latest [repository]/hello-world:latest
Generate a repository key (auto-generated when not available) and then add the signer "Hilscher" to this repo. Only this person can modify the repo from now on
Code:
docker trust signer add --key ~/.docker/trust/hilscher.pub hilscher [repository]/hello-world:latest
Login to Docker hub ... enter your credentials when asked:
Code:
docker login
Push the trusted container image. The meta data is uploaded to the Notary server automatically as well:
Code:
docker push [repository]/hello-world:latest
Inspect the image
Code:
docker trust inspect --pretty [repository]/hello-world:latest
Now if someone has a trusted Docker running using the command
Code:
export DOCKER_CONTENT_TRUST=1
Tell him first how to reach your Notify server as URL like https://[URL]:4443. Then hand him over also the certificate from here /notary/fixtures/intermediate-ca.crt to make it know on the machine that pulls the images and he will be able to pull any of the trusted image from your repository.
„You never fail until you stop trying.“, Albert Einstein (1879 - 1955)