Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACME Reprovisioning #4522

Merged
merged 51 commits into from Feb 11, 2019
Merged
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e3e159d
fix typo
hawkowl Jan 24, 2019
f6a7149
fix
hawkowl Jan 24, 2019
e148691
fix
hawkowl Jan 24, 2019
3ca24d5
fix
hawkowl Jan 24, 2019
8aa6d71
fix
hawkowl Jan 24, 2019
7ea34b0
fix
hawkowl Jan 24, 2019
70170e0
fix
hawkowl Jan 24, 2019
92e893e
fix
hawkowl Jan 24, 2019
f8c4258
fix
hawkowl Jan 24, 2019
9a66c51
fix
hawkowl Jan 24, 2019
7c99df8
fix
hawkowl Jan 24, 2019
0f0187e
fix
hawkowl Jan 24, 2019
4b9fd2b
fix
hawkowl Jan 24, 2019
e2615be
fix
hawkowl Jan 24, 2019
abc4e7d
fix
hawkowl Jan 24, 2019
666fc90
fix
hawkowl Jan 24, 2019
f6b58aa
fix
hawkowl Jan 24, 2019
26f4f5a
Merge remote-tracking branch 'origin/develop' into hawkowl/sighup-tls
hawkowl Jan 28, 2019
aaf9220
fix
hawkowl Jan 28, 2019
7df3114
changelog
hawkowl Jan 28, 2019
3fe07f7
fix
hawkowl Jan 29, 2019
2340ae5
fix
hawkowl Jan 29, 2019
08de6c9
fix
hawkowl Jan 29, 2019
cd78e7e
Merge remote-tracking branch 'origin/develop' into hawkowl/sighup-tls
hawkowl Jan 29, 2019
14e4c4f
fix
hawkowl Jan 29, 2019
d08ef7b
fix
hawkowl Jan 29, 2019
45f9d6c
reprovisioning code
hawkowl Jan 29, 2019
97eec0a
reprovisioning code
hawkowl Jan 30, 2019
edd51a1
Merge remote-tracking branch 'origin/develop' into hawkowl/acme-repro…
hawkowl Jan 30, 2019
62b4e01
pep8 fixes
hawkowl Jan 30, 2019
965921c
pep8 fixes
hawkowl Jan 30, 2019
d21f762
fixes
hawkowl Jan 30, 2019
67c30d3
Merge remote-tracking branch 'origin/develop' into hawkowl/acme-repro…
hawkowl Jan 30, 2019
14274eb
fixes
hawkowl Jan 30, 2019
12696ab
fixes
hawkowl Jan 30, 2019
fe36f24
fixes
hawkowl Jan 30, 2019
9c9d261
changelog
hawkowl Jan 30, 2019
e9e4c52
Merge remote-tracking branch 'origin/develop' into hawkowl/acme-repro…
hawkowl Jan 30, 2019
45810a4
Merge remote-tracking branch 'origin/develop' into hawkowl/acme-repro…
hawkowl Jan 30, 2019
512dfeb
fixes
hawkowl Jan 30, 2019
5fdaf5c
port over
hawkowl Feb 5, 2019
3fa83ab
changelog
hawkowl Feb 5, 2019
1779696
fix
hawkowl Feb 5, 2019
89fba92
some cleanup
hawkowl Feb 8, 2019
b232c17
some cleanup
hawkowl Feb 8, 2019
ffdac50
some cleanup
hawkowl Feb 8, 2019
54ea80c
Merge branch 'hawkowl/dedupe-start' into hawkowl/acme-reprovision
hawkowl Feb 8, 2019
759ceb8
Merge remote-tracking branch 'origin/develop' into hawkowl/acme-repro…
hawkowl Feb 8, 2019
fcb2fe1
Update _base.py
hawkowl Feb 8, 2019
565b3d2
some docs
hawkowl Feb 11, 2019
50046cc
fix changelog
richvdh Feb 11, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+76 −35
Diff settings

Always

Just for now

reprovisioning code

  • Loading branch information...
hawkowl committed Jan 29, 2019
commit 45f9d6cef1942343d118fc47420f40d2c03192a0
Copy path View file
@@ -380,56 +380,87 @@ def refresh_certificate(*args):
Refresh the TLS certificates that Synapse is using by re-reading them
from disk and updating the TLS context factories to use them.
"""
logging.info("Reloading certificate from disk...")
logging.info("Loading certificate from disk...")
hs.config.read_certificate_from_disk()
hs.tls_server_context_factory = context_factory.ServerContextFactory(config)
hs.tls_client_options_factory = context_factory.ClientTLSOptionsFactory(
config
)
logging.info("Certificate reloaded.")

logging.info("Updating context factories...")
for i in hs._listening_services:
if isinstance(i.factory, TLSMemoryBIOFactory):
i.factory = TLSMemoryBIOFactory(
hs.tls_server_context_factory,
False,
i.factory.wrappedFactory
)
logging.info("Context factories updated.")
logging.info("Certificate loaded.")

if hs._listening_services:
logging.info("Updating context factories...")
for i in hs._listening_services:
if isinstance(i.factory, TLSMemoryBIOFactory):
i.factory = TLSMemoryBIOFactory(
hs.tls_server_context_factory,
False,
i.factory.wrappedFactory
)
logging.info("Context factories updated.")

sighup_callbacks.append(refresh_certificate)

@defer.inlineCallbacks
def do_acme():
"""
Reprovision an ACME certificate, if it's required.
Returns:
Deferred[bool]: Whether the cert has been updated.
"""
acme = hs.get_acme_handler()

# Check how long the certificate is active for.
cert_days_remaining = hs.config.is_disk_cert_valid(
allow_self_signed=False
)

# We want to reprovision if cert_days_remaining is None (meaning no
# certificate exists), or the days remaining number it returns
# is less than our re-registration threshold.
provision = False

if (cert_days_remaining is None):
provision = True

if cert_days_remaining > hs.config.acme_reprovision_threshold:
provision = True

if provision:
yield acme.provision_certificate()

defer.returnValue(provision)

@defer.inlineCallbacks
def reprovision_acme():
"""
Provision a certificate from ACME, if required, and reload the TLS
certificate if it's renewed.
"""
reprovisioned = yield do_acme()
if reprovisioned:
refresh_certificate()

@defer.inlineCallbacks
def start():
try:
# Check if the certificate is still valid.
cert_days_remaining = hs.config.is_disk_cert_valid()

# Run the ACME provisioning code, if it's enabled.
if hs.config.acme_enabled:
# If ACME is enabled, we might need to provision a certificate
# before starting.
acme = hs.get_acme_handler()

# Start up the webservices which we will respond to ACME
# challenges with.
# challenges with, and then provision.
yield acme.start_listening()
yield do_acme()

# We want to reprovision if cert_days_remaining is None (meaning no
# certificate exists), or the days remaining number it returns
# is less than our re-registration threshold.
if (cert_days_remaining is None) or (
not cert_days_remaining > hs.config.acme_reprovision_threshold
):
yield acme.provision_certificate()

# Read the certificate from disk and build the context factories for
# TLS.
hs.config.read_certificate_from_disk()
hs.tls_server_context_factory = context_factory.ServerContextFactory(config)
hs.tls_client_options_factory = context_factory.ClientTLSOptionsFactory(
config
)
# Check if it needs to be reprovisioned every day.
hs.get_clock().looping_call(
reprovision_acme,
24 * 60 * 60 * 1000
)

# Load the certificate from disk.
refresh_certificate()

# It is now safe to start your Synapse.
hs.start_listening()
Copy path View file
@@ -56,10 +56,14 @@ def read_config(self, config):
self.tls_certificate = None
self.tls_private_key = None

def is_disk_cert_valid(self):
def is_disk_cert_valid(self, allow_self_signed=True):
"""
Is the certificate we have on disk valid, and if so, for how long?
Args:
allow_self_signed (bool): Should we allow the certificate we
read to be self signed?
Returns:
int: Days remaining of certificate validity.
None: No certificate exists.
@@ -80,6 +84,12 @@ def is_disk_cert_valid(self):
logger.exception("Failed to parse existing certificate off disk!")
raise

if not allow_self_signed:
if tls_certificate.get_subject() == tls_certificate.get_issuer():
raise ValueError(
"TLS Certificate is self signed, and this is not permitted"
)

# YYYYMMDDhhmmssZ -- in UTC
expires_on = datetime.strptime(
tls_certificate.get_notAfter().decode('ascii'), "%Y%m%d%H%M%SZ"
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.