Repository: matrix-org/synapse

Issue:
ip_range_whitelist has no impact on federation client
<!--

**THIS IS NOT A SUPPORT CHANNEL!**
**IF YOU HAVE SUPPORT QUESTIONS ABOUT RUNNING OR CONFIGURING YOUR OWN HOME SERVER**,
please ask in **#synapse:matrix.org** (using a matrix.org account if necessary)

If you want to report a security issue, please see https://matrix.org/security-disclosure-policy/

This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue.

You can also preview your report before submitting it. You may remove sections
that aren't relevant to your particular case.

Text between <!-- and --​> marks will be invisible in the report.

-->

### Description
`ip_range_whitelist` does not affect federation ip blacklisting. I have an internal matrix server which cannot federate with other servers on the same network. 
<!-- Describe here the problem that you are experiencing -->

### Steps to reproduce

- Setup a homeserver using an internal ip address
- Set `ip_range_whitelist` to include the other servers ip address
- Attempt to federate with it

Relevant log entry

```
INFO - None - Dropped 10.x.x.x from DNS resolution to hs-name due to blacklist
```

Looking at the code the federation client is setup without passing an ip_whitelist to its DNS resolver. Only application services appears to at present use the `ip_range_whitelist` attribute.

### Version information

<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->

<!-- Was this issue identified on matrix.org or another homeserver? -->

<!--
 What version of Synapse is running?

You can find the Synapse version with this command:

$ curl http://localhost:8008/_synapse/admin/v1/server_version

(You may need to replace `localhost:8008` if Synapse is not configured to
listen on that port.)
-->
- **Version**: 1.29.0

- **Install method**: debian package
<!-- examples: package manager/git clone/pip  -->

- **Platform**: debian
<!--
Tell us about the environment in which your homeserver is operating
distro, hardware, if it's running in a vm/container, etc.
-->



Discussion:
I think we weren't 100% sure how to handle it in light of the old `federation_ip_range_blacklist` option.

I think the right thing to do the following:

* Set a `federation_ip_range_whitelist` value around [here](https://github.com/matrix-org/synapse/blob/58114f8a17a5b52a9b90b89b3c7d9b595307c9a8/synapse/config/server.py#L384-L389) which is `None` if `federation_ip_range_blacklist` is defined, otherwise it gets set to `ip_range_whitelist`.
* Update the code [around here](https://github.com/matrix-org/synapse/blob/58114f8a17a5b52a9b90b89b3c7d9b595307c9a8/synapse/http/matrixfederationclient.py#L238-L240) to pass in this `federation_ip_range_whitelist` value.

I think that will match the expected backwards compatibility.
> if `federation_ip_range_blacklist` is defined

This might be a bit unclear since `federation_ip_range_blacklist` falls back to `ip_range_whitelist` in the linked code. But you meant if `federation_ip_range_blacklist` is not specified in the config file, correct?
> But you meant if `federation_ip_range_blacklist` is not specified in the config file, correct?

Sorry for the confusion...I mean if it is *not defined in the config file*, yes. 👍 

Resolving patch:
diff --git a/synapse/config/server.py b/synapse/config/server.py
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -397,19 +397,22 @@ def read_config(self, config, **kwargs):
         self.ip_range_whitelist = generate_ip_set(
             config.get("ip_range_whitelist", ()), config_path=("ip_range_whitelist",)
         )
-
         # The federation_ip_range_blacklist is used for backwards-compatibility
-        # and only applies to federation and identity servers. If it is not given,
-        # default to ip_range_blacklist.
-        federation_ip_range_blacklist = config.get(
-            "federation_ip_range_blacklist", ip_range_blacklist
-        )
-        # Always blacklist 0.0.0.0, ::
-        self.federation_ip_range_blacklist = generate_ip_set(
-            federation_ip_range_blacklist,
-            ["0.0.0.0", "::"],
-            config_path=("federation_ip_range_blacklist",),
-        )
+        # and only applies to federation and identity servers.
+        if "federation_ip_range_blacklist" in config:
+            # Always blacklist 0.0.0.0, ::
+            self.federation_ip_range_blacklist = generate_ip_set(
+                config["federation_ip_range_blacklist"],
+                ["0.0.0.0", "::"],
+                config_path=("federation_ip_range_blacklist",),
+            )
+            # 'federation_ip_range_whitelist' was never a supported configuration option.
+            self.federation_ip_range_whitelist = None
+        else:
+            # No backwards-compatiblity requrired, as federation_ip_range_blacklist
+            # is not given. Default to ip_range_blacklist and ip_range_whitelist.
+            self.federation_ip_range_blacklist = self.ip_range_blacklist
+            self.federation_ip_range_whitelist = self.ip_range_whitelist
 
         # (undocumented) option for torturing the worker-mode replication a bit,
         # for testing. The value defines the number of milliseconds to pause before
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -318,7 +318,9 @@ def __init__(self, hs, tls_client_options_factory):
         # We need to use a DNS resolver which filters out blacklisted IP
         # addresses, to prevent DNS rebinding.
         self.reactor = BlacklistingReactorWrapper(
-            hs.get_reactor(), None, hs.config.federation_ip_range_blacklist
+            hs.get_reactor(),
+            hs.config.federation_ip_range_whitelist,
+            hs.config.federation_ip_range_blacklist,
         )  # type: ISynapseReactor
 
         user_agent = hs.version_string


Test patch: