mirror of
https://github.com/TecharoHQ/anubis.git
synced 2025-08-03 01:38:14 -04:00

* Add check endpoint which can be used with nginx' auth_request function * feat(cmd): allow configuring redirect domains * test: add test environment for the nginx_auth PR This is a full local setup of the nginx_auth PR including HTTPS so that it's easier to validate in isolation. This requires an install of k3s (https://k3s.io) with traefik set to listen on localhost. This will be amended in the future but for now this works enough to ship it. Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(cmd|lib): allow empty redirect domains variable Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(test): add space to target variable in anubis container Signed-off-by: Xe Iaso <me@xeiaso.net> * docs(admin): rewrite subrequest auth docs, make generic * docs(install): document REDIRECT_DOMAINS flag Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(lib): clamp redirects to the same HTTP host Only if REDIRECT_DOMAINS is not set. Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Co-authored-by: Xe Iaso <me@xeiaso.net>
193 lines
6.7 KiB
Plaintext
193 lines
6.7 KiB
Plaintext
package web
|
|
|
|
import (
|
|
"github.com/TecharoHQ/anubis"
|
|
"github.com/TecharoHQ/anubis/xess"
|
|
)
|
|
|
|
templ base(title string, body templ.Component, challenge any, ogTags map[string]string) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>{ title }</title>
|
|
<link rel="stylesheet" href={ xess.URL }/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
<meta name="robots" content="noindex,nofollow"/>
|
|
for key, value := range ogTags {
|
|
<meta property={ key } content={ value }/>
|
|
}
|
|
@templ.JSONScript("anubis_version", anubis.Version)
|
|
if challenge != nil {
|
|
@templ.JSONScript("anubis_challenge", challenge)
|
|
}
|
|
</head>
|
|
<body id="top">
|
|
<main>
|
|
<center>
|
|
<h1 id="title" class=".centered-div">{ title }</h1>
|
|
</center>
|
|
@body
|
|
<footer>
|
|
<center>
|
|
<p>
|
|
Protected by <a href="https://github.com/TecharoHQ/anubis">Anubis</a> from <a
|
|
href="https://techaro.lol"
|
|
>Techaro</a>. Made with ❤️ in 🇨🇦.
|
|
</p>
|
|
<p>Mascot design by <a href="https://bsky.app/profile/celphase.bsky.social">CELPHASE</a>.</p>
|
|
</center>
|
|
</footer>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
}
|
|
|
|
templ index() {
|
|
<div class="centered-div">
|
|
<img
|
|
id="image"
|
|
style="width:100%;max-width:256px;"
|
|
src={ "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
|
anubis.Version }
|
|
/>
|
|
<img
|
|
style="display:none;"
|
|
style="width:100%;max-width:256px;"
|
|
src={ "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" +
|
|
anubis.Version }
|
|
/>
|
|
<p id="status">Loading...</p>
|
|
<script async type="module" src={ "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
|
|
<div id="progress" role="progressbar" aria-labelledby="status">
|
|
<div class="bar-inner"></div>
|
|
</div>
|
|
<details>
|
|
<summary>Why am I seeing this?</summary>
|
|
<p>
|
|
You are seeing this because the administrator of this website has set up <a
|
|
href="https://github.com/TecharoHQ/anubis"
|
|
>Anubis</a> to protect the server against the scourge of
|
|
<a href="https://thelibre.news/foss-infrastructure-is-under-attack-by-ai-companies/">
|
|
AI companies
|
|
aggressively scraping websites
|
|
</a>. This can and does cause downtime for the websites, which makes their
|
|
resources inaccessible for everyone.
|
|
</p>
|
|
<p>
|
|
Anubis is a compromise. Anubis uses a <a href="https://anubis.techaro.lol/docs/design/why-proof-of-work">Proof-of-Work</a>
|
|
scheme in the vein of <a href="https://en.wikipedia.org/wiki/Hashcash">Hashcash</a>, a proposed
|
|
proof-of-work scheme for reducing email spam. The idea is that at individual scales the additional load is
|
|
ignorable, but at mass scraper levels it adds up and makes scraping much more expensive.
|
|
</p>
|
|
<p>
|
|
Ultimately, this is a hack whose real purpose is to give a "good enough" placeholder solution so that more
|
|
time can be spent on fingerprinting and identifying headless browsers (EG: via how they do font rendering)
|
|
so that the challenge proof of work page doesn't need to be presented to users that are much more likely to
|
|
be legitimate.
|
|
</p>
|
|
<p>
|
|
Please note that Anubis requires the use of modern JavaScript features that plugins like <a
|
|
href="https://jshelter.org/"
|
|
>JShelter</a> will disable. Please disable JShelter or other such
|
|
plugins for this domain.
|
|
</p>
|
|
</details>
|
|
<noscript>
|
|
<p>
|
|
Sadly, you must enable JavaScript to get past this challenge. This is required because AI companies have
|
|
changed
|
|
the social contract around how website hosting works. A no-JS solution is a work-in-progress.
|
|
</p>
|
|
</noscript>
|
|
<div id="testarea"></div>
|
|
</div>
|
|
}
|
|
|
|
templ errorPage(message string, mail string) {
|
|
<div class="centered-div">
|
|
<img
|
|
id="image"
|
|
alt="Sad Anubis"
|
|
style="width:100%;max-width:256px;"
|
|
src={ "/.within.website/x/cmd/anubis/static/img/reject.webp?cacheBuster=" + anubis.Version }
|
|
/>
|
|
<p>{ message }.</p>
|
|
<button onClick="window.location.reload();">Try again</button>
|
|
if mail != "" {
|
|
<p>
|
|
<a href="/">Go home</a> or if you believe you should not be blocked, please contact the webmaster at
|
|
<a href={ "mailto:" + templ.SafeURL(mail) }>
|
|
{ mail }
|
|
</a>
|
|
</p>
|
|
} else {
|
|
<p><a href="/">Go home</a></p>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
templ StaticHappy() {
|
|
<div class="centered-div">
|
|
<img
|
|
style="display:none;"
|
|
style="width:100%;max-width:256px;"
|
|
src={ "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" +
|
|
anubis.Version }
|
|
/>
|
|
<p>This is just a check endpoint for your reverse proxy to use.</p>
|
|
</div>
|
|
}
|
|
|
|
templ bench() {
|
|
<div style="height:20rem;display:flex">
|
|
<table style="margin-top:1rem;display:grid;grid-template:auto 1fr/auto auto;gap:0 0.5rem">
|
|
<thead style="border-bottom:1px solid black;padding:0.25rem 0;display:grid;grid-template:1fr/subgrid;grid-column:1/-1">
|
|
<tr id="table-header" style="display:contents">
|
|
<th style="width:4.5rem">Time</th>
|
|
<th style="width:4rem">Iters</th>
|
|
</tr>
|
|
<tr id="table-header-compare" style="display:none">
|
|
<th style="width:4.5rem">Time A</th>
|
|
<th style="width:4rem">Iters A</th>
|
|
<th style="width:4.5rem">Time B</th>
|
|
<th style="width:4rem">Iters B</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody
|
|
id="results"
|
|
style="padding-top:0.25rem;display:grid;grid-template-columns:subgrid;grid-auto-rows:min-content;grid-column:1/-1;row-gap:0.25rem;overflow-y:auto;font-variant-numeric:tabular-nums"
|
|
></tbody>
|
|
</table>
|
|
<div class="centered-div">
|
|
<img
|
|
id="image"
|
|
style="width:100%;max-width:256px;"
|
|
src={ "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
|
anubis.Version }
|
|
/>
|
|
<p id="status" style="max-width:256px">Loading...</p>
|
|
<script async type="module" src={ "/.within.website/x/cmd/anubis/static/js/bench.mjs?cacheBuster=" + anubis.Version }></script>
|
|
<div id="sparkline"></div>
|
|
<noscript>
|
|
<p>Running the benchmark tool requires JavaScript to be enabled.</p>
|
|
</noscript>
|
|
</div>
|
|
</div>
|
|
<form id="controls" style="position:fixed;top:0.5rem;right:0.5rem">
|
|
<div style="display:flex;justify-content:end">
|
|
<label for="difficulty-input" style="margin-right:0.5rem">Difficulty:</label>
|
|
<input id="difficulty-input" type="number" name="difficulty" style="width:3rem"/>
|
|
</div>
|
|
<div style="margin-top:0.25rem;display:flex;justify-content:end">
|
|
<label for="algorithm-select" style="margin-right:0.5rem">Algorithm:</label>
|
|
<select id="algorithm-select" name="algorithm"></select>
|
|
</div>
|
|
<div style="margin-top:0.25rem;display:flex;justify-content:end">
|
|
<label for="compare-select" style="margin-right:0.5rem">Compare:</label>
|
|
<select id="compare-select" name="compare">
|
|
<option value="NONE">-</option>
|
|
</select>
|
|
</div>
|
|
</form>
|
|
}
|