mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-25 19:15:51 +03:00
send SNI for federation requests
This commit is contained in:
parent
1d009013b3
commit
3d605853c8
15 changed files with 71 additions and 13 deletions
|
@ -153,11 +153,13 @@ def start(config_options):
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ss = ClientReaderServer(
|
ss = ClientReaderServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -171,11 +171,13 @@ def start(config_options):
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ss = EventCreatorServer(
|
ss = EventCreatorServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -142,11 +142,13 @@ def start(config_options):
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ss = FederationReaderServer(
|
ss = FederationReaderServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -185,11 +185,13 @@ def start(config_options):
|
||||||
config.send_federation = True
|
config.send_federation = True
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ps = FederationSenderServer(
|
ps = FederationSenderServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -209,11 +209,13 @@ def start(config_options):
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ss = FrontendProxyServer(
|
ss = FrontendProxyServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -321,6 +321,7 @@ def setup(config_options):
|
||||||
events.USE_FROZEN_DICTS = config.use_frozen_dicts
|
events.USE_FROZEN_DICTS = config.use_frozen_dicts
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
config.database_config["args"]["cp_openfun"] = database_engine.on_new_connection
|
config.database_config["args"]["cp_openfun"] = database_engine.on_new_connection
|
||||||
|
@ -329,6 +330,7 @@ def setup(config_options):
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -156,11 +156,13 @@ def start(config_options):
|
||||||
database_engine = create_engine(config.database_config)
|
database_engine = create_engine(config.database_config)
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ss = MediaRepositoryServer(
|
ss = MediaRepositoryServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -213,11 +213,13 @@ def start(config_options):
|
||||||
config.update_user_directory = True
|
config.update_user_directory = True
|
||||||
|
|
||||||
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
tls_server_context_factory = context_factory.ServerContextFactory(config)
|
||||||
|
tls_client_options_factory = context_factory.ClientTLSOptionsFactory(config)
|
||||||
|
|
||||||
ps = UserDirectoryServer(
|
ps = UserDirectoryServer(
|
||||||
config.server_name,
|
config.server_name,
|
||||||
db_config=config.database_config,
|
db_config=config.database_config,
|
||||||
tls_server_context_factory=tls_server_context_factory,
|
tls_server_context_factory=tls_server_context_factory,
|
||||||
|
tls_client_options_factory=tls_client_options_factory,
|
||||||
config=config,
|
config=config,
|
||||||
version_string="Synapse/" + get_version_string(synapse),
|
version_string="Synapse/" + get_version_string(synapse),
|
||||||
database_engine=database_engine,
|
database_engine=database_engine,
|
||||||
|
|
|
@ -47,6 +47,8 @@ class TlsConfig(Config):
|
||||||
|
|
||||||
self.tls_fingerprints = config["tls_fingerprints"]
|
self.tls_fingerprints = config["tls_fingerprints"]
|
||||||
|
|
||||||
|
self.tls_ignore_certificate_validation = config.get("tls_ignore_certificate_validation", False)
|
||||||
|
|
||||||
# Check that our own certificate is included in the list of fingerprints
|
# Check that our own certificate is included in the list of fingerprints
|
||||||
# and include it if it is not.
|
# and include it if it is not.
|
||||||
x509_certificate_bytes = crypto.dump_certificate(
|
x509_certificate_bytes = crypto.dump_certificate(
|
||||||
|
@ -73,6 +75,8 @@ class TlsConfig(Config):
|
||||||
tls_private_key_path = base_key_name + ".tls.key"
|
tls_private_key_path = base_key_name + ".tls.key"
|
||||||
tls_dh_params_path = base_key_name + ".tls.dh"
|
tls_dh_params_path = base_key_name + ".tls.dh"
|
||||||
|
|
||||||
|
tls_ignore_certificate_validation = False
|
||||||
|
|
||||||
return """\
|
return """\
|
||||||
# PEM encoded X509 certificate for TLS.
|
# PEM encoded X509 certificate for TLS.
|
||||||
# You can replace the self-signed certificate that synapse
|
# You can replace the self-signed certificate that synapse
|
||||||
|
@ -117,6 +121,11 @@ class TlsConfig(Config):
|
||||||
#
|
#
|
||||||
tls_fingerprints: []
|
tls_fingerprints: []
|
||||||
# tls_fingerprints: [{"sha256": "<base64_encoded_sha256_fingerprint>"}]
|
# tls_fingerprints: [{"sha256": "<base64_encoded_sha256_fingerprint>"}]
|
||||||
|
|
||||||
|
# Ignore certificate validation for TLS client connections to other
|
||||||
|
# homeservers using federation. Don't enable this in a production
|
||||||
|
# environment, unless you know what you are doing!
|
||||||
|
tls_ignore_certificate_validation: %(tls_ignore_certificate_validation)s
|
||||||
""" % locals()
|
""" % locals()
|
||||||
|
|
||||||
def read_tls_certificate(self, cert_path):
|
def read_tls_certificate(self, cert_path):
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
|
|
||||||
from twisted.internet import ssl
|
from twisted.internet import ssl
|
||||||
from OpenSSL import SSL, crypto
|
from OpenSSL import SSL, crypto
|
||||||
from twisted.internet._sslverify import _defaultCurveName
|
from twisted.internet._sslverify import _defaultCurveName, ClientTLSOptions, OpenSSLCertificateOptions, \
|
||||||
|
optionsForClientTLS
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -48,3 +49,34 @@ class ServerContextFactory(ssl.ContextFactory):
|
||||||
|
|
||||||
def getContext(self):
|
def getContext(self):
|
||||||
return self._context
|
return self._context
|
||||||
|
|
||||||
|
|
||||||
|
class ClientTLSOptionsNoCertVerification(ClientTLSOptions):
|
||||||
|
"""Redefinition of ClientTLSOptions to completely ignore certificate
|
||||||
|
validation. Should be kept in sync with the original class in Twisted.
|
||||||
|
This version of ClientTLSOptions is only intended for development use."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ClientTLSOptionsNoCertVerification, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def do_nothing(*_args, **_kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self._ctx.set_info_callback(do_nothing)
|
||||||
|
|
||||||
|
|
||||||
|
class ClientTLSOptionsFactory(object):
|
||||||
|
"""Factory for Twisted ClientTLSOptions that are used to make connections
|
||||||
|
to remote servers for federation."""
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self._ignore_certificate_validation = config.tls_ignore_certificate_validation
|
||||||
|
|
||||||
|
def get_options(self, host):
|
||||||
|
if self._ignore_certificate_validation:
|
||||||
|
return ClientTLSOptionsNoCertVerification(
|
||||||
|
unicode(host),
|
||||||
|
OpenSSLCertificateOptions(verify=False).getContext()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return optionsForClientTLS(unicode(host))
|
||||||
|
|
|
@ -28,14 +28,14 @@ KEY_API_V1 = b"/_matrix/key/v1/"
|
||||||
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def fetch_server_key(server_name, ssl_context_factory, path=KEY_API_V1):
|
def fetch_server_key(server_name, tls_client_options_factory, path=KEY_API_V1):
|
||||||
"""Fetch the keys for a remote server."""
|
"""Fetch the keys for a remote server."""
|
||||||
|
|
||||||
factory = SynapseKeyClientFactory()
|
factory = SynapseKeyClientFactory()
|
||||||
factory.path = path
|
factory.path = path
|
||||||
factory.host = server_name
|
factory.host = server_name
|
||||||
endpoint = matrix_federation_endpoint(
|
endpoint = matrix_federation_endpoint(
|
||||||
reactor, server_name, ssl_context_factory, timeout=30
|
reactor, server_name, tls_client_options_factory, timeout=30
|
||||||
)
|
)
|
||||||
|
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
|
|
|
@ -510,7 +510,7 @@ class Keyring(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
(response, tls_certificate) = yield fetch_server_key(
|
(response, tls_certificate) = yield fetch_server_key(
|
||||||
server_name, self.hs.tls_server_context_factory,
|
server_name, self.tls_client_options_factory,
|
||||||
path=(b"/_matrix/key/v2/server/%s" % (
|
path=(b"/_matrix/key/v2/server/%s" % (
|
||||||
urllib.quote(requested_key_id),
|
urllib.quote(requested_key_id),
|
||||||
)).encode("ascii"),
|
)).encode("ascii"),
|
||||||
|
@ -653,7 +653,7 @@ class Keyring(object):
|
||||||
# Try to fetch the key from the remote server.
|
# Try to fetch the key from the remote server.
|
||||||
|
|
||||||
(response, tls_certificate) = yield fetch_server_key(
|
(response, tls_certificate) = yield fetch_server_key(
|
||||||
server_name, self.hs.tls_server_context_factory
|
server_name, self.hs.tls_client_options_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check the response.
|
# Check the response.
|
||||||
|
|
|
@ -26,7 +26,6 @@ import time
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
SERVER_CACHE = {}
|
SERVER_CACHE = {}
|
||||||
|
|
||||||
# our record of an individual server which can be tried to reach a destination.
|
# our record of an individual server which can be tried to reach a destination.
|
||||||
|
@ -38,15 +37,15 @@ _Server = collections.namedtuple(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def matrix_federation_endpoint(reactor, destination, ssl_context_factory=None,
|
def matrix_federation_endpoint(reactor, destination, tls_client_options_factory=None,
|
||||||
timeout=None):
|
timeout=None):
|
||||||
"""Construct an endpoint for the given matrix destination.
|
"""Construct an endpoint for the given matrix destination.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
reactor: Twisted reactor.
|
reactor: Twisted reactor.
|
||||||
destination (bytes): The name of the server to connect to.
|
destination (bytes): The name of the server to connect to.
|
||||||
ssl_context_factory (twisted.internet.ssl.ContextFactory): Factory
|
tls_client_options_factory (synapse.crypto.context_factory.ClientTLSOptionsFactory):
|
||||||
which generates SSL contexts to use for TLS.
|
Factory which generates TLS options for client connections.
|
||||||
timeout (int): connection timeout in seconds
|
timeout (int): connection timeout in seconds
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -59,13 +58,13 @@ def matrix_federation_endpoint(reactor, destination, ssl_context_factory=None,
|
||||||
if timeout is not None:
|
if timeout is not None:
|
||||||
endpoint_kw_args.update(timeout=timeout)
|
endpoint_kw_args.update(timeout=timeout)
|
||||||
|
|
||||||
if ssl_context_factory is None:
|
if tls_client_options_factory is None:
|
||||||
transport_endpoint = HostnameEndpoint
|
transport_endpoint = HostnameEndpoint
|
||||||
default_port = 8008
|
default_port = 8008
|
||||||
else:
|
else:
|
||||||
def transport_endpoint(reactor, host, port, timeout):
|
def transport_endpoint(reactor, host, port, timeout):
|
||||||
return wrapClientTLS(
|
return wrapClientTLS(
|
||||||
ssl_context_factory,
|
tls_client_options_factory.get_options(unicode(host)),
|
||||||
HostnameEndpoint(reactor, host, port, timeout=timeout))
|
HostnameEndpoint(reactor, host, port, timeout=timeout))
|
||||||
default_port = 8448
|
default_port = 8448
|
||||||
|
|
||||||
|
|
|
@ -62,14 +62,14 @@ MAX_SHORT_RETRIES = 3
|
||||||
|
|
||||||
class MatrixFederationEndpointFactory(object):
|
class MatrixFederationEndpointFactory(object):
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
self.tls_server_context_factory = hs.tls_server_context_factory
|
self.tls_client_options_factory = hs.tls_client_options_factory
|
||||||
|
|
||||||
def endpointForURI(self, uri):
|
def endpointForURI(self, uri):
|
||||||
destination = uri.netloc
|
destination = uri.netloc
|
||||||
|
|
||||||
return matrix_federation_endpoint(
|
return matrix_federation_endpoint(
|
||||||
reactor, destination, timeout=10,
|
reactor, destination, timeout=10,
|
||||||
ssl_context_factory=self.tls_server_context_factory
|
tls_client_options_factory = self.tls_client_options_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ def setup_test_homeserver(name="test", datastore=None, config=None, reactor=None
|
||||||
database_engine=db_engine,
|
database_engine=db_engine,
|
||||||
room_list_handler=object(),
|
room_list_handler=object(),
|
||||||
tls_server_context_factory=Mock(),
|
tls_server_context_factory=Mock(),
|
||||||
|
tls_client_options_factory=Mock(),
|
||||||
reactor=reactor,
|
reactor=reactor,
|
||||||
**kargs
|
**kargs
|
||||||
)
|
)
|
||||||
|
@ -134,6 +135,7 @@ def setup_test_homeserver(name="test", datastore=None, config=None, reactor=None
|
||||||
database_engine=db_engine,
|
database_engine=db_engine,
|
||||||
room_list_handler=object(),
|
room_list_handler=object(),
|
||||||
tls_server_context_factory=Mock(),
|
tls_server_context_factory=Mock(),
|
||||||
|
tls_client_options_factory=Mock(),
|
||||||
**kargs
|
**kargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue