forked from MirrorHub/synapse
Do not generate self-signed TLS certificates by default. (#4509)
This commit is contained in:
parent
b8d75ef53e
commit
6bd4374636
1
changelog.d/4509.removal
Normal file
1
changelog.d/4509.removal
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Synapse no longer generates self-signed TLS certificates when generating a configuration file.
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import warnings
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
|
||||||
|
@ -39,8 +40,8 @@ class TlsConfig(Config):
|
||||||
self.acme_bind_addresses = acme_config.get("bind_addresses", ["127.0.0.1"])
|
self.acme_bind_addresses = acme_config.get("bind_addresses", ["127.0.0.1"])
|
||||||
self.acme_reprovision_threshold = acme_config.get("reprovision_threshold", 30)
|
self.acme_reprovision_threshold = acme_config.get("reprovision_threshold", 30)
|
||||||
|
|
||||||
self.tls_certificate_file = os.path.abspath(config.get("tls_certificate_path"))
|
self.tls_certificate_file = self.abspath(config.get("tls_certificate_path"))
|
||||||
self.tls_private_key_file = os.path.abspath(config.get("tls_private_key_path"))
|
self.tls_private_key_file = self.abspath(config.get("tls_private_key_path"))
|
||||||
self._original_tls_fingerprints = config["tls_fingerprints"]
|
self._original_tls_fingerprints = config["tls_fingerprints"]
|
||||||
self.tls_fingerprints = list(self._original_tls_fingerprints)
|
self.tls_fingerprints = list(self._original_tls_fingerprints)
|
||||||
self.no_tls = config.get("no_tls", False)
|
self.no_tls = config.get("no_tls", False)
|
||||||
|
@ -94,6 +95,16 @@ class TlsConfig(Config):
|
||||||
"""
|
"""
|
||||||
self.tls_certificate = self.read_tls_certificate(self.tls_certificate_file)
|
self.tls_certificate = self.read_tls_certificate(self.tls_certificate_file)
|
||||||
|
|
||||||
|
# Check if it is self-signed, and issue a warning if so.
|
||||||
|
if self.tls_certificate.get_issuer() == self.tls_certificate.get_subject():
|
||||||
|
warnings.warn(
|
||||||
|
(
|
||||||
|
"Self-signed TLS certificates will not be accepted by Synapse 1.0. "
|
||||||
|
"Please either provide a valid certificate, or use Synapse's ACME "
|
||||||
|
"support to provision one."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if not self.no_tls:
|
if not self.no_tls:
|
||||||
self.tls_private_key = self.read_tls_private_key(self.tls_private_key_file)
|
self.tls_private_key = self.read_tls_private_key(self.tls_private_key_file)
|
||||||
|
|
||||||
|
@ -118,10 +129,11 @@ class TlsConfig(Config):
|
||||||
return (
|
return (
|
||||||
"""\
|
"""\
|
||||||
# PEM encoded X509 certificate for TLS.
|
# PEM encoded X509 certificate for TLS.
|
||||||
# You can replace the self-signed certificate that synapse
|
# This certificate, as of Synapse 1.0, will need to be a valid
|
||||||
# autogenerates on launch with your own SSL certificate + key pair
|
# and verifiable certificate, with a root that is available in
|
||||||
# if you like. Any required intermediary certificates can be
|
# the root store of other servers you wish to federate to. Any
|
||||||
# appended after the primary certificate in hierarchical order.
|
# required intermediary certificates can be appended after the
|
||||||
|
# primary certificate in hierarchical order.
|
||||||
tls_certificate_path: "%(tls_certificate_path)s"
|
tls_certificate_path: "%(tls_certificate_path)s"
|
||||||
|
|
||||||
# PEM encoded private key for TLS
|
# PEM encoded private key for TLS
|
||||||
|
@ -183,40 +195,3 @@ class TlsConfig(Config):
|
||||||
def read_tls_private_key(self, private_key_path):
|
def read_tls_private_key(self, private_key_path):
|
||||||
private_key_pem = self.read_file(private_key_path, "tls_private_key")
|
private_key_pem = self.read_file(private_key_path, "tls_private_key")
|
||||||
return crypto.load_privatekey(crypto.FILETYPE_PEM, private_key_pem)
|
return crypto.load_privatekey(crypto.FILETYPE_PEM, private_key_pem)
|
||||||
|
|
||||||
def generate_files(self, config):
|
|
||||||
tls_certificate_path = config["tls_certificate_path"]
|
|
||||||
tls_private_key_path = config["tls_private_key_path"]
|
|
||||||
|
|
||||||
if not self.path_exists(tls_private_key_path):
|
|
||||||
with open(tls_private_key_path, "wb") as private_key_file:
|
|
||||||
tls_private_key = crypto.PKey()
|
|
||||||
tls_private_key.generate_key(crypto.TYPE_RSA, 2048)
|
|
||||||
private_key_pem = crypto.dump_privatekey(
|
|
||||||
crypto.FILETYPE_PEM, tls_private_key
|
|
||||||
)
|
|
||||||
private_key_file.write(private_key_pem)
|
|
||||||
else:
|
|
||||||
with open(tls_private_key_path) as private_key_file:
|
|
||||||
private_key_pem = private_key_file.read()
|
|
||||||
tls_private_key = crypto.load_privatekey(
|
|
||||||
crypto.FILETYPE_PEM, private_key_pem
|
|
||||||
)
|
|
||||||
|
|
||||||
if not self.path_exists(tls_certificate_path):
|
|
||||||
with open(tls_certificate_path, "wb") as certificate_file:
|
|
||||||
cert = crypto.X509()
|
|
||||||
subject = cert.get_subject()
|
|
||||||
subject.CN = config["server_name"]
|
|
||||||
|
|
||||||
cert.set_serial_number(1000)
|
|
||||||
cert.gmtime_adj_notBefore(0)
|
|
||||||
cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
|
|
||||||
cert.set_issuer(cert.get_subject())
|
|
||||||
cert.set_pubkey(tls_private_key)
|
|
||||||
|
|
||||||
cert.sign(tls_private_key, 'sha256')
|
|
||||||
|
|
||||||
cert_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
|
|
||||||
|
|
||||||
certificate_file.write(cert_pem)
|
|
||||||
|
|
|
@ -50,8 +50,6 @@ class ConfigGenerationTestCase(unittest.TestCase):
|
||||||
"homeserver.yaml",
|
"homeserver.yaml",
|
||||||
"lemurs.win.log.config",
|
"lemurs.win.log.config",
|
||||||
"lemurs.win.signing.key",
|
"lemurs.win.signing.key",
|
||||||
"lemurs.win.tls.crt",
|
|
||||||
"lemurs.win.tls.key",
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
set(os.listdir(self.dir)),
|
set(os.listdir(self.dir)),
|
||||||
|
|
75
tests/config/test_tls.py
Normal file
75
tests/config/test_tls.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2019 New Vector Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from synapse.config.tls import TlsConfig
|
||||||
|
|
||||||
|
from tests.unittest import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TLSConfigTests(TestCase):
|
||||||
|
|
||||||
|
def test_warn_self_signed(self):
|
||||||
|
"""
|
||||||
|
Synapse will give a warning when it loads a self-signed certificate.
|
||||||
|
"""
|
||||||
|
config_dir = self.mktemp()
|
||||||
|
os.mkdir(config_dir)
|
||||||
|
with open(os.path.join(config_dir, "cert.pem"), 'w') as f:
|
||||||
|
f.write("""-----BEGIN CERTIFICATE-----
|
||||||
|
MIID6DCCAtACAws9CjANBgkqhkiG9w0BAQUFADCBtzELMAkGA1UEBhMCVFIxDzAN
|
||||||
|
BgNVBAgMBsOHb3J1bTEUMBIGA1UEBwwLQmHFn21ha8OnxLExEjAQBgNVBAMMCWxv
|
||||||
|
Y2FsaG9zdDEcMBoGA1UECgwTVHdpc3RlZCBNYXRyaXggTGFiczEkMCIGA1UECwwb
|
||||||
|
QXV0b21hdGVkIFRlc3RpbmcgQXV0aG9yaXR5MSkwJwYJKoZIhvcNAQkBFhpzZWN1
|
||||||
|
cml0eUB0d2lzdGVkbWF0cml4LmNvbTAgFw0xNzA3MTIxNDAxNTNaGA8yMTE3MDYx
|
||||||
|
ODE0MDE1M1owgbcxCzAJBgNVBAYTAlRSMQ8wDQYDVQQIDAbDh29ydW0xFDASBgNV
|
||||||
|
BAcMC0JhxZ9tYWvDp8SxMRIwEAYDVQQDDAlsb2NhbGhvc3QxHDAaBgNVBAoME1R3
|
||||||
|
aXN0ZWQgTWF0cml4IExhYnMxJDAiBgNVBAsMG0F1dG9tYXRlZCBUZXN0aW5nIEF1
|
||||||
|
dGhvcml0eTEpMCcGCSqGSIb3DQEJARYac2VjdXJpdHlAdHdpc3RlZG1hdHJpeC5j
|
||||||
|
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDwT6kbqtMUI0sMkx4h
|
||||||
|
I+L780dA59KfksZCqJGmOsMD6hte9EguasfkZzvCF3dk3NhwCjFSOvKx6rCwiteo
|
||||||
|
WtYkVfo+rSuVNmt7bEsOUDtuTcaxTzIFB+yHOYwAaoz3zQkyVW0c4pzioiLCGCmf
|
||||||
|
FLdiDBQGGp74tb+7a0V6kC3vMLFoM3L6QWq5uYRB5+xLzlPJ734ltyvfZHL3Us6p
|
||||||
|
cUbK+3WTWvb4ER0W2RqArAj6Bc/ERQKIAPFEiZi9bIYTwvBH27OKHRz+KoY/G8zY
|
||||||
|
+l+WZoJqDhupRAQAuh7O7V/y6bSP+KNxJRie9QkZvw1PSaGSXtGJI3WWdO12/Ulg
|
||||||
|
epJpAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJXEq5P9xwvP9aDkXIqzcD0L8sf8
|
||||||
|
ewlhlxTQdeqt2Nace0Yk18lIo2oj1t86Y8jNbpAnZJeI813Rr5M7FbHCXoRc/SZG
|
||||||
|
I8OtG1xGwcok53lyDuuUUDexnK4O5BkjKiVlNPg4HPim5Kuj2hRNFfNt/F2BVIlj
|
||||||
|
iZupikC5MT1LQaRwidkSNxCku1TfAyueiBwhLnFwTmIGNnhuDCutEVAD9kFmcJN2
|
||||||
|
SznugAcPk4doX2+rL+ila+ThqgPzIkwTUHtnmjI0TI6xsDUlXz5S3UyudrE2Qsfz
|
||||||
|
s4niecZKPBizL6aucT59CsunNmmb5Glq8rlAcU+1ZTZZzGYqVYhF6axB9Qg=
|
||||||
|
-----END CERTIFICATE-----""")
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"tls_certificate_path": os.path.join(config_dir, "cert.pem"),
|
||||||
|
"no_tls": True,
|
||||||
|
"tls_fingerprints": []
|
||||||
|
}
|
||||||
|
|
||||||
|
t = TlsConfig()
|
||||||
|
t.read_config(config)
|
||||||
|
t.read_certificate_from_disk()
|
||||||
|
|
||||||
|
warnings = self.flushWarnings()
|
||||||
|
self.assertEqual(len(warnings), 1)
|
||||||
|
self.assertEqual(
|
||||||
|
warnings[0]["message"],
|
||||||
|
(
|
||||||
|
"Self-signed TLS certificates will not be accepted by "
|
||||||
|
"Synapse 1.0. Please either provide a valid certificate, "
|
||||||
|
"or use Synapse's ACME support to provision one."
|
||||||
|
)
|
||||||
|
)
|
Loading…
Reference in a new issue