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
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@ -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
|
||||
===================
|
||||
|
||||
A critical capability within PKI is to revoke a certificate - to ensure that it
|
||||
is no longer trusted by any peer. Unfortunately research has demonstrated that
|
||||
the two typical methods of revocation (Certificate Revocation Lists and Online
|
||||
Certificate Status Protocol) both have failings that make them unreliable,
|
||||
especially when attempting to leverage PKI outside of web-browser software.
|
||||
A critical capability within PKI is to revoke a certificate - to ensure
|
||||
that it is no longer trusted by any peer. Unfortunately research has
|
||||
demonstrated that the two typical methods of revocation (Certificate
|
||||
Revocation Lists and Online Certificate Status Protocol) both have
|
||||
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
|
||||
"passive revocation". By issuing certificates with lifetimes measured in hours,
|
||||
revocation can be achieved by simply not re-issuing certificates to clients.
|
||||
Through the use of short-lifetime certificates Anchor introduces the
|
||||
concept of "passive revocation". By issuing certificates with lifetimes
|
||||
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
|
||||
* always tested certificate update mechanism (used daily)
|
||||
@ -29,47 +32,48 @@ The benefits of using Anchor instead of manual long-term certificates are:
|
||||
Installation
|
||||
============
|
||||
|
||||
In order to install Anchor from source, the following system dependencies need
|
||||
to be present:
|
||||
In order to install Anchor from source, the following system
|
||||
dependencies need to be present:
|
||||
|
||||
* python 2.7
|
||||
* python (dev files)
|
||||
* libffi (dev)
|
||||
* libssl (dev)
|
||||
|
||||
When everything is in place, Anchor can be installed in one of three ways. For
|
||||
development with virtualenv, run:
|
||||
When everything is in place, Anchor can be installed in one of three
|
||||
ways. For development with virtualenv, run:
|
||||
|
||||
virtualenv .venv
|
||||
source .venv/bin/activate
|
||||
pip install .
|
||||
|
||||
For installing in production, either install a perpared system package, or
|
||||
install globally in the system:
|
||||
For installing in production, either install a perpared system package,
|
||||
or install globally in the system:
|
||||
|
||||
python setup.py install
|
||||
|
||||
Running the service
|
||||
===================
|
||||
|
||||
In order to run the service, it needs to be started via the `pecan` application
|
||||
server. The only extra parameter is a config file:
|
||||
In order to run the service, it needs to be started via the `pecan`
|
||||
application server. The only extra parameter is a config file:
|
||||
|
||||
pecan serve config.py
|
||||
|
||||
For development, an additional `--reload` parameter may be used. It will cause
|
||||
the service to reload every time a source file is changed, however it requires
|
||||
installing an additional `watchdog` python module.
|
||||
For development, an additional `--reload` parameter may be used. It will
|
||||
cause the service to reload every time a source file is changed, however
|
||||
it requires installing an additional `watchdog` python module.
|
||||
|
||||
In the default configuration, Anchor will wait for web requests on port 5000 on
|
||||
local network interface. This can be adjusted in the `config.py` file.
|
||||
In the default configuration, Anchor will wait for web requests on port
|
||||
5016 on local network interface. This can be adjusted in the `config.py`
|
||||
file.
|
||||
|
||||
Preparing a test environment
|
||||
============================
|
||||
|
||||
In order to test Anchor with the default configuration, the following can be
|
||||
done to create a test CA. The test certificate can be then used to sign the new
|
||||
certificates.
|
||||
In order to test Anchor with the default configuration, the following
|
||||
can be done to create a test CA. The test certificate can be then used
|
||||
to sign the new certificates.
|
||||
|
||||
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
|
||||
@ -81,127 +85,109 @@ Next, a new certificate request may be generated:
|
||||
-keyout anchor-test.example.com.key -newkey rsa:2048 \
|
||||
-subj "/CN=anchor-test.example.com"
|
||||
|
||||
That reqest can be submitted using curl (while `pecan serve config.py` is
|
||||
running):
|
||||
That reqest can be submitted using curl (while `pecan serve config.py`
|
||||
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 '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
|
||||
=======================
|
||||
We have prepared a base docker container for Anchor and a Dockerfile that will
|
||||
install the latest upstream version of Anchor and start the service. These
|
||||
instructions expect the reader to have a working Docker install already.
|
||||
We have provided a Dockerfile that can be used to build a container that
|
||||
will run anchor
|
||||
|
||||
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,
|
||||
built on ubuntu that has lots of libraries and requirements installed in order
|
||||
to quickly test anchor changes and build into CI processes. "Dockerfile.ubuntu"
|
||||
is used to build a complete Anchor stack, based on the latest available ubuntu
|
||||
docker image.
|
||||
Assuming you are already in the anchor directory, build a container
|
||||
called 'anchor' that runs the anchor service, with any local changes
|
||||
that have been made in the repo:
|
||||
|
||||
Fetch the most recent version of the Dockerfile.ubuntu:
|
||||
docker build -t anchor .
|
||||
|
||||
git clone -n git://git.openstack.org/openstack/anchor --depth 1
|
||||
cd anchor
|
||||
git checkout HEAD Dockerfile.ubuntu
|
||||
To start the service in the container and serve Anchor on port 8080:
|
||||
|
||||
Build a new Anchor container image using the Dockerfile:
|
||||
docker run -p 8080:5016 anchor
|
||||
|
||||
docker build -t anchor-dev -f Dockerfile.ubuntu .
|
||||
|
||||
[Optional] If you have previously built a container using the Dockerfile it will contain
|
||||
a cached version of the Anchor source code. If you require the latest version
|
||||
of anchor, build using the --no-cache option:
|
||||
|
||||
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:
|
||||
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 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
|
||||
============================
|
||||
|
||||
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
|
||||
expect from a http proxy - for example dealing well with deliberately slow
|
||||
connections, or using multiple workers. Anchor can however be run in production
|
||||
using a better frontend.
|
||||
application server (Pecan) and doesn't have all the features you'd
|
||||
normally expect from a http proxy - for example dealing well with
|
||||
deliberately slow connections, or using multiple workers. Anchor can
|
||||
however be run in production using a better frontend.
|
||||
|
||||
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
|
||||
custom headers, rate limiting, or source filtering a complete HTTP proxy like
|
||||
Nginx may be needed. This is however out of scope for Anchor project. You can
|
||||
read more about production deployment in
|
||||
In case a more complex scripted configuration is needed, for example to
|
||||
handle custom headers, rate limiting, or source filtering a complete
|
||||
HTTP proxy like Nginx may be needed. This is however out of scope for
|
||||
Anchor project. You can read more about production deployment in
|
||||
[Pecan documentation](http://pecan.readthedocs.org/en/latest/deployment.html).
|
||||
|
||||
Additionally, using an AppArmor profile for Anchor is a good idea to prevent
|
||||
exploits relying on one of the native libraries used by Anchor (for example
|
||||
OpenSSL). This can be done with sample profiles which you can find in the
|
||||
`tools/apparmor.anchor_*` files. The used file needs to be reviewed and updated
|
||||
with the right paths depending on the deployment location.
|
||||
Additionally, using an AppArmor profile for Anchor is a good idea to
|
||||
prevent exploits relying on one of the native libraries used by Anchor
|
||||
(for example OpenSSL). This can be done with sample profiles which you
|
||||
can find in the `tools/apparmor.anchor_*` files. The used file needs to
|
||||
be reviewed and updated with the right paths depending on the deployment
|
||||
location.
|
||||
|
||||
Validators
|
||||
==========
|
||||
|
||||
One of the main features of Anchor are the validators which make sure that all
|
||||
requests match a given set of rules. They're configured in `config.json` and
|
||||
the sample configuration includes a few of them.
|
||||
One of the main features of Anchor are the validators which make sure
|
||||
that all requests match a given set of rules. They're configured in
|
||||
`config.json` and the sample configuration includes a few of them.
|
||||
|
||||
Each validator takes a dictionary of options which provide the specific
|
||||
matching conditions.
|
||||
|
||||
Currently available validators are:
|
||||
|
||||
* `common_name` ensures CN matches one of names in `allowed_domains` or ranges
|
||||
in `allowed_networks`
|
||||
* `common_name` ensures CN matches one of names in `allowed_domains` or
|
||||
ranges in `allowed_networks`
|
||||
|
||||
* `alternative_names` ensures alternative names match one of the names in
|
||||
`allowed_domains`
|
||||
* `alternative_names` ensures alternative names match one of the names
|
||||
in `allowed_domains`
|
||||
|
||||
* `alternative_names_ip` ensures alternative names match one of the names in
|
||||
`allowed_domains` or IP ranges in `allowed_networks`
|
||||
* `alternative_names_ip` ensures alternative names match one of the
|
||||
names in `allowed_domains` or IP ranges in `allowed_networks`
|
||||
|
||||
* `blacklist_names` ensures CN and alternative names do not contain any of the
|
||||
configured `domains`
|
||||
* `blacklist_names` ensures CN and alternative names do not contain any
|
||||
of the configured `domains`
|
||||
|
||||
* `server_group` ensures the group the requester is contained within
|
||||
`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
|
||||
|
||||
* `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
|
||||
config:
|
||||
A configuration entry for a validator might look like one from the
|
||||
sample config:
|
||||
|
||||
"key_usage": {
|
||||
"allowed_usage": [
|
||||
@ -214,11 +200,11 @@ config:
|
||||
Authentication
|
||||
==============
|
||||
|
||||
Anchor can use one of the following authentication modules: static, keystone,
|
||||
ldap.
|
||||
Anchor can use one of the following authentication modules: static,
|
||||
keystone, ldap.
|
||||
|
||||
Static: Username and password are present in `config.json`. This mode should be
|
||||
used only for development and testing.
|
||||
Static: Username and password are present in `config.json`. This mode
|
||||
should be used only for development and testing.
|
||||
|
||||
"auth": {
|
||||
"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 location.
|
||||
Keystone: Username is ignored, but password is a token valid in the
|
||||
configured keystone location.
|
||||
|
||||
"auth": {
|
||||
"keystone": {
|
||||
@ -236,10 +222,11 @@ keystone location.
|
||||
}
|
||||
}
|
||||
|
||||
LDAP: Username and password are used to bind to an LDAP user in a configured
|
||||
domain. User's groups for the `server_group` filter are retrieved from
|
||||
attribute `memberOf` in search for `(sAMAccountName=username@domain)`. The
|
||||
search is done in the configured base.
|
||||
LDAP: Username and password are used to bind to an LDAP user in a
|
||||
configured domain. User's groups for the `server_group` filter are
|
||||
retrieved from attribute `memberOf` in search for
|
||||
`(sAMAccountName=username@domain)`. The search is done in the configured
|
||||
base.
|
||||
|
||||
"auth": {
|
||||
"ldap": {
|
||||
@ -254,16 +241,16 @@ search is done in the configured base.
|
||||
Signing backends
|
||||
================
|
||||
|
||||
Anchor allows the use of configurable signing backend. While it provides one
|
||||
implementation (based on cryptography.io and OpenSSL), other implementations
|
||||
may be configured.
|
||||
Anchor allows the use of configurable signing backend. While it provides
|
||||
one implementation (based on cryptography.io and OpenSSL), other
|
||||
implementations may be configured.
|
||||
|
||||
The resulting certificate is stored locally if the `output_path` is set to any
|
||||
string. This does not depend on the configured backend.
|
||||
The resulting certificate is stored locally if the `output_path` is set
|
||||
to any string. This does not depend on the configured backend.
|
||||
|
||||
Backends can specify their own options - please refer to the backend
|
||||
documentation for the specific list. The default backend takes the following
|
||||
options:
|
||||
documentation for the specific list. The default backend takes the
|
||||
following options:
|
||||
|
||||
* `cert_path`: path where local CA certificate can be found
|
||||
|
||||
@ -288,12 +275,13 @@ For more information, please refer to the documentation.
|
||||
Fixups
|
||||
======
|
||||
|
||||
Anchor can modify the submitted CSRs in order to enforce some rules, remove
|
||||
deprecated elements, or just add information. Submitted CSR may be modified or
|
||||
entirely redone. Fixup are loaded from "anchor.fixups" namespace and can take
|
||||
parameters just like validators.
|
||||
Anchor can modify the submitted CSRs in order to enforce some rules,
|
||||
remove deprecated elements, or just add information. Submitted CSR may
|
||||
be modified or entirely redone. Fixup are loaded from "anchor.fixups"
|
||||
namespace and can take parameters just like validators.
|
||||
|
||||
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…
x
Reference in New Issue
Block a user