254 lines
10 KiB
Markdown
254 lines
10 KiB
Markdown
|
---
|
||
|
description: Run your own notary service to host arbitrary content signing.
|
||
|
keywords: docker, notary, notary-server, notary server, notary-signer, notary signer
|
||
|
title: Run a Notary service
|
||
|
---
|
||
|
|
||
|
This document is for anyone who wants to run their own Notary
|
||
|
service (such as those who want to use Notary with a
|
||
|
private Docker registry). Running a Notary service requires that you are already
|
||
|
familiar with using [Docker Engine](/engine/userguide/)
|
||
|
and [Docker Compose](/compose/).
|
||
|
|
||
|
## Run a service for testing or development
|
||
|
|
||
|
The quickest way to spin up a full Notary service for testing and development
|
||
|
purposes is to use the Docker compose file in the
|
||
|
[Notary project](https://github.com/docker/notary).
|
||
|
|
||
|
```bash
|
||
|
$ git clone https://github.com/theupdateframework/notary.git
|
||
|
$ cd notary
|
||
|
$ docker-compose up
|
||
|
```
|
||
|
|
||
|
This builds the development Notary server and Notary signer images, and
|
||
|
start up containers for the Notary server, Notary signer, and the MySQL
|
||
|
database that both of them share. The MySQL data is stored in a volume.
|
||
|
|
||
|
Notary server and Notary signer communicate over mutually authenticated TLS
|
||
|
(using the self-signed testing certs in the repository), and Notary server
|
||
|
listens for HTTPS traffic on port 4443.
|
||
|
|
||
|
By default, this development Notary server container runs with the testing
|
||
|
self-signed TLS certificates. Before you can successfully connect to
|
||
|
it, you must use the root CA file in `fixtures/root-ca.crt`.
|
||
|
|
||
|
For example, to connect using OpenSSL:
|
||
|
|
||
|
```bash
|
||
|
$ openssl s_client -connect <docker host>:4443 -CAfile fixtures/root-ca.crt -no_ssl3 -no_ssl2
|
||
|
```
|
||
|
|
||
|
To connect using the Notary Client CLI, see [Getting Started](getting_started.md).
|
||
|
The version of the Notary server and signer
|
||
|
needs to be greater than or equal to that of the Notary Client CLI to ensure feature compatibility.
|
||
|
For instance, if you use Notary Client CLI 0.2, the server and signer each need
|
||
|
to be at least version 0.2 as well.
|
||
|
|
||
|
The self-signed certificate's subject name and subject alternative names are
|
||
|
`notary-server`, `notaryserver`, and `localhost`, so if your Docker host is not
|
||
|
on `localhost` (for example if you are using Docker Machine),
|
||
|
update your hosts file such that the name `notary-server` is associated with
|
||
|
the IP address of your Docker host.
|
||
|
|
||
|
## Advanced configuration options
|
||
|
|
||
|
Both the Notary server and the Notary signer take
|
||
|
[JSON configuration files](reference/index.md). Pre-built images, such as
|
||
|
the [development images above](running_a_service.md#run-a-service-for-testing-or-development)
|
||
|
provide these configuration files for you with some sane defaults.
|
||
|
|
||
|
However, for running in production, or if you just want to change those defaults
|
||
|
on your development service, you probably want to change those defaults.
|
||
|
|
||
|
### Running with different command line arguments
|
||
|
|
||
|
You can override the `docker run` command for the image if you want to pass
|
||
|
different command line options. Both Notary server and Notary signer take
|
||
|
the following command line arguments:
|
||
|
|
||
|
- `-config=<config file>` - specify the path to the JSON configuration file.
|
||
|
|
||
|
- `-debug` - Passing this flag enables the debugging server on `localhost:8080`.
|
||
|
The debugging server provides
|
||
|
[pprof](https://golang.org/pkg/net/http/pprof) and
|
||
|
[expvar](ttps://golang.org/pkg/expvar/) endpoints.
|
||
|
(Remember, this is localhost with respect to the running container - this endpoint is not
|
||
|
exposed from the container).
|
||
|
|
||
|
This option can also be set in the configuration file.
|
||
|
|
||
|
- `-logf=<format>` - This flag sets the output format for the logs. Possible
|
||
|
formats are "json" and "logfmt".
|
||
|
|
||
|
This option cannot be set in the configuration file, since some log
|
||
|
messages are produced on startup before the configuration file has been
|
||
|
read.
|
||
|
|
||
|
### Specifying your own configuration files
|
||
|
|
||
|
You can run the images with your own configuration files entirely.
|
||
|
You just need to mount your configuration directory, and then pass the
|
||
|
path to that configuration file as an argument to the `docker run` command.
|
||
|
|
||
|
### Overriding configuration file parameters using environment variables
|
||
|
|
||
|
You can also override the parameters of the configuration by
|
||
|
setting environment variables of the form `NOTARY_SERVER_<var>` or
|
||
|
`NOTARY_SIGNER_<var>`.
|
||
|
|
||
|
`var` is the ALL-CAPS, `"_"`-delimited path of keys from the top level of the
|
||
|
configuration JSON.
|
||
|
|
||
|
For instance, if you wanted to override the storage URL of the Notary server
|
||
|
configuration:
|
||
|
|
||
|
```json
|
||
|
"storage": {
|
||
|
"backend": "mysql",
|
||
|
"db_url": "dockercondemo:dockercondemo@tcp(notary-mysql)/dockercondemo"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
You would need to set the environment variable `NOTARY_SERVER_STORAGE_DB_URL`,
|
||
|
because the `db_url` is in the `storage` section of the Notary server
|
||
|
configuration JSON.
|
||
|
|
||
|
ou cannot override a key whose value is another map. For instance, setting
|
||
|
`NOTARY_SERVER_STORAGE='{"storage": {"backend": "memory"}}'` does not set
|
||
|
in-memory storage. It just fails to parse. You can only override keys whose
|
||
|
values are strings or numbers.
|
||
|
|
||
|
For example, let's say that you wanted to run a single Notary server instance:
|
||
|
|
||
|
- with your own TLS cert and keys
|
||
|
- with a local, in-memory signer service rather than using Notary signer
|
||
|
- using a local, in-memory TUF metadata store rather than using MySQL
|
||
|
- produce JSON-formatted logs
|
||
|
|
||
|
One way to do this would be:
|
||
|
|
||
|
1. Generate your own TLS certificate and key as `server.crt` and `server.key`,
|
||
|
and put them in the directory `/tmp/server-configdir`.
|
||
|
|
||
|
2. Write the following configuration file to `/tmp/server-configdir/config.json`:
|
||
|
|
||
|
{
|
||
|
"server": {
|
||
|
"http_addr": ":4443",
|
||
|
"tls_key_file": "./server.key",
|
||
|
"tls_cert_file": "./server.crt"
|
||
|
},
|
||
|
"trust_service": {
|
||
|
"type": "remote",
|
||
|
"hostname": "notarysigner",
|
||
|
"port": "7899",
|
||
|
"tls_ca_file": "./root-ca.crt",
|
||
|
"key_algorithm": "ecdsa",
|
||
|
"tls_client_cert": "./notary-server.crt",
|
||
|
"tls_client_key": "./notary-server.key"
|
||
|
},
|
||
|
"storage": {
|
||
|
"backend": "mysql",
|
||
|
"db_url": "server@tcp(mysql:3306)/notaryserver?parseTime=True"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
NWe include a remote trust service and a database storage
|
||
|
type to demonstrate how environment variables can override
|
||
|
configuration parameters.
|
||
|
|
||
|
3. Run the following command (assuming you've already built or pulled a Notary server docker image):
|
||
|
|
||
|
$ docker run \
|
||
|
-p "4443:4443" \
|
||
|
-v /tmp/server-configdir:/etc/docker/notary-server/ \
|
||
|
-e NOTARY_SERVER_TRUST_SERVICE_TYPE=local \
|
||
|
-e NOTARY_SERVER_STORAGE_BACKEND=memory \
|
||
|
-e NOTARY_SERVER_LOGGING_LEVEL=debug \
|
||
|
notary_server \
|
||
|
-config=/etc/docker/notary-server/config.json \
|
||
|
-logf=json
|
||
|
{"level":"info","msg":"Version: 0.2, Git commit: 619f8cf","time":"2016-02-25T00:53:59Z"}
|
||
|
{"level":"info","msg":"Using local signing service, which requires ED25519. Ignoring all other trust_service parameters, including keyAlgorithm","time":"2016-02-25T00:53:59Z"}
|
||
|
{"level":"info","msg":"Using memory backend","time":"2016-02-25T00:53:59Z"}
|
||
|
{"level":"info","msg":"Starting Server","time":"2016-02-25T00:53:59Z"}
|
||
|
{"level":"info","msg":"Enabling TLS","time":"2016-02-25T00:53:59Z"}
|
||
|
{"level":"info","msg":"Starting on :4443","time":"2016-02-25T00:53:59Z"}
|
||
|
|
||
|
You can do the same using
|
||
|
[Docker Compose](/compose/) by setting volumes,
|
||
|
environment variables, and overriding the default command for the Notary server
|
||
|
containers in the Compose file.
|
||
|
|
||
|
|
||
|
## Recommendations for deploying in production
|
||
|
|
||
|
When moving from development to production there are a number of considerations
|
||
|
that must be made to ensure security and scalability.
|
||
|
|
||
|
### Certificates
|
||
|
|
||
|
The Notary repository includes sample certificates in the fixtures directory.
|
||
|
When you initialize a development service using the provided `docker-compose.yml`
|
||
|
file, these sample certificates are used to create a more production like
|
||
|
environment.
|
||
|
|
||
|
**You must acquire your own certificates to use in a production deployment.**
|
||
|
|
||
|
The sample private key files in the Notary repository are obviously public knowledge
|
||
|
and using them in a production deployment is highly insecure.
|
||
|
|
||
|
### Certificate directory
|
||
|
|
||
|
Notary is a user/client-based system, and it searches for certificates in the
|
||
|
user's home directory, at `~/.docker/trust`. To streamline using Notary from
|
||
|
the command line, create an alias that maps the user's `trust` directory to
|
||
|
the system's `ca-certificates` directory.
|
||
|
|
||
|
```bash
|
||
|
$ alias notary="notary -s https://<dtr-url> -d ~/.docker/trust --tlscacert /usr/local/share/ca-certificates/<dtr-url>.crt"
|
||
|
```
|
||
|
|
||
|
### Databases
|
||
|
|
||
|
The server and signer each require a database. These should be separate databases
|
||
|
with different users. The users should be limited in their permissions. We recommend
|
||
|
giving the following MySQL (or equivalent) permissions to the users restricted to
|
||
|
only their own databases:
|
||
|
|
||
|
- Notary server database user: `SELECT, INSERT, UPDATE, DELETE`
|
||
|
- Notary signer database user: `SELECT, INSERT, DELETE`
|
||
|
|
||
|
### High Availability
|
||
|
|
||
|
To increase availability, you can run multiple instances
|
||
|
of both the server and signer applications. These can scale arbitrarily and
|
||
|
independently. The database can also scale independently but this is left as
|
||
|
an exercise for experienced DBAs and Operations teams. A typical deployment
|
||
|
looks like this:
|
||
|
|
||
|
![Notary server Deployment Diagram](https://cdn.rawgit.com/docker/notary/09f81717080f53276e6881ece57cbbbf91b8e2a7/docs/images/service-deployment.svg)
|
||
|
|
||
|
In the diagram, a load balancer routes external traffic to a cluster of Notary server
|
||
|
instances. These may make requests to Notary signer instances if either a) signing
|
||
|
is required, or b) key generation is required. The requests from a Notary server
|
||
|
to a Notary signer cluster are router via an internal load balancer.
|
||
|
|
||
|
Notary can be used with a CDN or other caching system. All GET requests for JSON
|
||
|
files may be cached indefinitely __except__ URLs matching:
|
||
|
|
||
|
- `*/root.json`
|
||
|
- `*/timestamp.json`
|
||
|
|
||
|
All other requests for JSON files include sha256 checksums of the file being requested
|
||
|
and are therefore immutable. Requests for JSON files make up the vast majority of
|
||
|
all notary requests. Requests for anything other than a GET of a JSON file should
|
||
|
not be cached.
|
||
|
|
||
|
## Related information
|
||
|
|
||
|
* [Notary service architecture](service_architecture.md)
|
||
|
* [Notary configuration files](reference/index.md)
|