matrix-org / matrix-federation-tester

Tester for matrix federation written in golang.
78 stars 17 forks source link

SRV record and IP address #93

Closed saintger closed 4 years ago

saintger commented 4 years ago

I have a server with multiple website hosted, therefore I would like to put everything behind nginx. I decided to use a Synapse server name (example.com) different from the hostname (matrix.example.com).

Therefore I added a SRV record to point to matrix.example.com on port 443. And nginx is redirecting any request on matrix.example.com:443 to internal port 8008.

However it seems that the Federation tester is not compatible with this set up because I receive an error message: Get https://<ip address>:443/_matrix/key/v2/server: EOF

Why is the Federation tester trying to access through the IP address ?

richvdh commented 4 years ago

I'm afraid I don't really understand your error report.

And nginx is redirecting any request on matrix.example.com:443 to internal port 8008.

I hope you mean "proxying" rather than "redirecting".

Why is the Federation tester trying to access through the IP address ?

I don't know what you mean by this at all. Everything on the internet routes by IP address...?

At a guess, the problem is that your server isn't responding to requests with a Host header of 'example.com'.

I'm pretty sure the federation tester behaves correctly. If you think it's wrong, I suggest (a) reading https://github.com/matrix-org/synapse/blob/master/docs/federate.md (b) telling us an actual domain name that we can use to reproduce the problem, and (c) discussing with #synapse:matrix.org before raising an issue.

saintger commented 4 years ago

I hope you mean "proxying" rather than "redirecting".

Yes indeed, my mistake

I don't know what you mean by this at all. Everything on the internet routes by IP address...?

There was a formatting error in my original message (that I just corrected). I think the error is that instead of accessing: https://matrix.example.com:443/_matrix/key/v2/server The federation tester is trying to access: https://<ip address>:443/_matrix/key/v2/server

But the request is automatically rejected by nginx because it expects a regular domain name in the request.

I did try using the .well-known method using matrix.example.com and the federation tester is reporting a success, but I4d prefer to use the SRV record method.

Sorry as it is for the moment a private homeserver (I was just testing the federation) I cannot share its URL.

saintger commented 4 years ago

I finally found the issue by logging the $host on the nginx log. It seems that even though my Synapse lives on matrix.example.com, the Federation tester insist on sending requests to example.com. So you have to configure nginx to answer on this server name as well. For me it was enough to accept requests whose path start with _matrix.

richvdh commented 4 years ago

as I said...

At a guess, the problem is that your server isn't responding to requests with a Host header of 'example.com'.

saintger commented 4 years ago

Indeed this was the workaround but this still doesn't feel right for me. What is the point of having matrix.example.com if I have to answer matrix requests as well on example.com ?

My use case is that one server is handling example.com and another server is handling matrix.example.com

With the .well-known, at least it is working as expected: I just have to put a .well-known on example.com and all matrix requests are handled by matrix.example.com With the DNS SRV, the behavior is different. Even though the DNS SRV clearly specifies that matrix requests should be handled by matrix.example.com, I still have to handle matrix requests on example.com.

I am thoroughly confused and don't understand the logic behind. It will probably help if you could point me to the correct part of the documentation which explain why it is working like that ?

Thanks in advance

richvdh commented 4 years ago

https://matrix.org/docs/spec/server_server/r0.1.2#resolving-server-names https://github.com/matrix-org/matrix-doc/blob/master/proposals/1711-x509-for-federation.md#interaction-with-srv-records

saintger commented 4 years ago
 For example, if there were an SRV record at _matrix._tcp.matrix.org which pointed to server.example.com, then any federation requests for matrix.org would be routed to server.example.com. The question arises as to which certificate server.example.com should present.

In short: the server should present a certificate for the matrix domain (matrix.org in the above example).

That's exactly what I set up: server.example.com is presenting a certificate for server.example.com and also for matrix.org. I haven't read that matrix.org should answer to requests like matrix.org/_matrix/key/v2/server ?

richvdh commented 4 years ago

This conversation is very difficult in the abstract. If you think that the implementation doesn't match the spec, please demonstrate it with a pair of servers configured as you suggest.

saintger commented 4 years ago

The explanation is given in the Federation API point 4:

If the /.well-known request resulted in an error response, a server is found by resolving an SRV record for _matrix._tcp.. This may result in a hostname (to be resolved using AAAA or A records) and port. Requests are made to the resolved IP address and port, using 8448 as a default port, with a Host header of . The target server must present a valid certificate for .

That means that even though the SRV record _matrix._tcp.matrix.org points to server.example.com, a request will be made anyway to matrix.org (e.g. matrix.org/_matrix/key/v2/server) to check the certificate.

So there is indeed no bug in the Federation Tester but for my use case, it means that the SRV record has absolutely no advantages compared to the .well-known approach (I was hoping to avoid answering any request to matrix.org as everything was under server.example.com).

Thanks for Richard for having provided the explanation.

breuerfelix commented 3 years ago

@saintger it took me forever to get my head around that... i was so confused and i thought they did something wrong in implementing the spec BUT this one line is what makes this whole srv stuff incompatible with a reverse proxy: In short: the server should present a certificate for the matrix domain (matrix.org in the above example).
As you already mentioned, the request headers are and will always be matrix.org so the reverse proxy will never be able to route the traffic to example.com because it uses this header to identify which virtual host to choose.

they stated that this is due to security but if i own the domain and am able to add this srv record, it should be fine to trust the sub domain cert. but nvm. srv record is useless for reverse proxy. seems like we have to add the well known route to the root domain, no matter what :S