mirror of
https://github.com/rkivalin/certforge.git
synced 2026-10-13 00:00:42 +00:00
Initial implementation of certforge ACME certificate manager
Rust CLI tool for automated ACME certificate management with: - DNS-01 challenge via RFC 2136 dynamic DNS updates with TSIG auth - DANE TLSA record publication (RFC 6698/7671/7672) - systemd credential integration (systemd-creds encrypt/decrypt) - systemd unit management via D-Bus (zbus) - Post-renewal hooks (systemctl reload/restart, arbitrary commands) - Key rotation with DANE pre-publication protocol - TOML configuration with per-zone DNS overrides Tested against Let's Encrypt staging. 12 unit tests, zero warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Certforge ACME certificate renewal
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/certforge renew
|
||||
|
||||
# Hardening
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/etc/certforge/certs /var/lib/certforge /etc/credstore.encrypted
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=yes
|
||||
ProtectHome=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectControlGroups=yes
|
||||
RestrictSUIDSGID=yes
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Certforge daily certificate check
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 02:30:00
|
||||
RandomizedDelaySec=1800
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,85 @@
|
||||
# Example certforge configuration
|
||||
#
|
||||
# Full documentation: see the project README
|
||||
|
||||
[acme]
|
||||
directory_url = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
# Use staging for testing:
|
||||
# directory_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
# ACME account key: stored as encrypted systemd credential
|
||||
account_key_credential = "/etc/credstore.encrypted/acme-account-key"
|
||||
# Or as a plain file:
|
||||
# account_key_path = "/etc/certforge/account.key"
|
||||
|
||||
contact = ["mailto:admin@example.com"]
|
||||
|
||||
# Default DNS server for RFC 2136 updates
|
||||
[dns.defaults]
|
||||
server = "ns1.example.com"
|
||||
tsig_key_credential = "/etc/credstore.encrypted/dns-tsig-key"
|
||||
# tsig_key_path = "/etc/certforge/tsig.key"
|
||||
tsig_key_name = "certforge-update."
|
||||
tsig_algorithm = "hmac-sha256"
|
||||
port = 53
|
||||
protocol = "tcp"
|
||||
|
||||
# Per-zone DNS overrides (optional)
|
||||
# [dns.zones."example.org"]
|
||||
# server = "ns2.example.org"
|
||||
# tsig_key_credential = "/etc/credstore.encrypted/dns-tsig-org"
|
||||
|
||||
# Mail server certificate
|
||||
[[certificate]]
|
||||
name = "mail"
|
||||
domains = ["mail.example.com"]
|
||||
key_type = "ecdsa-p256"
|
||||
key_credential = "/etc/credstore.encrypted/mail-tls-key"
|
||||
cert_path = "/etc/certforge/certs/mail.pem"
|
||||
renew_before_days = 30
|
||||
rotate_key = false
|
||||
|
||||
# DANE TLSA for SMTP (port 25)
|
||||
[[certificate.dane]]
|
||||
usage = "ee"
|
||||
selector = "spki"
|
||||
matching = "sha256"
|
||||
names = ["_25._tcp.mail.example.com"]
|
||||
ttl = 300
|
||||
pre_publish = true
|
||||
|
||||
# DANE TLSA for IMAP (port 993)
|
||||
[[certificate.dane]]
|
||||
usage = "ee"
|
||||
selector = "spki"
|
||||
matching = "sha256"
|
||||
names = ["_993._tcp.mail.example.com"]
|
||||
ttl = 300
|
||||
|
||||
[[certificate.hook]]
|
||||
type = "systemd-reload"
|
||||
unit = "postfix.service"
|
||||
|
||||
[[certificate.hook]]
|
||||
type = "systemd-restart"
|
||||
unit = "dovecot.service"
|
||||
|
||||
# Web server certificate
|
||||
[[certificate]]
|
||||
name = "web"
|
||||
domains = ["example.com", "www.example.com"]
|
||||
key_type = "ecdsa-p256"
|
||||
key_credential = "/etc/credstore.encrypted/web-tls-key"
|
||||
cert_path = "/etc/certforge/certs/web.pem"
|
||||
renew_before_days = 30
|
||||
|
||||
[[certificate.dane]]
|
||||
usage = "ee"
|
||||
selector = "spki"
|
||||
matching = "sha256"
|
||||
names = ["_443._tcp.example.com", "_443._tcp.www.example.com"]
|
||||
ttl = 3600
|
||||
|
||||
[[certificate.hook]]
|
||||
type = "systemd-reload"
|
||||
unit = "nginx.service"
|
||||
Reference in New Issue
Block a user