Initial commit
This commit is contained in:
183
vendor/github.com/hyperhq/hypercli/docs/security/apparmor.md
generated
vendored
Normal file
183
vendor/github.com/hyperhq/hypercli/docs/security/apparmor.md
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
<!-- [metadata]>
|
||||
+++
|
||||
title = "AppArmor security profiles for Docker"
|
||||
description = "Enabling AppArmor in Docker"
|
||||
keywords = ["AppArmor, security, docker, documentation"]
|
||||
[menu.main]
|
||||
parent= "smn_secure_docker"
|
||||
weight=5
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# AppArmor security profiles for Docker
|
||||
|
||||
AppArmor (Application Armor) is a Linux security module that protects an
|
||||
operating system and its applications from security threats. To use it, a system
|
||||
administrator associates an AppArmor security profile with each program. Docker
|
||||
expects to find an AppArmor policy loaded and enforced.
|
||||
|
||||
Docker automatically loads container profiles. The Docker binary installs
|
||||
a `docker-default` profile in the `/etc/apparmor.d/docker` file. This profile
|
||||
is used on containers, _not_ on the Docker Daemon.
|
||||
|
||||
A profile for the Docker Engine Daemon exists but it is not currently installed
|
||||
with the deb packages. If you are interested in the source for the Daemon
|
||||
profile, it is located in
|
||||
[contrib/apparmor](https://github.com/docker/docker/tree/master/contrib/apparmor)
|
||||
in the Docker Engine source repository.
|
||||
|
||||
## Understand the policies
|
||||
|
||||
The `docker-default` profile is the default for running containers. It is
|
||||
moderately protective while providing wide application compatibility. The
|
||||
profile is the following:
|
||||
|
||||
```
|
||||
#include <tunables/global>
|
||||
|
||||
|
||||
profile docker-default flags=(attach_disconnected,mediate_deleted) {
|
||||
|
||||
#include <abstractions/base>
|
||||
|
||||
|
||||
network,
|
||||
capability,
|
||||
file,
|
||||
umount,
|
||||
|
||||
deny @{PROC}/{*,**^[0-9*],sys/kernel/shm*} wkx,
|
||||
deny @{PROC}/sysrq-trigger rwklx,
|
||||
deny @{PROC}/mem rwklx,
|
||||
deny @{PROC}/kmem rwklx,
|
||||
deny @{PROC}/kcore rwklx,
|
||||
|
||||
deny mount,
|
||||
|
||||
deny /sys/[^f]*/** wklx,
|
||||
deny /sys/f[^s]*/** wklx,
|
||||
deny /sys/fs/[^c]*/** wklx,
|
||||
deny /sys/fs/c[^g]*/** wklx,
|
||||
deny /sys/fs/cg[^r]*/** wklx,
|
||||
deny /sys/firmware/efi/efivars/** rwklx,
|
||||
deny /sys/kernel/security/** rwklx,
|
||||
}
|
||||
```
|
||||
|
||||
When you run a container, it uses the `docker-default` policy unless you
|
||||
override it with the `security-opt` option. For example, the following
|
||||
explicitly specifies the default policy:
|
||||
|
||||
```bash
|
||||
$ docker run --rm -it --security-opt apparmor:docker-default hello-world
|
||||
```
|
||||
|
||||
## Loading and Unloading Profiles
|
||||
|
||||
To load a new profile into AppArmor, for use with containers:
|
||||
|
||||
```
|
||||
$ apparmor_parser -r -W /path/to/your_profile
|
||||
```
|
||||
|
||||
Then you can run the custom profile with `--security-opt` like so:
|
||||
|
||||
```bash
|
||||
$ docker run --rm -it --security-opt apparmor:your_profile hello-world
|
||||
```
|
||||
|
||||
To unload a profile from AppArmor:
|
||||
|
||||
```bash
|
||||
# stop apparmor
|
||||
$ /etc/init.d/apparmor stop
|
||||
# unload the profile
|
||||
$ apparmor_parser -R /path/to/profile
|
||||
# start apparmor
|
||||
$ /etc/init.d/apparmor start
|
||||
```
|
||||
|
||||
## Debugging AppArmor
|
||||
|
||||
### Using `dmesg`
|
||||
|
||||
Here are some helpful tips for debugging any problems you might be facing with
|
||||
regard to AppArmor.
|
||||
|
||||
AppArmor sends quite verbose messaging to `dmesg`. Usually an AppArmor line
|
||||
will look like the following:
|
||||
|
||||
```
|
||||
[ 5442.864673] audit: type=1400 audit(1453830992.845:37): apparmor="ALLOWED" operation="open" profile="/usr/bin/docker" name="/home/jessie/docker/man/man1/docker-attach.1" pid=10923 comm="docker" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
|
||||
```
|
||||
|
||||
In the above example, the you can see `profile=/usr/bin/docker`. This means the
|
||||
user has the `docker-engine` (Docker Engine Daemon) profile loaded.
|
||||
|
||||
> **Note:** On version of Ubuntu > 14.04 this is all fine and well, but Trusty
|
||||
> users might run into some issues when trying to `docker exec`.
|
||||
|
||||
Let's look at another log line:
|
||||
|
||||
```
|
||||
[ 3256.689120] type=1400 audit(1405454041.341:73): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=17651 comm="docker" requested_mask="receive" denied_mask="receive"
|
||||
```
|
||||
|
||||
This time the profile is `docker-default`, which is run on containers by
|
||||
default unless in `privileged` mode. It is telling us, that apparmor has denied
|
||||
`ptrace` in the container. This is great.
|
||||
|
||||
### Using `aa-status`
|
||||
|
||||
If you need to check which profiles are loaded you can use `aa-status`. The
|
||||
output looks like:
|
||||
|
||||
```bash
|
||||
$ sudo aa-status
|
||||
apparmor module is loaded.
|
||||
14 profiles are loaded.
|
||||
1 profiles are in enforce mode.
|
||||
docker-default
|
||||
13 profiles are in complain mode.
|
||||
/usr/bin/docker
|
||||
/usr/bin/docker///bin/cat
|
||||
/usr/bin/docker///bin/ps
|
||||
/usr/bin/docker///sbin/apparmor_parser
|
||||
/usr/bin/docker///sbin/auplink
|
||||
/usr/bin/docker///sbin/blkid
|
||||
/usr/bin/docker///sbin/iptables
|
||||
/usr/bin/docker///sbin/mke2fs
|
||||
/usr/bin/docker///sbin/modprobe
|
||||
/usr/bin/docker///sbin/tune2fs
|
||||
/usr/bin/docker///sbin/xtables-multi
|
||||
/usr/bin/docker///sbin/zfs
|
||||
/usr/bin/docker///usr/bin/xz
|
||||
38 processes have profiles defined.
|
||||
37 processes are in enforce mode.
|
||||
docker-default (6044)
|
||||
...
|
||||
docker-default (31899)
|
||||
1 processes are in complain mode.
|
||||
/usr/bin/docker (29756)
|
||||
0 processes are unconfined but have a profile defined.
|
||||
```
|
||||
|
||||
In the above output you can tell that the `docker-default` profile running on
|
||||
various container PIDs is in `enforce` mode. This means AppArmor will actively
|
||||
block and audit in `dmesg` anything outside the bounds of the `docker-default`
|
||||
profile.
|
||||
|
||||
The output above also shows the `/usr/bin/docker` (Docker Engine Daemon)
|
||||
profile is running in `complain` mode. This means AppArmor will _only_ log to
|
||||
`dmesg` activity outside the bounds of the profile. (Except in the case of
|
||||
Ubuntu Trusty, where we have seen some interesting behaviors being enforced.)
|
||||
|
||||
## Contributing to AppArmor code in Docker
|
||||
|
||||
Advanced users and package managers can find a profile for `/usr/bin/docker`
|
||||
(Docker Engine Daemon) underneath
|
||||
[contrib/apparmor](https://github.com/docker/docker/tree/master/contrib/apparmor)
|
||||
in the Docker Engine source repository.
|
||||
|
||||
The `docker-default` profile for containers lives in
|
||||
[profiles/apparmor](https://github.com/docker/docker/tree/master/profiles/apparmor).
|
||||
85
vendor/github.com/hyperhq/hypercli/docs/security/certificates.md
generated
vendored
Normal file
85
vendor/github.com/hyperhq/hypercli/docs/security/certificates.md
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
aliases = ["/engine/articles/certificates/"]
|
||||
title = "Using certificates for repository client verification"
|
||||
description = "How to set up and use certificates with a registry to verify access"
|
||||
keywords = ["Usage, registry, repository, client, root, certificate, docker, apache, ssl, tls, documentation, examples, articles, tutorials"]
|
||||
[menu.main]
|
||||
parent = "smn_secure_docker"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Using certificates for repository client verification
|
||||
|
||||
In [Running Docker with HTTPS](https.md), you learned that, by default,
|
||||
Docker runs via a non-networked Unix socket and TLS must be enabled in order
|
||||
to have the Docker client and the daemon communicate securely over HTTPS. TLS ensures authenticity of the registry endpoint and that traffic to/from registry is encrypted.
|
||||
|
||||
This article demonstrates how to ensure the traffic between the Docker registry (i.e., *a server*) and the Docker daemon (i.e., *a client*) traffic is encrypted and a properly authenticated using *certificate-based client-server authentication*.
|
||||
|
||||
We will show you how to install a Certificate Authority (CA) root certificate
|
||||
for the registry and how to set the client TLS certificate for verification.
|
||||
|
||||
## Understanding the configuration
|
||||
|
||||
A custom certificate is configured by creating a directory under
|
||||
`/etc/docker/certs.d` using the same name as the registry's hostname (e.g.,
|
||||
`localhost`). All `*.crt` files are added to this directory as CA roots.
|
||||
|
||||
> **Note:**
|
||||
> In the absence of any root certificate authorities, Docker
|
||||
> will use the system default (i.e., host's root CA set).
|
||||
|
||||
The presence of one or more `<filename>.key/cert` pairs indicates to Docker
|
||||
that there are custom certificates required for access to the desired
|
||||
repository.
|
||||
|
||||
> **Note:**
|
||||
> If there are multiple certificates, each will be tried in alphabetical
|
||||
> order. If there is an authentication error (e.g., 403, 404, 5xx, etc.), Docker
|
||||
> will continue to try with the next certificate.
|
||||
|
||||
The following illustrates a configuration with multiple certs:
|
||||
|
||||
```
|
||||
/etc/docker/certs.d/ <-- Certificate directory
|
||||
└── localhost <-- Hostname
|
||||
├── client.cert <-- Client certificate
|
||||
├── client.key <-- Client key
|
||||
└── localhost.crt <-- Certificate authority that signed
|
||||
the registry certificate
|
||||
```
|
||||
|
||||
The preceding example is operating-system specific and is for illustrative
|
||||
purposes only. You should consult your operating system documentation for
|
||||
creating an os-provided bundled certificate chain.
|
||||
|
||||
|
||||
## Creating the client certificates
|
||||
|
||||
You will use OpenSSL's `genrsa` and `req` commands to first generate an RSA
|
||||
key and then use the key to create the certificate.
|
||||
|
||||
$ openssl genrsa -out client.key 4096
|
||||
$ openssl req -new -x509 -text -key client.key -out client.cert
|
||||
|
||||
> **Note:**
|
||||
> These TLS commands will only generate a working set of certificates on Linux.
|
||||
> The version of OpenSSL in Mac OS X is incompatible with the type of
|
||||
> certificate Docker requires.
|
||||
|
||||
## Troubleshooting tips
|
||||
|
||||
The Docker daemon interprets ``.crt` files as CA certificates and `.cert` files
|
||||
as client certificates. If a CA certificate is accidentally given the extension
|
||||
`.cert` instead of the correct `.crt` extension, the Docker daemon logs the
|
||||
following error message:
|
||||
|
||||
```
|
||||
Missing key KEY_NAME for client certificate CERT_NAME. Note that CA certificates should use the extension .crt.
|
||||
```
|
||||
|
||||
## Related Information
|
||||
|
||||
* [Use trusted images](index.md)
|
||||
* [Protect the Docker daemon socket](https.md)
|
||||
216
vendor/github.com/hyperhq/hypercli/docs/security/https.md
generated
vendored
Normal file
216
vendor/github.com/hyperhq/hypercli/docs/security/https.md
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
aliases = ["/engine/articles/https/"]
|
||||
title = "Protect the Docker daemon socket"
|
||||
description = "How to setup and run Docker with HTTPS"
|
||||
keywords = ["docker, docs, article, example, https, daemon, tls, ca, certificate"]
|
||||
[menu.main]
|
||||
parent = "smn_secure_docker"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Protect the Docker daemon socket
|
||||
|
||||
By default, Docker runs via a non-networked Unix socket. It can also
|
||||
optionally communicate using a HTTP socket.
|
||||
|
||||
If you need Docker to be reachable via the network in a safe manner, you can
|
||||
enable TLS by specifying the `tlsverify` flag and pointing Docker's
|
||||
`tlscacert` flag to a trusted CA certificate.
|
||||
|
||||
In the daemon mode, it will only allow connections from clients
|
||||
authenticated by a certificate signed by that CA. In the client mode,
|
||||
it will only connect to servers with a certificate signed by that CA.
|
||||
|
||||
> **Warning**:
|
||||
> Using TLS and managing a CA is an advanced topic. Please familiarize yourself
|
||||
> with OpenSSL, x509 and TLS before using it in production.
|
||||
|
||||
> **Warning**:
|
||||
> These TLS commands will only generate a working set of certificates on Linux.
|
||||
> Mac OS X comes with a version of OpenSSL that is incompatible with the
|
||||
> certificates that Docker requires.
|
||||
|
||||
## Create a CA, server and client keys with OpenSSL
|
||||
|
||||
> **Note**: replace all instances of `$HOST` in the following example with the
|
||||
> DNS name of your Docker daemon's host.
|
||||
|
||||
First generate CA private and public keys:
|
||||
|
||||
$ openssl genrsa -aes256 -out ca-key.pem 4096
|
||||
Generating RSA private key, 4096 bit long modulus
|
||||
............................................................................................................................................................................................++
|
||||
........++
|
||||
e is 65537 (0x10001)
|
||||
Enter pass phrase for ca-key.pem:
|
||||
Verifying - Enter pass phrase for ca-key.pem:
|
||||
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
|
||||
Enter pass phrase for ca-key.pem:
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [AU]:
|
||||
State or Province Name (full name) [Some-State]:Queensland
|
||||
Locality Name (eg, city) []:Brisbane
|
||||
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
|
||||
Organizational Unit Name (eg, section) []:Sales
|
||||
Common Name (e.g. server FQDN or YOUR name) []:$HOST
|
||||
Email Address []:Sven@home.org.au
|
||||
|
||||
Now that we have a CA, you can create a server key and certificate
|
||||
signing request (CSR). Make sure that "Common Name" (i.e., server FQDN or YOUR
|
||||
name) matches the hostname you will use to connect to Docker:
|
||||
|
||||
> **Note**: replace all instances of `$HOST` in the following example with the
|
||||
> DNS name of your Docker daemon's host.
|
||||
|
||||
$ openssl genrsa -out server-key.pem 4096
|
||||
Generating RSA private key, 4096 bit long modulus
|
||||
.....................................................................++
|
||||
.................................................................................................++
|
||||
e is 65537 (0x10001)
|
||||
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
|
||||
|
||||
Next, we're going to sign the public key with our CA:
|
||||
|
||||
Since TLS connections can be made via IP address as well as DNS name, they need
|
||||
to be specified when creating the certificate. For example, to allow connections
|
||||
using `10.10.10.20` and `127.0.0.1`:
|
||||
|
||||
$ echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
|
||||
|
||||
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
|
||||
Signature ok
|
||||
subject=/CN=your.host.com
|
||||
Getting CA Private Key
|
||||
Enter pass phrase for ca-key.pem:
|
||||
|
||||
For client authentication, create a client key and certificate signing
|
||||
request:
|
||||
|
||||
$ openssl genrsa -out key.pem 4096
|
||||
Generating RSA private key, 4096 bit long modulus
|
||||
.........................................................++
|
||||
................++
|
||||
e is 65537 (0x10001)
|
||||
$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
|
||||
|
||||
To make the key suitable for client authentication, create an extensions
|
||||
config file:
|
||||
|
||||
$ echo extendedKeyUsage = clientAuth > extfile.cnf
|
||||
|
||||
Now sign the public key:
|
||||
|
||||
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-CAcreateserial -out cert.pem -extfile extfile.cnf
|
||||
Signature ok
|
||||
subject=/CN=client
|
||||
Getting CA Private Key
|
||||
Enter pass phrase for ca-key.pem:
|
||||
|
||||
After generating `cert.pem` and `server-cert.pem` you can safely remove the
|
||||
two certificate signing requests:
|
||||
|
||||
$ rm -v client.csr server.csr
|
||||
|
||||
With a default `umask` of 022, your secret keys will be *world-readable* and
|
||||
writable for you and your group.
|
||||
|
||||
In order to protect your keys from accidental damage, you will want to remove their
|
||||
write permissions. To make them only readable by you, change file modes as follows:
|
||||
|
||||
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
|
||||
|
||||
Certificates can be world-readable, but you might want to remove write access to
|
||||
prevent accidental damage:
|
||||
|
||||
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
|
||||
|
||||
Now you can make the Docker daemon only accept connections from clients
|
||||
providing a certificate trusted by our CA:
|
||||
|
||||
$ docker daemon --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
|
||||
-H=0.0.0.0:2376
|
||||
|
||||
To be able to connect to Docker and validate its certificate, you now
|
||||
need to provide your client keys, certificates and trusted CA:
|
||||
|
||||
> **Note**: replace all instances of `$HOST` in the following example with the
|
||||
> DNS name of your Docker daemon's host.
|
||||
|
||||
$ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
|
||||
-H=$HOST:2376 version
|
||||
|
||||
> **Note**:
|
||||
> Docker over TLS should run on TCP port 2376.
|
||||
|
||||
> **Warning**:
|
||||
> As shown in the example above, you don't have to run the `docker` client
|
||||
> with `sudo` or the `docker` group when you use certificate authentication.
|
||||
> That means anyone with the keys can give any instructions to your Docker
|
||||
> daemon, giving them root access to the machine hosting the daemon. Guard
|
||||
> these keys as you would a root password!
|
||||
|
||||
## Secure by default
|
||||
|
||||
If you want to secure your Docker client connections by default, you can move
|
||||
the files to the `.docker` directory in your home directory -- and set the
|
||||
`DOCKER_HOST` and `DOCKER_TLS_VERIFY` variables as well (instead of passing
|
||||
`-H=tcp://$HOST:2376` and `--tlsverify` on every call).
|
||||
|
||||
$ mkdir -pv ~/.docker
|
||||
$ cp -v {ca,cert,key}.pem ~/.docker
|
||||
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
|
||||
|
||||
Docker will now connect securely by default:
|
||||
|
||||
$ docker ps
|
||||
|
||||
## Other modes
|
||||
|
||||
If you don't want to have complete two-way authentication, you can run
|
||||
Docker in various other modes by mixing the flags.
|
||||
|
||||
### Daemon modes
|
||||
|
||||
- `tlsverify`, `tlscacert`, `tlscert`, `tlskey` set: Authenticate clients
|
||||
- `tls`, `tlscert`, `tlskey`: Do not authenticate clients
|
||||
|
||||
### Client modes
|
||||
|
||||
- `tls`: Authenticate server based on public/default CA pool
|
||||
- `tlsverify`, `tlscacert`: Authenticate server based on given CA
|
||||
- `tls`, `tlscert`, `tlskey`: Authenticate with client certificate, do not
|
||||
authenticate server based on given CA
|
||||
- `tlsverify`, `tlscacert`, `tlscert`, `tlskey`: Authenticate with client
|
||||
certificate and authenticate server based on given CA
|
||||
|
||||
If found, the client will send its client certificate, so you just need
|
||||
to drop your keys into `~/.docker/{ca,cert,key}.pem`. Alternatively,
|
||||
if you want to store your keys in another location, you can specify that
|
||||
location using the environment variable `DOCKER_CERT_PATH`.
|
||||
|
||||
$ export DOCKER_CERT_PATH=~/.docker/zone1/
|
||||
$ docker --tlsverify ps
|
||||
|
||||
### Connecting to the secure Docker port using `curl`
|
||||
|
||||
To use `curl` to make test API requests, you need to use three extra command line
|
||||
flags:
|
||||
|
||||
$ curl https://$HOST:2376/images/json \
|
||||
--cert ~/.docker/cert.pem \
|
||||
--key ~/.docker/key.pem \
|
||||
--cacert ~/.docker/ca.pem
|
||||
|
||||
## Related information
|
||||
|
||||
* [Using certificates for repository client verification](certificates.md)
|
||||
* [Use trusted images](trust/index.md)
|
||||
10
vendor/github.com/hyperhq/hypercli/docs/security/https/Dockerfile
generated
vendored
Normal file
10
vendor/github.com/hyperhq/hypercli/docs/security/https/Dockerfile
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM debian
|
||||
|
||||
RUN apt-get update && apt-get install -yq openssl
|
||||
|
||||
ADD make_certs.sh /
|
||||
|
||||
|
||||
WORKDIR /data
|
||||
VOLUME ["/data"]
|
||||
CMD /make_certs.sh
|
||||
24
vendor/github.com/hyperhq/hypercli/docs/security/https/Makefile
generated
vendored
Normal file
24
vendor/github.com/hyperhq/hypercli/docs/security/https/Makefile
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
HOST:=boot2docker
|
||||
|
||||
makescript:
|
||||
./parsedocs.sh > make_certs.sh
|
||||
|
||||
build: clean makescript
|
||||
docker build -t makecerts .
|
||||
|
||||
cert: build
|
||||
docker run --rm -it -v $(CURDIR):/data -e HOST=$(HOST) -e YOUR_PUBLIC_IP=$(shell ip a | grep "inet " | sed "s/.*inet \([0-9.]*\)\/.*/\1/" | xargs echo | sed "s/ /,IP:/g") makecerts
|
||||
|
||||
certs: cert
|
||||
|
||||
run:
|
||||
sudo docker daemon -D --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:6666 --pidfile=$(pwd)/docker.pid --graph=$(pwd)/graph
|
||||
|
||||
client:
|
||||
sudo docker --tls --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=$(HOST):6666 version
|
||||
sudo docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=$(HOST):6666 info
|
||||
sudo curl https://$(HOST):6666/images/json --cert ./cert.pem --key ./key.pem --cacert ./ca.pem
|
||||
|
||||
clean:
|
||||
rm -f ca-key.pem ca.pem ca.srl cert.pem client.csr extfile.cnf key.pem server-cert.pem server-key.pem server.csr extfile.cnf
|
||||
32
vendor/github.com/hyperhq/hypercli/docs/security/https/README.md
generated
vendored
Normal file
32
vendor/github.com/hyperhq/hypercli/docs/security/https/README.md
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
draft = true
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
|
||||
|
||||
This is an initial attempt to make it easier to test the examples in the https.md
|
||||
doc
|
||||
|
||||
at this point, it has to be a manual thing, and I've been running it in boot2docker
|
||||
|
||||
so my process is
|
||||
|
||||
$ boot2docker ssh
|
||||
$$ git clone https://github.com/docker/docker
|
||||
$$ cd docker/docs/articles/https
|
||||
$$ make cert
|
||||
lots of things to see and manually answer, as openssl wants to be interactive
|
||||
**NOTE:** make sure you enter the hostname (`boot2docker` in my case) when prompted for `Computer Name`)
|
||||
$$ sudo make run
|
||||
|
||||
start another terminal
|
||||
|
||||
$ boot2docker ssh
|
||||
$$ cd docker/docs/articles/https
|
||||
$$ make client
|
||||
|
||||
the last will connect first with `--tls` and then with `--tlsverify`
|
||||
|
||||
both should succeed
|
||||
23
vendor/github.com/hyperhq/hypercli/docs/security/https/make_certs.sh
generated
vendored
Executable file
23
vendor/github.com/hyperhq/hypercli/docs/security/https/make_certs.sh
generated
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
openssl genrsa -aes256 -out ca-key.pem 2048
|
||||
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
|
||||
openssl genrsa -out server-key.pem 2048
|
||||
openssl req -subj "/CN=$HOST" -new -key server-key.pem -out server.csr
|
||||
echo subjectAltName = IP:$YOUR_PUBLIC_IP > extfile.cnf
|
||||
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
|
||||
openssl genrsa -out key.pem 2048
|
||||
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
|
||||
echo extendedKeyUsage = clientAuth > extfile.cnf
|
||||
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
|
||||
rm -v client.csr server.csr
|
||||
chmod -v 0400 ca-key.pem key.pem server-key.pem
|
||||
chmod -v 0444 ca.pem server-cert.pem cert.pem
|
||||
# docker -d --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:7778
|
||||
# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=$HOST:7778 version
|
||||
mkdir -pv ~/.docker
|
||||
cp -v {ca,cert,key}.pem ~/.docker
|
||||
export DOCKER_HOST=tcp://$HOST:7778 DOCKER_TLS_VERIFY=1
|
||||
# docker ps
|
||||
export DOCKER_CERT_PATH=~/.docker/zone1/
|
||||
# docker --tlsverify ps
|
||||
# curl https://$HOST:7778/images/json --cert ~/.docker/cert.pem --key ~/.docker/key.pem --cacert ~/.docker/ca.pem
|
||||
10
vendor/github.com/hyperhq/hypercli/docs/security/https/parsedocs.sh
generated
vendored
Executable file
10
vendor/github.com/hyperhq/hypercli/docs/security/https/parsedocs.sh
generated
vendored
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "#!/bin/sh"
|
||||
cat ../https.md | awk '{if (sub(/\\$/,"")) printf "%s", $0; else print $0}' \
|
||||
| grep ' $ ' \
|
||||
| sed 's/ $ //g' \
|
||||
| sed 's/2375/7777/g' \
|
||||
| sed 's/2376/7778/g' \
|
||||
| sed 's/^docker/# docker/g' \
|
||||
| sed 's/^curl/# curl/g'
|
||||
24
vendor/github.com/hyperhq/hypercli/docs/security/index.md
generated
vendored
Normal file
24
vendor/github.com/hyperhq/hypercli/docs/security/index.md
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<!-- [metadata]>
|
||||
+++
|
||||
title = "Secure Engine"
|
||||
description = "Sec"
|
||||
keywords = ["seccomp, security, docker, documentation"]
|
||||
[menu.main]
|
||||
identifier="smn_secure_docker"
|
||||
parent= "engine_use"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Secure Engine
|
||||
|
||||
This section discusses the security features you can configure and use within your Docker Engine installation.
|
||||
|
||||
* You can configure Docker's trust features so that your users can push and pull trusted images. To learn how to do this, see [Use trusted images](trust/index.md) in this section.
|
||||
|
||||
* You can protect the Docker daemon socket and ensure only trusted Docker client connections. For more information, [Protect the Docker daemon socket](https.md)
|
||||
|
||||
* You can use certificate-based client-server authentication to verify a Docker daemon has the rights to access images on a registry. For more information, see [Using certificates for repository client verification](certificates.md).
|
||||
|
||||
* You can configure secure computing mode (Seccomp) policies to secure system calls in a container. For more information, see [Seccomp security profiles for Docker](seccomp.md).
|
||||
|
||||
* An AppArmor profile for Docker is installed with the official *.deb* packages. For information about this profile and overriding it, see [AppArmor security profiles for Docker](apparmor.md).
|
||||
139
vendor/github.com/hyperhq/hypercli/docs/security/seccomp.md
generated
vendored
Normal file
139
vendor/github.com/hyperhq/hypercli/docs/security/seccomp.md
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<!-- [metadata]>
|
||||
+++
|
||||
title = "Seccomp security profiles for Docker"
|
||||
description = "Enabling seccomp in Docker"
|
||||
keywords = ["seccomp, security, docker, documentation"]
|
||||
[menu.main]
|
||||
parent= "smn_secure_docker"
|
||||
weight=90
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Seccomp security profiles for Docker
|
||||
|
||||
Secure computing mode (Seccomp) is a Linux kernel feature. You can use it to
|
||||
restrict the actions available within the container. The `seccomp()` system
|
||||
call operates on the seccomp state of the calling process. You can use this
|
||||
feature to restrict your application's access.
|
||||
|
||||
This feature is available only if the kernel is configured with `CONFIG_SECCOMP`
|
||||
enabled.
|
||||
|
||||
## Passing a profile for a container
|
||||
|
||||
The default seccomp profile provides a sane default for running containers with
|
||||
seccomp. It is moderately protective while providing wide application
|
||||
compatibility. The default Docker profile has layout in the following form:
|
||||
|
||||
```
|
||||
{
|
||||
"defaultAction": "SCMP_ACT_ALLOW",
|
||||
"syscalls": [
|
||||
{
|
||||
"name": "getcwd",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
},
|
||||
{
|
||||
"name": "mount",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
},
|
||||
{
|
||||
"name": "setns",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
},
|
||||
{
|
||||
"name": "create_module",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
},
|
||||
{
|
||||
"name": "chown",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
},
|
||||
{
|
||||
"name": "chmod",
|
||||
"action": "SCMP_ACT_ERRNO"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When you run a container, it uses the default profile unless you override
|
||||
it with the `security-opt` option. For example, the following explicitly
|
||||
specifies the default policy:
|
||||
|
||||
```
|
||||
$ docker run --rm -it --security-opt seccomp:/path/to/seccomp/profile.json hello-world
|
||||
```
|
||||
|
||||
### Syscalls blocked by the default profile
|
||||
|
||||
Docker's default seccomp profile is a whitelist which specifies the calls that
|
||||
are allowed. The table below lists the significant (but not all) syscalls that
|
||||
are effectively blocked because they are not on the whitelist. The table includes
|
||||
the reason each syscall is blocked rather than white-listed.
|
||||
|
||||
| Syscall | Description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `acct` | Accounting syscall which could let containers disable their own resource limits or process accounting. Also gated by `CAP_SYS_PACCT`. |
|
||||
| `add_key` | Prevent containers from using the kernel keyring, which is not namespaced. |
|
||||
| `adjtimex` | Similar to `clock_settime` and `settimeofday`, time/date is not namespaced. |
|
||||
| `bpf` | Deny loading potentially persistent bpf programs into kernel, already gated by `CAP_SYS_ADMIN`. |
|
||||
| `clock_adjtime` | Time/date is not namespaced. |
|
||||
| `clock_settime` | Time/date is not namespaced. |
|
||||
| `clone` | Deny cloning new namespaces. Also gated by `CAP_SYS_ADMIN` for CLONE_* flags, except `CLONE_USERNS`. |
|
||||
| `create_module` | Deny manipulation and functions on kernel modules. |
|
||||
| `delete_module` | Deny manipulation and functions on kernel modules. Also gated by `CAP_SYS_MODULE`. |
|
||||
| `finit_module` | Deny manipulation and functions on kernel modules. Also gated by `CAP_SYS_MODULE`. |
|
||||
| `get_kernel_syms` | Deny retrieval of exported kernel and module symbols. |
|
||||
| `get_mempolicy` | Syscall that modifies kernel memory and NUMA settings. Already gated by `CAP_SYS_NICE`. |
|
||||
| `init_module` | Deny manipulation and functions on kernel modules. Also gated by `CAP_SYS_MODULE`. |
|
||||
| `ioperm` | Prevent containers from modifying kernel I/O privilege levels. Already gated by `CAP_SYS_RAWIO`. |
|
||||
| `iopl` | Prevent containers from modifying kernel I/O privilege levels. Already gated by `CAP_SYS_RAWIO`. |
|
||||
| `kcmp` | Restrict process inspection capabilities, already blocked by dropping `CAP_PTRACE`. |
|
||||
| `kexec_file_load` | Sister syscall of `kexec_load` that does the same thing, slightly different arguments. |
|
||||
| `kexec_load` | Deny loading a new kernel for later execution. |
|
||||
| `keyctl` | Prevent containers from using the kernel keyring, which is not namespaced. |
|
||||
| `lookup_dcookie` | Tracing/profiling syscall, which could leak a lot of information on the host. |
|
||||
| `mbind` | Syscall that modifies kernel memory and NUMA settings. Already gated by `CAP_SYS_NICE`. |
|
||||
| `modify_ldt` | Old syscall only used in 16-bit code and a potential information leak. |
|
||||
| `mount` | Deny mounting, already gated by `CAP_SYS_ADMIN`. |
|
||||
| `move_pages` | Syscall that modifies kernel memory and NUMA settings. |
|
||||
| `name_to_handle_at` | Sister syscall to `open_by_handle_at`. Already gated by `CAP_SYS_NICE`. |
|
||||
| `nfsservctl` | Deny interaction with the kernel nfs daemon. |
|
||||
| `open_by_handle_at` | Cause of an old container breakout. Also gated by `CAP_DAC_READ_SEARCH`. |
|
||||
| `perf_event_open` | Tracing/profiling syscall, which could leak a lot of information on the host. |
|
||||
| `personality` | Prevent container from enabling BSD emulation. Not inherently dangerous, but poorly tested, potential for a lot of kernel vulns. |
|
||||
| `pivot_root` | Deny `pivot_root`, should be privileged operation. |
|
||||
| `process_vm_readv` | Restrict process inspection capabilities, already blocked by dropping `CAP_PTRACE`. |
|
||||
| `process_vm_writev` | Restrict process inspection capabilities, already blocked by dropping `CAP_PTRACE`. |
|
||||
| `ptrace` | Tracing/profiling syscall, which could leak a lot of information on the host. Already blocked by dropping `CAP_PTRACE`. |
|
||||
| `query_module` | Deny manipulation and functions on kernel modules. |
|
||||
| `quotactl` | Quota syscall which could let containers disable their own resource limits or process accounting. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `reboot` | Don't let containers reboot the host. Also gated by `CAP_SYS_BOOT`. |
|
||||
| `restart_syscall` | Don't allow containers to restart a syscall. Possible seccomp bypass see: https://code.google.com/p/chromium/issues/detail?id=408827. |
|
||||
| `request_key` | Prevent containers from using the kernel keyring, which is not namespaced. |
|
||||
| `set_mempolicy` | Syscall that modifies kernel memory and NUMA settings. Already gated by `CAP_SYS_NICE`. |
|
||||
| `setns` | Deny associating a thread with a namespace. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `settimeofday` | Time/date is not namespaced. Also gated by `CAP_SYS_TIME`. |
|
||||
| `stime` | Time/date is not namespaced. Also gated by `CAP_SYS_TIME`. |
|
||||
| `swapon` | Deny start/stop swapping to file/device. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `swapoff` | Deny start/stop swapping to file/device. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `sysfs` | Obsolete syscall. |
|
||||
| `_sysctl` | Obsolete, replaced by /proc/sys. |
|
||||
| `umount` | Should be a privileged operation. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `umount2` | Should be a privileged operation. |
|
||||
| `unshare` | Deny cloning new namespaces for processes. Also gated by `CAP_SYS_ADMIN`, with the exception of `unshare --user`. |
|
||||
| `uselib` | Older syscall related to shared libraries, unused for a long time. |
|
||||
| `ustat` | Obsolete syscall. |
|
||||
| `vm86` | In kernel x86 real mode virtual machine. Also gated by `CAP_SYS_ADMIN`. |
|
||||
| `vm86old` | In kernel x86 real mode virtual machine. Also gated by `CAP_SYS_ADMIN`. |
|
||||
|
||||
## Run without the default seccomp profile
|
||||
|
||||
You can pass `unconfined` to run a container without the default seccomp
|
||||
profile.
|
||||
|
||||
```
|
||||
$ docker run --rm -it --security-opt seccomp:unconfined debian:jessie \
|
||||
unshare --map-root-user --user sh -c whoami
|
||||
```
|
||||
286
vendor/github.com/hyperhq/hypercli/docs/security/security.md
generated
vendored
Normal file
286
vendor/github.com/hyperhq/hypercli/docs/security/security.md
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
aliases = ["/engine/articles/security/"]
|
||||
title = "Docker security"
|
||||
description = "Review of the Docker Daemon attack surface"
|
||||
keywords = ["Docker, Docker documentation, security"]
|
||||
[menu.main]
|
||||
parent = "smn_secure_docker"
|
||||
weight =-99
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Docker security
|
||||
|
||||
There are three major areas to consider when reviewing Docker security:
|
||||
|
||||
- the intrinsic security of the kernel and its support for
|
||||
namespaces and cgroups;
|
||||
- the attack surface of the Docker daemon itself;
|
||||
- loopholes in the container configuration profile, either by default,
|
||||
or when customized by users.
|
||||
- the "hardening" security features of the kernel and how they
|
||||
interact with containers.
|
||||
|
||||
## Kernel namespaces
|
||||
|
||||
Docker containers are very similar to LXC containers, and they have
|
||||
similar security features. When you start a container with
|
||||
`docker run`, behind the scenes Docker creates a set of namespaces and control
|
||||
groups for the container.
|
||||
|
||||
**Namespaces provide the first and most straightforward form of
|
||||
isolation**: processes running within a container cannot see, and even
|
||||
less affect, processes running in another container, or in the host
|
||||
system.
|
||||
|
||||
**Each container also gets its own network stack**, meaning that a
|
||||
container doesn't get privileged access to the sockets or interfaces
|
||||
of another container. Of course, if the host system is setup
|
||||
accordingly, containers can interact with each other through their
|
||||
respective network interfaces — just like they can interact with
|
||||
external hosts. When you specify public ports for your containers or use
|
||||
[*links*](../userguide/networking/default_network/dockerlinks.md)
|
||||
then IP traffic is allowed between containers. They can ping each other,
|
||||
send/receive UDP packets, and establish TCP connections, but that can be
|
||||
restricted if necessary. From a network architecture point of view, all
|
||||
containers on a given Docker host are sitting on bridge interfaces. This
|
||||
means that they are just like physical machines connected through a
|
||||
common Ethernet switch; no more, no less.
|
||||
|
||||
How mature is the code providing kernel namespaces and private
|
||||
networking? Kernel namespaces were introduced [between kernel version
|
||||
2.6.15 and
|
||||
2.6.26](http://lxc.sourceforge.net/index.php/about/kernel-namespaces/).
|
||||
This means that since July 2008 (date of the 2.6.26 release, now 7 years
|
||||
ago), namespace code has been exercised and scrutinized on a large
|
||||
number of production systems. And there is more: the design and
|
||||
inspiration for the namespaces code are even older. Namespaces are
|
||||
actually an effort to reimplement the features of [OpenVZ](
|
||||
http://en.wikipedia.org/wiki/OpenVZ) in such a way that they could be
|
||||
merged within the mainstream kernel. And OpenVZ was initially released
|
||||
in 2005, so both the design and the implementation are pretty mature.
|
||||
|
||||
## Control groups
|
||||
|
||||
Control Groups are another key component of Linux Containers. They
|
||||
implement resource accounting and limiting. They provide many
|
||||
useful metrics, but they also help ensure that each container gets
|
||||
its fair share of memory, CPU, disk I/O; and, more importantly, that a
|
||||
single container cannot bring the system down by exhausting one of those
|
||||
resources.
|
||||
|
||||
So while they do not play a role in preventing one container from
|
||||
accessing or affecting the data and processes of another container, they
|
||||
are essential to fend off some denial-of-service attacks. They are
|
||||
particularly important on multi-tenant platforms, like public and
|
||||
private PaaS, to guarantee a consistent uptime (and performance) even
|
||||
when some applications start to misbehave.
|
||||
|
||||
Control Groups have been around for a while as well: the code was
|
||||
started in 2006, and initially merged in kernel 2.6.24.
|
||||
|
||||
## Docker daemon attack surface
|
||||
|
||||
Running containers (and applications) with Docker implies running the
|
||||
Docker daemon. This daemon currently requires `root` privileges, and you
|
||||
should therefore be aware of some important details.
|
||||
|
||||
First of all, **only trusted users should be allowed to control your
|
||||
Docker daemon**. This is a direct consequence of some powerful Docker
|
||||
features. Specifically, Docker allows you to share a directory between
|
||||
the Docker host and a guest container; and it allows you to do so
|
||||
without limiting the access rights of the container. This means that you
|
||||
can start a container where the `/host` directory will be the `/` directory
|
||||
on your host; and the container will be able to alter your host filesystem
|
||||
without any restriction. This is similar to how virtualization systems
|
||||
allow filesystem resource sharing. Nothing prevents you from sharing your
|
||||
root filesystem (or even your root block device) with a virtual machine.
|
||||
|
||||
This has a strong security implication: for example, if you instrument Docker
|
||||
from a web server to provision containers through an API, you should be
|
||||
even more careful than usual with parameter checking, to make sure that
|
||||
a malicious user cannot pass crafted parameters causing Docker to create
|
||||
arbitrary containers.
|
||||
|
||||
For this reason, the REST API endpoint (used by the Docker CLI to
|
||||
communicate with the Docker daemon) changed in Docker 0.5.2, and now
|
||||
uses a UNIX socket instead of a TCP socket bound on 127.0.0.1 (the
|
||||
latter being prone to cross-site-scripting attacks if you happen to run
|
||||
Docker directly on your local machine, outside of a VM). You can then
|
||||
use traditional UNIX permission checks to limit access to the control
|
||||
socket.
|
||||
|
||||
You can also expose the REST API over HTTP if you explicitly decide to do so.
|
||||
However, if you do that, being aware of the above mentioned security
|
||||
implication, you should ensure that it will be reachable only from a
|
||||
trusted network or VPN; or protected with e.g., `stunnel` and client SSL
|
||||
certificates. You can also secure them with [HTTPS and
|
||||
certificates](https.md).
|
||||
|
||||
The daemon is also potentially vulnerable to other inputs, such as image
|
||||
loading from either disk with 'docker load', or from the network with
|
||||
'docker pull'. This has been a focus of improvement in the community,
|
||||
especially for 'pull' security. While these overlap, it should be noted
|
||||
that 'docker load' is a mechanism for backup and restore and is not
|
||||
currently considered a secure mechanism for loading images. As of
|
||||
Docker 1.3.2, images are now extracted in a chrooted subprocess on
|
||||
Linux/Unix platforms, being the first-step in a wider effort toward
|
||||
privilege separation.
|
||||
|
||||
Eventually, it is expected that the Docker daemon will run restricted
|
||||
privileges, delegating operations well-audited sub-processes,
|
||||
each with its own (very limited) scope of Linux capabilities,
|
||||
virtual network setup, filesystem management, etc. That is, most likely,
|
||||
pieces of the Docker engine itself will run inside of containers.
|
||||
|
||||
Finally, if you run Docker on a server, it is recommended to run
|
||||
exclusively Docker in the server, and move all other services within
|
||||
containers controlled by Docker. Of course, it is fine to keep your
|
||||
favorite admin tools (probably at least an SSH server), as well as
|
||||
existing monitoring/supervision processes (e.g., NRPE, collectd, etc).
|
||||
|
||||
## Linux kernel capabilities
|
||||
|
||||
By default, Docker starts containers with a restricted set of
|
||||
capabilities. What does that mean?
|
||||
|
||||
Capabilities turn the binary "root/non-root" dichotomy into a
|
||||
fine-grained access control system. Processes (like web servers) that
|
||||
just need to bind on a port below 1024 do not have to run as root: they
|
||||
can just be granted the `net_bind_service` capability instead. And there
|
||||
are many other capabilities, for almost all the specific areas where root
|
||||
privileges are usually needed.
|
||||
|
||||
This means a lot for container security; let's see why!
|
||||
|
||||
Your average server (bare metal or virtual machine) needs to run a bunch
|
||||
of processes as root. Those typically include SSH, cron, syslogd;
|
||||
hardware management tools (e.g., load modules), network configuration
|
||||
tools (e.g., to handle DHCP, WPA, or VPNs), and much more. A container is
|
||||
very different, because almost all of those tasks are handled by the
|
||||
infrastructure around the container:
|
||||
|
||||
- SSH access will typically be managed by a single server running on
|
||||
the Docker host;
|
||||
- `cron`, when necessary, should run as a user
|
||||
process, dedicated and tailored for the app that needs its
|
||||
scheduling service, rather than as a platform-wide facility;
|
||||
- log management will also typically be handed to Docker, or by
|
||||
third-party services like Loggly or Splunk;
|
||||
- hardware management is irrelevant, meaning that you never need to
|
||||
run `udevd` or equivalent daemons within
|
||||
containers;
|
||||
- network management happens outside of the containers, enforcing
|
||||
separation of concerns as much as possible, meaning that a container
|
||||
should never need to perform `ifconfig`,
|
||||
`route`, or ip commands (except when a container
|
||||
is specifically engineered to behave like a router or firewall, of
|
||||
course).
|
||||
|
||||
This means that in most cases, containers will not need "real" root
|
||||
privileges *at all*. And therefore, containers can run with a reduced
|
||||
capability set; meaning that "root" within a container has much less
|
||||
privileges than the real "root". For instance, it is possible to:
|
||||
|
||||
- deny all "mount" operations;
|
||||
- deny access to raw sockets (to prevent packet spoofing);
|
||||
- deny access to some filesystem operations, like creating new device
|
||||
nodes, changing the owner of files, or altering attributes (including
|
||||
the immutable flag);
|
||||
- deny module loading;
|
||||
- and many others.
|
||||
|
||||
This means that even if an intruder manages to escalate to root within a
|
||||
container, it will be much harder to do serious damage, or to escalate
|
||||
to the host.
|
||||
|
||||
This won't affect regular web apps; but malicious users will find that
|
||||
the arsenal at their disposal has shrunk considerably! By default Docker
|
||||
drops all capabilities except [those
|
||||
needed](https://github.com/docker/docker/blob/87de5fdd5972343a11847922e0f41d9898b5cff7/daemon/execdriver/native/template/default_template_linux.go#L16-L29),
|
||||
a whitelist instead of a blacklist approach. You can see a full list of
|
||||
available capabilities in [Linux
|
||||
manpages](http://man7.org/linux/man-pages/man7/capabilities.7.html).
|
||||
|
||||
One primary risk with running Docker containers is that the default set
|
||||
of capabilities and mounts given to a container may provide incomplete
|
||||
isolation, either independently, or when used in combination with
|
||||
kernel vulnerabilities.
|
||||
|
||||
Docker supports the addition and removal of capabilities, allowing use
|
||||
of a non-default profile. This may make Docker more secure through
|
||||
capability removal, or less secure through the addition of capabilities.
|
||||
The best practice for users would be to remove all capabilities except
|
||||
those explicitly required for their processes.
|
||||
|
||||
## Other kernel security features
|
||||
|
||||
Capabilities are just one of the many security features provided by
|
||||
modern Linux kernels. It is also possible to leverage existing,
|
||||
well-known systems like TOMOYO, AppArmor, SELinux, GRSEC, etc. with
|
||||
Docker.
|
||||
|
||||
While Docker currently only enables capabilities, it doesn't interfere
|
||||
with the other systems. This means that there are many different ways to
|
||||
harden a Docker host. Here are a few examples.
|
||||
|
||||
- You can run a kernel with GRSEC and PAX. This will add many safety
|
||||
checks, both at compile-time and run-time; it will also defeat many
|
||||
exploits, thanks to techniques like address randomization. It doesn't
|
||||
require Docker-specific configuration, since those security features
|
||||
apply system-wide, independent of containers.
|
||||
- If your distribution comes with security model templates for
|
||||
Docker containers, you can use them out of the box. For instance, we
|
||||
ship a template that works with AppArmor and Red Hat comes with SELinux
|
||||
policies for Docker. These templates provide an extra safety net (even
|
||||
though it overlaps greatly with capabilities).
|
||||
- You can define your own policies using your favorite access control
|
||||
mechanism.
|
||||
|
||||
Just like there are many third-party tools to augment Docker containers
|
||||
with e.g., special network topologies or shared filesystems, you can
|
||||
expect to see tools to harden existing Docker containers without
|
||||
affecting Docker's core.
|
||||
|
||||
Recent improvements in Linux namespaces will soon allow to run
|
||||
full-featured containers without root privileges, thanks to the new user
|
||||
namespace. This is covered in detail [here](
|
||||
http://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/).
|
||||
Moreover, this will solve the problem caused by sharing filesystems
|
||||
between host and guest, since the user namespace allows users within
|
||||
containers (including the root user) to be mapped to other users in the
|
||||
host system.
|
||||
|
||||
Today, Docker does not directly support user namespaces, but they
|
||||
may still be utilized by Docker containers on supported kernels,
|
||||
by directly using the clone syscall, or utilizing the 'unshare'
|
||||
utility. Using this, some users may find it possible to drop
|
||||
more capabilities from their process as user namespaces provide
|
||||
an artificial capabilities set. Likewise, however, this artificial
|
||||
capabilities set may require use of 'capsh' to restrict the
|
||||
user-namespace capabilities set when using 'unshare'.
|
||||
|
||||
Eventually, it is expected that Docker will have direct, native support
|
||||
for user-namespaces, simplifying the process of hardening containers.
|
||||
|
||||
## Conclusions
|
||||
|
||||
Docker containers are, by default, quite secure; especially if you take
|
||||
care of running your processes inside the containers as non-privileged
|
||||
users (i.e., non-`root`).
|
||||
|
||||
You can add an extra layer of safety by enabling AppArmor, SELinux,
|
||||
GRSEC, or your favorite hardening solution.
|
||||
|
||||
Last but not least, if you see interesting security features in other
|
||||
containerization systems, these are simply kernels features that may
|
||||
be implemented in Docker as well. We welcome users to submit issues,
|
||||
pull requests, and communicate via the mailing list.
|
||||
|
||||
## Related Information
|
||||
|
||||
* [Use trusted images](../security/trust/index.md)
|
||||
* [Seccomp security profiles for Docker](../security/seccomp.md)
|
||||
* [AppArmor security profiles for Docker](../security/apparmor.md)
|
||||
* [On the Security of Containers (2014)](https://medium.com/@ewindisch/on-the-security-of-containers-2c60ffe25a9e)
|
||||
305
vendor/github.com/hyperhq/hypercli/docs/security/trust/content_trust.md
generated
vendored
Normal file
305
vendor/github.com/hyperhq/hypercli/docs/security/trust/content_trust.md
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Content trust in Docker"
|
||||
description = "Enabling content trust in Docker"
|
||||
keywords = ["content, trust, security, docker, documentation"]
|
||||
[menu.main]
|
||||
parent= "smn_content_trust"
|
||||
weight=-1
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Content trust in Docker
|
||||
|
||||
When transferring data among networked systems, *trust* is a central concern. In
|
||||
particular, when communicating over an untrusted medium such as the internet, it
|
||||
is critical to ensure the integrity and publisher of all the data a system
|
||||
operates on. You use Docker to push and pull images (data) to a registry. Content trust
|
||||
gives you the ability to both verify the integrity and the publisher of all the
|
||||
data received from a registry over any channel.
|
||||
|
||||
Content trust is currently only available for users of the public Docker Hub. It
|
||||
is currently not available for the Docker Trusted Registry or for private
|
||||
registries.
|
||||
|
||||
## Understand trust in Docker
|
||||
|
||||
Content trust allows operations with a remote Docker registry to enforce
|
||||
client-side signing and verification of image tags. Content trust provides the
|
||||
ability to use digital signatures for data sent to and received from remote
|
||||
Docker registries. These signatures allow client-side verification of the
|
||||
integrity and publisher of specific image tags.
|
||||
|
||||
Currently, content trust is disabled by default. You must enabled it by setting
|
||||
the `DOCKER_CONTENT_TRUST` environment variable. Refer to the
|
||||
[environment variables](../../reference/commandline/cli.md#environment-variables)
|
||||
and [Notary](../../reference/commandline/cli.md#notary) configuration
|
||||
for the docker client for more options.
|
||||
|
||||
Once content trust is enabled, image publishers can sign their images. Image consumers can
|
||||
ensure that the images they use are signed. publishers and consumers can be
|
||||
individuals alone or in organizations. Docker's content trust supports users and
|
||||
automated processes such as builds.
|
||||
|
||||
### Image tags and content trust
|
||||
|
||||
An individual image record has the following identifier:
|
||||
|
||||
```
|
||||
[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
|
||||
```
|
||||
|
||||
A particular image `REPOSITORY` can have multiple tags. For example, `latest` and
|
||||
`3.1.2` are both tags on the `mongo` image. An image publisher can build an image
|
||||
and tag combination many times changing the image with each build.
|
||||
|
||||
Content trust is associated with the `TAG` portion of an image. Each image
|
||||
repository has a set of keys that image publishers use to sign an image tag.
|
||||
Image publishers have discretion on which tags they sign.
|
||||
|
||||
An image repository can contain an image with one tag that is signed and another
|
||||
tag that is not. For example, consider [the Mongo image
|
||||
repository](https://hub.docker.com/r/library/mongo/tags/). The `latest`
|
||||
tag could be unsigned while the `3.1.6` tag could be signed. It is the
|
||||
responsibility of the image publisher to decide if an image tag is signed or
|
||||
not. In this representation, some image tags are signed, others are not:
|
||||
|
||||

|
||||
|
||||
Publishers can choose to sign a specific tag or not. As a result, the content of
|
||||
an unsigned tag and that of a signed tag with the same name may not match. For
|
||||
example, a publisher can push a tagged image `someimage:latest` and sign it.
|
||||
Later, the same publisher can push an unsigned `someimage:latest` image. This second
|
||||
push replaces the last unsigned tag `latest` but does not affect the signed `latest` version.
|
||||
The ability to choose which tags they can sign, allows publishers to iterate over
|
||||
the unsigned version of an image before officially signing it.
|
||||
|
||||
Image consumers can enable content trust to ensure that images they use were
|
||||
signed. If a consumer enables content trust, they can only pull, run, or build
|
||||
with trusted images. Enabling content trust is like wearing a pair of
|
||||
rose-colored glasses. Consumers "see" only signed images tags and the less
|
||||
desirable, unsigned image tags are "invisible" to them.
|
||||
|
||||

|
||||
|
||||
To the consumer who does not enabled content trust, nothing about how they
|
||||
work with Docker images changes. Every image is visible regardless of whether it
|
||||
is signed or not.
|
||||
|
||||
|
||||
### Content trust operations and keys
|
||||
|
||||
When content trust is enabled, `docker` CLI commands that operate on tagged images must
|
||||
either have content signatures or explicit content hashes. The commands that
|
||||
operate with content trust are:
|
||||
|
||||
* `push`
|
||||
* `build`
|
||||
* `create`
|
||||
* `pull`
|
||||
* `run`
|
||||
|
||||
For example, with content trust enabled a `docker pull someimage:latest` only
|
||||
succeeds if `someimage:latest` is signed. However, an operation with an explicit
|
||||
content hash always succeeds as long as the hash exists:
|
||||
|
||||
```bash
|
||||
$ docker pull someimage@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
|
||||
```
|
||||
|
||||
Trust for an image tag is managed through the use of signing keys. A key set is
|
||||
created when an operation using content trust is first invoked. Docker's content
|
||||
trust makes use of four different keys:
|
||||
|
||||
| Key | Description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| root key | Root of content trust for a image tag. When content trust is enabled, you create the root key once. |
|
||||
| target and snapshot | These two keys are known together as the "repository" key. When content trust is enabled, you create this key when you add a new image repository. If you have the root key, you can export the repository key and allow other publishers to sign the image tags. |
|
||||
| timestamp | This key applies to a repository. It allows Docker repositories to have freshness security guarantees without requiring periodic content refreshes on the client's side. |
|
||||
|
||||
With the exception of the timestamp, all the keys are generated and stored locally
|
||||
client-side. The timestamp is safely generated and stored in a signing server that
|
||||
is deployed alongside the Docker registry. All keys are generated in a backend
|
||||
service that isn't directly exposed to the internet and are encrypted at rest.
|
||||
|
||||
The following image depicts the various signing keys and their relationships:
|
||||
|
||||

|
||||
|
||||
>**WARNING**: Loss of the root key is **very difficult** to recover from.
|
||||
>Correcting this loss requires intervention from [Docker
|
||||
>Support](https://support.docker.com) to reset the repository state. This loss
|
||||
>also requires **manual intervention** from every consumer that used a signed
|
||||
>tag from this repository prior to the loss.
|
||||
|
||||
You should backup the root key somewhere safe. Given that it is only required
|
||||
to create new repositories, it is a good idea to store it offline. Make sure you
|
||||
read [Manage keys for content trust](trust_key_mng.md) information
|
||||
for details on securing, and backing up your keys.
|
||||
|
||||
## Survey of typical content trust operations
|
||||
|
||||
This section surveys the typical trusted operations users perform with Docker
|
||||
images.
|
||||
|
||||
### Enable and disable content trust per-shell or per-invocation
|
||||
|
||||
In a shell, you can enable content trust by setting the `DOCKER_CONTENT_TRUST`
|
||||
environment variable. Enabling per-shell is useful because you can have one
|
||||
shell configured for trusted operations and another terminal shell for untrusted
|
||||
operations. You can also add this declaration to your shell profile to have it
|
||||
turned on always by default.
|
||||
|
||||
To enable content trust in a `bash` shell enter the following command:
|
||||
|
||||
```bash
|
||||
export DOCKER_CONTENT_TRUST=1
|
||||
```
|
||||
|
||||
Once set, each of the "tag" operations requires a key for a trusted tag.
|
||||
|
||||
In an environment where `DOCKER_CONTENT_TRUST` is set, you can use the
|
||||
`--disable-content-trust` flag to run individual operations on tagged images
|
||||
without content trust on an as-needed basis.
|
||||
|
||||
```bash
|
||||
$ docker pull --disable-content-trust docker/trusttest:untrusted
|
||||
```
|
||||
|
||||
To invoke a command with content trust enabled regardless of whether or how the `DOCKER_CONTENT_TRUST` variable is set:
|
||||
|
||||
```bash
|
||||
$ docker build --disable-content-trust=false -t docker/trusttest:testing .
|
||||
```
|
||||
|
||||
All of the trusted operations support the `--disable-content-trust` flag.
|
||||
|
||||
|
||||
### Push trusted content
|
||||
|
||||
To create signed content for a specific image tag, simply enable content trust
|
||||
and push a tagged image. If this is the first time you have pushed an image
|
||||
using content trust on your system, the session looks like this:
|
||||
|
||||
```bash
|
||||
$ docker push docker/trusttest:latest
|
||||
The push refers to a repository [docker.io/docker/trusttest] (len: 1)
|
||||
9a61b6b1315e: Image already exists
|
||||
902b87aaaec9: Image already exists
|
||||
latest: digest: sha256:d02adacee0ac7a5be140adb94fa1dae64f4e71a68696e7f8e7cbf9db8dd49418 size: 3220
|
||||
Signing and pushing trust metadata
|
||||
You are about to create a new root signing key passphrase. This passphrase
|
||||
will be used to protect the most sensitive key in your signing system. Please
|
||||
choose a long, complex passphrase and be careful to keep the password and the
|
||||
key file itself secure and backed up. It is highly recommended that you use a
|
||||
password manager to generate the passphrase and keep it safe. There will be no
|
||||
way to recover this key. You can find the key in your config directory.
|
||||
Enter passphrase for new root key with id a1d96fb:
|
||||
Repeat passphrase for new root key with id a1d96fb:
|
||||
Enter passphrase for new repository key with id docker.io/docker/trusttest (3a932f1):
|
||||
Repeat passphrase for new repository key with id docker.io/docker/trusttest (3a932f1):
|
||||
Finished initializing "docker.io/docker/trusttest"
|
||||
```
|
||||
When you push your first tagged image with content trust enabled, the `docker`
|
||||
client recognizes this is your first push and:
|
||||
|
||||
- alerts you that it will create a new root key
|
||||
- requests a passphrase for the key
|
||||
- generates a root key in the `~/.docker/trust` directory
|
||||
- generates a repository key for in the `~/.docker/trust` directory
|
||||
|
||||
The passphrase you chose for both the root key and your content key-pair
|
||||
should be randomly generated and stored in a *password manager*.
|
||||
|
||||
> **NOTE**: If you omit the `latest` tag, content trust is skipped. This is true
|
||||
even if content trust is enabled and even if this is your first push.
|
||||
|
||||
```bash
|
||||
$ docker push docker/trusttest
|
||||
The push refers to a repository [docker.io/docker/trusttest] (len: 1)
|
||||
9a61b6b1315e: Image successfully pushed
|
||||
902b87aaaec9: Image successfully pushed
|
||||
latest: digest: sha256:a9a9c4402604b703bed1c847f6d85faac97686e48c579bd9c3b0fa6694a398fc size: 3220
|
||||
No tag specified, skipping trust metadata push
|
||||
```
|
||||
|
||||
It is skipped because as the message states, you did not supply an image `TAG`
|
||||
value. In Docker content trust, signatures are associated with tags.
|
||||
|
||||
Once you have a root key on your system, subsequent images repositories
|
||||
you create can use that same root key:
|
||||
|
||||
```bash
|
||||
$ docker push docker.io/docker/seaside:latest
|
||||
The push refers to a repository [docker.io/docker/seaside] (len: 1)
|
||||
a9539b34a6ab: Image successfully pushed
|
||||
b3dbab3810fc: Image successfully pushed
|
||||
latest: digest: sha256:d2ba1e603661a59940bfad7072eba698b79a8b20ccbb4e3bfb6f9e367ea43939 size: 3346
|
||||
Signing and pushing trust metadata
|
||||
Enter key passphrase for root key with id a1d96fb:
|
||||
Enter passphrase for new repository key with id docker.io/docker/seaside (bb045e3):
|
||||
Repeat passphrase for new repository key with id docker.io/docker/seaside (bb045e3):
|
||||
Finished initializing "docker.io/docker/seaside"
|
||||
```
|
||||
|
||||
The new image has its own repository key and timestamp key. The `latest` tag is signed with both of
|
||||
these.
|
||||
|
||||
|
||||
### Pull image content
|
||||
|
||||
A common way to consume an image is to `pull` it. With content trust enabled, the Docker
|
||||
client only allows `docker pull` to retrieve signed images.
|
||||
|
||||
```
|
||||
$ docker pull docker/seaside
|
||||
Using default tag: latest
|
||||
Pull (1 of 1): docker/trusttest:latest@sha256:d149ab53f871
|
||||
...
|
||||
Tagging docker/trusttest@sha256:d149ab53f871 as docker/trusttest:latest
|
||||
```
|
||||
|
||||
The `seaside:latest` image is signed. In the following example, the command does not specify a tag, so the system uses
|
||||
the `latest` tag by default again and the `docker/cliffs:latest` tag is not signed.
|
||||
|
||||
```bash
|
||||
$ docker pull docker/cliffs
|
||||
Using default tag: latest
|
||||
no trust data available
|
||||
```
|
||||
|
||||
Because the tag `docker/cliffs:latest` is not trusted, the `pull` fails.
|
||||
|
||||
|
||||
### Disable content trust for specific operations
|
||||
|
||||
A user that wants to disable content trust for a particular operation can use the
|
||||
`--disable-content-trust` flag. **Warning: this flag disables content trust for
|
||||
this operation**. With this flag, Docker will ignore content-trust and allow all
|
||||
operations to be done without verifying any signatures. If we wanted the
|
||||
previous untrusted build to succeed we could do:
|
||||
|
||||
```
|
||||
$ cat Dockerfile
|
||||
FROM docker/trusttest:notrust
|
||||
RUN echo
|
||||
$ docker build --disable-content-trust -t docker/trusttest:testing .
|
||||
Sending build context to Docker daemon 42.84 MB
|
||||
...
|
||||
Successfully built f21b872447dc
|
||||
```
|
||||
|
||||
The same is true for all the other commands, such as `pull` and `push`:
|
||||
|
||||
```
|
||||
$ docker pull --disable-content-trust docker/trusttest:untrusted
|
||||
...
|
||||
$ docker push --disable-content-trust docker/trusttest:untrusted
|
||||
...
|
||||
```
|
||||
|
||||
## Related information
|
||||
|
||||
* [Manage keys for content trust](trust_key_mng.md)
|
||||
* [Automation with content trust](trust_automation.md)
|
||||
* [Play in a content trust sandbox](trust_sandbox.md)
|
||||
34
vendor/github.com/hyperhq/hypercli/docs/security/trust/deploying_notary.md
generated
vendored
Normal file
34
vendor/github.com/hyperhq/hypercli/docs/security/trust/deploying_notary.md
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Deploying Notary"
|
||||
description = "Deploying Notary"
|
||||
keywords = ["trust, security, notary, deployment"]
|
||||
[menu.main]
|
||||
parent= "smn_content_trust"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Deploying Notary Server with Compose
|
||||
|
||||
The easiest way to deploy Notary Server is by using Docker Compose. To follow the procedure on this page, you must have already [installed Docker Compose](/compose/install.md).
|
||||
|
||||
1. Clone the Notary repository
|
||||
|
||||
git clone git@github.com:docker/notary.git
|
||||
|
||||
2. Build and start Notary Server with the sample certificates.
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
|
||||
For more detailed documentation about how to deploy Notary Server see https://github.com/docker/notary.
|
||||
3. Make sure that your Docker or Notary client trusts Notary Server's certificate before you try to interact with the Notary server.
|
||||
|
||||
See the instructions for [Docker](../../reference/commandline/cli.md#notary) or
|
||||
for [Notary](https://github.com/docker/notary#using-notary) depending on which one you are using.
|
||||
|
||||
## If you want to use Notary in production
|
||||
|
||||
Please check back here for instructions after Notary Server has an official
|
||||
stable release. To get a head start on deploying Notary in production see
|
||||
https://github.com/docker/notary.
|
||||
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/tag_signing.png
generated
vendored
Normal file
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/tag_signing.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_.gliffy
generated
vendored
Normal file
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_.gliffy
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_components.gliffy
generated
vendored
Normal file
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_components.gliffy
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_components.png
generated
vendored
Normal file
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_components.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_signing.gliffy
generated
vendored
Normal file
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_signing.gliffy
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_signing.png
generated
vendored
Normal file
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_signing.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_view.gliffy
generated
vendored
Normal file
1
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_view.gliffy
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_view.png
generated
vendored
Normal file
BIN
vendor/github.com/hyperhq/hypercli/docs/security/trust/images/trust_view.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
20
vendor/github.com/hyperhq/hypercli/docs/security/trust/index.md
generated
vendored
Normal file
20
vendor/github.com/hyperhq/hypercli/docs/security/trust/index.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Use trusted images"
|
||||
description = "Use trusted images"
|
||||
keywords = ["trust, security, docker, index"]
|
||||
[menu.main]
|
||||
identifier="smn_content_trust"
|
||||
parent= "smn_secure_docker"
|
||||
weight=4
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Use trusted images
|
||||
|
||||
The following topics are available:
|
||||
|
||||
* [Content trust in Docker](content_trust.md)
|
||||
* [Manage keys for content trust](trust_key_mng.md)
|
||||
* [Automation with content trust](trust_automation.md)
|
||||
* [Play in a content trust sandbox](trust_sandbox.md)
|
||||
79
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_automation.md
generated
vendored
Normal file
79
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_automation.md
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Automation with content trust"
|
||||
description = "Automating content push pulls with trust"
|
||||
keywords = ["trust, security, docker, documentation, automation"]
|
||||
[menu.main]
|
||||
parent= "smn_content_trust"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Automation with content trust
|
||||
|
||||
Your automation systems that pull or build images can also work with trust. Any automation environment must set `DOCKER_TRUST_ENABLED` either manually or in in a scripted fashion before processing images.
|
||||
|
||||
## Bypass requests for passphrases
|
||||
|
||||
To allow tools to wrap docker and push trusted content, there are two
|
||||
environment variables that allow you to provide the passphrases without an
|
||||
expect script, or typing them in:
|
||||
|
||||
- `DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE`
|
||||
- `DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE`
|
||||
|
||||
Docker attempts to use the contents of these environment variables as passphrase
|
||||
for the keys. For example, an image publisher can export the repository `target`
|
||||
and `snapshot` passphrases:
|
||||
|
||||
```bash
|
||||
$ export DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE="u7pEQcGoebUHm6LHe6"
|
||||
$ export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE="l7pEQcTKJjUHm6Lpe4"
|
||||
```
|
||||
|
||||
Then, when pushing a new tag the Docker client does not request these values but signs automatically:
|
||||
|
||||
```bash
|
||||
$ docker push docker/trusttest:latest
|
||||
The push refers to a repository [docker.io/docker/trusttest] (len: 1)
|
||||
a9539b34a6ab: Image already exists
|
||||
b3dbab3810fc: Image already exists
|
||||
latest: digest: sha256:d149ab53f871 size: 3355
|
||||
Signing and pushing trust metadata
|
||||
```
|
||||
|
||||
## Building with content trust
|
||||
|
||||
You can also build with content trust. Before running the `docker build` command, you should set the environment variable `DOCKER_CONTENT_TRUST` either manually or in in a scripted fashion. Consider the simple Dockerfile below.
|
||||
|
||||
```Dockerfile
|
||||
FROM docker/trusttest:latest
|
||||
RUN echo
|
||||
```
|
||||
|
||||
The `FROM` tag is pulling a signed image. You cannot build an image that has a
|
||||
`FROM` that is not either present locally or signed. Given that content trust
|
||||
data exists for the tag `latest`, the following build should succeed:
|
||||
|
||||
```bash
|
||||
$ docker build -t docker/trusttest:testing .
|
||||
Using default tag: latest
|
||||
latest: Pulling from docker/trusttest
|
||||
|
||||
b3dbab3810fc: Pull complete
|
||||
a9539b34a6ab: Pull complete
|
||||
Digest: sha256:d149ab53f871
|
||||
```
|
||||
|
||||
If content trust is enabled, building from a Dockerfile that relies on tag without trust data, causes the build command to fail:
|
||||
|
||||
```bash
|
||||
$ docker build -t docker/trusttest:testing .
|
||||
unable to process Dockerfile: No trust data for notrust
|
||||
```
|
||||
|
||||
## Related information
|
||||
|
||||
* [Content trust in Docker](content_trust.md)
|
||||
* [Manage keys for content trust](trust_key_mng.md)
|
||||
* [Play in a content trust sandbox](trust_sandbox.md)
|
||||
|
||||
73
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_key_mng.md
generated
vendored
Normal file
73
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_key_mng.md
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Manage keys for content trust"
|
||||
description = "Manage keys for content trust"
|
||||
keywords = ["trust, security, root, keys, repository"]
|
||||
[menu.main]
|
||||
parent= "smn_content_trust"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Manage keys for content trust
|
||||
|
||||
Trust for an image tag is managed through the use of keys. Docker's content
|
||||
trust makes use four different keys:
|
||||
|
||||
| Key | Description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| root key | Root of content trust for a image tag. When content trust is enabled, you create the root key once. |
|
||||
| target and snapshot | These two keys are known together as the "repository" key. When content trust is enabled, you create this key when you add a new image repository. If you have the root key, you can export the repository key and allow other publishers to sign the image tags. |
|
||||
| timestamp | This key applies to a repository. It allows Docker repositories to have freshness security guarantees without requiring periodic content refreshes on the client's side. |
|
||||
|
||||
With the exception of the timestamp, all the keys are generated and stored locally
|
||||
client-side. The timestamp is safely generated and stored in a signing server that
|
||||
is deployed alongside the Docker registry. All keys are generated in a backend
|
||||
service that isn't directly exposed to the internet and are encrypted at rest.
|
||||
|
||||
## Choosing a passphrase
|
||||
|
||||
The passphrases you chose for both the root key and your repository key should
|
||||
be randomly generated and stored in a password manager. Having the repository key
|
||||
allow users to sign image tags on a repository. Passphrases are used to encrypt
|
||||
your keys at rest and ensures that a lost laptop or an unintended backup doesn't
|
||||
put the private key material at risk.
|
||||
|
||||
## Back up your keys
|
||||
|
||||
All the Docker trust keys are stored encrypted using the passphrase you provide
|
||||
on creation. Even so, you should still take care of the location where you back them up.
|
||||
Good practice is to create two encrypted USB keys.
|
||||
|
||||
It is very important that you backup your keys to a safe, secure location. Loss
|
||||
of the repository key is recoverable; loss of the root key is not.
|
||||
|
||||
The Docker client stores the keys in the `~/.docker/trust/private` directory.
|
||||
Before backing them up, you should `tar` them into an archive:
|
||||
|
||||
```bash
|
||||
$ umask 077; tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private; umask 022
|
||||
```
|
||||
|
||||
## Lost keys
|
||||
|
||||
If a publisher loses keys it means losing the ability to sign trusted content for
|
||||
your repositories. If you lose a key, contact [Docker
|
||||
Support](https://support.docker.com) (support@docker.com) to reset the repository
|
||||
state.
|
||||
|
||||
This loss also requires **manual intervention** from every consumer that pulled
|
||||
the tagged image prior to the loss. Image consumers would get an error for
|
||||
content that they already downloaded:
|
||||
|
||||
```
|
||||
could not validate the path to a trusted root: failed to validate data with current trusted certificates
|
||||
```
|
||||
|
||||
To correct this, they need to download a new image tag with that is signed with
|
||||
the new key.
|
||||
|
||||
## Related information
|
||||
|
||||
* [Content trust in Docker](content_trust.md)
|
||||
* [Automation with content trust](trust_automation.md)
|
||||
* [Play in a content trust sandbox](trust_sandbox.md)
|
||||
331
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_sandbox.md
generated
vendored
Normal file
331
vendor/github.com/hyperhq/hypercli/docs/security/trust/trust_sandbox.md
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "Play in a content trust sandbox"
|
||||
description = "Play in a trust sandbox"
|
||||
keywords = ["trust, security, root, keys, repository, sandbox"]
|
||||
[menu.main]
|
||||
parent= "smn_content_trust"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# Play in a content trust sandbox
|
||||
|
||||
This page explains how to set up and use a sandbox for experimenting with trust.
|
||||
The sandbox allows you to configure and try trust operations locally without
|
||||
impacting your production images.
|
||||
|
||||
Before working through this sandbox, you should have read through the [trust
|
||||
overview](content_trust.md).
|
||||
|
||||
### Prerequisites
|
||||
|
||||
These instructions assume you are running in Linux or Mac OS X. You can run
|
||||
this sandbox on a local machine or on a virtual machine. You will need to
|
||||
have `sudo` privileges on your local machine or in the VM.
|
||||
|
||||
This sandbox requires you to install two Docker tools: Docker Engine and Docker
|
||||
Compose. To install the Docker Engine, choose from the [list of supported
|
||||
platforms](../../installation/index.md). To install Docker Compose, see the
|
||||
[detailed instructions here](https://docs.docker.com/compose/install/).
|
||||
|
||||
Finally, you'll need to have `git` installed on your local system or VM.
|
||||
|
||||
## What is in the sandbox?
|
||||
|
||||
If you are just using trust out-of-the-box you only need your Docker Engine
|
||||
client and access to the Docker hub. The sandbox mimics a
|
||||
production trust environment, and requires these additional components:
|
||||
|
||||
| Container | Description |
|
||||
|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| notarysandbox | A container with the latest version of Docker Engine and with some preconfigured certifications. This is your sandbox where you can use the `docker` client to test trust operations. |
|
||||
| Registry server | A local registry service. |
|
||||
| Notary server | The service that does all the heavy-lifting of managing trust |
|
||||
| Notary signer | A service that ensures that your keys are secure. |
|
||||
| MySQL | The database where all of the trust information will be stored |
|
||||
|
||||
The sandbox uses the Docker daemon on your local system. Within the `notarysandbox`
|
||||
you interact with a local registry rather than the Docker Hub. This means
|
||||
your everyday image repositories are not used. They are protected while you play.
|
||||
|
||||
When you play in the sandbox, you'll also create root and repository keys. The
|
||||
sandbox is configured to store all the keys and files inside the `notarysandbox`
|
||||
container. Since the keys you create in the sandbox are for play only,
|
||||
destroying the container destroys them as well.
|
||||
|
||||
|
||||
## Build the sandbox
|
||||
|
||||
In this section, you build the Docker components for your trust sandbox. If you
|
||||
work exclusively with the Docker Hub, you would not need with these components.
|
||||
They are built into the Docker Hub for you. For the sandbox, however, you must
|
||||
build your own entire, mock production environment and registry.
|
||||
|
||||
### Configure /etc/hosts
|
||||
|
||||
The sandbox' `notaryserver` and `sandboxregistry` run on your local server. The
|
||||
client inside the `notarysandbox` container connects to them over your network.
|
||||
So, you'll need an entry for both the servers in your local `/etc/hosts` file.
|
||||
|
||||
1. Add an entry for the `notaryserver` to `/etc/hosts`.
|
||||
|
||||
$ sudo sh -c 'echo "127.0.0.1 notaryserver" >> /etc/hosts'
|
||||
|
||||
2. Add an entry for the `sandboxregistry` to `/etc/hosts`.
|
||||
|
||||
$ sudo sh -c 'echo "127.0.0.1 sandboxregistry" >> /etc/hosts'
|
||||
|
||||
|
||||
### Build the notarytest image
|
||||
|
||||
1. Create a `notarytest` directory on your system.
|
||||
|
||||
$ mkdir notarysandbox
|
||||
|
||||
2. Change into your `notarysandbox` directory.
|
||||
|
||||
$ cd notarysandbox
|
||||
|
||||
3. Create a `notarytest` directory then change into that.
|
||||
|
||||
$ mkdir notarytest
|
||||
$ cd notarytest
|
||||
|
||||
4. Create a filed called `Dockerfile` with your favorite editor.
|
||||
|
||||
5. Add the following to the new file.
|
||||
|
||||
FROM debian:jessie
|
||||
|
||||
ADD https://master.dockerproject.org/linux/amd64/docker /usr/bin/docker
|
||||
RUN chmod +x /usr/bin/docker \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y \
|
||||
tree \
|
||||
vim \
|
||||
git \
|
||||
ca-certificates \
|
||||
--no-install-recommends
|
||||
|
||||
WORKDIR /root
|
||||
RUN git clone -b trust-sandbox https://github.com/docker/notary.git
|
||||
RUN cp /root/notary/fixtures/root-ca.crt /usr/local/share/ca-certificates/root-ca.crt
|
||||
RUN update-ca-certificates
|
||||
|
||||
ENTRYPOINT ["bash"]
|
||||
|
||||
6. Save and close the file.
|
||||
|
||||
7. Build the testing container.
|
||||
|
||||
$ docker build -t notarysandbox .
|
||||
Sending build context to Docker daemon 2.048 kB
|
||||
Step 1 : FROM debian:jessie
|
||||
...
|
||||
Successfully built 5683f17e9d72
|
||||
|
||||
|
||||
### Build and start up the trust servers
|
||||
|
||||
In this step, you get the source code for your notary and registry services.
|
||||
Then, you'll use Docker Compose to build and start them on your local system.
|
||||
|
||||
1. Change to back to the root of your `notarysandbox` directory.
|
||||
|
||||
$ cd notarysandbox
|
||||
|
||||
2. Clone the `notary` project.
|
||||
|
||||
$ git clone -b trust-sandbox https://github.com/docker/notary.git
|
||||
|
||||
3. Clone the `distribution` project.
|
||||
|
||||
$ git clone https://github.com/docker/distribution.git
|
||||
|
||||
4. Change to the `notary` project directory.
|
||||
|
||||
$ cd notary
|
||||
|
||||
The directory contains a `docker-compose` file that you'll use to run a
|
||||
notary server together with a notary signer and the corresponding MySQL
|
||||
databases. The databases store the trust information for an image.
|
||||
|
||||
5. Build the server images.
|
||||
|
||||
$ docker-compose build
|
||||
|
||||
The first time you run this, the build takes some time.
|
||||
|
||||
6. Run the server containers on your local system.
|
||||
|
||||
$ docker-compose up -d
|
||||
|
||||
Once the trust services are up, you'll setup a local version of the Docker
|
||||
Registry v2.
|
||||
|
||||
7. Change to the `notarysandbox/distribution` directory.
|
||||
|
||||
8. Build the `sandboxregistry` server.
|
||||
|
||||
$ docker build -t sandboxregistry .
|
||||
|
||||
9. Start the `sandboxregistry` server running.
|
||||
|
||||
$ docker run -p 5000:5000 --name sandboxregistry sandboxregistry &
|
||||
|
||||
## Playing in the sandbox
|
||||
|
||||
Now that everything is setup, you can go into your `notarysandbox` container and
|
||||
start testing Docker content trust.
|
||||
|
||||
|
||||
### Start the notarysandbox container
|
||||
|
||||
In this procedure, you start the `notarysandbox` and link it to the running
|
||||
`notary_notaryserver_1` and `sandboxregistry` containers. The links allow
|
||||
communication among the containers.
|
||||
|
||||
```
|
||||
$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock --link notary_notaryserver_1:notaryserver --link sandboxregistry:sandboxregistry notarysandbox
|
||||
root@0710762bb59a:/#
|
||||
```
|
||||
|
||||
Mounting the `docker.sock` gives the `notarysandbox` access to the `docker`
|
||||
daemon on your host, while storing all the keys and files inside the sandbox
|
||||
container. When you destroy the container, you destroy the "play" keys.
|
||||
|
||||
### Test some trust operations
|
||||
|
||||
Now, you'll pull some images.
|
||||
|
||||
1. Download a `docker` image to test with.
|
||||
|
||||
# docker pull docker/trusttest
|
||||
docker pull docker/trusttest
|
||||
Using default tag: latest
|
||||
latest: Pulling from docker/trusttest
|
||||
|
||||
b3dbab3810fc: Pull complete
|
||||
a9539b34a6ab: Pull complete
|
||||
Digest: sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
|
||||
Status: Downloaded newer image for docker/trusttest:latest
|
||||
|
||||
2. Tag it to be pushed to our sandbox registry:
|
||||
|
||||
# docker tag docker/trusttest sandboxregistry:5000/test/trusttest:latest
|
||||
|
||||
3. Enable content trust.
|
||||
|
||||
# export DOCKER_CONTENT_TRUST=1
|
||||
|
||||
4. Identify the trust server.
|
||||
|
||||
# export DOCKER_CONTENT_TRUST_SERVER=https://notaryserver:4443
|
||||
|
||||
This step is only necessary because the sandbox is using its own server.
|
||||
Normally, if you are using the Docker Public Hub this step isn't necessary.
|
||||
|
||||
5. Pull the test image.
|
||||
|
||||
# docker pull sandboxregistry:5000/test/trusttest
|
||||
Using default tag: latest
|
||||
no trust data available
|
||||
|
||||
You see an error, because this content doesn't exist on the `sandboxregistry` yet.
|
||||
|
||||
6. Push the trusted image.
|
||||
|
||||
# docker push sandboxregistry:5000/test/trusttest:latest
|
||||
The push refers to a repository [sandboxregistry:5000/test/trusttest] (len: 1)
|
||||
a9539b34a6ab: Image successfully pushed
|
||||
b3dbab3810fc: Image successfully pushed
|
||||
latest: digest: sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c size: 3348
|
||||
Signing and pushing trust metadata
|
||||
You are about to create a new root signing key passphrase. This passphrase
|
||||
will be used to protect the most sensitive key in your signing system. Please
|
||||
choose a long, complex passphrase and be careful to keep the password and the
|
||||
key file itself secure and backed up. It is highly recommended that you use a
|
||||
password manager to generate the passphrase and keep it safe. There will be no
|
||||
way to recover this key. You can find the key in your config directory.
|
||||
Enter passphrase for new root key with id 8c69e04:
|
||||
Repeat passphrase for new root key with id 8c69e04:
|
||||
Enter passphrase for new repository key with id sandboxregistry:5000/test/trusttest (93c362a):
|
||||
Repeat passphrase for new repository key with id sandboxregistry:5000/test/trusttest (93c362a):
|
||||
Finished initializing "sandboxregistry:5000/test/trusttest"
|
||||
latest: digest: sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a size: 3355
|
||||
Signing and pushing trust metadata
|
||||
|
||||
7. Try pulling the image you just pushed:
|
||||
|
||||
# docker pull sandboxregistry:5000/test/trusttest
|
||||
Using default tag: latest
|
||||
Pull (1 of 1): sandboxregistry:5000/test/trusttest:latest@sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c
|
||||
sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c: Pulling from test/trusttest
|
||||
b3dbab3810fc: Already exists
|
||||
a9539b34a6ab: Already exists
|
||||
Digest: sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c
|
||||
Status: Downloaded newer image for sandboxregistry:5000/test/trusttest@sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c
|
||||
Tagging sandboxregistry:5000/test/trusttest@sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c as sandboxregistry:5000/test/trusttest:latest
|
||||
|
||||
|
||||
### Test with malicious images
|
||||
|
||||
What happens when data is corrupted and you try to pull it when trust is
|
||||
enabled? In this section, you go into the `sandboxregistry` and tamper with some
|
||||
data. Then, you try and pull it.
|
||||
|
||||
1. Leave the sandbox container running.
|
||||
|
||||
2. Open a new bash terminal from your host into the `sandboxregistry`.
|
||||
|
||||
$ docker exec -it sandboxregistry bash
|
||||
296db6068327#
|
||||
|
||||
3. Change into the registry storage.
|
||||
|
||||
You'll need to provide the `sha` you received when you pushed the image.
|
||||
|
||||
# cd /var/lib/registry/docker/registry/v2/blobs/sha256/aa/aac0c133338db2b18ff054943cee3267fe50c75cdee969aed88b1992539ed042
|
||||
|
||||
4. Add malicious data to one of the trusttest layers:
|
||||
|
||||
# echo "Malicious data" > data
|
||||
|
||||
5. Got back to your sandbox terminal.
|
||||
|
||||
6. List the trusttest image.
|
||||
|
||||
# docker images | grep trusttest
|
||||
docker/trusttest latest a9539b34a6ab 7 weeks ago 5.025 MB
|
||||
sandboxregistry:5000/test/trusttest latest a9539b34a6ab 7 weeks ago 5.025 MB
|
||||
sandboxregistry:5000/test/trusttest <none> a9539b34a6ab 7 weeks ago 5.025 MB
|
||||
|
||||
7. Remove the `trusttest:latest` image.
|
||||
|
||||
# docker rmi -f a9539b34a6ab
|
||||
Untagged: docker/trusttest:latest
|
||||
Untagged: sandboxregistry:5000/test/trusttest:latest
|
||||
Untagged: sandboxregistry:5000/test/trusttest@sha256:1d871dcb16805f0604f10d31260e79c22070b35abc71a3d1e7ee54f1042c8c7c
|
||||
Deleted: a9539b34a6aba01d3942605dfe09ab821cd66abf3cf07755b0681f25ad81f675
|
||||
Deleted: b3dbab3810fc299c21f0894d39a7952b363f14520c2f3d13443c669b63b6aa20
|
||||
|
||||
8. Pull the image again.
|
||||
|
||||
# docker pull sandboxregistry:5000/test/trusttest
|
||||
Using default tag: latest
|
||||
...
|
||||
b3dbab3810fc: Verifying Checksum
|
||||
a9539b34a6ab: Pulling fs layer
|
||||
filesystem layer verification failed for digest sha256:aac0c133338db2b18ff054943cee3267fe50c75cdee969aed88b1992539ed042
|
||||
|
||||
You'll see the the pull did not complete because the trust system was
|
||||
unable to verify the image.
|
||||
|
||||
## More play in the sandbox
|
||||
|
||||
Now, that you have a full Docker content trust sandbox on your local system,
|
||||
feel free to play with it and see how it behaves. If you find any security
|
||||
issues with Docker, feel free to send us an email at <security@docker.com>.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user