Compare commits
No commits in common. "master" and "feature/cleandoc" have entirely different histories.
master
...
feature/cl
13 changed files with 11 additions and 202 deletions
18
.drone.yml
18
.drone.yml
|
@ -25,9 +25,9 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- cargo build --release
|
- cargo build --release
|
||||||
- mkdir coffer-${DRONE_TAG}-x86_64-musl
|
- mkdir coffer-${DRONE_TAG}-x86_64-musl
|
||||||
- mv target/x86_64-unknown-linux-musl/release/coffer-server
|
- mv target/x86_64-unknown-linux-musl/release/coffer-server \
|
||||||
target/x86_64-unknown-linux-musl/release/coffer-client
|
target/x86_64-unknown-linux-musl/release/coffer-client \
|
||||||
target/x86_64-unknown-linux-musl/release/coffer-companion
|
target/x86_64-unknown-linux-musl/release/coffer-companion \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl
|
coffer-${DRONE_TAG}-x86_64-musl
|
||||||
- strip coffer-${DRONE_TAG}-x86_64-musl/coffer-server
|
- strip coffer-${DRONE_TAG}-x86_64-musl/coffer-server
|
||||||
- strip coffer-${DRONE_TAG}-x86_64-musl/coffer-client
|
- strip coffer-${DRONE_TAG}-x86_64-musl/coffer-client
|
||||||
|
@ -36,13 +36,13 @@ steps:
|
||||||
- name: package
|
- name: package
|
||||||
image: alpine
|
image: alpine
|
||||||
commands:
|
commands:
|
||||||
- tar cjf coffer-${DRONE_TAG}-x86_64-musl.tar.bz2
|
- tar cjf coffer-${DRONE_TAG}-x86_64-musl.tar.bz2 \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-server
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-server \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-client
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-client \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-companion
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-companion
|
||||||
- tar czf coffer-${DRONE_TAG}-x86_64-musl.tar.gz
|
- tar czf coffer-${DRONE_TAG}-x86_64-musl.tar.gz \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-server
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-server \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-client
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-client \
|
||||||
coffer-${DRONE_TAG}-x86_64-musl/coffer-companion
|
coffer-${DRONE_TAG}-x86_64-musl/coffer-companion
|
||||||
|
|
||||||
- name: publish
|
- name: publish
|
||||||
|
|
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -2,5 +2,3 @@
|
||||||
*.cert filter=lfs diff=lfs merge=lfs -text
|
*.cert filter=lfs diff=lfs merge=lfs -text
|
||||||
overview.png filter=lfs diff=lfs merge=lfs -text
|
overview.png filter=lfs diff=lfs merge=lfs -text
|
||||||
overview.svg filter=lfs diff=lfs merge=lfs -text
|
overview.svg filter=lfs diff=lfs merge=lfs -text
|
||||||
coffer-client filter=lfs diff=lfs merge=lfs -text
|
|
||||||
coffer-server filter=lfs diff=lfs merge=lfs -text
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Coffer
|
# Coffer
|
||||||
[![Build Status](https://drone.friedl.net/api/badges/incubator/coffer/status.svg?ref=refs/heads/develop)](https://drone.friedl.net/incubator/coffer)
|
[![Build Status](https://drone.friedl.net/api/badges/incubator/coffer/status.svg)](https://drone.friedl.net/incubator/coffer)
|
||||||
|
|
||||||
Coffer is a collection of tools for the simple but secure management of
|
Coffer is a collection of tools for the simple but secure management of
|
||||||
application configuration.
|
application configuration.
|
||||||
|
@ -68,7 +68,7 @@ certificates are distributed and kept secret according to your threat model. An
|
||||||
attacker in control of a certificate can steal secret configuration!
|
attacker in control of a certificate can steal secret configuration!
|
||||||
|
|
||||||
Coffer does not assume a trust anchor for you. Instead, you are free to choose
|
Coffer does not assume a trust anchor for you. Instead, you are free to choose
|
||||||
your own trust anchor. In a simple personal server setup this might
|
your own trust anchor according. In a simple personal server setup this might
|
||||||
mean just distributing certificates by hand. In a more complex, corporate
|
mean just distributing certificates by hand. In a more complex, corporate
|
||||||
environment you may want to set up a secure, central authority.
|
environment you may want to set up a secure, central authority.
|
||||||
|
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
Here you can find a simple example on how to run coffer.
|
|
||||||
|
|
||||||
# Run the example
|
|
||||||
|
|
||||||
To run the example, simply execute:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
docker-compose up
|
|
||||||
```
|
|
||||||
|
|
||||||
This should print out:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
@@@@@@@ @@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@
|
|
||||||
@@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@
|
|
||||||
!@@ @@! @@@ @@! @@! @@! @@! @@@
|
|
||||||
!@! !@! @!@ !@! !@! !@! !@! @!@
|
|
||||||
!@! @!@ !@! @!!!:! @!!!:! @!!!:! @!@!!@!
|
|
||||||
!!! !@! !!! !!!!!: !!!!!: !!!!!: !!@!@!
|
|
||||||
:!! !!: !!! !!: !!: !!: !!: :!!
|
|
||||||
:!: :!: !:! :!: :!: :!: :!: !:!
|
|
||||||
::: ::: ::::: :: :: :: :: :::: :: :::
|
|
||||||
:: :: : : : : : : : :: :: : : :
|
|
||||||
|
|
||||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
||||||
TERM=xterm
|
|
||||||
container=podman
|
|
||||||
HOSTNAME=f7a1614d8752
|
|
||||||
HOME=/root
|
|
||||||
CLIENT_SECRET=SECRETKEY
|
|
||||||
client
|
|
||||||
0
|
|
||||||
```
|
|
||||||
|
|
||||||
Where `CLIENT_SECRET` is the secret set into the environment of `printenv` in
|
|
||||||
the client. `printenv` is the coffer'ed process.
|
|
||||||
|
|
||||||
Note that if you connect to a shell in the client container you are not able to
|
|
||||||
retrieve the secret. The secret _only_ exists in the environment of the
|
|
||||||
coffer'ed process. It does not even exist in some parent process of the
|
|
||||||
coffer'ed process, as coffer reaps itself while starting the sub-process. This
|
|
||||||
is quite different from other alternatives that either set the secrets into the
|
|
||||||
environment of the container, or into a volume on the container. Both of which
|
|
||||||
are accessible (with more or less effort) from anyone that has access to the
|
|
||||||
container.
|
|
||||||
|
|
||||||
Also note how the whole server container, despite being able to service hundreds
|
|
||||||
of clients in parallel, uses less than 3 MB in total.
|
|
||||||
|
|
||||||
# Setup and Configuration
|
|
||||||
In this example we create a [coffer server](server/Dockerfile) with some [client secrets](config.toml)
|
|
||||||
and a simple [client container](client/Dockerfile). The container are built, run and connected a shared
|
|
||||||
network via [docker-compose](docker-compose.yml).
|
|
||||||
|
|
||||||
Both, the client and the server, need a certificate. The client for
|
|
||||||
authenticating with the server, and the server for decrypting the client
|
|
||||||
secrets.
|
|
||||||
|
|
||||||
Certificates can be generated with:
|
|
||||||
```shell
|
|
||||||
coffer-companion certificate certificate.cert
|
|
||||||
```
|
|
||||||
|
|
||||||
Furthermore, the secrets need to be authorized. Even though a coffer server can
|
|
||||||
handle secrets for multiple clients, a client can only request its own secrets.
|
|
||||||
Secrets retrieval is authorized by the public key of the client. You can get the
|
|
||||||
public key by
|
|
||||||
```shell
|
|
||||||
coffer-companion info certificate.cert
|
|
||||||
```
|
|
||||||
|
|
||||||
The public key must be put into the `id` section of a secret. For
|
|
||||||
example, our [secrets](config.toml) contain a section like this:
|
|
||||||
```toml
|
|
||||||
[client]
|
|
||||||
id = "452B0788D966059B21DB04FF37BC6161072B15EA2CDF88A5040FEEAB89D1143A"
|
|
||||||
CLIENT_SECRET = "SECRETKEY"
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, the promise of coffer is that certificates are the fundamental trust
|
|
||||||
anchor. This also means they are the _only_ thing you have to care about for
|
|
||||||
security of your secrets. Consequently, [secrets themselves are encrypted](server/config.enc)
|
|
||||||
with the server certificate:
|
|
||||||
```shell
|
|
||||||
coffer-companion encrypt --certificate certificate.cert --out config.enc --yaml config.toml
|
|
||||||
```
|
|
||||||
|
|
||||||
# Encoffering the client
|
|
||||||
You may have noticed that the actual client program (`printenv`) is not run
|
|
||||||
directly. Instead the [Dockerfile](client/Dockerfile) contains an entrypoint like this:
|
|
||||||
```Dockerfile
|
|
||||||
ENTRYPOINT ["coffer-client"]
|
|
||||||
|
|
||||||
CMD ["--certificate", "client.cert", \
|
|
||||||
"--server-address", "server:9187", \
|
|
||||||
"--", \
|
|
||||||
"printenv"]
|
|
||||||
```
|
|
||||||
|
|
||||||
The coffer client will connect to the server and retrieve its secrets.
|
|
||||||
Afterwards it sets the secrets into the process environment and replaces its own
|
|
||||||
process image with the coffer'ed command.
|
|
||||||
|
|
||||||
The major drawback of this approach is that you have to build your own images.
|
|
||||||
If you want to coffer your own software this is probably only a minor
|
|
||||||
inconvenience. For pre-build images like e.g. the official
|
|
||||||
[postgres](https://hub.docker.com/_/postgres) image this means you have to
|
|
||||||
derive your own image for and coffer the entrypoint. For postgres this might
|
|
||||||
look like:
|
|
||||||
```Dockerfile
|
|
||||||
FROM postgres:12-alpine
|
|
||||||
|
|
||||||
COPY ./coffer-client /usr/local/bin
|
|
||||||
COPY ./postgres.cert .
|
|
||||||
|
|
||||||
ENTRYPOINT ["coffer-client", \
|
|
||||||
"--certificate", "postgres.cert",
|
|
||||||
"--server-address", "server:9187",
|
|
||||||
"--",
|
|
||||||
"docker-entrypoint.sh"]
|
|
||||||
|
|
||||||
CMD ["postgres"]
|
|
||||||
|
|
||||||
```
|
|
|
@ -1,13 +0,0 @@
|
||||||
FROM busybox
|
|
||||||
|
|
||||||
RUN mkdir -p /usr/local/bin
|
|
||||||
|
|
||||||
COPY ./coffer-client /usr/local/bin
|
|
||||||
COPY ./client.cert .
|
|
||||||
|
|
||||||
ENTRYPOINT ["coffer-client"]
|
|
||||||
|
|
||||||
CMD ["--certificate", "client.cert", \
|
|
||||||
"--server-address", "server:9187", \
|
|
||||||
"--", \
|
|
||||||
"printenv"]
|
|
BIN
example/client/client.cert
(Stored with Git LFS)
BIN
example/client/client.cert
(Stored with Git LFS)
Binary file not shown.
BIN
example/client/coffer-client
(Stored with Git LFS)
BIN
example/client/coffer-client
(Stored with Git LFS)
Binary file not shown.
|
@ -1,3 +0,0 @@
|
||||||
[client]
|
|
||||||
id = "452B0788D966059B21DB04FF37BC6161072B15EA2CDF88A5040FEEAB89D1143A"
|
|
||||||
CLIENT_SECRET = "SECRETKEY"
|
|
|
@ -1,21 +0,0 @@
|
||||||
version: "3"
|
|
||||||
|
|
||||||
services:
|
|
||||||
server:
|
|
||||||
container_name: server
|
|
||||||
build:
|
|
||||||
context: ./server/
|
|
||||||
networks:
|
|
||||||
- coffer
|
|
||||||
|
|
||||||
client:
|
|
||||||
container_name: client
|
|
||||||
build:
|
|
||||||
context: ./client/
|
|
||||||
networks:
|
|
||||||
- coffer
|
|
||||||
depends_on:
|
|
||||||
- server
|
|
||||||
|
|
||||||
networks:
|
|
||||||
coffer:
|
|
|
@ -1,13 +0,0 @@
|
||||||
FROM gcr.io/distroless/static
|
|
||||||
|
|
||||||
COPY ./coffer-server .
|
|
||||||
COPY ./server.cert .
|
|
||||||
COPY ./config.enc .
|
|
||||||
|
|
||||||
|
|
||||||
EXPOSE 9187
|
|
||||||
ENTRYPOINT ["./coffer-server"]
|
|
||||||
|
|
||||||
CMD ["--certificate", "server.cert", \
|
|
||||||
"--secrets", "config.enc", \
|
|
||||||
"--address", "0.0.0.0:9187"]
|
|
BIN
example/server/coffer-server
(Stored with Git LFS)
BIN
example/server/coffer-server
(Stored with Git LFS)
Binary file not shown.
BIN
example/server/config.enc
(Stored with Git LFS)
BIN
example/server/config.enc
(Stored with Git LFS)
Binary file not shown.
BIN
example/server/server.cert
(Stored with Git LFS)
BIN
example/server/server.cert
(Stored with Git LFS)
Binary file not shown.
Loading…
Reference in a new issue