Compare commits
23 Commits
wizard
...
cd190d2e3f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd190d2e3f | ||
|
|
13438044e6 | ||
|
|
ecda3d4369 | ||
|
|
3d377634aa | ||
|
|
eb37a1992a | ||
|
|
d834a543ee | ||
|
|
80a59bb0a8 | ||
|
|
2bfdd5543f | ||
|
|
39650c2122 | ||
|
|
4fbf229c0d | ||
|
|
f9347eb2bc | ||
|
|
4123ac3c00 | ||
|
|
f3bd116e91 | ||
|
|
f6492a2c5f | ||
|
|
8f60dad7f6 | ||
|
|
b0f1ae358b | ||
|
|
487dfe2e45 | ||
|
|
d08c3c750e | ||
|
|
83fd98a29b | ||
|
|
f62d110adc | ||
|
|
cba3d0eab9 | ||
|
|
0fee09099a | ||
|
|
8000b32cea |
@@ -7,7 +7,9 @@
|
|||||||
protocols tls1.3
|
protocols tls1.3
|
||||||
client_auth {
|
client_auth {
|
||||||
mode require_and_verify
|
mode require_and_verify
|
||||||
trusted_ca_cert_file /certs/root_ca.crt
|
trust_pool file {
|
||||||
|
pem_file /certs/root_ca.crt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reverse_proxy rest-server:8000
|
reverse_proxy rest-server:8000
|
||||||
|
|||||||
@@ -8,16 +8,15 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
OPTIONS: --no-auth
|
OPTIONS: --no-auth
|
||||||
|
|
||||||
caddy:
|
envoy:
|
||||||
image: caddy:alpine
|
image: envoyproxy/envoy:v1.33-latest
|
||||||
container_name: caddy
|
user: root
|
||||||
|
container_name: envoy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "443:443"
|
- "443:10000"
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
- ./envoy.yaml:/etc/envoy/envoy.yaml:ro
|
||||||
- ./certs/soteria.crt:/certs/soteria.crt:ro
|
- /var/lib/tls:/certs
|
||||||
- ./certs/soteria.key:/certs/soteria.key:ro
|
|
||||||
- ${HOME}/.step/certs/root_ca.crt:/certs/root_ca.crt:ro
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- rest-server
|
- rest-server
|
||||||
62
envoy.yaml
Normal file
62
envoy.yaml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
static_resources:
|
||||||
|
listeners:
|
||||||
|
- name: listener_0
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: 0.0.0.0
|
||||||
|
port_value: 10000
|
||||||
|
filter_chains:
|
||||||
|
- transport_socket:
|
||||||
|
name: envoy.transport_sockets.tls
|
||||||
|
typed_config:
|
||||||
|
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
|
||||||
|
require_client_certificate: true
|
||||||
|
common_tls_context:
|
||||||
|
tls_params:
|
||||||
|
tls_minimum_protocol_version: TLSv1_3
|
||||||
|
validation_context:
|
||||||
|
trusted_ca:
|
||||||
|
filename: /certs/root_ca.crt
|
||||||
|
match_typed_subject_alt_names:
|
||||||
|
- san_type: URI
|
||||||
|
matcher:
|
||||||
|
# exact: proxy-postgres-frontend.example.com
|
||||||
|
exact: spiffe://john-stream.com/ubuntu
|
||||||
|
tls_certificates:
|
||||||
|
- certificate_chain:
|
||||||
|
filename: /certs/cert.pem
|
||||||
|
private_key:
|
||||||
|
filename: /certs/envoy.pem
|
||||||
|
filters:
|
||||||
|
- name: envoy.filters.network.http_connection_manager
|
||||||
|
typed_config:
|
||||||
|
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||||
|
stat_prefix: ingress_http
|
||||||
|
route_config:
|
||||||
|
name: local_route
|
||||||
|
virtual_hosts:
|
||||||
|
- name: local_service
|
||||||
|
domains: ["*"]
|
||||||
|
routes:
|
||||||
|
- match:
|
||||||
|
prefix: "/"
|
||||||
|
route:
|
||||||
|
cluster: rest_server
|
||||||
|
http_filters:
|
||||||
|
- name: envoy.filters.http.router
|
||||||
|
typed_config:
|
||||||
|
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
|
||||||
|
clusters:
|
||||||
|
- name: rest_server
|
||||||
|
connect_timeout: 0.25s
|
||||||
|
type: STRICT_DNS
|
||||||
|
lb_policy: ROUND_ROBIN
|
||||||
|
load_assignment:
|
||||||
|
cluster_name: rest_server
|
||||||
|
endpoints:
|
||||||
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: rest-server
|
||||||
|
port_value: 8000
|
||||||
@@ -102,8 +102,15 @@ install_unit() {
|
|||||||
local filename=$(basename "$template_url")
|
local filename=$(basename "$template_url")
|
||||||
local dest_path=/etc/systemd/system/"$filename"
|
local dest_path=/etc/systemd/system/"$filename"
|
||||||
|
|
||||||
log_info "Installing $filename..."
|
if [ -e "$dest_path" ]; then
|
||||||
|
get_input "CONFIRM_OVERWRITE" "Overwrite $dest_path? (y/n)" "y" "false"
|
||||||
|
if [[ "${CONFIRM_OVERWRITE,,}" != "y" ]]; then
|
||||||
|
echo "Skipping overwrite of ${dest_path}."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Installing $filename..."
|
||||||
curl -sL $template_url | envsubst > "$dest_path"
|
curl -sL $template_url | envsubst > "$dest_path"
|
||||||
log_success "$filename installed to $dest_path"
|
log_success "$filename installed to $dest_path"
|
||||||
}
|
}
|
||||||
@@ -115,31 +122,75 @@ install_unit() {
|
|||||||
echo "Starting Interactive Setup..."
|
echo "Starting Interactive Setup..."
|
||||||
echo "-----------------------------"
|
echo "-----------------------------"
|
||||||
|
|
||||||
# 1. Collect Inputs
|
# Verify required external binaries
|
||||||
# Example:
|
if ! command -v step >/dev/null 2>&1; then
|
||||||
get_input "HOST_NAME" "Enter Hostname" "$(hostname)" "false"
|
# Prompt the user to install the step CLI
|
||||||
get_input "CERT_DIR" "Enter directory for certificates" "$(step path)/certs" "false"
|
get_input "INSTALL_STEP" "The 'step' CLI was not found. Install now? (y/n)" "y" "false"
|
||||||
get_input "CERT_LOCATION" "Enter specific path for cert" "${CERT_DIR}/${HOSTNAME}.crt" "false"
|
|
||||||
get_input "KEY_LOCATION" "Enter specific path for private key" "${CERT_DIR}/${HOSTNAME}.key" "false"
|
|
||||||
|
|
||||||
export CERT_LOCATION=$(readlink -f $CERT_LOCATION)
|
if [[ "${INSTALL_STEP,,}" == "y" ]]; then
|
||||||
export KEY_LOCATION=$(readlink -f $KEY_LOCATION)
|
apt-get update && apt-get install -y --no-install-recommends curl vim gpg ca-certificates
|
||||||
|
curl -fsSL https://packages.smallstep.com/keys/apt/repo-signing-key.gpg -o /etc/apt/trusted.gpg.d/smallstep.asc && \
|
||||||
|
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/smallstep.asc] https://packages.smallstep.com/stable/debian debs main' \
|
||||||
|
| tee /etc/apt/sources.list.d/smallstep.list
|
||||||
|
apt-get update && apt-get -y install step-cli step-ca
|
||||||
|
else
|
||||||
|
log_error "Cannot continue without 'step'. Aborting." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_success "Step CA installed\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_input "CERT_DIR" "Enter directory for certificates" "/var/lib/tls" "false"
|
||||||
|
get_input "CERT_FILENAME" "Name for cert file" "cert.pem" "false"
|
||||||
|
get_input "KEY_FILENAME" "Name for private key" "key.pem" "false"
|
||||||
|
get_input "SPIFFE" "SPIFFE identity" "node" "false"
|
||||||
|
|
||||||
|
|
||||||
|
if [ ! -e "$CERT_DIR" ]; then
|
||||||
|
(umask 077; mkdir -p "${CERT_DIR}")
|
||||||
|
log_info "Created ${CERT_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# These need to get set so that they get filled into the service correctly.
|
||||||
|
export CERT_LOCATION=$(readlink -f ${CERT_DIR}/$CERT_FILENAME)
|
||||||
|
export KEY_LOCATION=$(readlink -f ${CERT_DIR}/$KEY_FILENAME)
|
||||||
|
|
||||||
# 2. Confirm
|
|
||||||
confirm_inputs "CERT_LOCATION" "KEY_LOCATION"
|
confirm_inputs "CERT_LOCATION" "KEY_LOCATION"
|
||||||
|
|
||||||
# 3. Configure
|
if [ ! -e "${CERT_DIR}/root_ca.crt" ]; then
|
||||||
REPO_URL_BASE=https://gitea.john-stream.com/john/soteria/raw/branch/main/
|
step ca root "${CERT_DIR}/root_ca.crt"
|
||||||
SERVICE_TEMPLATE_URL="${REPO_URL_BASE}systemd/cert-renewer.service"
|
fi
|
||||||
TIMER_TEMPLATE_URL="${REPO_URL_BASE}systemd/cert-renewer.timer"
|
|
||||||
|
|
||||||
# 3. Execute
|
if [ ! -f "$CERT_LOCATION" ] || [ ! -f "$KEY_LOCATION" ]; then
|
||||||
# echo "Configuring $HOST_NAME..."
|
hostname=$(hostname -s)
|
||||||
|
ip_address=$(ip -4 addr show dev eth0 | awk '/inet /{print $2}' | cut -d/ -f1)
|
||||||
|
step ca certificate "$hostname" \
|
||||||
|
"${CERT_DIR}/cert.pem" "${CERT_DIR}/key.pem" \
|
||||||
|
--san "$hostname" \
|
||||||
|
--san "$hostname.john-stream.com" \
|
||||||
|
--san "$ip_address" \
|
||||||
|
--san "spiffe://john-stream.com/$SPIFFE" \
|
||||||
|
--provisioner admin
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo -e "${GREEN}=== Cert information ===${NC}" >&2
|
||||||
|
openssl x509 -noout -subject -issuer -ext extendedKeyUsage,subjectAltName -enddate -in "$CERT_LOCATION"
|
||||||
|
|
||||||
|
SERVICE_FILE="cert-renewer.service"
|
||||||
|
TIMER_FILE="cert-renewer.timer"
|
||||||
|
REPO_URL_BASE=https://gitea.john-stream.com/john/soteria/raw/branch/main/
|
||||||
|
SERVICE_TEMPLATE_URL="${REPO_URL_BASE}systemd/${SERVICE_FILE}"
|
||||||
|
TIMER_TEMPLATE_URL="${REPO_URL_BASE}systemd/${TIMER_FILE}"
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo -e "${GREEN}=== Installing rotation services ===${NC}" >&2
|
||||||
install_unit ${SERVICE_TEMPLATE_URL}
|
install_unit ${SERVICE_TEMPLATE_URL}
|
||||||
install_unit ${TIMER_TEMPLATE_URL}
|
install_unit ${TIMER_TEMPLATE_URL}
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo -e "${GREEN}=== Reloading services ===${NC}" >&2
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable --now "$(basename "${TIMER_TEMPLATE_URL}")"
|
systemctl enable --now "${TIMER_FILE}" "${SERVICE_FILE}"
|
||||||
|
systemctl list-unit-files $SERVICE_FILE $TIMER_FILE
|
||||||
systemctl status "$(basename "${SERVICE_TEMPLATE_URL}")" --no-pager
|
|
||||||
systemctl status "$(basename "${TIMER_TEMPLATE_URL}")" --no-pager
|
|
||||||
|
|||||||
@@ -3,22 +3,18 @@ Description=Certificate renewal
|
|||||||
After=network-online.target
|
After=network-online.target
|
||||||
Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production
|
Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production
|
||||||
StartLimitIntervalSec=0
|
StartLimitIntervalSec=0
|
||||||
; PartOf=cert-renewer.target
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
User=root
|
User=root
|
||||||
|
|
||||||
; ExecCondition checks if the certificate is ready for renewal,
|
; ExecCondition checks if the certificate is ready for renewal.
|
||||||
; based on the exit status of the command.
|
; ExecCondition=/usr/bin/step certificate needs-renewal ${CERT_LOCATION}
|
||||||
; (In systemd <242, you can use ExecStartPre= here.)
|
|
||||||
ExecCondition=/usr/bin/step certificate needs-renewal ${CERT_LOCATION}
|
|
||||||
|
|
||||||
; ExecStart renews the certificate, if ExecStartPre was successful.
|
; ExecStart renews the certificate, if ExecCondition was successful.
|
||||||
ExecStart=/usr/bin/step ca renew --force ${CERT_LOCATION} ${KEY_LOCATION}
|
ExecStart=/usr/bin/step ca renew --force ${CERT_LOCATION} ${KEY_LOCATION}
|
||||||
|
|
||||||
; ExecStartPost=/usr/bin/openssl x509 -noout -enddate -in ${CERT_LOCATION}
|
ExecStartPost=/usr/bin/openssl x509 -noout -subject -issuer -enddate -in ${CERT_LOCATION}
|
||||||
; ExecStartPost=/usr/bin/docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
Reference in New Issue
Block a user