Side note, I haven't heard failover used in the context of kicking unhealthy backends before. Failover is typically something that would be implemented with carp(4) (aka VRRP, but with support for active/active setups) on two different machines running relayd.
Seconded. Nice, concise volume that helped me setup hosting for multiple sites on a single VM with different requirements (some reverse proxy, some CGI, some static).
Really looking forward to the 3rd edition of Absolute OpenBSD.
“The trunk is set up in failover mode, so either interface can be used. If both are available, it will prefer the bge0 port, since that is the first one added to the trunk device.“
Is it for relaying any tcp/udp or just http? At first I thought it was the former but it understands http headers. Does it support any other protocols?
My understanding is that it started life as a fork(note: by same author) of openbsd's httpd. The author wanted to add reverse proxy capability to httpd and decided that the problem domain was complex enough that it would hurt httpd's simplicity and warranted it's own program.
So it's heart is a reverse http proxy. generalized to be a generic application layer proxy. and then integrated with the pf firewall to be a ip layer forwarder. note the distinction in the manual between redirections(ip forwarder) and relays(application proxy)
According to the manual it has application specific relays for http and dns. for other than that you have to use the generic tcp relay. if you are redirecting, it does not look at the internals of the packet at all.
I have moved my homelab applications from Nginx Proxy Manager to relayd on my OpenBSD router, and honestly, it works very well for these small loads. It does filtering, virtual hosts and TLS, all controlled from a single file and consuming negligible amounts of memory. Scaling is rumored to be a wall most OpenBSD products hit at some point, but for my use case, it's excellent.
> Scaling is rumored to be a wall most OpenBSD products hit at some point
I suspect the vast majority of OpenBSD users never hit a "scaling wall". What do you mean by product?
In a previous life I installed two OpenBSD routers with a 10GbE card each. With carp(4) they could push nearly 20Gbps total. This was back in 2015 or so.
"Scaling" would just be matter of adding more nodes, or replace with 40GbE cards (which would require a more powerful CPU).
Perhaps running a high traffic relayd on them would have reduced the throughput. But that smells like poor architecture: let routers be routers and load balancers be load balancers :)
I'm interested to understand whether it's thread, process or singlethread event loop based. And maybe other architectural nuance that set relayd apart for example with nginx.
In case no one familiar with the internals shows up, here are some pointers if you want to dig: the configuration man page[0] has a prefork option, and nothing thread-related:
prefork number
When using relays, run the specified number of processes to handle relayed
connections. This increases the performance and prevents delays when connecting
to a relay. relayd(8) runs 3 relay processes by default and every process
will handle all configured relays.
The source[1] seems to be quite clear; relayd(8)[2] describes the main notions ("entities": relay, protocol, etc.) involved in the configuration/source.
Unless I am mistaken it's "credentialless" forwarding. I couldn't see any directive which would make the relay check user, its the IP routing mechanism to make something "inside" visible "outside" with loadshare, failover, test-before-connect, but not "gate keep"
an ssh -D SOCKS5 tunnel requires you to present credentials on the jump host. This daemon bypasses that need. (happy to be corrected. I'd love to be wrong)
Update: I think strictly speaking auth is outside the scope of relayd, but looking at the docs, I bet I could wire something together around having specific cookies or other headers.
match request type cookie "ident" value "hashed password"
or
match request header "Authorization" value "Basic dXNlcm5hbWU6dGhpcyBpcyBzZWNyZXQK"
The above will not work by the way, last time I used relayd I found it to be one of the few openbsd programs where I had a hard time thinking the same way as it's author. That is, The syntax made my head hurt. I got it working but it was a chore. I think it is more that it ends up being a very complicated domain than poor syntax.
It was just about time, considering there was a jestful tricking the developer of relayd to reprogram it to httpd. IIRC he got epic tricked into it! In the sense he didn't even know he was making a webserver until he actually made it. This may not be a very true version, but I love to believe so.
The camaraderie and passion in the project is mind boggling.
Note to self: Compare memory usage of using stunnel with large stunnel.conf containing many backends versus relayd with large table containing many backends.
From relayd.conf manpage:
"TLS client and server
When combining both modes, TLS server and client, relayd(8) can filter TLS connections as a man-in-the-middle. This combined mode is also called "TLS inspection". The configuration requires additional X.509 certificate settings; see the ca key description in the PROTOCOLS section for more details."
https://man.openbsd.org/man8/relayd.8
https://man.openbsd.org/man8/relayctl.8
https://man.openbsd.org/man5/relayd.conf.5
Side note, I haven't heard failover used in the context of kicking unhealthy backends before. Failover is typically something that would be implemented with carp(4) (aka VRRP, but with support for active/active setups) on two different machines running relayd.
https://man.openbsd.org/man4/carp.4
Nothing beats the sheer elegance of OpenBSD for networking tasks. :-)