Replaced the existing Dockerfiles. Tidied up Readme
I replaced the Dockerfiles that existed, which pulled anchor down from git with a single Dockerfile that uses the local version of anchor. This makes testing local changes to anchor very simple. I also updated the README to reflect these changes and fixed the varying line lenghts within that file. Change-Id: I313c840f594639e6c92ed6ff067da79652b74ed0
This commit is contained in:
parent
c917306533
commit
1c584f8569
|
@ -0,0 +1,14 @@
|
||||||
|
FROM python:2.7
|
||||||
|
RUN pip install pecan
|
||||||
|
ADD . /code
|
||||||
|
WORKDIR /code
|
||||||
|
RUN pip install -e .
|
||||||
|
RUN openssl req -out CA/root-ca.crt \
|
||||||
|
-keyout CA/root-ca-unwrapped.key \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-subj "/CN=Anchor Test CA" \
|
||||||
|
-nodes \
|
||||||
|
-x509 \
|
||||||
|
-days 365
|
||||||
|
RUN chmod 0400 CA/root-ca-unwrapped.key
|
||||||
|
ENTRYPOINT ["pecan", "serve", "/code/config.py"]
|
|
@ -1,33 +0,0 @@
|
||||||
FROM openstacksecurity/anchor:base
|
|
||||||
# According to http://crosbymichael.com/dockerfile-best-practices-take-2.html
|
|
||||||
# Rolling your own python base is in line with probably best practice
|
|
||||||
MAINTAINER Robert Clark <hyakuhei@gmail.com>
|
|
||||||
|
|
||||||
# Clone our repo
|
|
||||||
# Users may want to use --no-cache to ensure that when building the container
|
|
||||||
# an up to date version of Anchor is cloned.
|
|
||||||
WORKDIR /root
|
|
||||||
RUN git clone git://git.openstack.org/openstack/anchor
|
|
||||||
WORKDIR /root/anchor
|
|
||||||
|
|
||||||
RUN pip install -e .
|
|
||||||
|
|
||||||
RUN cp config.py /home/anchor/ ;\
|
|
||||||
cp config.json /home/anchor/ ;\
|
|
||||||
chown anchor:anchor /home/anchor/config.py ;\
|
|
||||||
chown anchor:anchor /home/anchor/config.json
|
|
||||||
|
|
||||||
RUN su - anchor
|
|
||||||
|
|
||||||
WORKDIR /home/anchor
|
|
||||||
RUN mkdir CA
|
|
||||||
RUN openssl req -out CA/root-ca.crt \
|
|
||||||
-keyout CA/root-ca-unwrapped.key \
|
|
||||||
-newkey rsa:4096 \
|
|
||||||
-subj "/CN=Anchor Test CA" \
|
|
||||||
-nodes \
|
|
||||||
-x509 \
|
|
||||||
-days 365 ;\
|
|
||||||
chmod 0400 CA/root-ca-unwrapped.key
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/pecan", "serve", "/home/anchor/config.py"]
|
|
|
@ -1,37 +0,0 @@
|
||||||
FROM ubuntu:latest
|
|
||||||
MAINTAINER Robert Clark <hyakuhei@gmail.com>
|
|
||||||
|
|
||||||
# root user operations
|
|
||||||
# Upgrade the base and install required packages
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
python-dev \
|
|
||||||
libssl-dev \
|
|
||||||
libffi-dev \
|
|
||||||
python-pip \
|
|
||||||
git
|
|
||||||
|
|
||||||
# Clone Anchor, install required python packages
|
|
||||||
# Setup a user to run anchor
|
|
||||||
WORKDIR /root
|
|
||||||
RUN git clone git://git.openstack.org/openstack/anchor
|
|
||||||
WORKDIR /root/anchor
|
|
||||||
RUN pip install -e .
|
|
||||||
RUN adduser --disabled-password --gecos '' anchor
|
|
||||||
|
|
||||||
# anchor user operations
|
|
||||||
RUN cp config.py /home/anchor/
|
|
||||||
RUN cp config.json /home/anchor/
|
|
||||||
RUN chown anchor:anchor /home/anchor/config.py
|
|
||||||
RUN chown anchor:anchor /home/anchor/config.json
|
|
||||||
RUN su - anchor
|
|
||||||
WORKDIR /home/anchor
|
|
||||||
RUN mkdir CA
|
|
||||||
RUN openssl req -out CA/root-ca.crt \
|
|
||||||
-keyout CA/root-ca-unwrapped.key \
|
|
||||||
-newkey rsa:4096 \
|
|
||||||
-subj "/CN=Anchor Test CA" \
|
|
||||||
-nodes \
|
|
||||||
-x509 \
|
|
||||||
-days 365
|
|
||||||
RUN chmod 0400 CA/root-ca-unwrapped.key
|
|
||||||
ENTRYPOINT ["/usr/local/bin/pecan", "serve", "/home/anchor/config.py"]
|
|
228
README.md
228
README.md
|
@ -8,17 +8,20 @@ The validity period can be set in the config file with hour resolution.
|
||||||
Ideas behind Anchor
|
Ideas behind Anchor
|
||||||
===================
|
===================
|
||||||
|
|
||||||
A critical capability within PKI is to revoke a certificate - to ensure that it
|
A critical capability within PKI is to revoke a certificate - to ensure
|
||||||
is no longer trusted by any peer. Unfortunately research has demonstrated that
|
that it is no longer trusted by any peer. Unfortunately research has
|
||||||
the two typical methods of revocation (Certificate Revocation Lists and Online
|
demonstrated that the two typical methods of revocation (Certificate
|
||||||
Certificate Status Protocol) both have failings that make them unreliable,
|
Revocation Lists and Online Certificate Status Protocol) both have
|
||||||
especially when attempting to leverage PKI outside of web-browser software.
|
failings that make them unreliable, especially when attempting to
|
||||||
|
leverage PKI outside of web-browser software.
|
||||||
|
|
||||||
Through the use of short-lifetime certificates Anchor introduces the concept of
|
Through the use of short-lifetime certificates Anchor introduces the
|
||||||
"passive revocation". By issuing certificates with lifetimes measured in hours,
|
concept of "passive revocation". By issuing certificates with lifetimes
|
||||||
revocation can be achieved by simply not re-issuing certificates to clients.
|
measured in hours, revocation can be achieved by simply not re-issuing
|
||||||
|
certificates to clients.
|
||||||
|
|
||||||
The benefits of using Anchor instead of manual long-term certificates are:
|
The benefits of using Anchor instead of manual long-term certificates
|
||||||
|
are:
|
||||||
|
|
||||||
* quick certificate revoking / rotation
|
* quick certificate revoking / rotation
|
||||||
* always tested certificate update mechanism (used daily)
|
* always tested certificate update mechanism (used daily)
|
||||||
|
@ -29,47 +32,48 @@ The benefits of using Anchor instead of manual long-term certificates are:
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
In order to install Anchor from source, the following system dependencies need
|
In order to install Anchor from source, the following system
|
||||||
to be present:
|
dependencies need to be present:
|
||||||
|
|
||||||
* python 2.7
|
* python 2.7
|
||||||
* python (dev files)
|
* python (dev files)
|
||||||
* libffi (dev)
|
* libffi (dev)
|
||||||
* libssl (dev)
|
* libssl (dev)
|
||||||
|
|
||||||
When everything is in place, Anchor can be installed in one of three ways. For
|
When everything is in place, Anchor can be installed in one of three
|
||||||
development with virtualenv, run:
|
ways. For development with virtualenv, run:
|
||||||
|
|
||||||
virtualenv .venv
|
virtualenv .venv
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
pip install .
|
pip install .
|
||||||
|
|
||||||
For installing in production, either install a perpared system package, or
|
For installing in production, either install a perpared system package,
|
||||||
install globally in the system:
|
or install globally in the system:
|
||||||
|
|
||||||
python setup.py install
|
python setup.py install
|
||||||
|
|
||||||
Running the service
|
Running the service
|
||||||
===================
|
===================
|
||||||
|
|
||||||
In order to run the service, it needs to be started via the `pecan` application
|
In order to run the service, it needs to be started via the `pecan`
|
||||||
server. The only extra parameter is a config file:
|
application server. The only extra parameter is a config file:
|
||||||
|
|
||||||
pecan serve config.py
|
pecan serve config.py
|
||||||
|
|
||||||
For development, an additional `--reload` parameter may be used. It will cause
|
For development, an additional `--reload` parameter may be used. It will
|
||||||
the service to reload every time a source file is changed, however it requires
|
cause the service to reload every time a source file is changed, however
|
||||||
installing an additional `watchdog` python module.
|
it requires installing an additional `watchdog` python module.
|
||||||
|
|
||||||
In the default configuration, Anchor will wait for web requests on port 5000 on
|
In the default configuration, Anchor will wait for web requests on port
|
||||||
local network interface. This can be adjusted in the `config.py` file.
|
5016 on local network interface. This can be adjusted in the `config.py`
|
||||||
|
file.
|
||||||
|
|
||||||
Preparing a test environment
|
Preparing a test environment
|
||||||
============================
|
============================
|
||||||
|
|
||||||
In order to test Anchor with the default configuration, the following can be
|
In order to test Anchor with the default configuration, the following
|
||||||
done to create a test CA. The test certificate can be then used to sign the new
|
can be done to create a test CA. The test certificate can be then used
|
||||||
certificates.
|
to sign the new certificates.
|
||||||
|
|
||||||
openssl req -out CA/root-ca.crt -keyout CA/root-ca-unwrapped.key \
|
openssl req -out CA/root-ca.crt -keyout CA/root-ca-unwrapped.key \
|
||||||
-newkey rsa:4096 -subj "/CN=Anchor Test CA" -nodes -x509 -days 365
|
-newkey rsa:4096 -subj "/CN=Anchor Test CA" -nodes -x509 -days 365
|
||||||
|
@ -81,127 +85,109 @@ Next, a new certificate request may be generated:
|
||||||
-keyout anchor-test.example.com.key -newkey rsa:2048 \
|
-keyout anchor-test.example.com.key -newkey rsa:2048 \
|
||||||
-subj "/CN=anchor-test.example.com"
|
-subj "/CN=anchor-test.example.com"
|
||||||
|
|
||||||
That reqest can be submitted using curl (while `pecan serve config.py` is
|
That reqest can be submitted using curl (while `pecan serve config.py`
|
||||||
running):
|
is running):
|
||||||
|
|
||||||
curl http://0.0.0.0:5000/v1/sign/default -F user='myusername' \
|
curl http://0.0.0.0:5016/v1/sign/default -F user='myusername' \
|
||||||
-F secret='simplepassword' -F encoding=pem \
|
-F secret='simplepassword' -F encoding=pem \
|
||||||
-F 'csr=<anchor-test.example.com.csr'
|
-F 'csr=<anchor-test.example.com.csr'
|
||||||
|
|
||||||
This will result in the signed request being created in the `certs` directory.
|
This will result in the signed request being created in the `certs`
|
||||||
|
directory.
|
||||||
|
|
||||||
Docker test environment
|
Docker test environment
|
||||||
=======================
|
=======================
|
||||||
We have prepared a base docker container for Anchor and a Dockerfile that will
|
We have provided a Dockerfile that can be used to build a container that
|
||||||
install the latest upstream version of Anchor and start the service. These
|
will run anchor
|
||||||
instructions expect the reader to have a working Docker install already.
|
|
||||||
|
|
||||||
Docker should *not* be used to serve Anchor in any production environments.
|
These instructions expect the reader to have a working Docker install
|
||||||
|
already. Docker should *not* be used to serve Anchor in any production
|
||||||
|
environments.
|
||||||
|
|
||||||
We use two Dockerfiles for Anchor. "Dockerfile.anchorbase" is a custom image,
|
Assuming you are already in the anchor directory, build a container
|
||||||
built on ubuntu that has lots of libraries and requirements installed in order
|
called 'anchor' that runs the anchor service, with any local changes
|
||||||
to quickly test anchor changes and build into CI processes. "Dockerfile.ubuntu"
|
that have been made in the repo:
|
||||||
is used to build a complete Anchor stack, based on the latest available ubuntu
|
|
||||||
docker image.
|
|
||||||
|
|
||||||
Fetch the most recent version of the Dockerfile.ubuntu:
|
docker build -t anchor .
|
||||||
|
|
||||||
git clone -n git://git.openstack.org/openstack/anchor --depth 1
|
To start the service in the container and serve Anchor on port 8080:
|
||||||
cd anchor
|
|
||||||
git checkout HEAD Dockerfile.ubuntu
|
|
||||||
|
|
||||||
Build a new Anchor container image using the Dockerfile:
|
docker run -p 8080:5016 anchor
|
||||||
|
|
||||||
docker build -t anchor-dev -f Dockerfile.ubuntu .
|
The anchor application should be accessible on port 8080. If you are
|
||||||
|
running docker natively on Linux, that will be 8080 on localhost
|
||||||
[Optional] If you have previously built a container using the Dockerfile it will contain
|
(127.0.0.1). If you are running docker under Microsoft Windows or Apple
|
||||||
a cached version of the Anchor source code. If you require the latest version
|
OSX it will be running in a docker machine. To find the docker machine
|
||||||
of anchor, build using the --no-cache option:
|
IP address run:
|
||||||
|
|
||||||
docker build --no-cache -t anchor-dev -f Dockerfile.ubuntu .
|
|
||||||
|
|
||||||
Start the service in the container and serve Anchor on port 8080:
|
|
||||||
|
|
||||||
docker run -p 8080:5000 anchor-dev
|
|
||||||
|
|
||||||
The anchor application should be accessible on port 8080. If you are running
|
|
||||||
docker natively on Linux, that will be 8080 on localhost (127.0.0.1). If you
|
|
||||||
are running docker under Microsoft Windows or Apple OSX it will be running in
|
|
||||||
a docker machine. To find the docker machine IP address run:
|
|
||||||
|
|
||||||
docker-machine ip default
|
docker-machine ip default
|
||||||
|
|
||||||
Docker development environment
|
|
||||||
==============================
|
|
||||||
Users who want to quickly test out changes to Anchor or who want to experiment
|
|
||||||
in other ways may find it more convenient to use Dockerfile.anchorbase file.
|
|
||||||
The instructions are very similar to using the ubuntu base as described above.
|
|
||||||
|
|
||||||
Simply replace "Dockerfile.ubuntu" with "Dockerfile.anchorbase" in the above
|
|
||||||
instructions.
|
|
||||||
|
|
||||||
Running Anchor in production
|
Running Anchor in production
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Anchor shouldn't be exposed directly to the network. It's running via an
|
Anchor shouldn't be exposed directly to the network. It's running via an
|
||||||
application server (Pecan) and doesn't have all the features you'd normally
|
application server (Pecan) and doesn't have all the features you'd
|
||||||
expect from a http proxy - for example dealing well with deliberately slow
|
normally expect from a http proxy - for example dealing well with
|
||||||
connections, or using multiple workers. Anchor can however be run in production
|
deliberately slow connections, or using multiple workers. Anchor can
|
||||||
using a better frontend.
|
however be run in production using a better frontend.
|
||||||
|
|
||||||
To run Anchor using uwsgi you can use the following command:
|
To run Anchor using uwsgi you can use the following command:
|
||||||
|
|
||||||
uwsgi --http-socket :5000 --venv path/to/venv --pecan config.py -p 4
|
uwsgi --http-socket :5016 --venv path/to/venv --pecan config.py -p 4
|
||||||
|
|
||||||
In case a more complex scripted configuration is needed, for example to handle
|
In case a more complex scripted configuration is needed, for example to
|
||||||
custom headers, rate limiting, or source filtering a complete HTTP proxy like
|
handle custom headers, rate limiting, or source filtering a complete
|
||||||
Nginx may be needed. This is however out of scope for Anchor project. You can
|
HTTP proxy like Nginx may be needed. This is however out of scope for
|
||||||
read more about production deployment in
|
Anchor project. You can read more about production deployment in
|
||||||
[Pecan documentation](http://pecan.readthedocs.org/en/latest/deployment.html).
|
[Pecan documentation](http://pecan.readthedocs.org/en/latest/deployment.html).
|
||||||
|
|
||||||
Additionally, using an AppArmor profile for Anchor is a good idea to prevent
|
Additionally, using an AppArmor profile for Anchor is a good idea to
|
||||||
exploits relying on one of the native libraries used by Anchor (for example
|
prevent exploits relying on one of the native libraries used by Anchor
|
||||||
OpenSSL). This can be done with sample profiles which you can find in the
|
(for example OpenSSL). This can be done with sample profiles which you
|
||||||
`tools/apparmor.anchor_*` files. The used file needs to be reviewed and updated
|
can find in the `tools/apparmor.anchor_*` files. The used file needs to
|
||||||
with the right paths depending on the deployment location.
|
be reviewed and updated with the right paths depending on the deployment
|
||||||
|
location.
|
||||||
|
|
||||||
Validators
|
Validators
|
||||||
==========
|
==========
|
||||||
|
|
||||||
One of the main features of Anchor are the validators which make sure that all
|
One of the main features of Anchor are the validators which make sure
|
||||||
requests match a given set of rules. They're configured in `config.json` and
|
that all requests match a given set of rules. They're configured in
|
||||||
the sample configuration includes a few of them.
|
`config.json` and the sample configuration includes a few of them.
|
||||||
|
|
||||||
Each validator takes a dictionary of options which provide the specific
|
Each validator takes a dictionary of options which provide the specific
|
||||||
matching conditions.
|
matching conditions.
|
||||||
|
|
||||||
Currently available validators are:
|
Currently available validators are:
|
||||||
|
|
||||||
* `common_name` ensures CN matches one of names in `allowed_domains` or ranges
|
* `common_name` ensures CN matches one of names in `allowed_domains` or
|
||||||
in `allowed_networks`
|
ranges in `allowed_networks`
|
||||||
|
|
||||||
* `alternative_names` ensures alternative names match one of the names in
|
* `alternative_names` ensures alternative names match one of the names
|
||||||
`allowed_domains`
|
in `allowed_domains`
|
||||||
|
|
||||||
* `alternative_names_ip` ensures alternative names match one of the names in
|
* `alternative_names_ip` ensures alternative names match one of the
|
||||||
`allowed_domains` or IP ranges in `allowed_networks`
|
names in `allowed_domains` or IP ranges in `allowed_networks`
|
||||||
|
|
||||||
* `blacklist_names` ensures CN and alternative names do not contain any of the
|
* `blacklist_names` ensures CN and alternative names do not contain any
|
||||||
configured `domains`
|
of the configured `domains`
|
||||||
|
|
||||||
* `server_group` ensures the group the requester is contained within
|
* `server_group` ensures the group the requester is contained within
|
||||||
`group_prefixes`
|
`group_prefixes`
|
||||||
|
|
||||||
* `extensions` ensures only `allowed_extensions` are present in the request
|
* `extensions` ensures only `allowed_extensions` are present in the
|
||||||
|
request
|
||||||
|
|
||||||
* `key_usage` ensures only `allowed_usage` is requested for the certificate
|
* `key_usage` ensures only `allowed_usage` is requested for the
|
||||||
|
certificate
|
||||||
|
|
||||||
* `ca_status` ensures the request does/doesn't require the CA flag
|
* `ca_status` ensures the request does/doesn't require the CA flag
|
||||||
|
|
||||||
* `source_cidrs` ensures the request comes from one of the ranges in `cidrs`
|
* `source_cidrs` ensures the request comes from one of the ranges in
|
||||||
|
`cidrs`
|
||||||
|
|
||||||
A configuration entry for a validator might look like one from the sample
|
A configuration entry for a validator might look like one from the
|
||||||
config:
|
sample config:
|
||||||
|
|
||||||
"key_usage": {
|
"key_usage": {
|
||||||
"allowed_usage": [
|
"allowed_usage": [
|
||||||
|
@ -214,11 +200,11 @@ config:
|
||||||
Authentication
|
Authentication
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Anchor can use one of the following authentication modules: static, keystone,
|
Anchor can use one of the following authentication modules: static,
|
||||||
ldap.
|
keystone, ldap.
|
||||||
|
|
||||||
Static: Username and password are present in `config.json`. This mode should be
|
Static: Username and password are present in `config.json`. This mode
|
||||||
used only for development and testing.
|
should be used only for development and testing.
|
||||||
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"static": {
|
"static": {
|
||||||
|
@ -227,8 +213,8 @@ used only for development and testing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keystone: Username is ignored, but password is a token valid in the configured
|
Keystone: Username is ignored, but password is a token valid in the
|
||||||
keystone location.
|
configured keystone location.
|
||||||
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"keystone": {
|
"keystone": {
|
||||||
|
@ -236,10 +222,11 @@ keystone location.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LDAP: Username and password are used to bind to an LDAP user in a configured
|
LDAP: Username and password are used to bind to an LDAP user in a
|
||||||
domain. User's groups for the `server_group` filter are retrieved from
|
configured domain. User's groups for the `server_group` filter are
|
||||||
attribute `memberOf` in search for `(sAMAccountName=username@domain)`. The
|
retrieved from attribute `memberOf` in search for
|
||||||
search is done in the configured base.
|
`(sAMAccountName=username@domain)`. The search is done in the configured
|
||||||
|
base.
|
||||||
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"ldap": {
|
"ldap": {
|
||||||
|
@ -254,16 +241,16 @@ search is done in the configured base.
|
||||||
Signing backends
|
Signing backends
|
||||||
================
|
================
|
||||||
|
|
||||||
Anchor allows the use of configurable signing backend. While it provides one
|
Anchor allows the use of configurable signing backend. While it provides
|
||||||
implementation (based on cryptography.io and OpenSSL), other implementations
|
one implementation (based on cryptography.io and OpenSSL), other
|
||||||
may be configured.
|
implementations may be configured.
|
||||||
|
|
||||||
The resulting certificate is stored locally if the `output_path` is set to any
|
The resulting certificate is stored locally if the `output_path` is set
|
||||||
string. This does not depend on the configured backend.
|
to any string. This does not depend on the configured backend.
|
||||||
|
|
||||||
Backends can specify their own options - please refer to the backend
|
Backends can specify their own options - please refer to the backend
|
||||||
documentation for the specific list. The default backend takes the following
|
documentation for the specific list. The default backend takes the
|
||||||
options:
|
following options:
|
||||||
|
|
||||||
* `cert_path`: path where local CA certificate can be found
|
* `cert_path`: path where local CA certificate can be found
|
||||||
|
|
||||||
|
@ -288,12 +275,13 @@ For more information, please refer to the documentation.
|
||||||
Fixups
|
Fixups
|
||||||
======
|
======
|
||||||
|
|
||||||
Anchor can modify the submitted CSRs in order to enforce some rules, remove
|
Anchor can modify the submitted CSRs in order to enforce some rules,
|
||||||
deprecated elements, or just add information. Submitted CSR may be modified or
|
remove deprecated elements, or just add information. Submitted CSR may
|
||||||
entirely redone. Fixup are loaded from "anchor.fixups" namespace and can take
|
be modified or entirely redone. Fixup are loaded from "anchor.fixups"
|
||||||
parameters just like validators.
|
namespace and can take parameters just like validators.
|
||||||
|
|
||||||
Reporting bugs and contributing
|
Reporting bugs and contributing
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
For bug reporting and contributing, please check the CONTRIBUTING.md file.
|
For bug reporting and contributing, please check the CONTRIBUTING.md
|
||||||
|
file.
|
||||||
|
|
Loading…
Reference in New Issue