diff --git a/synapse/http/client.py b/synapse/http/client.py
index c9479c81ff..09ea93e10d 100644
--- a/synapse/http/client.py
+++ b/synapse/http/client.py
@@ -117,22 +117,22 @@ RawHeaderValue = Union[
]
-def check_against_blacklist(
- ip_address: IPAddress, ip_whitelist: Optional[IPSet], ip_blacklist: IPSet
+def _is_ip_blocked(
+ ip_address: IPAddress, allowlist: Optional[IPSet], blocklist: IPSet
) -> bool:
"""
Compares an IP address to allowed and disallowed IP sets.
Args:
ip_address: The IP address to check
- ip_whitelist: Allowed IP addresses.
- ip_blacklist: Disallowed IP addresses.
+ allowlist: Allowed IP addresses.
+ blocklist: Disallowed IP addresses.
Returns:
- True if the IP address is in the blacklist and not in the whitelist.
+ True if the IP address is in the blocklist and not in the allowlist.
"""
- if ip_address in ip_blacklist:
- if ip_whitelist is None or ip_address not in ip_whitelist:
+ if ip_address in blocklist:
+ if allowlist is None or ip_address not in allowlist:
return True
return False
@@ -154,27 +154,27 @@ def _make_scheduler(
return _scheduler
-class _IPBlacklistingResolver:
+class _IPBlockingResolver:
"""
- A proxy for reactor.nameResolver which only produces non-blacklisted IP
- addresses, preventing DNS rebinding attacks on URL preview.
+ A proxy for reactor.nameResolver which only produces non-blocklisted IP
+ addresses, preventing DNS rebinding attacks.
"""
def __init__(
self,
reactor: IReactorPluggableNameResolver,
- ip_whitelist: Optional[IPSet],
- ip_blacklist: IPSet,
+ ip_allowlist: Optional[IPSet],
+ ip_blocklist: IPSet,
):
"""
Args:
reactor: The twisted reactor.
- ip_whitelist: IP addresses to allow.
- ip_blacklist: IP addresses to disallow.
+ ip_allowlist: IP addresses to allow.
+ ip_blocklist: IP addresses to disallow.
"""
self._reactor = reactor
- self._ip_whitelist = ip_whitelist
- self._ip_blacklist = ip_blacklist
+ self._ip_allowlist = ip_allowlist
+ self._ip_blocklist = ip_blocklist
def resolveHostName(
self, recv: IResolutionReceiver, hostname: str, portNumber: int = 0
@@ -191,16 +191,13 @@ class _IPBlacklistingResolver:
ip_address = IPAddress(address.host)
- if check_against_blacklist(
- ip_address, self._ip_whitelist, self._ip_blacklist
- ):
+ if _is_ip_blocked(ip_address, self._ip_allowlist, self._ip_blocklist):
logger.info(
- "Dropped %s from DNS resolution to %s due to blacklist"
- % (ip_address, hostname)
+ "Blocked %s from DNS resolution to %s" % (ip_address, hostname)
)
has_bad_ip = True
- # if we have a blacklisted IP, we'd like to raise an error to block the
+ # if we have a blocked IP, we'd like to raise an error to block the
# request, but all we can really do from here is claim that there were no
# valid results.
if not has_bad_ip:
@@ -232,24 +229,24 @@ class _IPBlacklistingResolver:
# ISynapseReactor implies IReactorCore, but explicitly marking it this as an implementer
# of IReactorCore seems to keep mypy-zope happier.
@implementer(IReactorCore, ISynapseReactor)
-class BlacklistingReactorWrapper:
+class BlocklistingReactorWrapper:
"""
- A Reactor wrapper which will prevent DNS resolution to blacklisted IP
+ A Reactor wrapper which will prevent DNS resolution to blocked IP
addresses, to prevent DNS rebinding.
"""
def __init__(
self,
reactor: IReactorPluggableNameResolver,
- ip_whitelist: Optional[IPSet],
- ip_blacklist: IPSet,
+ ip_allowlist: Optional[IPSet],
+ ip_blocklist: IPSet,
):
self._reactor = reactor
- # We need to use a DNS resolver which filters out blacklisted IP
+ # We need to use a DNS resolver which filters out blocked IP
# addresses, to prevent DNS rebinding.
- self._nameResolver = _IPBlacklistingResolver(
- self._reactor, ip_whitelist, ip_blacklist
+ self._nameResolver = _IPBlockingResolver(
+ self._reactor, ip_allowlist, ip_blocklist
)
def __getattr__(self, attr: str) -> Any:
@@ -260,7 +257,7 @@ class BlacklistingReactorWrapper:
return getattr(self._reactor, attr)
-class BlacklistingAgentWrapper(Agent):
+class BlocklistingAgentWrapper(Agent):
"""
An Agent wrapper which will prevent access to IP addresses being accessed
directly (without an IP address lookup).
@@ -269,18 +266,18 @@ class BlacklistingAgentWrapper(Agent):
def __init__(
self,
agent: IAgent,
- ip_blacklist: IPSet,
- ip_whitelist: Optional[IPSet] = None,
+ ip_blocklist: IPSet,
+ ip_allowlist: Optional[IPSet] = None,
):
"""
Args:
agent: The Agent to wrap.
- ip_whitelist: IP addresses to allow.
- ip_blacklist: IP addresses to disallow.
+ ip_allowlist: IP addresses to allow.
+ ip_blocklist: IP addresses to disallow.
"""
self._agent = agent
- self._ip_whitelist = ip_whitelist
- self._ip_blacklist = ip_blacklist
+ self._ip_allowlist = ip_allowlist
+ self._ip_blocklist = ip_blocklist
def request(
self,
@@ -299,13 +296,9 @@ class BlacklistingAgentWrapper(Agent):
# Not an IP
pass
else:
- if check_against_blacklist(
- ip_address, self._ip_whitelist, self._ip_blacklist
- ):
- logger.info("Blocking access to %s due to blacklist" % (ip_address,))
- e = SynapseError(
- HTTPStatus.FORBIDDEN, "IP address blocked by IP blacklist entry"
- )
+ if _is_ip_blocked(ip_address, self._ip_allowlist, self._ip_blocklist):
+ logger.info("Blocking access to %s" % (ip_address,))
+ e = SynapseError(HTTPStatus.FORBIDDEN, "IP address blocked")
return defer.fail(Failure(e))
return self._agent.request(
@@ -763,10 +756,9 @@ class SimpleHttpClient(BaseHttpClient):
Args:
hs: The HomeServer instance to pass in
treq_args: Extra keyword arguments to be given to treq.request.
- ip_blacklist: The IP addresses that are blacklisted that
- we may not request.
- ip_whitelist: The whitelisted IP addresses, that we can
- request if it were otherwise caught in a blacklist.
+ ip_blocklist: The IP addresses that we may not request.
+ ip_allowlist: The allowed IP addresses, that we can
+ request if it were otherwise caught in a blocklist.
use_proxy: Whether proxy settings should be discovered and used
from conventional environment variables.
"""
@@ -775,19 +767,19 @@ class SimpleHttpClient(BaseHttpClient):
self,
hs: "HomeServer",
treq_args: Optional[Dict[str, Any]] = None,
- ip_whitelist: Optional[IPSet] = None,
- ip_blacklist: Optional[IPSet] = None,
+ ip_allowlist: Optional[IPSet] = None,
+ ip_blocklist: Optional[IPSet] = None,
use_proxy: bool = False,
):
super().__init__(hs, treq_args=treq_args)
- self._ip_whitelist = ip_whitelist
- self._ip_blacklist = ip_blacklist
-
- if self._ip_blacklist:
- # If we have an IP blacklist, we need to use a DNS resolver which
- # filters out blacklisted IP addresses, to prevent DNS rebinding.
- self.reactor: ISynapseReactor = BlacklistingReactorWrapper(
- self.reactor, self._ip_whitelist, self._ip_blacklist
+ self._ip_allowlist = ip_allowlist
+ self._ip_blocklist = ip_blocklist
+
+ if self._ip_blocklist:
+ # If we have an IP blocklist, we need to use a DNS resolver which
+ # filters out blocked IP addresses, to prevent DNS rebinding.
+ self.reactor: ISynapseReactor = BlocklistingReactorWrapper(
+ self.reactor, self._ip_allowlist, self._ip_blocklist
)
# the pusher makes lots of concurrent SSL connections to Sygnal, and tends to
@@ -809,14 +801,13 @@ class SimpleHttpClient(BaseHttpClient):
use_proxy=use_proxy,
)
- if self._ip_blacklist:
- # If we have an IP blacklist, we then install the blacklisting Agent
- # which prevents direct access to IP addresses, that are not caught
- # by the DNS resolution.
- self.agent = BlacklistingAgentWrapper(
+ if self._ip_blocklist:
+ # If we have an IP blocklist, we then install the Agent which prevents
+ # direct access to IP addresses, that are not caught by the DNS resolution.
+ self.agent = BlocklistingAgentWrapper(
self.agent,
- ip_blacklist=self._ip_blacklist,
- ip_whitelist=self._ip_whitelist,
+ ip_blocklist=self._ip_blocklist,
+ ip_allowlist=self._ip_allowlist,
)
@@ -844,6 +835,7 @@ class ReplicationClient(BaseHttpClient):
self.agent: IAgent = ReplicationAgent(
hs.get_reactor(),
+ hs.config.worker.instance_map,
contextFactory=hs.get_http_client_context_factory(),
pool=pool,
)
diff --git a/synapse/http/federation/matrix_federation_agent.py b/synapse/http/federation/matrix_federation_agent.py
index 8d7d0a3875..7e8cf31682 100644
--- a/synapse/http/federation/matrix_federation_agent.py
+++ b/synapse/http/federation/matrix_federation_agent.py
@@ -36,7 +36,7 @@ from twisted.web.iweb import IAgent, IAgentEndpointFactory, IBodyProducer, IResp
from synapse.crypto.context_factory import FederationPolicyForHTTPS
from synapse.http import proxyagent
-from synapse.http.client import BlacklistingAgentWrapper, BlacklistingReactorWrapper
+from synapse.http.client import BlocklistingAgentWrapper, BlocklistingReactorWrapper
from synapse.http.connectproxyclient import HTTPConnectProxyEndpoint
from synapse.http.federation.srv_resolver import Server, SrvResolver
from synapse.http.federation.well_known_resolver import WellKnownResolver
@@ -65,12 +65,12 @@ class MatrixFederationAgent:
user_agent:
The user agent header to use for federation requests.
- ip_whitelist: Allowed IP addresses.
+ ip_allowlist: Allowed IP addresses.
- ip_blacklist: Disallowed IP addresses.
+ ip_blocklist: Disallowed IP addresses.
proxy_reactor: twisted reactor to use for connections to the proxy server
- reactor might have some blacklisting applied (i.e. for DNS queries),
+ reactor might have some blocking applied (i.e. for DNS queries),
but we need unblocked access to the proxy.
_srv_resolver:
@@ -87,17 +87,17 @@ class MatrixFederationAgent:
reactor: ISynapseReactor,
tls_client_options_factory: Optional[FederationPolicyForHTTPS],
user_agent: bytes,
- ip_whitelist: Optional[IPSet],
- ip_blacklist: IPSet,
+ ip_allowlist: Optional[IPSet],
+ ip_blocklist: IPSet,
_srv_resolver: Optional[SrvResolver] = None,
_well_known_resolver: Optional[WellKnownResolver] = None,
):
- # proxy_reactor is not blacklisted
+ # proxy_reactor is not blocklisting reactor
proxy_reactor = reactor
- # We need to use a DNS resolver which filters out blacklisted IP
+ # We need to use a DNS resolver which filters out blocked IP
# addresses, to prevent DNS rebinding.
- reactor = BlacklistingReactorWrapper(reactor, ip_whitelist, ip_blacklist)
+ reactor = BlocklistingReactorWrapper(reactor, ip_allowlist, ip_blocklist)
self._clock = Clock(reactor)
self._pool = HTTPConnectionPool(reactor)
@@ -120,7 +120,7 @@ class MatrixFederationAgent:
if _well_known_resolver is None:
_well_known_resolver = WellKnownResolver(
reactor,
- agent=BlacklistingAgentWrapper(
+ agent=BlocklistingAgentWrapper(
ProxyAgent(
reactor,
proxy_reactor,
@@ -128,7 +128,7 @@ class MatrixFederationAgent:
contextFactory=tls_client_options_factory,
use_proxy=True,
),
- ip_blacklist=ip_blacklist,
+ ip_blocklist=ip_blocklist,
),
user_agent=self.user_agent,
)
@@ -256,7 +256,7 @@ class MatrixHostnameEndpoint:
Args:
reactor: twisted reactor to use for underlying requests
proxy_reactor: twisted reactor to use for connections to the proxy server.
- 'reactor' might have some blacklisting applied (i.e. for DNS queries),
+ 'reactor' might have some blocking applied (i.e. for DNS queries),
but we need unblocked access to the proxy.
tls_client_options_factory:
factory to use for fetching client tls options, or none to disable TLS.
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index 634882487c..9094dab0fe 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -64,7 +64,7 @@ from synapse.api.errors import (
from synapse.crypto.context_factory import FederationPolicyForHTTPS
from synapse.http import QuieterFileBodyProducer
from synapse.http.client import (
- BlacklistingAgentWrapper,
+ BlocklistingAgentWrapper,
BodyExceededMaxSize,
ByteWriteable,
_make_scheduler,
@@ -392,15 +392,15 @@ class MatrixFederationHttpClient:
self.reactor,
tls_client_options_factory,
user_agent.encode("ascii"),
- hs.config.server.federation_ip_range_whitelist,
- hs.config.server.federation_ip_range_blacklist,
+ hs.config.server.federation_ip_range_allowlist,
+ hs.config.server.federation_ip_range_blocklist,
)
- # Use a BlacklistingAgentWrapper to prevent circumventing the IP
- # blacklist via IP literals in server names
- self.agent = BlacklistingAgentWrapper(
+ # Use a BlocklistingAgentWrapper to prevent circumventing the IP
+ # blocking via IP literals in server names
+ self.agent = BlocklistingAgentWrapper(
federation_agent,
- ip_blacklist=hs.config.server.federation_ip_range_blacklist,
+ ip_blocklist=hs.config.server.federation_ip_range_blocklist,
)
self.clock = hs.get_clock()
diff --git a/synapse/http/proxyagent.py b/synapse/http/proxyagent.py
index 94ef737b9e..7bdc4acae7 100644
--- a/synapse/http/proxyagent.py
+++ b/synapse/http/proxyagent.py
@@ -53,7 +53,7 @@ class ProxyAgent(_AgentBase):
connections.
proxy_reactor: twisted reactor to use for connections to the proxy server
- reactor might have some blacklisting applied (i.e. for DNS queries),
+ reactor might have some blocking applied (i.e. for DNS queries),
but we need unblocked access to the proxy.
contextFactory: A factory for TLS contexts, to control the
diff --git a/synapse/http/replicationagent.py b/synapse/http/replicationagent.py
index 5ecd08be0f..800f21873d 100644
--- a/synapse/http/replicationagent.py
+++ b/synapse/http/replicationagent.py
@@ -13,7 +13,7 @@
# limitations under the License.
import logging
-from typing import Optional
+from typing import Dict, Optional
from zope.interface import implementer
@@ -32,6 +32,7 @@ from twisted.web.iweb import (
IResponse,
)
+from synapse.config.workers import InstanceLocationConfig
from synapse.types import ISynapseReactor
logger = logging.getLogger(__name__)
@@ -44,9 +45,11 @@ class ReplicationEndpointFactory:
def __init__(
self,
reactor: ISynapseReactor,
+ instance_map: Dict[str, InstanceLocationConfig],
context_factory: IPolicyForHTTPS,
) -> None:
self.reactor = reactor
+ self.instance_map = instance_map
self.context_factory = context_factory
def endpointForURI(self, uri: URI) -> IStreamClientEndpoint:
@@ -58,15 +61,29 @@ class ReplicationEndpointFactory:
Returns: The correct client endpoint object
"""
- if uri.scheme in (b"http", b"https"):
- endpoint = HostnameEndpoint(self.reactor, uri.host, uri.port)
- if uri.scheme == b"https":
+ # The given URI has a special scheme and includes the worker name. The
+ # actual connection details are pulled from the instance map.
+ worker_name = uri.netloc.decode("utf-8")
+ scheme = self.instance_map[worker_name].scheme()
+
+ if scheme in ("http", "https"):
+ endpoint = HostnameEndpoint(
+ self.reactor,
+ self.instance_map[worker_name].host,
+ self.instance_map[worker_name].port,
+ )
+ if scheme == "https":
endpoint = wrapClientTLS(
- self.context_factory.creatorForNetloc(uri.host, uri.port), endpoint
+ # The 'port' argument below isn't actually used by the function
+ self.context_factory.creatorForNetloc(
+ self.instance_map[worker_name].host,
+ self.instance_map[worker_name].port,
+ ),
+ endpoint,
)
return endpoint
else:
- raise SchemeNotSupported(f"Unsupported scheme: {uri.scheme!r}")
+ raise SchemeNotSupported(f"Unsupported scheme: {scheme}")
@implementer(IAgent)
@@ -80,6 +97,7 @@ class ReplicationAgent(_AgentBase):
def __init__(
self,
reactor: ISynapseReactor,
+ instance_map: Dict[str, InstanceLocationConfig],
contextFactory: IPolicyForHTTPS,
connectTimeout: Optional[float] = None,
bindAddress: Optional[bytes] = None,
@@ -102,7 +120,9 @@ class ReplicationAgent(_AgentBase):
created.
"""
_AgentBase.__init__(self, reactor, pool)
- endpoint_factory = ReplicationEndpointFactory(reactor, contextFactory)
+ endpoint_factory = ReplicationEndpointFactory(
+ reactor, instance_map, contextFactory
+ )
self._endpointFactory = endpoint_factory
def request(
|