🚧 Update certificate management
This commit is contained in:
@@ -220,6 +220,9 @@ def _publish_certificates(db: Session) -> None:
|
||||
|
||||
Must run BEFORE the config referencing them is validated/activated,
|
||||
otherwise `mosquitto --test-config` fails on missing files.
|
||||
Files are owned by uid/gid 1883 (the broker user in the official
|
||||
image) with key mode 0640 — the broker must be able to read the key,
|
||||
but no other container user should.
|
||||
"""
|
||||
listeners = db.scalars(
|
||||
select(ListenerConfig).where(ListenerConfig.tls_enabled.is_(True))
|
||||
@@ -233,25 +236,39 @@ def _publish_certificates(db: Session) -> None:
|
||||
if cert is None or cert.private_key_pem is None:
|
||||
continue # nothing to publish (warned about in configgen)
|
||||
os.makedirs(CERTS_DIR, exist_ok=True)
|
||||
cert_path = os.path.join(CERTS_DIR, f"{cert.id}.crt")
|
||||
with open(cert_path, "w", encoding="utf-8") as f:
|
||||
f.write(cert.certificate_pem)
|
||||
os.chmod(cert_path, 0o644)
|
||||
# Private key: decrypted for the broker (DB keeps the AES-GCM copy)
|
||||
|
||||
from app.crypto import decrypt_secret
|
||||
|
||||
key_path = os.path.join(CERTS_DIR, f"{cert.id}.key")
|
||||
with open(key_path, "w", encoding="utf-8") as f:
|
||||
f.write(decrypt_secret(cert.private_key_pem))
|
||||
os.chmod(key_path, 0o600)
|
||||
# Issuing CA certificate (for cafile)
|
||||
def _write(path: str, content: str, mode: int) -> None:
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
os.chmod(path, mode)
|
||||
try:
|
||||
# The broker (and this sidecar) run as uid 1883 in the
|
||||
# official image; chown only works when we are root in
|
||||
# the container — skip silently in local dev on Windows.
|
||||
os.chown(path, 1883, 1883)
|
||||
except (PermissionError, OSError):
|
||||
pass
|
||||
|
||||
_write(
|
||||
os.path.join(CERTS_DIR, f"{cert.id}.crt"),
|
||||
cert.certificate_pem,
|
||||
0o644,
|
||||
)
|
||||
_write(
|
||||
os.path.join(CERTS_DIR, f"{cert.id}.key"),
|
||||
decrypt_secret(cert.private_key_pem),
|
||||
0o640,
|
||||
)
|
||||
if cert.parent_id is not None:
|
||||
ca = db.get(Certificate, cert.parent_id)
|
||||
if ca is not None:
|
||||
ca_path = os.path.join(CERTS_DIR, f"{ca.id}.crt")
|
||||
with open(ca_path, "w", encoding="utf-8") as f:
|
||||
f.write(ca.certificate_pem)
|
||||
os.chmod(ca_path, 0o644)
|
||||
_write(
|
||||
os.path.join(CERTS_DIR, f"{ca.id}.crt"),
|
||||
ca.certificate_pem,
|
||||
0o644,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/config/preview", response_model=ConfigPreviewOut)
|
||||
|
||||
Reference in New Issue
Block a user