Anubis now has support for weighing the soul of incoming requests with custom rules and thresholds. Anubis also can function without the use of client-side JavaScript using the metarefresh
challenge.
The big ticket items are as follows:
- Implement a no-JS challenge method:
metarefresh
(#95) - Implement request "weight", allowing administrators to customize the behaviour of Anubis based on specific criteria
- Implement GeoIP and ASN based checks via Thoth (#206)
- Add custom weight thresholds via CEL (#688)
- Move Open Graph configuration to the policy file
- Enable support for Open Graph metadata to be returned by default instead of doing lookups against the target
- Add
robots2policy
CLI utility to convert robots.txt files to Anubis challenge policies using CEL expressions (#409) - Refactor challenge presentation logic to use a challenge registry
- Allow challenge implementations to register HTTP routes
- Imprint/Impressum support (#362)
- Fix "invalid response" after "Success!" in Chromium (#564)
A lot of performance improvements have been made:
- Replace internal SHA256 hashing with xxhash for 4-6x performance improvement in policy evaluation and cache operations
- Optimized the OGTags subsystem with reduced allocations and runtime per request by up to 66%
- Replace cidranger with bart for IP range checking, improving IP matching performance by 3-20x with zero heap
allocations
And some cleanups/refactors were added:
- Fix OpenGraph passthrough (#717)
- Remove the unused
/test-error
endpoint and update the testing endpoint/make-challenge
to only be enabled in
development - Add
--xff-strip-private
flag/envvar to toggle skipping X-Forwarded-For private addresses or not - Bump AI-robots.txt to version 1.37
- Make progress bar styling more compatible (UXP, etc)
- Add
--strip-base-prefix
flag/envvar to strip the base prefix from request paths when forwarding to target servers - Fix an off-by-one in the default threshold config
- Add functionality for HS512 JWT algorithm
- Add support for dynamic cookie domains with the
--cookie-dynamic-domain
/COOKIE_DYNAMIC_DOMAIN
flag/envvar
Request weight is one of the biggest ticket features in Anubis. This enables Anubis to be much closer to a Web Application Firewall and when combined with custom thresholds allows administrators to have Anubis take advanced reactions. For more information about request weight, see the request weight section of the policy file documentation.
TL;DR when you have one or more WEIGHT rules like this:
bots:
- name: gitea-session-token
action: WEIGH
expression:
all:
- '"Cookie" in headers'
- headers["Cookie"].contains("i_love_gitea=")
# Remove 5 weight points
weight:
adjust: -5
You can configure custom thresholds like this:
thresholds:
- name: minimal-suspicion # This client is likely fine, its soul is lighter than a feather
expression: weight < 0 # a feather weighs zero units
action: ALLOW # Allow the traffic through
# For clients that had some weight reduced through custom rules, give them a
# lightweight challenge.
- name: mild-suspicion
expression:
all:
- weight >= 0
- weight < 10
action: CHALLENGE
challenge:
# https://anubis.techaro.lol/docs/admin/configuration/challenges/metarefresh
algorithm: metarefresh
difficulty: 1
report_as: 1
# For clients that are browser-like but have either gained points from custom
# rules or report as a standard browser.
- name: moderate-suspicion
expression:
all:
- weight >= 10
- weight < 20
action: CHALLENGE
challenge:
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
algorithm: fast
difficulty: 2 # two leading zeros, very fast for most clients
report_as: 2
# For clients that are browser like and have gained many points from custom
# rules
- name: extreme-suspicion
expression: weight >= 20
action: CHALLENGE
challenge:
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
algorithm: fast
difficulty: 4
report_as: 4
These thresholds apply when no other ALLOW
, DENY
, or CHALLENGE
rule matches the request. WEIGHT
rules add and remove request weight as needed:
bots:
- name: gitea-session-token
action: WEIGH
expression:
all:
- '"Cookie" in headers'
- headers["Cookie"].contains("i_love_gitea=")
# Remove 5 weight points
weight:
adjust: -5
- name: bot-like-user-agent
action: WEIGH
expression: '"Bot" in userAgent'
# Add 5 weight points
weight:
adjust: 5
Of note: the default "generic browser" rule assigns 10 weight points:
# Generic catchall rule
- name: generic-browser
user_agent_regex: >-
Mozilla|Opera
action: WEIGH
weight:
adjust: 10
Adjust this as you see fit.
What's Changed
- build(deps-dev): bump esbuild from 0.25.4 to 0.25.5 in the npm group by @dependabot in #600
- build(deps): bump docker/build-push-action from 6.17.0 to 6.18.0 in the github-actions group by @dependabot in #602
- build(deps): bump github.com/a-h/templ from 0.3.865 to 0.3.887 in the gomod group by @dependabot in #601
- docs(faq): anubis does not mine bitcoin by @Xe in #609
- feat: implement challenge registry by @Xe in #607
- docs(known-instances): add Alliance of Hessian Libraries by @CryptoCopter in #611
- docs(subrequest-auth): document required policy changes by @foosinn in #613
- docs: Adjust the name of the cookie to the current "techaro.lol-anubis-auth" by @jieter in #615
- fix(lib/challenge): allow challenges to register HTTP routes by @Xe in #620
- docs(known-instances): add wiki.dolphin-emu.org to known instances by @lotharsm in #626
- feat(lib/challenge): HTTP meta refresh challenge method by @Xe in #623
- style: Some minor fixes by @JasonLovesDoggo in #548
- Bump ai.robots.txt to v1.34 by @Dryusdan in #632
- build(deps): bump the gomod group with 2 updates by @dependabot in #634
- docs(admin/environments): Prefer IPv6 over IPv4 for apache2 listener directive by @lotharsm in #628
- build(deps): bump github/codeql-action from 3.28.18 to 3.28.19 in the github-actions group by @dependabot in #635
- Adds ability to toggle off stripping of private addrs from XFF by @dchandekstark in #619
- Make progress bar styling more compatible (UXP, etc) by @Fierelier in #636
- feat(lib): implement request weight by @Xe in #621
- Update known-instances.md to include SquirrelJME by @XerTheSquirrel in #643
- fix(anubis): nil check policy loading by @JasonLovesDoggo in #645
- test: introduce SSH based CI for non-native test hosts by @Xe in #644
- build(deps): bump github.com/cloudflare/circl from 1.6.0 to 1.6.1 by @dependabot in #650
- test(ssh-ci): re-enable GOARCH=ppc64le by @Xe in #651
- fix(gitattributes): update pattern for generated files by @JasonLovesDoggo in #652
- fix(ci): conditionally run SSH jobs for TecharoHQ/anubis by @JasonLovesDoggo in #654
- feat: add a strip-base-prefix option by @JasonLovesDoggo in #655
- refactor(ogtags): optimize URL construction and memory allocations by @JasonLovesDoggo in #647
- docs(known-instances): add bugs.scummvm.org and gitlab.postmarketos.org by @lotharsm in #661
- feat: add robots2policy CLI to convert robots.txt to Anubis CEL by @JasonLovesDoggo in #657
- Add ReactOS to known-instances.md by @ColinFinck in #664
- build(deps): bump the github-actions group with 3 updates by @dependabot in #666
- Add the blog section back by @Xe in #670
- feat: implement a client for Thoth, the IP reputation database for Anubis by @Xe in #637
- chore(sponsors): update canine.tools logo by @hyperdefined in #672
- perf: Replace internal SHA256 hashing with xxhash for 4-6x performance improvement by @JasonLovesDoggo in #676
- perf: replace cidranger with bart for significant performance improvements by @JasonLovesDoggo in #675
- docs(known-instances): add wiki.koha-community.org by @prettysunflower in #683
- chore: remove duplicate CHANGELOG entry by @JasonLovesDoggo in #684
- fix(geo): correct typo "counties" to "countries" by @hydrargyrum in #678
- docs(known-instances): add extensions.typo3.org by @lotharsm in #691
- Bump ai.robots.txt to v1.37 by @Dryusdan in #689
- feat(config): custom weight thresholds via CEL by @Xe in #688
- fix(config): actually load threshold config by @Xe in #696
- feat: add default OpenGraph tags to configuration file by @Xe in #694
- Makefile: Build robots2policy by @heftig in #699
- fix(default-config): off-by-one error in the default thresholds by @Xe in #701
- feat: implement imprint/impressum support by @Xe in #706
- fix(web/js): broken progress bar with slow algo by @yut23 in #673
- build(deps): bump the github-actions group with 3 updates by @dependabot in #708
- fix(lib): fix invalid response after success in Chrome by @Xe in #711
- build(deps): bump the gomod group with 4 updates by @dependabot in #709
- Populate OpenGraph configurations to
Options.OpenGraph
by @outloudvi in #717 - chore: Remove unused/dead code by @JasonLovesDoggo in #703
- feat: Add option to use HS512 secret for JWT instead of ED25519 by @Earl0fPudding in #680
- remove incorrect module mentions by @msporleder in #687
- feat: dynamic cookie domains by @Xe in #722
New Contributors
- @CryptoCopter made their first contribution in #611
- @foosinn made their first contribution in #613
- @jieter made their first contribution in #615
- @Fierelier made their first contribution in #636
- @XerTheSquirrel made their first contribution in #643
- @ColinFinck made their first contribution in #664
- @hydrargyrum made their first contribution in #678
- @yut23 made their first contribution in #673
- @outloudvi made their first contribution in #717
- @Earl0fPudding made their first contribution in #680
- @msporleder made their first contribution in #687
Full Changelog: v1.19.1...v1.20.0