element-hq / element-hq/synapse

federation: refresh devices_list for users more frequently

Open
#5,433 0 comments 0 reactions 0 assignees View on GitHub
A-Device-List-Tracking A-Federation O-Uncommon S-Major T-Enhancement z-feature z-p3 z-uisi
Dominant language
Python
Stars
4.6k
Forks
600
Avg merge
5d 22h
Merged PRs (30d)
51

Description

This issue has been migrated from [#5433](https://github.com/matrix-org/synapse/issues/5433).

---

**Description:**

Let's take two homeservers `A.com` and `B.com`. You've set up `A.com` and `B.com` and they are both federating with one another freely.

At the moment if you (possibly accidentally) nuke your already-federated `A.com` server and want to rebuild it using the same `server_name` things work mostly fine (`B.com` seems to accept the new signing key of your server without much issue, and federated events between `A.com` and `B.com` work properly).

However, one issue that occurs is that the cached device list of `A.com`'s users on `B.com` will persist (assuming that you've kept the same usernames on the new installation). Not only that, but because the database has been completely nuked, `A.com` won't know that it needs to send `m.device_list_update` EDUs to `B.com`. This results in E2EE over federation being basically broken permanently because users on `B.com` won't negotiate new Megolm session keys (because they don't see the new `A.com` devices and instead only see the ghost ones.

Would it be acceptable to make synapse automatically do a hard refresh of the devices list of the users on a federated server if the signing key of the homeserver changes? This could be done lazily (effectively just remove the cached information about devices, and when a user requests it then we fetch it over federation). Is there any attack that I'm missing which much result if we make this a default feature?

**Workaround**

As a quick hack, it is possible to fix this using the manhole in synapse -- by sending a `m.device_list_update` EDU to `B.com` which has a broken value of `prev_id`. [According to the spec](https://matrix.org/docs/spec/server_server/r0.1.1.html#device-management) this causes `B.com` to reset its cached device list:

> If a server receives an EDU which refers to a prev_id it does not recognise, it must resynchronise its list by calling the /user/keys/query API and resume the process.

Manhole Script -- USE AT YOUR OWN RISK

```python
broken_server = "B.com"
user_id = "@cyphar:A.com"

fs = hs.get_federation_sender()
k = fs._per_destination_queues[broken_server]._store.get_devices_with_keys_by_user(user_id)
content = {"user_id": user_id, "stream_id": k.result[0]+2, "prev_id": [k.result[0]+1], **k.result[1][0]}
fs.build_and_send_edu(broken_server, "m.device_list_update", content)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.