Skip to content

Commit

Permalink
Merge pull request #1 from resin-io/vpn-certs
Browse files Browse the repository at this point in the history
generate vpn certs + multiple bootstrap fixes
  • Loading branch information
wrboyce committed Oct 8, 2018
2 parents 3a0bed7 + 5d49872 commit adb1f1e
Show file tree
Hide file tree
Showing 17 changed files with 324 additions and 262 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: lint

lint:
shellcheck scripts/*
5 changes: 3 additions & 2 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ Vagrant.configure('2') do |config|
config.vm.provision :shell, inline: 'apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*'

# FIXME: remove `docker login`
config.vm.provision :shell, inline: "docker login --username resindev --password #{ENV.fetch('DOCKERHUB_PASSWORD')}"
config.vm.provision :shell, privileged: false, inline: "docker login --username resindev --password #{ENV.fetch('DOCKERHUB_PASSWORD')}"

config.vm.provision :shell, privileged: false,
inline: "cd /home/vagrant/open-balena && ./scripts/start-project #{ENV.fetch('OPENBALENA_PROJECT_NAME', '')} #{ENV.fetch('OPENBALENA_HOST_NAME', '')}"
# FIXME: -n/-d should only be passed if the relevant ENV var is set
inline: "cd /home/vagrant/open-balena && ./scripts/start-project -p -n #{ENV.fetch('OPENBALENA_PROJECT_NAME', 'demo')} -d #{ENV.fetch('OPENBALENA_DOMAIN', 'openbalena.local')}"
config.vm.provision :shell, privileged: false,
inline: 'cd /home/vagrant/open-balena && ./scripts/run-fig-command up -d || true',
run: 'always'
Expand Down
6 changes: 6 additions & 0 deletions compose/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ services:
SENTRY_DSN:
VPN_HAPROXY_USEPROXYPROTOCOL: 'true'
VPN_SERVICE_API_KEY: ${OPENBALENA_VPN_SERVICE_API_KEY}
VPN_OPENVPN_CA_CRT: ${OPENBALENA_VPN_CA}
VPN_OPENVPN_SERVER_CRT: ${OPENBALENA_VPN_SERVER_CRT}
VPN_OPENVPN_SERVER_KEY: ${OPENBALENA_VPN_SERVER_KEY}
VPN_OPENVPN_SERVER_DH: ${OPENBALENA_VPN_SERVER_DH}
# FIXME: remove all of the following
API_SERVICE_API_KEY: __unused__
PROXY_SERVICE_API_KEY: __unused__5
Expand Down Expand Up @@ -176,6 +180,8 @@ services:
- img.${OPENBALENA_HOST_NAME}
environment:
BALENA_ROOT_CA: ${OPENBALENA_ROOT_CA}
BALENA_HAPROXY_CRT: ${OPENBALENA_ROOT_CRT}
BALENA_HAPROXY_KEY: ${OPENBALENA_ROOT_KEY}
HAPROXY_HOSTNAME: ${OPENBALENA_HOST_NAME}

# FIXME: remove the following
Expand Down
17 changes: 9 additions & 8 deletions haproxy/entry.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/bin/sh
#!/bin/bash -eu

CA_B64="$BALENA_ROOT_CA"
CA_FILE=/etc/ssl/private/root.chain.pem

mkdir -p $(dirname "$CA_FILE")
echo "$CA_B64" | base64 -d >"$CA_FILE"

exec haproxy -f /usr/local/etc/haproxy/haproxy.cfg
HAPROXY_CHAIN=/etc/ssl/private/open-balena.pem
mkdir -p "$(dirname "${HAPROXY_CHAIN}")"
(
echo "${BALENA_HAPROXY_CRT}" | base64 -d
echo "${BALENA_HAPROXY_KEY}" | base64 -d
echo "${BALENA_ROOT_CA}" | base64 -d
) > "${HAPROXY_CHAIN}"
exec haproxy -f /usr/local/etc/haproxy/haproxy.cfg
2 changes: 1 addition & 1 deletion haproxy/haproxy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ backend redirect-to-https-in
frontend https-in
mode http
option forwardfor
bind 127.0.0.1:444 ssl crt /etc/ssl/private/root.chain.pem accept-proxy
bind 127.0.0.1:444 ssl crt /etc/ssl/private/open-balena.pem accept-proxy
reqadd X-Forwarded-Proto:\ https

acl host_api hdr_dom(host) -i "api.${HAPROXY_HOSTNAME}"
Expand Down
79 changes: 0 additions & 79 deletions scripts/_keyid.js

This file was deleted.

33 changes: 33 additions & 0 deletions scripts/gen-root-ca
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash -eu

usage() {
echo "usage: $0 COMMON_NAME [OUT]"
echo
echo " COMMON_NAME the domain name the certificate is valid for, eg. example.com"
echo " OUT path to output directory generated files will be placed in"
echo
}

if [ -z "$1" ]; then
usage
exit 1
fi

CMD="$(realpath "$0")"
DIR="$(dirname "${CMD}")"

CN="$1"
OUT="$(realpath "${2:-.}")"

# shellcheck source=scripts/ssl-common.sh
source "${DIR}/ssl-common.sh"

# Create a secret key and CA file for the self-signed CA
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" init-pki 2>/dev/null
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" --days="${CA_EXPIRY_DAYS}" --req-cn="ca.${CN}" build-ca nopass 2>/dev/null
ROOT_CA="${ROOT_PKI}/ca.crt"
echo "ROOT_CA=${ROOT_CA//$OUT/\$OUT}"

# update indexes and generate CRLs
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" update-db 2>/dev/null
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" gen-crl 2>/dev/null
55 changes: 0 additions & 55 deletions scripts/gen-root-ca-cert

This file was deleted.

34 changes: 34 additions & 0 deletions scripts/gen-root-cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash -eu

usage() {
echo "usage: $0 COMMON_NAME [OUT]"
echo
echo " COMMON_NAME the domain name the certificate is valid for, eg. example.com"
echo " OUT path to output directory generated files will be placed in"
echo
}

if [ -z "$1" ]; then
usage
exit 1
fi

CMD="$(realpath "$0")"
DIR="$(dirname "${CMD}")"

CN="$1"
OUT="$(realpath "${2:-.}")"

# shellcheck source=scripts/ssl-common.sh
source "${DIR}/ssl-common.sh"

# generate default CSR and sign (root + wildcard)
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" --days="${CRT_EXPIRY_DAYS}" --subject-alt-name="DNS:${CN}" build-server-full "*.${CN}" nopass 2>/dev/null
ROOT_CRT="${ROOT_PKI}"'/issued/*.'"${CN}"'.crt'
ROOT_KEY="${ROOT_PKI}"'/private/*.'"${CN}"'.key'
echo "ROOT_CRT=${ROOT_CRT//$OUT/\$OUT}"
echo "ROOT_KEY=${ROOT_KEY//$OUT/\$OUT}"

# update indexes and generate CRLs
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" update-db 2>/dev/null
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" gen-crl 2>/dev/null
62 changes: 32 additions & 30 deletions scripts/gen-token-auth-cert
Original file line number Diff line number Diff line change
@@ -1,42 +1,44 @@
#!/bin/sh

set -e

CMD=$0
DIR=$(dirname "$CMD")

CN=$1
OUT=${2:-.}

CERT_FILE="${OUT}/token-auth"
EXPIRY_DAYS=730
#!/bin/bash -eu

usage() {
echo "usage: $0 HOST_NAME [OUT]"
echo "usage: $0 COMMON_NAME [OUT]"
echo
echo " HOST_NAME the domain name the certificate is valid for, eg. example.com"
echo " OUT path to output directory generated files will be placed in"
echo " COMMON_NAME the domain name the certificate is valid for, eg. example.com"
echo " OUT path to output directory generated files will be placed in"
echo
}

keyid() {
# FIXME: do this in bash or python, not node
nodejs "${DIR}/_keyid.js" "$1"
}

if [ -z "$CN" ]; then
if [ -z "$1" ]; then
usage
exit 1
fi

openssl ecparam -name prime256v1 -genkey -noout -out "${CERT_FILE}.pem" 2>/dev/null
openssl req -x509 -new -nodes -days "${EXPIRY_DAYS}" -key "${CERT_FILE}.pem" -subj "/CN=api.${CN}" -out "${CERT_FILE}.crt" 2>/dev/null
openssl ec -in "${CERT_FILE}.pem" -pubout -outform DER -out "${CERT_FILE}".der 2>/dev/null
keyid "${CERT_FILE}".der >"${CERT_FILE}".kid
CMD="$(realpath "$0")"
DIR="$(dirname "${CMD}")"

CN="$1"
OUT="$(realpath "${2:-.}")"

# shellcheck source=scripts/ssl-common.sh
source "${DIR}/ssl-common.sh"

keyid() {
local der
der="$(openssl ec -in "$1" -pubout -outform DER 2>/dev/null)"
python -c "import sys as S; from base64 import b32encode as B; import hashlib as H; h = H.sha256(); h.update(S.argv[1].encode('ascii')); s = B(h.digest()[:30]).decode('ascii'); S.stdout.write(':'.join([s[i:i+4] for i in range(0, len(s), 4)]))" "${der}"
}

# generate api CSR and sign
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" --days=730 --use-algo=ec --curve=prime256v1 build-server-full "api.${CN}" nopass 2>/dev/null
JWT_CRT="${ROOT_PKI}/issued/api.${CN}.crt"
JWT_KEY="${ROOT_PKI}/private/api.${CN}.key"
echo "JWT_CRT=${JWT_CRT//$OUT/\$OUT}"
echo "JWT_KEY=${JWT_KEY//$OUT/\$OUT}"

# Cleanup
rm "${CERT_FILE}.der"
# update indexes and generate CRLs
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" update-db 2>/dev/null
"$easyrsa_bin" --pki-dir="${ROOT_PKI}" gen-crl 2>/dev/null

echo "PUB=${CERT_FILE}.crt"
echo "KEY=${CERT_FILE}.pem"
echo "KID=${CERT_FILE}.kid"
# generate key ID
JWT_KID="$(keyid "${JWT_CRT}")"
echo "JWT_KID=${JWT_KID//$OUT/\$OUT}"
Loading

0 comments on commit adb1f1e

Please sign in to comment.