mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 07:00:25 +00:00
NOISSUE - Fetch certs (#383)
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
FROM golang:1.25.5-alpine3.22 AS builder
|
||||
FROM golang:1.26rc2-alpine3.22 AS builder
|
||||
ARG SVC
|
||||
ARG GOARCH
|
||||
ARG GOARM
|
||||
|
||||
@@ -41,10 +41,14 @@ AM_CERTS_SECRET=12345678
|
||||
AM_CERTS_OPENBAO_HOST=http://certs-openbao:8200
|
||||
AM_CERTS_OPENBAO_APP_ROLE=absmach
|
||||
AM_CERTS_OPENBAO_APP_SECRET=absmach
|
||||
AM_CERTS_OPENBAO_SECRET_ID_TTL=87600h
|
||||
AM_CERTS_OPENBAO_SECRET_ID_TTL=720h
|
||||
AM_CERTS_OPENBAO_NAMESPACE=
|
||||
AM_CERTS_OPENBAO_PKI_PATH=pki
|
||||
AM_CERTS_OPENBAO_ROLE=absmach
|
||||
AM_CERTS_SERVICE_TOKEN_PATH=/openbao/service_token
|
||||
AM_CERTS_SECRET_ID_PATH=/openbao/secret_id
|
||||
AM_CERTS_SECRET_RENEW_THRESHOLD=24h
|
||||
AM_CERTS_SECRET_CHECK_INTERVAL=1h
|
||||
AM_CERTS_OPENBAO_PKI_CA_CN=Abstract Machines Certificate Authority
|
||||
AM_CERTS_OPENBAO_PKI_CA_OU=Abstract Machines
|
||||
AM_CERTS_OPENBAO_PKI_CA_O=AbstractMachines
|
||||
|
||||
@@ -16,8 +16,10 @@ services:
|
||||
image: ghcr.io/absmach/certs:${AM_CERTS_RELEASE_TAG}
|
||||
container_name: certs
|
||||
depends_on:
|
||||
- openbao
|
||||
- certs-db
|
||||
openbao:
|
||||
condition: service_healthy
|
||||
certs-db:
|
||||
condition: service_started
|
||||
restart: on-failure
|
||||
networks:
|
||||
- certs-base-net
|
||||
@@ -35,6 +37,7 @@ services:
|
||||
AM_CERTS_OPENBAO_NAMESPACE: ${AM_CERTS_OPENBAO_NAMESPACE}
|
||||
AM_CERTS_OPENBAO_PKI_PATH: ${AM_CERTS_OPENBAO_PKI_PATH}
|
||||
AM_CERTS_OPENBAO_ROLE: ${AM_CERTS_OPENBAO_ROLE}
|
||||
AM_CERTS_OPENBAO_SECRET_ID_TTL: ${AM_CERTS_OPENBAO_SECRET_ID_TTL}
|
||||
AM_CERTS_DB_HOST: ${AM_CERTS_DB_HOST}
|
||||
AM_CERTS_DB_PORT: ${AM_CERTS_DB_PORT}
|
||||
AM_CERTS_DB_USER: ${AM_CERTS_DB_USER}
|
||||
@@ -52,9 +55,15 @@ services:
|
||||
AM_DOMAINS_GRPC_CLIENT_KEY: ${AM_DOMAINS_GRPC_CLIENT_KEY:+/domains-grpc-client.key}
|
||||
AM_DOMAINS_GRPC_SERVER_CA_CERTS: ${AM_DOMAINS_GRPC_SERVER_CA_CERTS:+/domains-grpc-server-ca.crt}
|
||||
AM_CERTS_SECRET: ${AM_CERTS_SECRET}
|
||||
AM_CERTS_SERVICE_TOKEN_PATH: ${AM_CERTS_SERVICE_TOKEN_PATH}
|
||||
AM_CERTS_SECRET_ID_PATH: ${AM_CERTS_SECRET_ID_PATH}
|
||||
AM_CERTS_SECRET_RENEW_THRESHOLD: ${AM_CERTS_SECRET_RENEW_THRESHOLD}
|
||||
AM_CERTS_SECRET_CHECK_INTERVAL: ${AM_CERTS_SECRET_CHECK_INTERVAL}
|
||||
ports:
|
||||
- ${AM_CERTS_HTTP_PORT}:${AM_CERTS_HTTP_PORT}
|
||||
- ${AM_CERTS_GRPC_PORT}:${AM_CERTS_GRPC_PORT}
|
||||
volumes:
|
||||
- openbao-data:/openbao:ro
|
||||
|
||||
certs-db:
|
||||
image: postgres:16.2-alpine
|
||||
@@ -80,6 +89,12 @@ services:
|
||||
- certs-base-net
|
||||
ports:
|
||||
- 8200:8200
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "test -f /opt/openbao/data/service_token"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
start_period: 30s
|
||||
environment:
|
||||
- BAO_ADDR=http://127.0.0.1:8200
|
||||
- BAO_LOG_LEVEL=info
|
||||
|
||||
@@ -27,6 +27,66 @@ EOF
|
||||
|
||||
export BAO_ADDR=http://127.0.0.1:8200
|
||||
|
||||
create_pki_policy() {
|
||||
cat > /opt/openbao/config/pki-policy.hcl << EOF
|
||||
path "pki_int/issue/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/sign/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/sign-verbatim/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/certs" {
|
||||
capabilities = ["list"]
|
||||
}
|
||||
path "pki_int/cert/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/revoke" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/ca_chain" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/crl" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/ca_chain" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/crl" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "auth/token/renew-self" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
path "auth/token/lookup-self" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "sys/renew/*" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
path "auth/approle/role/${AM_CERTS_OPENBAO_PKI_ROLE}/secret-id" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "auth/approle/role/${AM_CERTS_OPENBAO_PKI_ROLE}/secret-id-accessor/lookup" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "auth/approle/role/${AM_CERTS_OPENBAO_PKI_ROLE}/secret-id-accessor/destroy" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
EOF
|
||||
bao policy write pki-policy /opt/openbao/config/pki-policy.hcl > /dev/null
|
||||
}
|
||||
|
||||
# Check if we have pre-configured unseal keys and root token
|
||||
if [ -n "$AM_CERTS_OPENBAO_UNSEAL_KEY_1" ] && [ -n "$AM_CERTS_OPENBAO_UNSEAL_KEY_2" ] && [ -n "$AM_CERTS_OPENBAO_UNSEAL_KEY_3" ] && [ -n "$AM_CERTS_OPENBAO_ROOT_TOKEN" ]; then
|
||||
echo "Using pre-configured unseal keys and root token..."
|
||||
@@ -229,6 +289,16 @@ if [ ! -f /opt/openbao/data/configured ]; then
|
||||
|
||||
echo "Intermediate CA certificate signed successfully!"
|
||||
|
||||
bao write pki/config/urls \
|
||||
issuing_certificates='http://127.0.0.1:8200/v1/pki/ca' \
|
||||
crl_distribution_points='http://127.0.0.1:8200/v1/pki/crl' \
|
||||
ocsp_servers='http://127.0.0.1:8200/v1/pki/ocsp' > /dev/null
|
||||
|
||||
bao write pki_int/config/urls \
|
||||
issuing_certificates='http://127.0.0.1:8200/v1/pki_int/ca' \
|
||||
crl_distribution_points='http://127.0.0.1:8200/v1/pki_int/crl' \
|
||||
ocsp_servers='http://127.0.0.1:8200/v1/pki_int/ocsp' > /dev/null
|
||||
|
||||
bao write pki_int/intermediate/set-signed certificate="$INTERMEDIATE_CERT" > /dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
@@ -240,16 +310,6 @@ if [ ! -f /opt/openbao/data/configured ]; then
|
||||
|
||||
echo "$INTERMEDIATE_CERT" > /opt/openbao/data/intermediate_ca.pem
|
||||
|
||||
bao write pki/config/urls \
|
||||
issuing_certificates='http://127.0.0.1:8200/v1/pki/ca' \
|
||||
crl_distribution_points='http://127.0.0.1:8200/v1/pki/crl' \
|
||||
ocsp_servers='http://127.0.0.1:8200/v1/pki/ocsp' > /dev/null
|
||||
|
||||
bao write pki_int/config/urls \
|
||||
issuing_certificates='http://127.0.0.1:8200/v1/pki_int/ca' \
|
||||
crl_distribution_points='http://127.0.0.1:8200/v1/pki_int/crl' \
|
||||
ocsp_servers='http://127.0.0.1:8200/v1/pki_int/ocsp' > /dev/null
|
||||
|
||||
ROLE_CMD="bao write pki_int/roles/${AM_CERTS_OPENBAO_PKI_ROLE} \
|
||||
allow_any_name=true \
|
||||
enforce_hostnames=false \
|
||||
@@ -271,66 +331,13 @@ if [ ! -f /opt/openbao/data/configured ]; then
|
||||
ext_key_usage=\"ServerAuth,ClientAuth,OCSPSigning\" \
|
||||
use_csr_common_name=true \
|
||||
use_csr_sans=true \
|
||||
copy_extensions=true \
|
||||
allowed_extensions=\"*\" \
|
||||
basic_constraints_valid_for_non_ca=true \
|
||||
max_ttl=720h \
|
||||
ttl=720h"
|
||||
|
||||
eval "$ROLE_CMD" > /dev/null
|
||||
|
||||
# Create PKI policy
|
||||
cat > /opt/openbao/config/pki-policy.hcl << EOF
|
||||
path "pki_int/issue/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/sign/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/sign-verbatim/${AM_CERTS_OPENBAO_PKI_ROLE}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/certs" {
|
||||
capabilities = ["list"]
|
||||
}
|
||||
path "pki_int/cert/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/revoke" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
path "pki_int/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/ca_chain" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki_int/crl" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/ca_chain" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
path "pki/crl" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
# Token management
|
||||
path "auth/token/renew-self" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
path "auth/token/lookup-self" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
# System lease renewal
|
||||
path "sys/renew/*" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
EOF
|
||||
|
||||
bao policy write pki-policy /opt/openbao/config/pki-policy.hcl > /dev/null
|
||||
create_pki_policy
|
||||
|
||||
# Create AppRole
|
||||
SECRET_ID_TTL="${AM_CERTS_OPENBAO_SECRET_ID_TTL}"
|
||||
@@ -346,9 +353,13 @@ EOF
|
||||
bao write auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/role-id role_id="$AM_CERTS_OPENBAO_APP_ROLE" > /dev/null
|
||||
fi
|
||||
|
||||
# Set custom secret ID if provided
|
||||
# Set custom secret ID if provided, otherwise generate one
|
||||
if [ -n "$AM_CERTS_OPENBAO_APP_SECRET" ]; then
|
||||
bao write auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/custom-secret-id secret_id="$AM_CERTS_OPENBAO_APP_SECRET" > /dev/null
|
||||
echo "$AM_CERTS_OPENBAO_APP_SECRET" > /opt/openbao/data/secret_id
|
||||
else
|
||||
GENERATED_SECRET_ID=$(bao write -field=secret_id -force auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/secret-id)
|
||||
echo "$GENERATED_SECRET_ID" > /opt/openbao/data/secret_id
|
||||
fi
|
||||
|
||||
# Generate service token for additional access
|
||||
@@ -364,7 +375,7 @@ EOF
|
||||
touch /opt/openbao/data/configured
|
||||
echo "OpenBao configuration completed successfully!"
|
||||
else
|
||||
echo "OpenBao already configured, skipping setup..."
|
||||
echo "OpenBao already configured, verifying and updating configuration..."
|
||||
|
||||
# Restore namespace if it exists
|
||||
if [ -f /opt/openbao/data/namespace ] && [ -n "$AM_CERTS_OPENBAO_NAMESPACE" ]; then
|
||||
@@ -374,17 +385,68 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$AM_CERTS_OPENBAO_APP_SECRET" ]; then
|
||||
echo "Verifying existing secret ID validity..."
|
||||
if ! bao write -field=client_token auth/approle/login role_id="$AM_CERTS_OPENBAO_APP_ROLE" secret_id="$AM_CERTS_OPENBAO_APP_SECRET" > /dev/null 2>&1; then
|
||||
echo "================================"
|
||||
echo "ERROR: Secret ID has expired!"
|
||||
echo "Please regenerate AM_CERTS_OPENBAO_APP_SECRET"
|
||||
echo "and update your environment configuration"
|
||||
echo "================================"
|
||||
else
|
||||
echo "Existing secret ID is valid"
|
||||
# Check if AppRole role exists, create if missing
|
||||
if ! bao read auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}" > /dev/null 2>&1; then
|
||||
if ! bao auth enable approle > /tmp/auth_success 2>/tmp/auth_error; then
|
||||
if ! grep -q "already in use" /tmp/auth_error; then
|
||||
echo "ERROR: Failed to enable AppRole auth method:" >&2
|
||||
cat /tmp/auth_error >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
rm -f /tmp/auth_error /tmp/auth_success
|
||||
|
||||
create_pki_policy
|
||||
|
||||
SECRET_ID_TTL="${AM_CERTS_OPENBAO_SECRET_ID_TTL}"
|
||||
bao write auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}" \
|
||||
token_policies=pki-policy \
|
||||
token_ttl=1h \
|
||||
token_max_ttl=4h \
|
||||
bind_secret_id=true \
|
||||
secret_id_ttl="$SECRET_ID_TTL" > /dev/null
|
||||
|
||||
if [ -n "$AM_CERTS_OPENBAO_APP_ROLE" ]; then
|
||||
bao write auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/role-id role_id="$AM_CERTS_OPENBAO_APP_ROLE" > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
SECRET_ID_VALID=false
|
||||
if [ -n "$AM_CERTS_OPENBAO_APP_SECRET" ]; then
|
||||
if bao write -field=client_token auth/approle/login role_id="$AM_CERTS_OPENBAO_APP_ROLE" secret_id="$AM_CERTS_OPENBAO_APP_SECRET" > /dev/null 2>&1; then
|
||||
SECRET_ID_VALID=true
|
||||
echo "$AM_CERTS_OPENBAO_APP_SECRET" > /opt/openbao/data/secret_id
|
||||
fi
|
||||
elif [ -f /opt/openbao/data/secret_id ]; then
|
||||
STORED_SECRET_ID=$(cat /opt/openbao/data/secret_id)
|
||||
if [ -n "$STORED_SECRET_ID" ]; then
|
||||
ROLE_ID=$(bao read -field=role_id auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/role-id)
|
||||
if bao write -field=client_token auth/approle/login role_id="$ROLE_ID" secret_id="$STORED_SECRET_ID" > /dev/null 2>&1; then
|
||||
SECRET_ID_VALID=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SECRET_ID_VALID" = "false" ]; then
|
||||
NEW_SECRET_ID=$(bao write -field=secret_id -force auth/approle/role/"${AM_CERTS_OPENBAO_PKI_ROLE}"/secret-id)
|
||||
|
||||
if [ -z "$NEW_SECRET_ID" ]; then
|
||||
echo "ERROR: Failed to generate new secret ID" >&2
|
||||
else
|
||||
echo "$NEW_SECRET_ID" > /opt/openbao/data/secret_id
|
||||
echo "Generated new secret ID for certs service"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Regenerate service token
|
||||
SERVICE_TOKEN=$(bao write -field=token auth/token/create \
|
||||
policies=pki-policy \
|
||||
ttl=24h \
|
||||
renewable=true \
|
||||
display_name="certs-service" 2>/dev/null)
|
||||
|
||||
if [ -n "$SERVICE_TOKEN" ]; then
|
||||
echo "SERVICE_TOKEN=$SERVICE_TOKEN" > /opt/openbao/data/service_token
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user