feat: New blog post
This commit is contained in:
parent
949563452b
commit
98cfbaf97c
125
content/blog/2023-07-15-prosody-traefik-2.md
Normal file
125
content/blog/2023-07-15-prosody-traefik-2.md
Normal file
@ -0,0 +1,125 @@
|
||||
<!-- title: Running Prosody on Port 443 Behind traefik 2: Electric ALPN -->
|
||||
<!-- description: In this blog post, I tell you how I changed my setup for proxying my XMPP server using traefik -->
|
||||
<!-- render: yes -->
|
||||
Hello everyone. Long time, no read.
|
||||
|
||||
In 2020, I published a post titled "[Running Prosody on Port 443 Behind traefik](https://blog.polynom.me/Running-Prosody-traefik.html)", where I described how I run my XMPP server
|
||||
behind the "application proxy" [*traefik*](https://github.com/traefik/traefik).
|
||||
I did this because I wanted to run my XMPP server *prosody* on port 443, so that the clients connected
|
||||
to my server can bypass firewalls that only allow web traffic. While that approach worked,
|
||||
over the last three years I changed my setup dramatically.
|
||||
|
||||
While migrating my old server from *Debian* to *NixOS*, I decided that I wanted a website
|
||||
hosted at the same domain I host my XMPP server at. This, however, was not possible with
|
||||
*traefik* back then because it only allowed the `HostSNI` rule, which differentiates TLS
|
||||
connections using the sent *Server Name Indication*. This is a problem, because a connection
|
||||
to `polynom.me` the website and `polynom.me` the XMPP server both result in the same SNI being
|
||||
sent by a connecting client.
|
||||
|
||||
Some time later, I stumbled upon [*sslh*](https://github.com/yrutschle/sslh), which is a
|
||||
tool similar to *traefik* in that it allows hosting multiple services on the same port, all
|
||||
differentiated by the SNI **and** the ALPN set by the connecting client. ALPN, or *Application-Layer Protocol Negotiation*, is an extension
|
||||
to TLS which allows a connecting client to advertise the protocol(s) it would like to use
|
||||
inside the encrypted session [(source)](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation). As such, I put
|
||||
*sslh* in front of my *traefik* and told it to route XMPP traffic (identified with an ALPN
|
||||
of `xmpp-client`) to my prosody server and everything else to my *traefik* server. While this
|
||||
worked well, there were two issues:
|
||||
|
||||
1. I was not running *sslh* in its ["transparent mode"](https://github.com/yrutschle/sslh/blob/master/doc/config.md#transparent-proxy-support), which uses some fancy iptable rules to allow the services behind it to see a connecting client's real IP address instead of just `127.0.0.1`. However, this requires more setup to work. This is an issue for services which enforce rate limits, like *NextCloud* and *Akkoma*. If one of theses services gets hit by many requests, all the services see are requests from `127.0.0.1` and may thus rate limit (or ban) `127.0.0.1`, meaning that all - even legitimate - requests are rate limited. Additionally, I was not sure if I could just use this to route an incoming IPv6 request to `127.0.0.1`, which is an IPv4 address.
|
||||
2. One day, as I was updating my server, I noticed that all my web services were responding very slowly. After some looking around, it turned out that *sslh* took about 5 seconds to route IPv6 requests, but not IPv4 requests. As I did not change anything (besides update the server), to this day I am not sure what happened.
|
||||
|
||||
Due to these two issues, I decided to revisit the idea I described in my old post.
|
||||
|
||||
## The Prosody Setup
|
||||
|
||||
On the prosody-side of things, I did not change a lot compared to the old post. I did, however,
|
||||
migrate from the `legacy_ssl_*` options to the newer `c2s_direct_tls_*` options, which
|
||||
[replace the former](https://hg.prosody.im/trunk/file/tip/doc/doap.xml#l758).
|
||||
|
||||
Thus, my prosody configuration regarding direct TLS connections now looks like this:
|
||||
|
||||
```lua
|
||||
c2s_direct_tls_ports = { 5223 }
|
||||
c2s_direct_tls_ssl = {
|
||||
[5223] = {
|
||||
key = "/etc/prosody/certs/polynom.me.key";
|
||||
certificate = "/etc/prosody/certs/polynom.me.crt";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## The *Traefik* Setup
|
||||
|
||||
On *traefik*-side of things, only one thing really changed: Instead of just having a rule using
|
||||
`HostSNI`, I now also require that the connection with the XMPP server advertises an ALPN
|
||||
of `xmpp-client`, which is specified in the
|
||||
[appropriate XMPP spec](https://xmpp.org/extensions/xep-0368.html). From my deployment
|
||||
experience, all clients I tested (*Conversations*, *Blabber*, *Gajim*, *Dino*, *Monal*, [Moxxy](https://moxxy.org))
|
||||
correctly set the ALPN when connecting via a direct TLS connection.
|
||||
|
||||
So my *traefik* configuration now looks something like this (Not really, because I let NixOS
|
||||
generate the actual config, but it is very similar):
|
||||
|
||||
```yaml
|
||||
tcp:
|
||||
routers:
|
||||
xmpps:
|
||||
entrypoints:
|
||||
- "https"
|
||||
rule: "HostSNI(`polynom.me`) && ALPN(`xmpp-client`)"
|
||||
service: prosody
|
||||
tls:
|
||||
passthrough: true
|
||||
# [...]
|
||||
services:
|
||||
prosody:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- address: "127.0.0.1:5223"
|
||||
|
||||
http:
|
||||
routers:
|
||||
web-secure:
|
||||
entrypoints:
|
||||
- "https"
|
||||
rule: "Host(`polynom.me`)"
|
||||
service: webserver
|
||||
tls:
|
||||
```
|
||||
|
||||
The entrypoint `https` is just set to listen on `:443`. This way, I can route IPv4 and IPv6
|
||||
requests. Also note the `passthrough: true` in the XMPP router's `tls` settings. If this is
|
||||
not set to `true`, then *traefik* would terminate the connection's TLS session before passing
|
||||
the data to the XMPP server.
|
||||
|
||||
However, this config has one really big issue: In order
|
||||
to have the website hosted at `polynom.me` be served using TLS, I have to set the
|
||||
router's `tls` attribute. The *traefik*
|
||||
documentation says that "*If both HTTP routers and TCP routers listen to the
|
||||
same entry points, the TCP routers will apply before the HTTP routers. If no matching route
|
||||
is found for the TCP routers, then the HTTP routers will take over.*"
|
||||
[(source)](https://doc.traefik.io/traefik/routing/routers/#general_1).
|
||||
|
||||
This, however, does not seem to be the case if a HTTP router (in my example with ```Host(`polynom.me`)```) and a TCP router (in my example with ```HostSNI(`polynom.me`)```) respond to the same
|
||||
SNI **and** the HTTP router has its `tls` attribute set. In that case, the HTTP router appears
|
||||
to be checked first and will complain, if the sent ALPN is not one of the
|
||||
[HTTP ALPNs](https://developer.mozilla.org/en-US/docs/Glossary/ALPN), for example when
|
||||
connecting using XMPP. As such we can connect to the HTTP server but not to the
|
||||
XMPP server.
|
||||
|
||||
It appears to be an issue that [I am not alone with](https://github.com/traefik/traefik/issues/9922), but also
|
||||
one that is not fixed. So I tried digging around in *traefik*'s code and tried a couple of
|
||||
things. So for my setup to work, I have to apply [this patch](https://github.com/PapaTutuWawa/traefik/commit/36f0e3c805ca4e645f3313f667a6b3ff5e2fe4a9) to *traefik*. With that, the issue *appears*
|
||||
to be gone, and I can access both my website and my XMPP server on the same domain and on the
|
||||
same port. Do note that this patch is not upstreamed and may break things. For me, it
|
||||
works. But I haven't run extensive tests or *traefik*'s integration and unit tests.
|
||||
|
||||
## Conclusion
|
||||
|
||||
This approach solves problem 2 fully and problem 1 partially. *Traefik* is able to route
|
||||
the connections correctly with no delay, compared to *sslh*. It also provides my web services
|
||||
with the connecting clients' IP addresses using HTTP headers. It does not, however, provide
|
||||
my XMPP server with a connecting client's IP address. This could be solved with some clever
|
||||
trickery, like telling *traefik* to use the [*PROXY* protocol](https://doc.traefik.io/traefik/routing/services/#proxy-protocol) when connecting to prosody,
|
||||
and enabling the [`net_proxy`](https://modules.prosody.im/mod_net_proxy.html) module. However,
|
||||
I have not yet tried such a setup, though I am very curious and may try that out.
|
90
content/blog/2023-07-15-prosody-traefik-2.md.sig
Normal file
90
content/blog/2023-07-15-prosody-traefik-2.md.sig
Normal file
@ -0,0 +1,90 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
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
|
||||
H2bMsbwali44xssO0iWPmhdhekYg9aBVTl0sFw8x8CtkC8pxPXHD74ty1pnWJWra
|
||||
LFWrFsYv2v72HYV0Nv2i81UCU7lXTTaTDfrn9S4RT6rfoiEnvD5YMfmiUq35LJqS
|
||||
W9TyHZKNA9D80ABuTaVLVRNH1LJsemloksAg6GCBImlGEi1VfIKBi0WfmvbIpgVq
|
||||
YYfHIpsLhh39+S2OTOODS7YuXbT4uEUjp5659PunrP/VLy409h98/7IlyZflZUvw
|
||||
s/GrTguAbiKgmzbQzXlZZlxkLD8pWbpp+KRFN/V+uvLeFZWr1n9/8v4PjZ94fbv4
|
||||
0YnK/W/ufc1zf/GW3HHmimXs/OvdO676zqf3P/rAfvvua/be1PuxI49NHvVae7xH
|
||||
nv3w7Uuvmrrs7nO8zXde/cTDB/f9ZOmPq6f+48KfH/7Ifc9Et19/3tlX9jbLn9m5
|
||||
67rByZsX/35F+ex/lqOdj/i3HPPQkieqPznmDU9969rOvTc8N3b+L9k4O+Fb+647
|
||||
+e/71nzqLVfeevwn9tsHfnzePQ/ecHTsTRddvfcLV7xmYsMLbXHo5511fzrr619b
|
||||
9f7H9x7/9Cs/f/jMH9z21UO/vP69teW33bH5td/b9Id7//zuLdfO7jr+nIvv+trK
|
||||
G+u/vv+dG75+8w8fe/iaVxz+7NHBu55+nr/8tPVi95Mv+cynfnX6e06vvOyylzy7
|
||||
60sr9t+7d+WOY29o9R677+OltV9ed/Czj1829Y6By9eecfDWu/Y99b4jJ3zjA2/c
|
||||
uv6e1t9etWTzw1ecdlvpzfXBPau3P/W2z22//IV3/fSSq4+cSx7aeu2Pnmr8effn
|
||||
Zq57tG//Q1/+ypKBf23b4i37yJ8+f9/DD377vH0vfehHu/751xPffeTAih0HLn/m
|
||||
wHffeMuhxss/dnCbsfiJ3z535NEdz//1L8OHvmge/dknP/Cz+nHffPr5V5/x65kH
|
||||
1t/Y9+r4pOk9X3jhuHte5x5bOXbp1I4nLzUvdK45cMWKvU8SY8+XXvqvt009c2K8
|
||||
4a2Ha6dddCU/dfzQPTvO/c2zXxmeaN558i333bis9/G7Xz975HBr0cab/ni0/cjz
|
||||
P208uOWxmfX/Bg==
|
||||
=/2ew
|
||||
-----END PGP MESSAGE-----
|
@ -5,7 +5,7 @@
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "blog";
|
||||
version = "20211128";
|
||||
version = "20231507";
|
||||
|
||||
src = ../.;
|
||||
|
||||
|
Reference in New Issue
Block a user