Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 344ab0b

Browse files
authored
Default to blacklisting reserved IP ranges and add a whitelist. (#8870)
This defaults `ip_range_blacklist` to reserved IP ranges and also adds an `ip_range_whitelist` setting to override it.
1 parent 6ff34e0 commit 344ab0b

File tree

10 files changed

+172
-89
lines changed

10 files changed

+172
-89
lines changed

INSTALL.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,9 @@ This is critical from a security perspective to stop arbitrary Matrix users
557557
spidering 'internal' URLs on your network. At the very least we recommend that
558558
your loopback and RFC1918 IP addresses are blacklisted.
559559

560-
This also requires the optional `lxml` and `netaddr` python dependencies to be
561-
installed. This in turn requires the `libxml2` library to be available - on
562-
Debian/Ubuntu this means `apt-get install libxml2-dev`, or equivalent for
563-
your OS.
560+
This also requires the optional `lxml` python dependency to be installed. This
561+
in turn requires the `libxml2` library to be available - on Debian/Ubuntu this
562+
means `apt-get install libxml2-dev`, or equivalent for your OS.
564563

565564
# Troubleshooting Installation
566565

UPGRADE.rst

+21
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ for example:
7575
wget https://packages.matrix.org/debian/pool/main/m/matrix-synapse-py3/matrix-synapse-py3_1.3.0+stretch1_amd64.deb
7676
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
7777
78+
Upgrading to v1.25.0
79+
====================
80+
81+
Blacklisting IP ranges
82+
----------------------
83+
84+
Synapse v1.25.0 includes new settings, ``ip_range_blacklist`` and
85+
``ip_range_whitelist``, for controlling outgoing requests from Synapse for federation,
86+
identity servers, push, and for checking key validity for third-party invite events.
87+
The previous setting, ``federation_ip_range_blacklist``, is deprecated. The new
88+
``ip_range_blacklist`` defaults to private IP ranges if it is not defined.
89+
90+
If you have never customised ``federation_ip_range_blacklist`` it is recommended
91+
that you remove that setting.
92+
93+
If you have customised ``federation_ip_range_blacklist`` you should update the
94+
setting name to ``ip_range_blacklist``.
95+
96+
If you have a custom push server that is reached via private IP space you may
97+
need to customise ``ip_range_blacklist`` or ``ip_range_whitelist``.
98+
7899
Upgrading to v1.24.0
79100
====================
80101

changelog.d/8821.bugfix

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Apply the `federation_ip_range_blacklist` to push and key revocation requests.
1+
Apply an IP range blacklist to push and key revocation requests.

changelog.d/8870.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Apply an IP range blacklist to push and key revocation requests.

docs/sample_config.yaml

+45-21
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,35 @@ pid_file: DATADIR/homeserver.pid
144144
#
145145
#enable_search: false
146146

147+
# Prevent outgoing requests from being sent to the following blacklisted IP address
148+
# CIDR ranges. If this option is not specified then it defaults to private IP
149+
# address ranges (see the example below).
150+
#
151+
# The blacklist applies to the outbound requests for federation, identity servers,
152+
# push servers, and for checking key validity for third-party invite events.
153+
#
154+
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
155+
# listed here, since they correspond to unroutable addresses.)
156+
#
157+
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
158+
#
159+
#ip_range_blacklist:
160+
# - '127.0.0.0/8'
161+
# - '10.0.0.0/8'
162+
# - '172.16.0.0/12'
163+
# - '192.168.0.0/16'
164+
# - '100.64.0.0/10'
165+
# - '192.0.0.0/24'
166+
# - '169.254.0.0/16'
167+
# - '198.18.0.0/15'
168+
# - '192.0.2.0/24'
169+
# - '198.51.100.0/24'
170+
# - '203.0.113.0/24'
171+
# - '224.0.0.0/4'
172+
# - '::1/128'
173+
# - 'fe80::/10'
174+
# - 'fc00::/7'
175+
147176
# List of ports that Synapse should listen on, their purpose and their
148177
# configuration.
149178
#
@@ -642,28 +671,17 @@ acme:
642671
# - nyc.example.com
643672
# - syd.example.com
644673

645-
# Prevent outgoing requests from being sent to the following blacklisted IP address
646-
# CIDR ranges. If this option is not specified, or specified with an empty list,
647-
# no IP range blacklist will be enforced.
674+
# List of IP address CIDR ranges that should be allowed for federation,
675+
# identity servers, push servers, and for checking key validity for
676+
# third-party invite events. This is useful for specifying exceptions to
677+
# wide-ranging blacklisted target IP ranges - e.g. for communication with
678+
# a push server only visible in your network.
648679
#
649-
# The blacklist applies to the outbound requests for federation, identity servers,
650-
# push servers, and for checking key validitity for third-party invite events.
651-
#
652-
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
653-
# listed here, since they correspond to unroutable addresses.)
654-
#
655-
# This option replaces federation_ip_range_blacklist in Synapse v1.24.0.
680+
# This whitelist overrides ip_range_blacklist and defaults to an empty
681+
# list.
656682
#
657-
ip_range_blacklist:
658-
- '127.0.0.0/8'
659-
- '10.0.0.0/8'
660-
- '172.16.0.0/12'
661-
- '192.168.0.0/16'
662-
- '100.64.0.0/10'
663-
- '169.254.0.0/16'
664-
- '::1/128'
665-
- 'fe80::/64'
666-
- 'fc00::/7'
683+
#ip_range_whitelist:
684+
# - '192.168.1.1'
667685

668686
# Report prometheus metrics on the age of PDUs being sent to and received from
669687
# the following domains. This can be used to give an idea of "delay" on inbound
@@ -955,9 +973,15 @@ media_store_path: "DATADIR/media_store"
955973
# - '172.16.0.0/12'
956974
# - '192.168.0.0/16'
957975
# - '100.64.0.0/10'
976+
# - '192.0.0.0/24'
958977
# - '169.254.0.0/16'
978+
# - '198.18.0.0/15'
979+
# - '192.0.2.0/24'
980+
# - '198.51.100.0/24'
981+
# - '203.0.113.0/24'
982+
# - '224.0.0.0/4'
959983
# - '::1/128'
960-
# - 'fe80::/64'
984+
# - 'fe80::/10'
961985
# - 'fc00::/7'
962986

963987
# List of IP address CIDR ranges that the URL preview spider is allowed

synapse/config/federation.py

+10-49
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15-
1615
from typing import Optional
1716

18-
from netaddr import IPSet
19-
20-
from synapse.config._base import Config, ConfigError
17+
from synapse.config._base import Config
2118
from synapse.config._util import validate_config
2219

2320

@@ -36,31 +33,6 @@ def read_config(self, config, **kwargs):
3633
for domain in federation_domain_whitelist:
3734
self.federation_domain_whitelist[domain] = True
3835

39-
ip_range_blacklist = config.get("ip_range_blacklist", [])
40-
41-
# Attempt to create an IPSet from the given ranges
42-
try:
43-
self.ip_range_blacklist = IPSet(ip_range_blacklist)
44-
except Exception as e:
45-
raise ConfigError("Invalid range(s) provided in ip_range_blacklist: %s" % e)
46-
# Always blacklist 0.0.0.0, ::
47-
self.ip_range_blacklist.update(["0.0.0.0", "::"])
48-
49-
# The federation_ip_range_blacklist is used for backwards-compatibility
50-
# and only applies to federation and identity servers. If it is not given,
51-
# default to ip_range_blacklist.
52-
federation_ip_range_blacklist = config.get(
53-
"federation_ip_range_blacklist", ip_range_blacklist
54-
)
55-
try:
56-
self.federation_ip_range_blacklist = IPSet(federation_ip_range_blacklist)
57-
except Exception as e:
58-
raise ConfigError(
59-
"Invalid range(s) provided in federation_ip_range_blacklist: %s" % e
60-
)
61-
# Always blacklist 0.0.0.0, ::
62-
self.federation_ip_range_blacklist.update(["0.0.0.0", "::"])
63-
6436
federation_metrics_domains = config.get("federation_metrics_domains") or []
6537
validate_config(
6638
_METRICS_FOR_DOMAINS_SCHEMA,
@@ -84,28 +56,17 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
8456
# - nyc.example.com
8557
# - syd.example.com
8658
87-
# Prevent outgoing requests from being sent to the following blacklisted IP address
88-
# CIDR ranges. If this option is not specified, or specified with an empty list,
89-
# no IP range blacklist will be enforced.
90-
#
91-
# The blacklist applies to the outbound requests for federation, identity servers,
92-
# push servers, and for checking key validitity for third-party invite events.
93-
#
94-
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
95-
# listed here, since they correspond to unroutable addresses.)
59+
# List of IP address CIDR ranges that should be allowed for federation,
60+
# identity servers, push servers, and for checking key validity for
61+
# third-party invite events. This is useful for specifying exceptions to
62+
# wide-ranging blacklisted target IP ranges - e.g. for communication with
63+
# a push server only visible in your network.
9664
#
97-
# This option replaces federation_ip_range_blacklist in Synapse v1.24.0.
65+
# This whitelist overrides ip_range_blacklist and defaults to an empty
66+
# list.
9867
#
99-
ip_range_blacklist:
100-
- '127.0.0.0/8'
101-
- '10.0.0.0/8'
102-
- '172.16.0.0/12'
103-
- '192.168.0.0/16'
104-
- '100.64.0.0/10'
105-
- '169.254.0.0/16'
106-
- '::1/128'
107-
- 'fe80::/64'
108-
- 'fc00::/7'
68+
#ip_range_whitelist:
69+
# - '192.168.1.1'
10970
11071
# Report prometheus metrics on the age of PDUs being sent to and received from
11172
# the following domains. This can be used to give an idea of "delay" on inbound

synapse/config/repository.py

+8-12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
from collections import namedtuple
1818
from typing import Dict, List
1919

20+
from netaddr import IPSet
21+
22+
from synapse.config.server import DEFAULT_IP_RANGE_BLACKLIST
2023
from synapse.python_dependencies import DependencyException, check_requirements
2124
from synapse.util.module_loader import load_module
2225

@@ -184,9 +187,6 @@ def read_config(self, config, **kwargs):
184187
"to work"
185188
)
186189

187-
# netaddr is a dependency for url_preview
188-
from netaddr import IPSet
189-
190190
self.url_preview_ip_range_blacklist = IPSet(
191191
config["url_preview_ip_range_blacklist"]
192192
)
@@ -215,6 +215,10 @@ def generate_config_section(self, data_dir_path, **kwargs):
215215
# strip final NL
216216
formatted_thumbnail_sizes = formatted_thumbnail_sizes[:-1]
217217

218+
ip_range_blacklist = "\n".join(
219+
" # - '%s'" % ip for ip in DEFAULT_IP_RANGE_BLACKLIST
220+
)
221+
218222
return (
219223
r"""
220224
## Media Store ##
@@ -285,15 +289,7 @@ def generate_config_section(self, data_dir_path, **kwargs):
285289
# you uncomment the following list as a starting point.
286290
#
287291
#url_preview_ip_range_blacklist:
288-
# - '127.0.0.0/8'
289-
# - '10.0.0.0/8'
290-
# - '172.16.0.0/12'
291-
# - '192.168.0.0/16'
292-
# - '100.64.0.0/10'
293-
# - '169.254.0.0/16'
294-
# - '::1/128'
295-
# - 'fe80::/64'
296-
# - 'fc00::/7'
292+
%(ip_range_blacklist)s
297293
298294
# List of IP address CIDR ranges that the URL preview spider is allowed
299295
# to access even if they are specified in url_preview_ip_range_blacklist.

synapse/config/server.py

+80
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import attr
2525
import yaml
26+
from netaddr import IPSet
2627

2728
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
2829
from synapse.http.endpoint import parse_and_validate_server_name
@@ -39,6 +40,34 @@
3940
# in the list.
4041
DEFAULT_BIND_ADDRESSES = ["::", "0.0.0.0"]
4142

43+
DEFAULT_IP_RANGE_BLACKLIST = [
44+
# Localhost
45+
"127.0.0.0/8",
46+
# Private networks.
47+
"10.0.0.0/8",
48+
"172.16.0.0/12",
49+
"192.168.0.0/16",
50+
# Carrier grade NAT.
51+
"100.64.0.0/10",
52+
# Address registry.
53+
"192.0.0.0/24",
54+
# Link-local networks.
55+
"169.254.0.0/16",
56+
# Testing networks.
57+
"198.18.0.0/15",
58+
"192.0.2.0/24",
59+
"198.51.100.0/24",
60+
"203.0.113.0/24",
61+
# Multicast.
62+
"224.0.0.0/4",
63+
# Localhost
64+
"::1/128",
65+
# Link-local addresses.
66+
"fe80::/10",
67+
# Unique local addresses.
68+
"fc00::/7",
69+
]
70+
4271
DEFAULT_ROOM_VERSION = "6"
4372

4473
ROOM_COMPLEXITY_TOO_GREAT = (
@@ -256,6 +285,38 @@ def read_config(self, config, **kwargs):
256285
# due to resource constraints
257286
self.admin_contact = config.get("admin_contact", None)
258287

288+
ip_range_blacklist = config.get(
289+
"ip_range_blacklist", DEFAULT_IP_RANGE_BLACKLIST
290+
)
291+
292+
# Attempt to create an IPSet from the given ranges
293+
try:
294+
self.ip_range_blacklist = IPSet(ip_range_blacklist)
295+
except Exception as e:
296+
raise ConfigError("Invalid range(s) provided in ip_range_blacklist.") from e
297+
# Always blacklist 0.0.0.0, ::
298+
self.ip_range_blacklist.update(["0.0.0.0", "::"])
299+
300+
try:
301+
self.ip_range_whitelist = IPSet(config.get("ip_range_whitelist", ()))
302+
except Exception as e:
303+
raise ConfigError("Invalid range(s) provided in ip_range_whitelist.") from e
304+
305+
# The federation_ip_range_blacklist is used for backwards-compatibility
306+
# and only applies to federation and identity servers. If it is not given,
307+
# default to ip_range_blacklist.
308+
federation_ip_range_blacklist = config.get(
309+
"federation_ip_range_blacklist", ip_range_blacklist
310+
)
311+
try:
312+
self.federation_ip_range_blacklist = IPSet(federation_ip_range_blacklist)
313+
except Exception as e:
314+
raise ConfigError(
315+
"Invalid range(s) provided in federation_ip_range_blacklist."
316+
) from e
317+
# Always blacklist 0.0.0.0, ::
318+
self.federation_ip_range_blacklist.update(["0.0.0.0", "::"])
319+
259320
if self.public_baseurl is not None:
260321
if self.public_baseurl[-1] != "/":
261322
self.public_baseurl += "/"
@@ -561,6 +622,10 @@ def has_tls_listener(self) -> bool:
561622
def generate_config_section(
562623
self, server_name, data_dir_path, open_private_ports, listeners, **kwargs
563624
):
625+
ip_range_blacklist = "\n".join(
626+
" # - '%s'" % ip for ip in DEFAULT_IP_RANGE_BLACKLIST
627+
)
628+
564629
_, bind_port = parse_and_validate_server_name(server_name)
565630
if bind_port is not None:
566631
unsecure_port = bind_port - 400
@@ -752,6 +817,21 @@ def generate_config_section(
752817
#
753818
#enable_search: false
754819
820+
# Prevent outgoing requests from being sent to the following blacklisted IP address
821+
# CIDR ranges. If this option is not specified then it defaults to private IP
822+
# address ranges (see the example below).
823+
#
824+
# The blacklist applies to the outbound requests for federation, identity servers,
825+
# push servers, and for checking key validity for third-party invite events.
826+
#
827+
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
828+
# listed here, since they correspond to unroutable addresses.)
829+
#
830+
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
831+
#
832+
#ip_range_blacklist:
833+
%(ip_range_blacklist)s
834+
755835
# List of ports that Synapse should listen on, their purpose and their
756836
# configuration.
757837
#

synapse/server.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,11 @@ def get_proxied_http_client(self) -> SimpleHttpClient:
370370
def get_proxied_blacklisted_http_client(self) -> SimpleHttpClient:
371371
"""
372372
An HTTP client that uses configured HTTP(S) proxies and blacklists IPs
373-
based on the IP range blacklist.
373+
based on the IP range blacklist/whitelist.
374374
"""
375375
return SimpleHttpClient(
376376
self,
377+
ip_whitelist=self.config.ip_range_whitelist,
377378
ip_blacklist=self.config.ip_range_blacklist,
378379
http_proxy=os.getenvb(b"http_proxy"),
379380
https_proxy=os.getenvb(b"HTTPS_PROXY"),

0 commit comments

Comments
 (0)