fetchcert: Add script to fetch certs from K8s
Since Fedora CoreOS machines are not managed by Ansible, we need another way to keep the HTTPS certificate up-to-date. To that end, I've added the `fetchcert.sh` script, along with a corresponding systemd service and timer unit, that will fetch the latest certificate from the Secret resource managed by the Kubernetes API. The script authenticates with a long-lived bearer token associated with a particular Kubernetes service account and downloads the current Secret to a local file. If the certificate in the Secret is different than the one already in place, the certificate and key files are updated and nginx is reloaded.master
parent
222f40426a
commit
d907b47db1
|
@ -1,2 +1,3 @@
|
|||
*.ign
|
||||
frigate.env
|
||||
*.token
|
||||
|
|
3
Makefile
3
Makefile
|
@ -20,6 +20,9 @@ $(foreach t,$(wildcard *.yaml),$(eval $(call genrules,$(t))))
|
|||
%.env: %.env.gpg
|
||||
gpg2 --decrypt $< > $@
|
||||
|
||||
%.token: %.token.gpg
|
||||
gpg2 --decrypt $< > $@
|
||||
|
||||
publish: \
|
||||
nvr1.ign
|
||||
rsync -rti $^ files.pyrocufflink.blue:public_html/
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
[Unit]
|
||||
Description=Fetch HTTPS certificate from Kubernetes Secret API
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh /etc/fetchcert/fetchcert.sh default pyrocufflink-cert
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/etc/pki/nginx
|
||||
CapabilityBoundingSet=CAP_CHOWN
|
||||
DeviceAllow=
|
||||
DevicePolicy=closed
|
||||
LockPersonality=yes
|
||||
MemoryDenyWriteExecute=yes
|
||||
NoNewPrivileges=yes
|
||||
PrivateDevices=yes
|
||||
PrivateUsers=yes
|
||||
PrivateTmp=yes
|
||||
ProcSubset=pid
|
||||
ProtectClock=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectHome=yes
|
||||
ProtectHostname=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectProc=invisible
|
||||
ProtectSystem=strict
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
RestrictSUIDSGID=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged @resources
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
# vim: set sw=4 ts=4 sts=4 et :
|
||||
|
||||
namespace=$2
|
||||
secret=$3
|
||||
|
||||
keyout=/etc/pki/nginx/private/server.key
|
||||
crtout=/etc/pki/nginx/server.crt
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'rm -rf "${tmpdir}"' INT TERM QUIT EXIT
|
||||
|
||||
cat > "${tmpdir}"/ca.crt <<EOF
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC/jCCAeagAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
|
||||
cm5ldGVzMB4XDTIyMDgwMTAyNTUzM1oXDTMyMDcyOTAyNTUzM1owFTETMBEGA1UE
|
||||
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMs6
|
||||
2PUOzIClsAgPv1Mn9CTwzSFMntAn7OppwK5BQ4E5Vd1yMjz3p0uA1ZINv1ORorG0
|
||||
mLl95C7y+CWUGPx+stHKQr/40sLGyypbX+AfjoPzHiDbIcbZEff8X5RwKqzmT9V7
|
||||
Yt29KewADod0z+fqNYa62MJDaUunfwaV8kKFU/WJM8IKv2eJxAtWzvK3iHAFhx0j
|
||||
Xo4TlyINL9V9UMKLf12w6CA3G41uZIBCN3G7aJEm++eGoMdrPZUXlbCpbSztO85/
|
||||
hbulVs+0hCIxWiI+mRmB5OoWlRYL4jA45oK/RtpEqSwZ95zlGNAChmH7rb0pTtNf
|
||||
N0/C2wKAEL4POLx9kscCAwEAAaNZMFcwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
|
||||
/wQFMAMBAf8wHQYDVR0OBBYEFHYActCjEWdtsA+Ju25gxJh/vaLQMBUGA1UdEQQO
|
||||
MAyCCmt1YmVybmV0ZXMwDQYJKoZIhvcNAQELBQADggEBAAfkYHecXUwyqvMSXmqr
|
||||
ETqEzDCBini14s89VDhaDHOXBID9TKMVyeePdEYcPAJz3wo8fbx/+TL37K6hEuo+
|
||||
7bUaamaumznsjg9L0Hth19GvuRKMXJlEpndRmE5K9hnaDLr94MLg9n1qGcEOt6tw
|
||||
O6X5qqHf9AuuL39vt1+kSw6PeZZFZNMDZ8BdiTssw4btjQ2bsWu0wSiOSz/F8iRf
|
||||
2vN5An5dheroDsFs4dZ9gnJ69TmqV1YqQxfRWqCxzfNJbgVm6AoBPwhL1JRuAU4N
|
||||
3nCNoM9n2tLFDojT4un1778UVU91PtcBVdM9Nq+RC2jhXIyLBqsEK0ofOqFYqj3F
|
||||
0EQ=
|
||||
-----END CERTIFICATE-----
|
||||
EOF
|
||||
|
||||
curl -fsSL \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer $(cat /etc/fetchcert/token)" \
|
||||
--cacert "${tmpdir}"/ca.crt \
|
||||
https://kubernetes.pyrocufflink.blue:6443/api/v1/namespaces/${namespace}/secrets/${secret} \
|
||||
-o "${tmpdir}"/secret.json \
|
||||
|| exit
|
||||
|
||||
jq -r '.data["tls.key"]' "${tmpdir}"/secret.json \
|
||||
| base64 -d > "${tmpdir}"/server.key
|
||||
jq -r '.data["tls.crt"]' "${tmpdir}"/secret.json | \
|
||||
base64 -d > "${tmpdir}"/server.crt
|
||||
|
||||
if [ "$(b2sum < "${tmpdir}"/server.crt)" != "$(b2sum < "${crtout}")" ]; then
|
||||
install -m u=rw,go= -o 101 -g 101 "${tmpdir}"/server.key "${keyout}"
|
||||
install -m u=rw,go=r -o root -g root "${tmpdir}"/server.crt "${crtout}"
|
||||
chcon -t container_file_t "${keyout}" "${crtout}"
|
||||
echo 'Certificate updated, reloading nginx ...' >&2
|
||||
podman exec -it systemd-nginx nginx -s reload
|
||||
fi
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Periodically fetch certificate from Kubernetes
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 0:0:0
|
||||
RandomizedDelaySec=8h
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
|
@ -0,0 +1,22 @@
|
|||
variant: fcos
|
||||
version: 1.4.0
|
||||
|
||||
storage:
|
||||
files:
|
||||
- path: /etc/fetchcert/fetchcert.sh
|
||||
mode: 0755
|
||||
contents:
|
||||
local: fetchcert.sh
|
||||
- path: /etc/systemd/system/fetchcert.service
|
||||
mode: 0644
|
||||
contents:
|
||||
local: fetchcert.service
|
||||
- path: /etc/systemd/system/fetchcert.timer
|
||||
mode: 0644
|
||||
contents:
|
||||
local: fetchcert.timer
|
||||
|
||||
systemd:
|
||||
units:
|
||||
- name: fetchcert.timer
|
||||
enabled: true
|
|
@ -1,6 +1,11 @@
|
|||
variant: fcos
|
||||
version: 1.4.0
|
||||
|
||||
ignition:
|
||||
config:
|
||||
merge:
|
||||
- local: fetchcert.ign
|
||||
|
||||
storage:
|
||||
files:
|
||||
- path: /etc/containers/systemd/nginx.container
|
||||
|
|
Loading…
Reference in New Issue