Disable keepalive

This commit is contained in:
Pascal Engélibert 2025-04-12 21:04:10 +02:00
commit f08543b533
3 changed files with 38 additions and 8 deletions

View file

@ -2,6 +2,10 @@
Mesozoa is a small animal living between a reverse-proxy and a server, protecting the server from crawlers by forcing the browser to run proof of work. Mesozoa is a small animal living between a reverse-proxy and a server, protecting the server from crawlers by forcing the browser to run proof of work.
It inspects request's HTTP header and passes the socket to the server directly (zero-copy).
[Try it online.](https://git.txmn.tk/tuxmain/mesozoa/commits/branch/main) (remove the cookie `mesozoa-proof` or change User-Agent to renew the experience)
## Why? ## Why?
Why not Anubis? Because it provides no build instructions and only supports Docker. Why not Anubis? Because it provides no build instructions and only supports Docker.
@ -12,14 +16,40 @@ And because it looked like a fun little project.
## Install ## Install
### Build
[Install rustup](https://rustup.rs) and a nightly Rust toolchain. [Install rustup](https://rustup.rs) and a nightly Rust toolchain.
cargo build --release cargo build --release
Must be used behind a reverse proxy providing `X-Forwarded-For`. ### Run
./target/release/mesozoa -c example-config.yaml ./target/release/mesozoa -c example-config.yaml
### Apache config
Note that the reverse-proxy must provide the HTTP header `X-Forwarded-For`.
Add this to your virtual host:
```
ProxyPreserveHost On
ProxyRequests Off
ProxyTimeout 600
<Proxy "http://127.0.0.1:8504">
ProxySet keepalive=Off
</Proxy>
<Location />
ProxyPass http://127.0.0.1:8504/
</Location>
```
**Note on keepalive**: When keepalive is On, connections between Apache and server are re-used, even for requests from different clients.
This increases server performance as it reduces connection overhead, but prevents Mesozoa from intercepting HTTP headers.
Hence we have to disable keepalive around Mesozoa. This does not prevent using keepalive between Apache and client.
## Challenge protocol ## Challenge protocol
### Challenge generation ### Challenge generation

View file

@ -17,7 +17,7 @@ challenge-timeout: 3600
# Action applied when no policy matches # Action applied when no policy matches
# (see below for legal values) # (see below for legal values)
default-action: challenge default-action: allow
# Policy groups are evaluated in order. # Policy groups are evaluated in order.
# The first matching group stops evaluation. # The first matching group stops evaluation.

View file

@ -8,7 +8,7 @@ use http::HeaderLineIterator;
use policy::CompiledPolicies; use policy::CompiledPolicies;
use rand::Rng; use rand::Rng;
use realm_syscall::socket2::TcpKeepalive; // use realm_syscall::socket2::TcpKeepalive;
use regex::bytes::Regex; use regex::bytes::Regex;
use std::{net::SocketAddr, time::Duration}; use std::{net::SocketAddr, time::Duration};
use tokio::{ use tokio::{
@ -226,15 +226,15 @@ async fn main() {
} }
async fn do_proxy(pass_addr: SocketAddr, mut client_stream: TcpStream) { async fn do_proxy(pass_addr: SocketAddr, mut client_stream: TcpStream) {
let keepalive_dur = Duration::from_secs(15); // let keepalive_dur = Duration::from_secs(15);
let mut keepalive = TcpKeepalive::new().with_time(keepalive_dur); // let mut keepalive = TcpKeepalive::new().with_time(keepalive_dur);
keepalive = TcpKeepalive::with_interval(keepalive, keepalive_dur); // keepalive = TcpKeepalive::with_interval(keepalive, keepalive_dur);
keepalive = TcpKeepalive::with_retries(keepalive, 3); // keepalive = TcpKeepalive::with_retries(keepalive, 3);
let pass_socket = realm_syscall::new_tcp_socket(&pass_addr).unwrap(); let pass_socket = realm_syscall::new_tcp_socket(&pass_addr).unwrap();
pass_socket.set_reuse_address(true).ok(); pass_socket.set_reuse_address(true).ok();
pass_socket.set_tcp_keepalive(&keepalive).ok(); // pass_socket.set_tcp_keepalive(&keepalive).ok();
let pass_socket = TcpSocket::from_std_stream(pass_socket.into()); let pass_socket = TcpSocket::from_std_stream(pass_socket.into());