Skip to content

Commit

Permalink
Better certificate generation
Browse files Browse the repository at this point in the history
  • Loading branch information
chregu committed Aug 14, 2019
1 parent 9b3bfc1 commit 01a2878
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 27 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@

# Local
.env


etc/
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

Create certificates for HTTPS
```bash
chmod u+x ./scripts/generate-certificates.sh
./scripts/generate-certificates.sh
./scripts/pontsun generate-cert
```
You need to add the generated certificate `etc/certificates/docker.rootCA.crt` to your browser authorities and trust related websites.
On OS X, this was automatically added to your keychain if the command above worked correctly. No need to do anything else.
```
You need to add the generated certificate `certificates/docker.rootCA.crt` to your browser authorities and trust related websites.
Start Traefik and Portainer
```bash
Expand Down
5 changes: 5 additions & 0 deletions build/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd $DIR
docker build -t liip/pontsun-helper:latest helper
5 changes: 5 additions & 0 deletions build/helper/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM debian:stable-slim

RUN apt-get update

RUN apt-get install -y openssl gnutls-bin
2 changes: 0 additions & 2 deletions config/openssl.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,3 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ${ENV::PROJECT_NAME}.${ENV::PROJECT_EXTENSION}
DNS.2 = *.${ENV::PROJECT_NAME}.${ENV::PROJECT_EXTENSION}
5 changes: 4 additions & 1 deletion containers/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ PROJECT_NAME=pontsun
PROJECT_EXTENSION=test
PROJECT_DOMAIN=pontsun.test

### Images tags

# could also be ~/.pontsun
PONTSUN_DIR_ETC=../etc

### Images tags
PORTAINER_TAG=1.19.2
TRAEFIK_TAG=1.7.2-alpine
2 changes: 1 addition & 1 deletion containers/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ services:
- '80:80'
- '443:443'
volumes:
- ../certificates/:/certs/
- ${PONTSUN_DIR_ETC:-../etc/}/certificates/:/certs/
- /var/run/docker.sock:/var/run/docker.sock
labels:
- 'traefik.enable=true'
Expand Down
Empty file added etc/.gitkeep
Empty file.
13 changes: 13 additions & 0 deletions scripts/env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash


DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

export PONTSUN_DIR=${PONTSUN_DIR:-$DIR/../}
export PONTSUN_DIR_ETC=${PONTSUN_DIR_ETC:-$PONTSUN_DIR/etc/}

# Load env file
set -a
# load env variables but only if not set already
test -f $PONTSUN_DIR/containers/.env && source <(grep -v '^\s*#' $PONTSUN_DIR/containers/.env | sed -E 's|^ *([^=]+)=(.*)$|: ${\1=\2}; export \1|g')

28 changes: 8 additions & 20 deletions scripts/generate-certificates.sh
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
#!/bin/bash
set -e
#!/usr/bin/env bash

# Load env file
set -a
test -f $(dirname $0)/../containers/.env && source $(dirname $0)/../containers/.env
set +a

cd $(dirname $0)/../certificates
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

if [ -f $PROJECT_NAME.crt ]; then
echo "Certificate already exists."
else
subj="/C=CH/ST=FR/L=Fribourg/O=Liip/OU=Pontsun/CN=$PROJECT_NAME.$PROJECT_EXTENSION"
. $DIR/env.sh

openssl genrsa -out $PROJECT_NAME.rootCA.key 4096
openssl req -x509 -new -nodes -key $PROJECT_NAME.rootCA.key -sha256 -days 1024 -out $PROJECT_NAME.rootCA.crt -subj "$subj"
mkdir -p $PONTSUN_DIR_ETC/certificates/

openssl genrsa -out $PROJECT_NAME.key 4096
openssl req -new -sha256 -subj "$subj" -key $PROJECT_NAME.key -out $PROJECT_NAME.csr -config ../config/openssl.cnf
openssl x509 -req -in $PROJECT_NAME.csr -CA $PROJECT_NAME.rootCA.crt -CAkey $PROJECT_NAME.rootCA.key -CAcreateserial -out $PROJECT_NAME.crt -days 365 -extensions v3_req -extfile ../config/openssl.cnf

cat $PROJECT_NAME.crt $PROJECT_NAME.key > $PROJECT_NAME.pem
chmod 600 $PROJECT_NAME.key $PROJECT_NAME.pem
fi
docker run --rm -v $DIR/../:/generate/ -v $PONTSUN_DIR_ETC/certificates/:/certs/ -it docker.gitlab.liip.ch/druids/docker-toolbox/pontsun-helper:latest /generate/scripts/helper/docker-generate-certificates.sh $1
if [[ "$OSTYPE" == "darwin"* ]]; then
$DIR/install-cert-macos.sh $PONTSUN_DIR_ETC/certificates/$PROJECT_NAME.rootCA.crt
fi
59 changes: 59 additions & 0 deletions scripts/helper/docker-generate-certificates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash
set -e

# Load env file
set -a
test -f $(dirname $0)/../../containers/.env && source $(dirname $0)/../../containers/.env
set +a

# check if there are certs in the local directory
cd /certs/
if [ -f $PROJECT_NAME.crt ] && [ -z $1 ]; then
echo "Certificate already exists in local certificates directory."
else
if [ -f $PROJECT_NAME.crt ]; then
# get existing alt names from the current cert, so that we can reuse them
EXISTING_ALT_NAMES=$(certtool -i < /certs/$PROJECT_NAME.crt | grep DNSname | cut -f 2 -d ":" | sed -e 's/^[[:space:]]*//')
ALT_NAMES=${EXISTING_ALT_NAMES}
else
ALT_NAMES=$PROJECT_NAME.$PROJECT_EXTENSION
ALT_NAMES=${ALT_NAMES}$'\n'*.$PROJECT_NAME.$PROJECT_EXTENSION
fi
# add additional altnames
if [[ ! -z $1 ]]; then
ALT_NAMES=${ALT_NAMES}$'\n'$1
ALT_NAMES=${ALT_NAMES}$'\n'*.$1
fi

# sort them and make them uniq to avoid duplicates
ALT_NAMES=$(echo $"${ALT_NAMES}" | sort | uniq)
EXISTING_ALT_NAMES=$(echo $"${EXISTING_ALT_NAMES}" | sort | uniq)

if [[ $ALT_NAMES == $EXISTING_ALT_NAMES ]]; then
echo "Certificate wouldn't change, don't generate a new one."
exit 0;
fi

I=1
#write the correct config lines
while read -r line; do
if [[ ! -z $line ]]; then
ALT_NAMES_CONFIG=$ALT_NAMES_CONFIG$'\n'"DNS.$I = $line"
((I++))
fi
done <<< "$ALT_NAMES"

subj="/C=CH/ST=FR/L=Fribourg/O=Liip/CN=$PROJECT_NAME.$PROJECT_EXTENSION"
# don't regenerate rootCA, if it already exists
if [ ! -f $PROJECT_NAME.rootCA.key ]; then
openssl genrsa -out $PROJECT_NAME.rootCA.key 4096
openssl req -x509 -new -nodes -key $PROJECT_NAME.rootCA.key -sha256 -days 1024 -out $PROJECT_NAME.rootCA.crt -subj "$subj"
fi
openssl genrsa -out $PROJECT_NAME.key 4096
openssl req -new -sha256 -subj "$subj" -key $PROJECT_NAME.key -out $PROJECT_NAME.csr -config <(cat /generate/config/openssl.cnf <(printf "$ALT_NAMES_CONFIG"))
openssl x509 -req -in $PROJECT_NAME.csr -CA $PROJECT_NAME.rootCA.crt -CAkey $PROJECT_NAME.rootCA.key -CAcreateserial -out $PROJECT_NAME.crt -days 365 -extensions v3_req -extfile <(cat /generate/config/openssl.cnf <(printf "$ALT_NAMES_CONFIG"))

cat $PROJECT_NAME.crt $PROJECT_NAME.key > $PROJECT_NAME.pem
chmod 600 $PROJECT_NAME.key $PROJECT_NAME.pem
fi

19 changes: 19 additions & 0 deletions scripts/install-cert-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
# base from https://gist.github.com/koop/84254d5214495e6fc49db3284c9b7772
# Usage
# $ ./install-cert-macos.sh "/path/to/cert"

CERT_PATH=$1



# First, grab the SHA-1 from the provided SSL cert.
CERT_SHA1=$(openssl x509 -in "$CERT_PATH" -sha1 -noout -fingerprint | cut -d "=" -f2 | sed "s/://g")

# Next, grab the SHA-1s of any standard.dev certs in the keychain.
# Don't return an error code if nothing is found.
EXISTING_CERT_SHAS=$(security find-certificate -a -c "$PROJECT_NAME.$PROJECT_EXTENSION" -Z /Library/Keychains/System.keychain | grep "SHA-1") || true
echo "$EXISTING_CERT_SHAS" | grep -q "$CERT_SHA1" || {
echo "Installing $CERT_PATH into your Keychain"
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "$CERT_PATH"
}
43 changes: 43 additions & 0 deletions scripts/pontsun
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
show_help() {
echo "Usage: pontsun [options] <command> [<args>]"
echo
echo " -h Print this help."
echo
echo "Common commands:"
echo " generate-cert [host] Generates needed ssl certificates"
}

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

OPTIND=1 # Reset in case getopts has been used previously in the shell.

while getopts "hv" opt; do
case "$opt" in
h*)
show_help
exit 0
;;
esac
done

shift $((OPTIND-1))

[ "${1:-}" = "--" ] && shift

if [ -z $1 ]; then
show_help
exit 0
fi

case "$1" in
generate-cert)
$DIR/generate-certificates.sh $2
;;
*)
echo "No such command: $1"
show_help
;;
esac


0 comments on commit 01a2878

Please sign in to comment.