9flare
9flare is a minimal, extensible proof-of-work CAPTCHA implementation written in C, inspired by Anubis. It operates as a FastCGI program, forgoing an integrated HTTP server in the interest of simplicity, and relies on nginx to forward cleared visitors to their destination via its error code fallback mechanism. Broad browser compatibility is a design priority, so you will experience no friction using 9flare with lightweight browsers such as NetSurf or Lynx. JavaScript is entirely optional, and all JavaScript is advertised as AGPLv3 to LibreJS.
9flare makes no attempt to be a comprehensive crawling deterrent in the way that Anubis is. Anubis employs extensive fingerprinting, strict token expiration, and enforces consistency between the IP address and user agent at solve time and at access time, in addition to many other security measures. While thorough, this approach can prove frustrating for legitimate visitors, who may find themselves re-solving the proof-of-work regularly. 9flare takes the opposite philosophy: its purpose is to deter primitive web crawlers that headlessly scrape pages and place unnecessary strain on server resources, not to serve as a hardened defense against sophisticated or targeted attacks. It maintains no database of generated solutions, its solution cookies are valid indefinitely, and it can be circumvented with minimal effort by design. The goal is a low-friction barrier sufficient to deter the vast majority of scrapers, reducing server load without standing in the way of real users, and without causing breakage to those using simpler web browsers. For a more comprehensive and paranoid solution, projects such as Anubis, go-away, or iocaine are better suited to the task.
Building
Dependencies:
( gnutls || libsodium || openssl )
make
Nginx Config
...
location / {
if ($http_user_agent ~* "^(git/|connect-go/)") {
return 421; # skip 9flare
}
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /opt/9flare/9flare;
fastcgi_intercept_errors on;
error_page 421 = @fallback;
error_page 502 = @fallback; # needed for >512kb uploads
}
location @fallback {
proxy_pass http://127.0.0.1:8080;
}
...