1
0

Compare commits

...

57 Commits

Author SHA1 Message Date
Andrew Morgan
bc4b14849f regen sample config 2019-04-08 18:26:15 +01:00
Andrew Morgan
92cc6b0383 Heavier warning about disabling TLS verification 2019-04-08 17:58:54 +01:00
Andrew Morgan
669199876d Add comment and simplify diff 2019-04-08 13:39:07 +01:00
Andrew Morgan
93850f0ac8 domain globbing 2019-04-04 16:20:56 +01:00
Andrew Morgan
edf2dd4744 sample confiiiiiiiiiiiiiiiiiiiiiiig 2019-04-04 16:05:04 +01:00
Andrew Morgan
595d6ecd86 fix domain_whitelist 2019-04-04 16:01:04 +01:00
Andrew Morgan
3dbad0603f lint 2019-04-04 15:56:13 +01:00
Andrew Morgan
396eb64d92 Change federation whitelist stuff back 2019-04-04 15:55:02 +01:00
Andrew Morgan
433db40f6e Address changes 2019-04-04 15:47:12 +01:00
Andrew Morgan
e337c2d9db Addressed changes 2019-04-04 15:27:50 +01:00
Andrew Morgan
09f66222d9 provide an arg to default_config 2019-04-03 13:29:16 +01:00
Andrew Morgan
d3f926a5c3 regen 2019-04-03 13:27:03 +01:00
Andrew Morgan
9bd1432f91 regen config 2019-04-03 12:01:27 +01:00
Andrew Morgan
507cdf2b6f fix domain whitelist 2019-04-03 11:57:09 +01:00
Andrew Morgan
999f7db6b0 Don't break logic when refactoring 2019-04-03 11:41:28 +01:00
Andrew Morgan
a5ab4afced None is very different from [] 2019-04-03 11:34:37 +01:00
Andrew Morgan
892c71dd53 Change test defaults 2019-04-03 11:12:01 +01:00
Andrew Morgan
4f03528d34 Raise config error if empty ca list 2019-04-03 11:11:13 +01:00
Andrew Morgan
7c432de63e Simplify with better exception handling 2019-04-03 10:58:50 +01:00
Andrew Morgan
1fd5680496 Don't laugh at my own jokes 2019-04-03 10:57:18 +01:00
Andrew Morgan
983474d250 Remove turning cert validation off from faq 2019-04-03 10:50:37 +01:00
Andrew Morgan
a87b556ab8 regen sample config 2019-04-02 18:13:48 +01:00
Andrew Morgan
e083ae39cd Address changes. Make federation_domain_whitelist not None 2019-04-02 18:10:13 +01:00
Andrew Morgan
a8adde0624 Restart build 2019-04-02 14:39:58 +01:00
Andrew Morgan
3f1fe92a3b Shuffle config 2019-04-02 13:45:58 +01:00
Andrew Morgan
f38da61ae7 Pass config 2019-04-02 13:35:53 +01:00
Andrew Morgan
3e29d458f2 isort 2019-04-02 13:18:49 +01:00
Andrew Morgan
61a39a44d3 isort 2019-04-02 13:15:23 +01:00
Andrew Morgan
3adf15d357 Correct imports 2019-04-02 13:12:21 +01:00
Andrew Morgan
d194e5daf5 liiint 2019-04-02 12:07:38 +01:00
Andrew Morgan
86470139e0 lint 2019-04-02 12:05:40 +01:00
Andrew Morgan
cc149b11ea Give MFA config access 2019-04-02 11:49:10 +01:00
Andrew Morgan
40702b638e Check for type instead of not None 2019-04-02 11:47:00 +01:00
Andrew Morgan
821baa4e7b Give tests config with default config values 2019-04-02 11:30:51 +01:00
Andrew Morgan
aeffa4d84a Use platformTrust instead of verify=True 2019-04-02 11:09:43 +01:00
Andrew Morgan
fec0c9a074 Remove TODO 2019-04-02 10:57:18 +01:00
Andrew Morgan
a7d7c5a060 Don't run validation code if validation is turned off 2019-04-02 10:53:03 +01:00
Andrew Morgan
ee0c7e1ab4 again 2019-04-01 18:52:13 +01:00
Andrew Morgan
5575f7a9a6 again 2019-04-01 18:35:06 +01:00
Andrew Morgan
4f177c5002 again 2019-04-01 18:20:32 +01:00
Andrew Morgan
9d27f8e9e8 Cache config 2019-04-01 18:14:30 +01:00
Andrew Morgan
86dfaf4d76 Merge branch 'develop' into anoa/msc_1711 2019-04-01 18:01:02 +01:00
Andrew Morgan
0f0775494f Fix documentation 2019-04-01 15:19:02 +01:00
Andrew Morgan
d95b4efb24 No tls. 2019-04-01 15:18:32 +01:00
Andrew Morgan
2851e647e9 Generate config and remove extra newline 2019-04-01 15:06:58 +01:00
Andrew Morgan
0ce5b5bcfe words 2019-04-01 15:01:10 +01:00
Andrew Morgan
2325928149 consolidate logic 2019-04-01 14:59:45 +01:00
Andrew Morgan
da23aa26c5 Cleaner code logic 2019-04-01 14:56:36 +01:00
Andrew Morgan
ffc9c10b6e punctuation 2019-04-01 14:50:48 +01:00
Andrew Morgan
8b1c4592db lint 2019-04-01 14:48:31 +01:00
Andrew Morgan
6de7ab82ca flake8 lied to me :c 2019-04-01 14:47:19 +01:00
Andrew Morgan
8e89fc5fe3 fixes and lint 2019-04-01 14:45:32 +01:00
Andrew Morgan
904ea6c7e0 Add changelog 2019-04-01 14:41:09 +01:00
Andrew Morgan
4d1002fd52 Documentation of new options 2019-04-01 14:39:05 +01:00
Andrew Morgan
9146059419 Ability to specify list of custom CA certificates 2019-04-01 14:09:33 +01:00
Andrew Morgan
5fd4cd0ddd Whitelist per domain 2019-03-29 14:09:07 +00:00
Andrew Morgan
dbb3319e5c Config option for verifying federation certificates 2019-03-28 18:08:43 +00:00
8 changed files with 158 additions and 17 deletions

1
changelog.d/4967.feature Normal file
View File

@@ -0,0 +1 @@
Implementation of [MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711) including config options for requiring valid TLS certificates for federation traffic, the ability to disable TLS validation for specific domains, and the ability to specify your own list of CA certificates.

View File

@@ -177,7 +177,6 @@ You can do this with a `.well-known` file as follows:
on `customer.example.net:8000` it correctly handles HTTP requests with
Host header set to `customer.example.net:8000`.
## FAQ
### Synapse 0.99.0 has just been released, what do I need to do right now?

View File

@@ -257,6 +257,40 @@ listeners:
#
#tls_private_key_path: "CONFDIR/SERVERNAME.tls.key"
# Whether to verify TLS certificates when sending federation traffic.
#
# This currently defaults to `false`, however this will change in
# Synapse 1.0 when valid federation certificates will be required.
#
#federation_verify_certificates: true
# Skip federation certificate verification on the following whitelist
# of domains.
#
# This setting should only be used in very specific cases, such as
# federation over Tor hidden services and similar. For private networks
# of homeservers, you likely want to use a private CA instead.
#
# Only effective if federation_verify_certicates is `true`.
#
#federation_certificate_verification_whitelist:
# - lon.example.com
# - *.domain.com
# - *.onion
# List of custom certificate authorities for federation traffic.
#
# This setting should only normally be used within a private network of
# homeservers.
#
# Note that this list will replace those that are provided by your
# operating environment. Certificates must be in PEM format.
#
#federation_custom_ca_list:
# - myCA1.pem
# - myCA2.pem
# - myCA3.pem
# ACME support: This will configure Synapse to request a valid TLS certificate
# for your configured `server_name` via Let's Encrypt.
#

View File

@@ -113,11 +113,13 @@ class ServerConfig(Config):
# FIXME: federation_domain_whitelist needs sytests
self.federation_domain_whitelist = None
federation_domain_whitelist = config.get(
"federation_domain_whitelist", None
"federation_domain_whitelist", None,
)
# turn the whitelist into a hash for speed of lookup
if federation_domain_whitelist is not None:
# turn the whitelist into a hash for speed of lookup
self.federation_domain_whitelist = {}
for domain in federation_domain_whitelist:
self.federation_domain_whitelist[domain] = True

View File

@@ -24,8 +24,10 @@ import six
from unpaddedbase64 import encode_base64
from OpenSSL import crypto
from twisted.internet._sslverify import Certificate, trustRootFromCertificates
from synapse.config._base import Config, ConfigError
from synapse.util import glob_to_regex
logger = logging.getLogger(__name__)
@@ -70,6 +72,53 @@ class TlsConfig(Config):
self.tls_fingerprints = list(self._original_tls_fingerprints)
# Whether to verify certificates on outbound federation traffic
self.federation_verify_certificates = config.get(
"federation_verify_certificates", False,
)
# Whitelist of domains to not verify certificates for
fed_whitelist_entries = config.get(
"federation_certificate_verification_whitelist", [],
)
# Support globs (*) in whitelist values
self.federation_certificate_verification_whitelist = []
for entry in fed_whitelist_entries:
# Convert globs to regex
entry_regex = glob_to_regex(entry)
self.federation_certificate_verification_whitelist.append(entry_regex)
# List of custom certificate authorities for federation traffic validation
custom_ca_list = config.get(
"federation_custom_ca_list", None,
)
# Read in and parse custom CA certificates
self.federation_ca_trust_root = None
if custom_ca_list is not None:
if len(custom_ca_list) == 0:
# A trustroot cannot be generated without any CA certificates.
# Raise an error if this option has been specified without any
# corresponding certificates.
raise ConfigError("federation_custom_ca_list specified without "
"any certificate files")
certs = []
for ca_file in custom_ca_list:
logger.debug("Reading custom CA certificate file: %s", ca_file)
content = self.read_file(ca_file)
# Parse the CA certificates
try:
cert_base = Certificate.loadPEM(content)
certs.append(cert_base)
except Exception as e:
raise ConfigError("Error parsing custom CA certificate file %s: %s"
% (ca_file, e))
self.federation_ca_trust_root = trustRootFromCertificates(certs)
# This config option applies to non-federation HTTP clients
# (e.g. for talking to recaptcha, identity servers, and such)
# It should never be used in production, and is intended for
@@ -99,15 +148,15 @@ class TlsConfig(Config):
try:
with open(self.tls_certificate_file, 'rb') as f:
cert_pem = f.read()
except Exception:
logger.exception("Failed to read existing certificate off disk!")
raise
except Exception as e:
raise ConfigError("Failed to read existing certificate file %s: %s"
% (self.tls_certificate_file, e))
try:
tls_certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem)
except Exception:
logger.exception("Failed to parse existing certificate off disk!")
raise
except Exception as e:
raise ConfigError("Failed to parse existing certificate file %s: %s"
% (self.tls_certificate_file, e))
if not allow_self_signed:
if tls_certificate.get_subject() == tls_certificate.get_issuer():
@@ -192,6 +241,40 @@ class TlsConfig(Config):
#
#tls_private_key_path: "%(tls_private_key_path)s"
# Whether to verify TLS certificates when sending federation traffic.
#
# This currently defaults to `false`, however this will change in
# Synapse 1.0 when valid federation certificates will be required.
#
#federation_verify_certificates: true
# Skip federation certificate verification on the following whitelist
# of domains.
#
# This setting should only be used in very specific cases, such as
# federation over Tor hidden services and similar. For private networks
# of homeservers, you likely want to use a private CA instead.
#
# Only effective if federation_verify_certicates is `true`.
#
#federation_certificate_verification_whitelist:
# - lon.example.com
# - *.domain.com
# - *.onion
# List of custom certificate authorities for federation traffic.
#
# This setting should only normally be used within a private network of
# homeservers.
#
# Note that this list will replace those that are provided by your
# operating environment. Certificates must be in PEM format.
#
#federation_custom_ca_list:
# - myCA1.pem
# - myCA2.pem
# - myCA3.pem
# ACME support: This will configure Synapse to request a valid TLS certificate
# for your configured `server_name` via Let's Encrypt.
#

View File

@@ -18,10 +18,10 @@ import logging
from zope.interface import implementer
from OpenSSL import SSL, crypto
from twisted.internet._sslverify import _defaultCurveName
from twisted.internet._sslverify import ClientTLSOptions, _defaultCurveName
from twisted.internet.abstract import isIPAddress, isIPv6Address
from twisted.internet.interfaces import IOpenSSLClientConnectionCreator
from twisted.internet.ssl import CertificateOptions, ContextFactory
from twisted.internet.ssl import CertificateOptions, ContextFactory, platformTrust
from twisted.python.failure import Failure
logger = logging.getLogger(__name__)
@@ -90,7 +90,7 @@ def _tolerateErrors(wrapped):
@implementer(IOpenSSLClientConnectionCreator)
class ClientTLSOptions(object):
class ClientTLSOptionsNoVerify(object):
"""
Client creator for TLS without certificate identity verification. This is a
copy of twisted.internet._sslverify.ClientTLSOptions with the identity
@@ -127,9 +127,30 @@ class ClientTLSOptionsFactory(object):
to remote servers for federation."""
def __init__(self, config):
# We don't use config options yet
self._options = CertificateOptions(verify=False)
self._config = config
self._options_noverify = CertificateOptions()
# Check if we're using a custom list of a CA certificates
trust_root = config.federation_ca_trust_root
if trust_root is None:
# Use CA root certs provided by OpenSSL
trust_root = platformTrust()
self._options_verify = CertificateOptions(trustRoot=trust_root)
def get_options(self, host):
# Use _makeContext so that we get a fresh OpenSSL CTX each time.
return ClientTLSOptions(host, self._options._makeContext())
# Check if certificate verification has been enabled
should_verify = self._config.federation_verify_certificates
# Check if we've disabled certificate verification for this host
if should_verify:
for regex in self._config.federation_certificate_verification_whitelist:
if regex.match(host):
should_verify = False
break
if should_verify:
return ClientTLSOptions(host, self._options_verify._makeContext())
return ClientTLSOptionsNoVerify(host, self._options_noverify._makeContext())

View File

@@ -149,7 +149,7 @@ class MatrixFederationAgent(object):
tls_options = None
else:
tls_options = self._tls_client_options_factory.get_options(
res.tls_server_name.decode("ascii")
res.tls_server_name.decode("ascii"),
)
# make sure that the Host header is set correctly

View File

@@ -39,6 +39,7 @@ from synapse.util.logcontext import LoggingContext
from tests.http import ServerTLSContext
from tests.server import FakeTransport, ThreadedMemoryReactorClock
from tests.unittest import TestCase
from tests.utils import default_config
logger = logging.getLogger(__name__)
@@ -53,7 +54,7 @@ class MatrixFederationAgentTests(TestCase):
self.agent = MatrixFederationAgent(
reactor=self.reactor,
tls_client_options_factory=ClientTLSOptionsFactory(None),
tls_client_options_factory=ClientTLSOptionsFactory(default_config("test")),
_well_known_tls_policy=TrustingTLSPolicyForHTTPS(),
_srv_resolver=self.mock_resolver,
_well_known_cache=self.well_known_cache,