mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-06 00:38:18 +00:00
Compare commits
30 Commits
v1.16.0
...
Xe/pkgserv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff17954d3 | ||
|
|
bd1835aa98 | ||
|
|
b15017d097 | ||
|
|
2d22491e8c | ||
|
|
150523b9d3 | ||
|
|
6f652e711c | ||
|
|
75b97eb03d | ||
|
|
f5827721c3 | ||
|
|
a40c5e99fc | ||
|
|
af831f0d7f | ||
|
|
095e18d0c8 | ||
|
|
f844dba3dc | ||
|
|
736c3ade09 | ||
|
|
b20774d9a6 | ||
|
|
2c94090fde | ||
|
|
df3509ec99 | ||
|
|
8689143214 | ||
|
|
5d4d2e3e2a | ||
|
|
2ebce26709 | ||
|
|
ac273a8ad5 | ||
|
|
9865e3ded8 | ||
|
|
3438595f32 | ||
|
|
62e20a213a | ||
|
|
f2cb6ae121 | ||
|
|
92dbc22db0 | ||
|
|
971e781965 | ||
|
|
503f466ecf | ||
|
|
81307bcb5c | ||
|
|
40d7b2ec55 | ||
|
|
20f1d40b61 |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@@ -1 +1,2 @@
|
||||
patreon: cadey
|
||||
patreon: cadey
|
||||
github: xe
|
||||
2
.github/workflows/docker-pr.yml
vendored
2
.github/workflows/docker-pr.yml
vendored
@@ -12,7 +12,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
2
.github/workflows/docs-deploy.yml
vendored
2
.github/workflows/docs-deploy.yml
vendored
@@ -13,7 +13,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
6
.github/workflows/go.yml
vendored
6
.github/workflows/go.yml
vendored
@@ -13,7 +13,7 @@ permissions:
|
||||
jobs:
|
||||
go_tests:
|
||||
#runs-on: alrest-techarohq
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
@@ -68,8 +68,8 @@ jobs:
|
||||
|
||||
- name: install playwright browsers
|
||||
run: |
|
||||
npx --yes playwright@1.50.1 install --with-deps
|
||||
npx --yes playwright@1.50.1 run-server --port 9001 &
|
||||
npx --yes playwright@1.51.1 install --with-deps
|
||||
npx --yes playwright@1.51.1 run-server --port 9001 &
|
||||
|
||||
- name: install node deps
|
||||
run: |
|
||||
|
||||
10
.github/workflows/package-builds-stable.yml
vendored
10
.github/workflows/package-builds-stable.yml
vendored
@@ -11,9 +11,9 @@ permissions:
|
||||
jobs:
|
||||
package_builds:
|
||||
#runs-on: alrest-techarohq
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-tags: true
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Setup Homebrew cellar cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
/home/linuxbrew/.linuxbrew/Cellar
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
brew bundle
|
||||
|
||||
- name: Setup Golang caches
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
@@ -78,4 +78,4 @@ jobs:
|
||||
cd var
|
||||
for file in *; do
|
||||
gh release upload $RELEASE $file
|
||||
done
|
||||
done
|
||||
|
||||
12
.github/workflows/package-builds-unstable.yml
vendored
12
.github/workflows/package-builds-unstable.yml
vendored
@@ -13,9 +13,9 @@ permissions:
|
||||
jobs:
|
||||
package_builds:
|
||||
#runs-on: alrest-techarohq
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-tags: true
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Setup Homebrew cellar cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
/home/linuxbrew/.linuxbrew/Cellar
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
brew bundle
|
||||
|
||||
- name: Setup Golang caches
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
sudo apt -y install -f ./var/yeet.deb
|
||||
yeet
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: packages
|
||||
path: var/*
|
||||
path: var/*
|
||||
|
||||
4
.github/workflows/zizmor.yml
vendored
4
.github/workflows/zizmor.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
zizmor:
|
||||
name: zizmor latest via PyPI
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13
|
||||
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: zizmor
|
||||
|
||||
42
Makefile
42
Makefile
@@ -1,27 +1,31 @@
|
||||
NODE_MODULES = node_modules
|
||||
VERSION := $(shell cat ./VERSION)
|
||||
VERSION= $(shell cat ./VERSION)
|
||||
GO?= go
|
||||
NPM?= npm
|
||||
|
||||
.PHONY: build assets deps lint prebaked-build test
|
||||
|
||||
assets:
|
||||
npm run assets
|
||||
|
||||
deps:
|
||||
npm ci
|
||||
go mod download
|
||||
|
||||
build: deps
|
||||
npm run build
|
||||
@echo "Anubis is now built to ./var/anubis"
|
||||
|
||||
all: build
|
||||
|
||||
lint:
|
||||
go vet ./...
|
||||
go tool staticcheck ./...
|
||||
deps:
|
||||
$(NPM) ci
|
||||
$(GO) mod download
|
||||
|
||||
assets: PATH:=$(PWD)/node_modules/.bin:$(PATH)
|
||||
assets: deps
|
||||
$(GO) generate ./...
|
||||
./web/build.sh
|
||||
./xess/build.sh
|
||||
|
||||
build: assets
|
||||
$(GO) build -o ./var/anubis ./cmd/anubis
|
||||
@echo "Anubis is now built to ./var/anubis"
|
||||
|
||||
lint: assets
|
||||
$(GO) vet ./...
|
||||
$(GO) tool staticcheck ./...
|
||||
|
||||
prebaked-build:
|
||||
go build -o ./var/anubis -ldflags "-X 'github.com/TecharoHQ/anubis.Version=$(VERSION)'" ./cmd/anubis
|
||||
$(GO) build -o ./var/anubis -ldflags "-X 'github.com/TecharoHQ/anubis.Version=$(VERSION)'" ./cmd/anubis
|
||||
|
||||
test:
|
||||
npm run test
|
||||
test: assets
|
||||
$(GO) test ./...
|
||||
|
||||
@@ -33,3 +33,11 @@ For live chat, please join the [Patreon](https://patreon.com/cadey) and ask in t
|
||||
## Packaging Status
|
||||
|
||||
[](https://repology.org/project/anubis-anti-crawler/versions)
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/TecharoHQ/anubis/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=TecharoHQ/anubis" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||
@@ -123,10 +123,10 @@ func parseImageList(imageList string) ([]image, error) {
|
||||
// reg.xeiaso.net/techaro/anubis:latest
|
||||
// repository: reg.xeiaso.net/techaro/anubis
|
||||
// tag: latest
|
||||
parts := strings.SplitN(img, ":", 2)
|
||||
index := strings.LastIndex(img, ":")
|
||||
result = append(result, image{
|
||||
repository: parts[0],
|
||||
tag: parts[1],
|
||||
repository: img[:index],
|
||||
tag: img[index+1:],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
14
cryptography/techaro-pkgs.pub.asc
Normal file
14
cryptography/techaro-pkgs.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU/hRYJKwYBBAHaRw8BAQdANg5d753IR7Q3NxfE+vVgpBx9w66HSzx74zEz
|
||||
2djVqZm0NlRlY2hhcm8gUGFja2FnZXMgU2lnbmF0dXJlcyA8Z3BnK3BhY2thZ2Vz
|
||||
QHRlY2hhcm8ubG9sPoiZBBMWCgBBFiEEgz9kFhFntQEFjDlHVjddot8Cq/8FAmgF
|
||||
P4UCGwMFCRLMAwAFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQVjddot8C
|
||||
q/8PYwEAk1B1r8cBZi54fTOpMnkKUJnbk9wnmNLdUkRADlPRCcIBAN3Zgsjb/SXw
|
||||
nWINVPKvodwUVanDwl5uZuXtROv1mQ8GuDgEaAU/hRIKKwYBBAGXVQEFAQEHQLqY
|
||||
3RXQiv/4d7y+eGs+YE4BymAguYG44jRtHHwFERZEAwEIB4h+BBgWCgAmFiEEgz9k
|
||||
FhFntQEFjDlHVjddot8Cq/8FAmgFP4UCGwwFCRLMAwAACgkQVjddot8Cq/8WXgEA
|
||||
lMjj013kuKsSCrczDxCSH0boW6xSTfyjnC2SQ4VDj78A/i6JrmkMq0wUSevgxlGw
|
||||
ZIoXIS4aVdSnfY9LMcnklKcL
|
||||
=zIdk
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
14
cryptography/techaro-root.pub.asc
Normal file
14
cryptography/techaro-root.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU+KxYJKwYBBAHaRw8BAQdAroyz8ysjSTBcQgfN+StN6WAfNzPDwiTF1LvS
|
||||
bVRSu0a0KlRlY2hhcm8gUm9vdCBTaWduaW5nIEtleSA8Z3BnQHRlY2hhcm8ubG9s
|
||||
PoiZBBMWCgBBFiEEia0uWmNauBlpQAXmU41NIwnMwuwFAmgFPisCGwMFCRLMAwAF
|
||||
CwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQU41NIwnMwuxKFQD/ZovOrWC3
|
||||
DKcrYYKpCrX30iWDd+U2hqlPFFvRKhFx52UA+gO+UYeCBy/dnxc0GrNPE84yWQqr
|
||||
9eas/yEf1rsMInIEuDgEaAU+KxIKKwYBBAGXVQEFAQEHQAaSsoWAStlNTHgN9xuW
|
||||
aVsxZ9DQzPlD2osWHuvXCwknAwEIB4h+BBgWCgAmFiEEia0uWmNauBlpQAXmU41N
|
||||
IwnMwuwFAmgFPisCGwwFCRLMAwAACgkQU41NIwnMwuxs+AEAijEEHvssBYt80YZW
|
||||
/jCrp3vuD6aTFzb5NzvdQafPH5AA/0dt5ayS/vu31z2YTfSg5WNGWKvOvyGAG6jz
|
||||
TS5tWMYJ
|
||||
=uI7D
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
2
cryptography/var/.gitignore
vendored
Normal file
2
cryptography/var/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
27
cryptography/yeetfile.js
Normal file
27
cryptography/yeetfile.js
Normal file
@@ -0,0 +1,27 @@
|
||||
rpm.build({
|
||||
name: "techaro-repo-keys",
|
||||
description: "Public keys for techaro.lol RPM packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
|
||||
build: (out) => {
|
||||
yeet.run(`mkdir`, `-p`, `${out}/etc/pki/rpm-gpg/techaro.lol-keys`);
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-root.asc`);
|
||||
},
|
||||
});
|
||||
|
||||
deb.build({
|
||||
name: "techaro-repo-keys",
|
||||
description: "Public keys for techaro.lol RPM packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
|
||||
build: (out) => {
|
||||
yeet.run(`mkdir`, `-p`, `${out}/usr/share/keyrings`);
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/usr/share/keyrings/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/usr/share/keyrings/techaro-root.asc`);
|
||||
},
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"bots": [
|
||||
{
|
||||
"name": "amazonbot",
|
||||
"user_agent_regex": "Amazonbot",
|
||||
"name": "ai-robots-txt",
|
||||
"user_agent_regex": "AI2Bot|Ai2Bot-Dolma|Amazonbot|anthropic-ai|Applebot|Applebot-Extended|Brightbot 1.0|Bytespider|CCBot|ChatGPT-User|Claude-Web|ClaudeBot|cohere-ai|cohere-training-data-crawler|Crawlspace|Diffbot|DuckAssistBot|FacebookBot|FriendlyCrawler|Google-Extended|GoogleOther|GoogleOther-Image|GoogleOther-Video|GPTBot|iaskspider/2.0|ICC-Crawler|ImagesiftBot|img2dataset|ISSCyberRiskCrawler|Kangaroo Bot|Meta-ExternalAgent|Meta-ExternalFetcher|OAI-SearchBot|omgili|omgilibot|PanguBot|Perplexity-User|PerplexityBot|PetalBot|Scrapy|SemrushBot-OCOB|SemrushBot-SWA|Sidetrade indexer bot|Timpibot|VelenPublicWebCrawler|Webzio-Extended|YouBot",
|
||||
"action": "DENY"
|
||||
},
|
||||
{
|
||||
@@ -304,6 +304,282 @@
|
||||
"40.77.178.0/23"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "duckduckbot",
|
||||
"user_agent_regex": "\\+http\\://duckduckgo\\.com/duckduckbot\\.html",
|
||||
"action": "ALLOW",
|
||||
"remote_addresses": [
|
||||
"57.152.72.128/32",
|
||||
"51.8.253.152/32",
|
||||
"40.80.242.63/32",
|
||||
"20.12.141.99/32",
|
||||
"20.49.136.28/32",
|
||||
"51.116.131.221/32",
|
||||
"51.107.40.209/32",
|
||||
"20.40.133.240/32",
|
||||
"20.50.168.91/32",
|
||||
"51.120.48.122/32",
|
||||
"20.193.45.113/32",
|
||||
"40.76.173.151/32",
|
||||
"40.76.163.7/32",
|
||||
"20.185.79.47/32",
|
||||
"52.142.26.175/32",
|
||||
"20.185.79.15/32",
|
||||
"52.142.24.149/32",
|
||||
"40.76.162.208/32",
|
||||
"40.76.163.23/32",
|
||||
"40.76.162.191/32",
|
||||
"40.76.162.247/32",
|
||||
"40.88.21.235/32",
|
||||
"20.191.45.212/32",
|
||||
"52.146.59.12/32",
|
||||
"52.146.59.156/32",
|
||||
"52.146.59.154/32",
|
||||
"52.146.58.236/32",
|
||||
"20.62.224.44/32",
|
||||
"51.104.180.53/32",
|
||||
"51.104.180.47/32",
|
||||
"51.104.180.26/32",
|
||||
"51.104.146.225/32",
|
||||
"51.104.146.235/32",
|
||||
"20.73.202.147/32",
|
||||
"20.73.132.240/32",
|
||||
"20.71.12.143/32",
|
||||
"20.56.197.58/32",
|
||||
"20.56.197.63/32",
|
||||
"20.43.150.93/32",
|
||||
"20.43.150.85/32",
|
||||
"20.44.222.1/32",
|
||||
"40.89.243.175/32",
|
||||
"13.89.106.77/32",
|
||||
"52.143.242.6/32",
|
||||
"52.143.241.111/32",
|
||||
"52.154.60.82/32",
|
||||
"20.197.209.11/32",
|
||||
"20.197.209.27/32",
|
||||
"20.226.133.105/32",
|
||||
"191.234.216.4/32",
|
||||
"191.234.216.178/32",
|
||||
"20.53.92.211/32",
|
||||
"20.53.91.2/32",
|
||||
"20.207.99.197/32",
|
||||
"20.207.97.190/32",
|
||||
"40.81.250.205/32",
|
||||
"40.64.106.11/32",
|
||||
"40.64.105.247/32",
|
||||
"20.72.242.93/32",
|
||||
"20.99.255.235/32",
|
||||
"20.113.3.121/32",
|
||||
"52.224.16.221/32",
|
||||
"52.224.21.53/32",
|
||||
"52.224.20.204/32",
|
||||
"52.224.21.19/32",
|
||||
"52.224.20.249/32",
|
||||
"52.224.20.203/32",
|
||||
"52.224.20.190/32",
|
||||
"52.224.16.229/32",
|
||||
"52.224.21.20/32",
|
||||
"52.146.63.80/32",
|
||||
"52.224.20.227/32",
|
||||
"52.224.20.193/32",
|
||||
"52.190.37.160/32",
|
||||
"52.224.21.23/32",
|
||||
"52.224.20.223/32",
|
||||
"52.224.20.181/32",
|
||||
"52.224.21.49/32",
|
||||
"52.224.21.55/32",
|
||||
"52.224.21.61/32",
|
||||
"52.224.19.152/32",
|
||||
"52.224.20.186/32",
|
||||
"52.224.21.27/32",
|
||||
"52.224.21.51/32",
|
||||
"52.224.20.174/32",
|
||||
"52.224.21.4/32",
|
||||
"51.104.164.109/32",
|
||||
"51.104.167.71/32",
|
||||
"51.104.160.177/32",
|
||||
"51.104.162.149/32",
|
||||
"51.104.167.95/32",
|
||||
"51.104.167.54/32",
|
||||
"51.104.166.111/32",
|
||||
"51.104.167.88/32",
|
||||
"51.104.161.32/32",
|
||||
"51.104.163.250/32",
|
||||
"51.104.164.189/32",
|
||||
"51.104.167.19/32",
|
||||
"51.104.160.167/32",
|
||||
"51.104.167.110/32",
|
||||
"20.191.44.119/32",
|
||||
"51.104.167.104/32",
|
||||
"20.191.44.234/32",
|
||||
"51.104.164.215/32",
|
||||
"51.104.167.52/32",
|
||||
"20.191.44.22/32",
|
||||
"51.104.167.87/32",
|
||||
"51.104.167.96/32",
|
||||
"20.191.44.16/32",
|
||||
"51.104.167.61/32",
|
||||
"51.104.164.147/32",
|
||||
"20.50.48.159/32",
|
||||
"40.114.182.172/32",
|
||||
"20.50.50.130/32",
|
||||
"20.50.50.163/32",
|
||||
"20.50.50.46/32",
|
||||
"40.114.182.153/32",
|
||||
"20.50.50.118/32",
|
||||
"20.50.49.55/32",
|
||||
"20.50.49.25/32",
|
||||
"40.114.183.251/32",
|
||||
"20.50.50.123/32",
|
||||
"20.50.49.237/32",
|
||||
"20.50.48.192/32",
|
||||
"20.50.50.134/32",
|
||||
"51.138.90.233/32",
|
||||
"40.114.183.196/32",
|
||||
"20.50.50.146/32",
|
||||
"40.114.183.88/32",
|
||||
"20.50.50.145/32",
|
||||
"20.50.50.121/32",
|
||||
"20.50.49.40/32",
|
||||
"51.138.90.206/32",
|
||||
"40.114.182.45/32",
|
||||
"51.138.90.161/32",
|
||||
"20.50.49.0/32",
|
||||
"40.119.232.215/32",
|
||||
"104.43.55.167/32",
|
||||
"40.119.232.251/32",
|
||||
"40.119.232.50/32",
|
||||
"40.119.232.146/32",
|
||||
"40.119.232.218/32",
|
||||
"104.43.54.127/32",
|
||||
"104.43.55.117/32",
|
||||
"104.43.55.116/32",
|
||||
"104.43.55.166/32",
|
||||
"52.154.169.50/32",
|
||||
"52.154.171.70/32",
|
||||
"52.154.170.229/32",
|
||||
"52.154.170.113/32",
|
||||
"52.154.171.44/32",
|
||||
"52.154.172.2/32",
|
||||
"52.143.244.81/32",
|
||||
"52.154.171.87/32",
|
||||
"52.154.171.250/32",
|
||||
"52.154.170.28/32",
|
||||
"52.154.170.122/32",
|
||||
"52.143.243.117/32",
|
||||
"52.143.247.235/32",
|
||||
"52.154.171.235/32",
|
||||
"52.154.171.196/32",
|
||||
"52.154.171.0/32",
|
||||
"52.154.170.243/32",
|
||||
"52.154.170.26/32",
|
||||
"52.154.169.200/32",
|
||||
"52.154.170.96/32",
|
||||
"52.154.170.88/32",
|
||||
"52.154.171.150/32",
|
||||
"52.154.171.205/32",
|
||||
"52.154.170.117/32",
|
||||
"52.154.170.209/32",
|
||||
"191.235.202.48/32",
|
||||
"191.233.3.202/32",
|
||||
"191.235.201.214/32",
|
||||
"191.233.3.197/32",
|
||||
"191.235.202.38/32",
|
||||
"20.53.78.144/32",
|
||||
"20.193.24.10/32",
|
||||
"20.53.78.236/32",
|
||||
"20.53.78.138/32",
|
||||
"20.53.78.123/32",
|
||||
"20.53.78.106/32",
|
||||
"20.193.27.215/32",
|
||||
"20.193.25.197/32",
|
||||
"20.193.12.126/32",
|
||||
"20.193.24.251/32",
|
||||
"20.204.242.101/32",
|
||||
"20.207.72.113/32",
|
||||
"20.204.242.19/32",
|
||||
"20.219.45.67/32",
|
||||
"20.207.72.11/32",
|
||||
"20.219.45.190/32",
|
||||
"20.204.243.55/32",
|
||||
"20.204.241.148/32",
|
||||
"20.207.72.110/32",
|
||||
"20.204.240.172/32",
|
||||
"20.207.72.21/32",
|
||||
"20.204.246.81/32",
|
||||
"20.207.107.181/32",
|
||||
"20.204.246.254/32",
|
||||
"20.219.43.246/32",
|
||||
"52.149.25.43/32",
|
||||
"52.149.61.51/32",
|
||||
"52.149.58.139/32",
|
||||
"52.149.60.38/32",
|
||||
"52.148.165.38/32",
|
||||
"52.143.95.162/32",
|
||||
"52.149.56.151/32",
|
||||
"52.149.30.45/32",
|
||||
"52.149.58.173/32",
|
||||
"52.143.95.204/32",
|
||||
"52.149.28.83/32",
|
||||
"52.149.58.69/32",
|
||||
"52.148.161.87/32",
|
||||
"52.149.58.27/32",
|
||||
"52.149.28.18/32",
|
||||
"20.79.226.26/32",
|
||||
"20.79.239.66/32",
|
||||
"20.79.238.198/32",
|
||||
"20.113.14.159/32",
|
||||
"20.75.144.152/32",
|
||||
"20.43.172.120/32",
|
||||
"20.53.134.160/32",
|
||||
"20.201.15.208/32",
|
||||
"20.93.28.24/32",
|
||||
"20.61.34.40/32",
|
||||
"52.242.224.168/32",
|
||||
"20.80.129.80/32",
|
||||
"20.195.108.47/32",
|
||||
"4.195.133.120/32",
|
||||
"4.228.76.163/32",
|
||||
"4.182.131.108/32",
|
||||
"4.209.224.56/32",
|
||||
"108.141.83.74/32",
|
||||
"4.213.46.14/32",
|
||||
"172.169.17.165/32",
|
||||
"51.8.71.117/32",
|
||||
"20.3.1.178/32",
|
||||
"52.149.56.151/32",
|
||||
"52.149.30.45/32",
|
||||
"52.149.58.173/32",
|
||||
"52.143.95.204/32",
|
||||
"52.149.28.83/32",
|
||||
"52.149.58.69/32",
|
||||
"52.148.161.87/32",
|
||||
"52.149.58.27/32",
|
||||
"52.149.28.18/32",
|
||||
"20.79.226.26/32",
|
||||
"20.79.239.66/32",
|
||||
"20.79.238.198/32",
|
||||
"20.113.14.159/32",
|
||||
"20.75.144.152/32",
|
||||
"20.43.172.120/32",
|
||||
"20.53.134.160/32",
|
||||
"20.201.15.208/32",
|
||||
"20.93.28.24/32",
|
||||
"20.61.34.40/32",
|
||||
"52.242.224.168/32",
|
||||
"20.80.129.80/32",
|
||||
"20.195.108.47/32",
|
||||
"4.195.133.120/32",
|
||||
"4.228.76.163/32",
|
||||
"4.182.131.108/32",
|
||||
"4.209.224.56/32",
|
||||
"108.141.83.74/32",
|
||||
"4.213.46.14/32",
|
||||
"172.169.17.165/32",
|
||||
"51.8.71.117/32",
|
||||
"20.3.1.178/32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "qwantbot",
|
||||
"user_agent_regex": "\\+https\\://help\\.qwant\\.com/bot/",
|
||||
@@ -312,6 +588,15 @@
|
||||
"91.242.162.0/24"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "internet-archive",
|
||||
"action": "ALLOW",
|
||||
"remote_addresses": [
|
||||
"207.241.224.0/20",
|
||||
"208.70.24.0/21",
|
||||
"2620:0:9c0::/48"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "kagibot",
|
||||
"user_agent_regex": "\\+https\\://kagi\\.com/bot",
|
||||
@@ -390,9 +675,9 @@
|
||||
},
|
||||
{
|
||||
"name": "generic-browser",
|
||||
"user_agent_regex": "Mozilla",
|
||||
"user_agent_regex": "Mozilla|Opera",
|
||||
"action": "CHALLENGE"
|
||||
}
|
||||
],
|
||||
"dnsbl": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
slug: first-blog-post
|
||||
title: First Blog Post
|
||||
authors: [slorber, yangshun]
|
||||
tags: [hola, docusaurus]
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet...
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
slug: long-blog-post
|
||||
title: Long Blog Post
|
||||
authors: yangshun
|
||||
tags: [hello, docusaurus]
|
||||
---
|
||||
|
||||
This is the summary of a very long blog post,
|
||||
|
||||
Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
slug: mdx-blog-post
|
||||
title: MDX Blog Post
|
||||
authors: [slorber]
|
||||
tags: [docusaurus]
|
||||
---
|
||||
|
||||
Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
|
||||
|
||||
:::tip
|
||||
|
||||
Use the power of React to create interactive blog posts.
|
||||
|
||||
:::
|
||||
|
||||
{/* truncate */}
|
||||
|
||||
For example, use JSX to create an interactive button:
|
||||
|
||||
```js
|
||||
<button onClick={() => alert('button clicked!')}>Click me!</button>
|
||||
```
|
||||
|
||||
<button onClick={() => alert('button clicked!')}>Click me!</button>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB |
@@ -1,29 +0,0 @@
|
||||
---
|
||||
slug: welcome
|
||||
title: Welcome
|
||||
authors: [slorber, yangshun]
|
||||
tags: [facebook, hello, docusaurus]
|
||||
---
|
||||
|
||||
[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
|
||||
|
||||
Here are a few tips you might find useful.
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
Simply add Markdown files (or folders) to the `blog` directory.
|
||||
|
||||
Regular blog authors can be added to `authors.yml`.
|
||||
|
||||
The blog post date can be extracted from filenames, such as:
|
||||
|
||||
- `2019-05-30-welcome.md`
|
||||
- `2019-05-30-welcome/index.md`
|
||||
|
||||
A blog post folder can be convenient to co-locate blog post images:
|
||||
|
||||

|
||||
|
||||
The blog supports tags as well!
|
||||
|
||||
**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.
|
||||
@@ -1,23 +0,0 @@
|
||||
yangshun:
|
||||
name: Yangshun Tay
|
||||
title: Front End Engineer @ Facebook
|
||||
url: https://github.com/yangshun
|
||||
image_url: https://github.com/yangshun.png
|
||||
page: true
|
||||
socials:
|
||||
x: yangshunz
|
||||
github: yangshun
|
||||
|
||||
slorber:
|
||||
name: Sébastien Lorber
|
||||
title: Docusaurus maintainer
|
||||
url: https://sebastienlorber.com
|
||||
image_url: https://github.com/slorber.png
|
||||
page:
|
||||
# customize the url of the author page at /blog/authors/<permalink>
|
||||
permalink: '/all-sebastien-lorber-articles'
|
||||
socials:
|
||||
x: sebastienlorber
|
||||
linkedin: sebastienlorber
|
||||
github: slorber
|
||||
newsletter: https://thisweekinreact.com
|
||||
@@ -1,19 +0,0 @@
|
||||
facebook:
|
||||
label: Facebook
|
||||
permalink: /facebook
|
||||
description: Facebook tag description
|
||||
|
||||
hello:
|
||||
label: Hello
|
||||
permalink: /hello
|
||||
description: Hello tag description
|
||||
|
||||
docusaurus:
|
||||
label: Docusaurus
|
||||
permalink: /docusaurus
|
||||
description: Docusaurus tag description
|
||||
|
||||
hola:
|
||||
label: Hola
|
||||
permalink: /hola
|
||||
description: Hola tag description
|
||||
@@ -11,6 +11,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Add more AI user agents based on the [ai.robots.txt](https://github.com/ai-robots-txt/ai.robots.txt) project
|
||||
- Embedded challenge data in initial HTML response to improve performance
|
||||
- Whitelisted [DuckDuckBot](https://duckduckgo.com/duckduckgo-help-pages/results/duckduckbot/) in botPolicies
|
||||
- Improvements to build scripts to make them less independent of the build host
|
||||
- Improved the OpenGraph error logging
|
||||
- Added `Opera` to the `generic-browser` bot policy rule
|
||||
- Added FreeBSD rc.d script so can be run as a FreeBSD daemon.
|
||||
- Allow requests from the Internet Archive
|
||||
- Added example nginx configuration to documentation
|
||||
- Added example Apache configuration to the documentation [#277](https://github.com/TecharoHQ/anubis/issues/277)
|
||||
- Move per-environment configuration details into their own pages
|
||||
|
||||
## v1.16.0
|
||||
|
||||
Fordola rem Lupis
|
||||
|
||||
8
docs/docs/admin/environments/_category_.json
Normal file
8
docs/docs/admin/environments/_category_.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"label": "Environments",
|
||||
"position": 20,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Detailed information about individual environments (such as HTTP servers, platforms, etc.) Anubis is known to work with."
|
||||
}
|
||||
}
|
||||
151
docs/docs/admin/environments/apache.mdx
Normal file
151
docs/docs/admin/environments/apache.mdx
Normal file
@@ -0,0 +1,151 @@
|
||||
# Apache
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Anubis is intended to be a filter proxy. The way to integrate this is to break your configuration up into two parts: TLS termination and then HTTP routing. Consider this diagram:
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Apache as tls terminator and HTTP router
|
||||
---
|
||||
|
||||
flowchart LR
|
||||
T(User Traffic)
|
||||
subgraph Apache 2
|
||||
TCP(TCP 80/443)
|
||||
US(TCP 3001)
|
||||
end
|
||||
|
||||
An(Anubis)
|
||||
B(Backend)
|
||||
|
||||
T --> |TLS termination| TCP
|
||||
TCP --> |Traffic filtering| An
|
||||
An --> |Happy traffic| US
|
||||
US --> |whatever you're doing| B
|
||||
```
|
||||
|
||||
Effectively you have one trip through Apache to do TLS termination, a detour through Anubis for traffic scrubbing, and then going to the backend directly. This final socket is what will do HTTP routing.
|
||||
|
||||
:::note
|
||||
|
||||
These examples assume that you are using a setup where your nginx configuration is made up of a bunch of files in `/etc/httpd/conf.d/*.conf`. This is not true for all deployments of Apache. If you are not in such an environment, append these snippets to your `/etc/httpd/conf/httpd.conf` file.
|
||||
|
||||
:::
|
||||
|
||||
## Dependencies
|
||||
|
||||
Install the following dependencies for proxying HTTP:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="rpm" label="Red Hat / RPM" default>
|
||||
|
||||
```text
|
||||
dnf -y install mod_proxy_html
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="deb" label="Debian / Ubuntu / apt">
|
||||
|
||||
```text
|
||||
apt-get install -y libapache2-mod-proxy-html libxml2-dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Configuration
|
||||
|
||||
Assuming you are protecting `anubistest.techaro.lol`, you need the following server configuration blocks:
|
||||
|
||||
1. A block on port 80 that forwards HTTP to HTTPS
|
||||
2. A block on port 443 that terminates TLS and forwards to Anubis
|
||||
3. A block on port 3001 that actually serves your websites
|
||||
|
||||
```text
|
||||
# Plain HTTP redirect to HTTPS
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin your@email.here
|
||||
ServerName anubistest.techaro.lol
|
||||
DocumentRoot /var/www/anubistest.techaro.lol
|
||||
ErrorLog /var/log/httpd/anubistest.techaro.lol_error.log
|
||||
CustomLog /var/log/httpd/anubistest.techaro.lol_access.log combined
|
||||
RewriteEngine on
|
||||
RewriteCond %{SERVER_NAME} =anubistest.techaro.lol
|
||||
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
|
||||
</VirtualHost>
|
||||
|
||||
# HTTPS listener that forwards to Anubis
|
||||
<VirtualHost *:443>
|
||||
ServerAdmin your@email.here
|
||||
ServerName anubistest.techaro.lol
|
||||
DocumentRoot /var/www/anubistest.techaro.lol
|
||||
ErrorLog /var/log/httpd/anubistest.techaro.lol_error.log
|
||||
CustomLog /var/log/httpd/anubistest.techaro.lol_access.log combined
|
||||
|
||||
SSLCertificateFile /etc/letsencrypt/live/anubistest.techaro.lol/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/anubistest.techaro.lol/privkey.pem
|
||||
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||
|
||||
# These headers need to be set or else Anubis will
|
||||
# throw an "admin misconfiguration" error.
|
||||
RequestHeader set "X-Real-Ip" expr=%{REMOTE_ADDR}
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPreserveHost On
|
||||
|
||||
ProxyRequests Off
|
||||
ProxyVia Off
|
||||
|
||||
# Replace 9000 with the port Anubis listens on
|
||||
ProxyPass / http://[::1]:9000/
|
||||
ProxyPassReverse / http://[::1]:9000/
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
|
||||
# Actual website config
|
||||
<VirtualHost *:3001>
|
||||
ServerAdmin your@email.here
|
||||
ServerName anubistest.techaro.lol
|
||||
DocumentRoot /var/www/anubistest.techaro.lol
|
||||
ErrorLog /var/log/httpd/anubistest.techaro.lol_error.log
|
||||
CustomLog /var/log/httpd/anubistest.techaro.lol_access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
Make sure to add a separate configuration file for the listener on port 3001:
|
||||
|
||||
```text
|
||||
# /etc/httpd/conf.d/listener-3001.conf
|
||||
|
||||
Listen 3001
|
||||
```
|
||||
|
||||
This can be repeated for multiple sites. Anubis does not care about the HTTP `Host` header and will happily cope with multiple websites via the same instance.
|
||||
|
||||
Then reload your Apache config and load your website. You should see Anubis protecting your apps!
|
||||
|
||||
```text
|
||||
sudo systemctl reload httpd.service
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Here are some answers to questions that came in in testing:
|
||||
|
||||
### I'm running on a Red Hat distribution and Apache is saying "service unavailable" for every page load
|
||||
|
||||
If you see a "Service unavailable" error on every page load and run a Red Hat derived distribution, you are missing a `selinux` setting. The exact command will be in a journalctl log message like this:
|
||||
|
||||
```text
|
||||
***** Plugin catchall_boolean (89.3 confidence) suggests ******************
|
||||
|
||||
If you want to allow HTTPD scripts and modules to connect to the network using TCP.
|
||||
Then you must tell SELinux about this by enabling the 'httpd_can_network_connect' boolean.
|
||||
|
||||
Do
|
||||
setsebool -P httpd_can_network_connect 1
|
||||
```
|
||||
|
||||
This will fix the error immediately.
|
||||
26
docs/docs/admin/environments/docker-compose.mdx
Normal file
26
docs/docs/admin/environments/docker-compose.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
# Docker compose
|
||||
|
||||
Docker compose is typically used in concert with other load balancers such as [Apache](./apache.mdx) or [Nginx](./nginx.mdx). Below is a minimal example showing you how to set up an instance of Anubis listening on host port 8080 that points to a static website containing data in `./www`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
anubis-nginx:
|
||||
image: ghcr.io/techarohq/anubis:latest
|
||||
environment:
|
||||
BIND: ":8080"
|
||||
DIFFICULTY: "5"
|
||||
METRICS_BIND: ":9090"
|
||||
SERVE_ROBOTS_TXT: "true"
|
||||
TARGET: "http://nginx"
|
||||
POLICY_FNAME: "/data/cfg/botPolicy.json"
|
||||
OG_PASSTHROUGH: "true"
|
||||
OG_EXPIRY_TIME: "24h"
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- "./botPolicy.json:/data/cfg/botPolicy.json:ro"
|
||||
nginx:
|
||||
image: nginx
|
||||
volumes:
|
||||
- "./www:/usr/share/nginx/html"
|
||||
```
|
||||
128
docs/docs/admin/environments/kubernetes.mdx
Normal file
128
docs/docs/admin/environments/kubernetes.mdx
Normal file
@@ -0,0 +1,128 @@
|
||||
# Kubernetes
|
||||
|
||||
When setting up Anubis in Kubernetes, you want to make sure that you thread requests through Anubis kinda like this:
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Anubis embedded into workload pods
|
||||
---
|
||||
|
||||
flowchart LR
|
||||
T(User Traffic)
|
||||
|
||||
IngressController(IngressController)
|
||||
|
||||
subgraph Service
|
||||
AnPort(Anubis Port)
|
||||
BPort(Backend Port)
|
||||
end
|
||||
|
||||
subgraph Pod
|
||||
An(Anubis)
|
||||
B(Backend)
|
||||
end
|
||||
|
||||
T --> IngressController
|
||||
IngressController --> AnPort
|
||||
AnPort --> An
|
||||
An --> B
|
||||
```
|
||||
|
||||
Anubis is lightweight enough that you should be able to have many instances of it running without many problems. If this is a concern for you, please check out [ingress-anubis](https://github.com/jaredallard/ingress-anubis?ref=anubis.techaro.lol).
|
||||
|
||||
This example makes the following assumptions:
|
||||
|
||||
- Your target service is listening on TCP port `5000`.
|
||||
- Anubis will be listening on port `8080`.
|
||||
|
||||
Adjust these values as facts and circumstances demand.
|
||||
|
||||
Create a secret with the signing key Anubis should use for its responses:
|
||||
|
||||
```
|
||||
kubectl create secret generic anubis-key \
|
||||
--namespace default \
|
||||
--from-literal=ED25519_PRIVATE_KEY_HEX=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
Attach Anubis to your Deployment:
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
# ...
|
||||
- name: anubis
|
||||
image: ghcr.io/techarohq/anubis:latest
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: "BIND"
|
||||
value: ":8080"
|
||||
- name: "DIFFICULTY"
|
||||
value: "4"
|
||||
- name: ED25519_PRIVATE_KEY_HEX
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: anubis-key
|
||||
key: ED25519_PRIVATE_KEY_HEX
|
||||
- name: "METRICS_BIND"
|
||||
value: ":9090"
|
||||
- name: "SERVE_ROBOTS_TXT"
|
||||
value: "true"
|
||||
- name: "TARGET"
|
||||
value: "http://localhost:5000"
|
||||
- name: "OG_PASSTHROUGH"
|
||||
value: "true"
|
||||
- name: "OG_EXPIRY_TIME"
|
||||
value: "24h"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 750m
|
||||
memory: 256Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
|
||||
Then add a Service entry for Anubis:
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
spec:
|
||||
ports:
|
||||
# diff-add
|
||||
- protocol: TCP
|
||||
# diff-add
|
||||
port: 8080
|
||||
# diff-add
|
||||
targetPort: 8080
|
||||
# diff-add
|
||||
name: anubis
|
||||
```
|
||||
|
||||
Then point your Ingress to the Anubis port:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- host: git.xeserv.us
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: "/"
|
||||
backend:
|
||||
service:
|
||||
name: git
|
||||
port:
|
||||
# diff-remove
|
||||
name: http
|
||||
# diff-add
|
||||
name: anubis
|
||||
```
|
||||
166
docs/docs/admin/environments/nginx.mdx
Normal file
166
docs/docs/admin/environments/nginx.mdx
Normal file
@@ -0,0 +1,166 @@
|
||||
# Nginx
|
||||
|
||||
Anubis is intended to be a filter proxy. The way to integrate this with nginx is to break your configuration up into two parts: TLS termination and then HTTP routing. Consider this diagram:
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Nginx as tls terminator and HTTP router
|
||||
---
|
||||
|
||||
flowchart LR
|
||||
T(User Traffic)
|
||||
subgraph Nginx
|
||||
TCP(TCP 80/443)
|
||||
US(Unix Socket or
|
||||
another TCP port)
|
||||
end
|
||||
|
||||
An(Anubis)
|
||||
B(Backend)
|
||||
|
||||
T --> |TLS termination| TCP
|
||||
TCP --> |Traffic filtering| An
|
||||
An --> |Happy traffic| US
|
||||
US --> |whatever you're doing| B
|
||||
```
|
||||
|
||||
Instead of your traffic going right from TLS termination into the backend, it takes a detour through Anubis. Anubis filters out the "bad" traffic and then passes the "good" traffic to another socket that Nginx has open. This final socket is what you will use to do HTTP routing.
|
||||
|
||||
Effectively, you have two roles for nginx: TLS termination (converting HTTPS to HTTP) and HTTP routing (distributing requests to the individual vhosts). This can stack with something like Apache in case you have a legacy deployment. Make sure you have the right [TLS certificates configured](https://code.kuederle.com/letsencrypt/) at the TLS termination level.
|
||||
|
||||
:::note
|
||||
|
||||
These examples assume that you are using a setup where your nginx configuration is made up of a bunch of files in `/etc/nginx/conf.d/*.conf`. This is not true for all deployments of nginx. If you are not in such an environment, append these snippets to your `/etc/nginx/nginx.conf` file.
|
||||
|
||||
:::
|
||||
|
||||
Assuming that we are protecting `anubistest.techaro.lol`, here's what the server configuration file would look like:
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/conf.d/server-anubistest-techaro-lol.conf
|
||||
|
||||
# HTTP - Redirect all HTTP traffic to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name anubistest.techaro.lol;
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# TLS termination server, this will listen over TLS (https) and then
|
||||
# proxy all traffic to the target via Anubis.
|
||||
server {
|
||||
# Listen on TCP port 443 with TLS (https) and HTTP/2
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass http://anubis;
|
||||
}
|
||||
|
||||
server_name anubistest.techaro.lol;
|
||||
|
||||
ssl_certificate /path/to/your/certs/anubistest.techaro.lol.crt;
|
||||
ssl_certificate_key /path/to/your/certs/anubistest.techaro.lol.key;
|
||||
}
|
||||
|
||||
# Backend server, this is where your webapp should actually live.
|
||||
server {
|
||||
listen unix:/run/nginx/nginx.sock;
|
||||
|
||||
server_name anubistest.techaro.lol;
|
||||
root "/srv/http/anubistest.techaro.lol";
|
||||
index index.html;
|
||||
|
||||
# Your normal configuration can go here
|
||||
# location .php { fastcgi...} etc.
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
You can copy the `location /` block into a separate file named something like `conf-anubis.inc` and then include it inline to other `server` blocks:
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/conf.d/conf-anubis.inc
|
||||
|
||||
# Forward to anubis
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass http://anubis;
|
||||
}
|
||||
```
|
||||
|
||||
Then in a server block:
|
||||
|
||||
<details>
|
||||
<summary>Full nginx config</summary>
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/conf.d/server-mimi-techaro-lol.conf
|
||||
|
||||
server {
|
||||
# Listen on 443 with SSL
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
# Slipstream via Anubis
|
||||
include "conf-anubis.inc";
|
||||
|
||||
server_name mimi.techaro.lol;
|
||||
|
||||
ssl_certificate /path/to/your/certs/mimi.techaro.lol.crt;
|
||||
ssl_certificate_key /path/to/your/certs/mimi.techaro.lol.key;
|
||||
}
|
||||
|
||||
server {
|
||||
listen unix:/run/nginx/nginx.sock;
|
||||
|
||||
server_name mimi.techaro.lol;
|
||||
root "/srv/http/mimi.techaro.lol";
|
||||
index index.html;
|
||||
|
||||
# Your normal configuration can go here
|
||||
# location .php { fastcgi...} etc.
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
Create an upstream for Anubis.
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/conf.d/upstream-anubis.conf
|
||||
|
||||
upstream anubis {
|
||||
# Make sure this matches the values you set for `BIND` and `BIND_NETWORK`.
|
||||
# If this does not match, your services will not be protected by Anubis.
|
||||
|
||||
# Try anubis first over a UNIX socket
|
||||
server unix:/run/anubis/nginx.sock;
|
||||
#server http://127.0.0.1:8923;
|
||||
|
||||
# Optional: fall back to serving the websites directly. This allows your
|
||||
# websites to be resilient against Anubis failing, at the risk of exposing
|
||||
# them to the raw internet without protection. This is a tradeoff and can
|
||||
# be worth it in some edge cases.
|
||||
#server unix:/run/nginx.sock backup;
|
||||
}
|
||||
```
|
||||
|
||||
This can be repeated for multiple sites. Anubis does not care about the HTTP `Host` header and will happily cope with multiple websites via the same instance.
|
||||
|
||||
Then reload your nginx config and load your website. You should see Anubis protecting your apps!
|
||||
|
||||
```text
|
||||
sudo systemctl reload nginx.service
|
||||
```
|
||||
@@ -4,6 +4,9 @@ title: Setting up Anubis
|
||||
|
||||
import RandomKey from "@site/src/components/RandomKey";
|
||||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Anubis is meant to sit between your reverse proxy (such as Nginx or Caddy) and your target service. One instance of Anubis must be used per service you are protecting.
|
||||
|
||||
<center>
|
||||
@@ -38,6 +41,10 @@ The Docker image runs Anubis as user ID 1000 and group ID 1000. If you are mount
|
||||
|
||||
Anubis has very minimal system requirements. I suspect that 128Mi of ram may be sufficient for a large number of concurrent clients. Anubis may be a poor fit for apps that use WebSockets and maintain open connections, but I don't have enough real-world experience to know one way or another.
|
||||
|
||||
## Native packages
|
||||
|
||||
For more detailed information on installing Anubis with native packages, please read [the native install directions](./native-install.mdx).
|
||||
|
||||
## Environment variables
|
||||
|
||||
Anubis uses these environment variables for configuration:
|
||||
@@ -76,113 +83,11 @@ Alternatively here is a key generated by your browser:
|
||||
|
||||
<RandomKey />
|
||||
|
||||
## Docker compose
|
||||
## Next steps
|
||||
|
||||
Add Anubis to your compose file pointed at your service:
|
||||
To get Anubis filtering your traffic, you need to make sure it's added to your HTTP load balancer or platform configuration. See the [environments category](/docs/category/environments) for detailed information on individual environments.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
anubis-nginx:
|
||||
image: ghcr.io/techarohq/anubis:latest
|
||||
environment:
|
||||
BIND: ":8080"
|
||||
DIFFICULTY: "5"
|
||||
METRICS_BIND: ":9090"
|
||||
SERVE_ROBOTS_TXT: "true"
|
||||
TARGET: "http://nginx"
|
||||
POLICY_FNAME: "/data/cfg/botPolicy.json"
|
||||
OG_PASSTHROUGH: "true"
|
||||
OG_EXPIRY_TIME: "24h"
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- "./botPolicy.json:/data/cfg/botPolicy.json:ro"
|
||||
nginx:
|
||||
image: nginx
|
||||
volumes:
|
||||
- "./www:/usr/share/nginx/html"
|
||||
```
|
||||
|
||||
## Kubernetes
|
||||
|
||||
This example makes the following assumptions:
|
||||
|
||||
- Your target service is listening on TCP port `5000`.
|
||||
- Anubis will be listening on port `8080`.
|
||||
|
||||
Attach Anubis to your Deployment:
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
# ...
|
||||
- name: anubis
|
||||
image: ghcr.io/techarohq/anubis:latest
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: "BIND"
|
||||
value: ":8080"
|
||||
- name: "DIFFICULTY"
|
||||
value: "5"
|
||||
- name: "METRICS_BIND"
|
||||
value: ":9090"
|
||||
- name: "SERVE_ROBOTS_TXT"
|
||||
value: "true"
|
||||
- name: "TARGET"
|
||||
value: "http://localhost:5000"
|
||||
- name: "OG_PASSTHROUGH"
|
||||
value: "true"
|
||||
- name: "OG_EXPIRY_TIME"
|
||||
value: "24h"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
|
||||
Then add a Service entry for Anubis:
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
spec:
|
||||
ports:
|
||||
# diff-add
|
||||
- protocol: TCP
|
||||
# diff-add
|
||||
port: 8080
|
||||
# diff-add
|
||||
targetPort: 8080
|
||||
# diff-add
|
||||
name: anubis
|
||||
```
|
||||
|
||||
Then point your Ingress to the Anubis port:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- host: git.xeserv.us
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: "/"
|
||||
backend:
|
||||
service:
|
||||
name: git
|
||||
port:
|
||||
# diff-remove
|
||||
name: http
|
||||
# diff-add
|
||||
name: anubis
|
||||
```
|
||||
- [Apache](./environments/apache.mdx)
|
||||
- [Docker compose](./environments/docker-compose.mdx)
|
||||
- [Kubernetes](./environments/kubernetes.mdx)
|
||||
- [Nginx](./environments/nginx.mdx)
|
||||
|
||||
@@ -5,6 +5,8 @@ title: Installing Anubis with a native package
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
|
||||
Download the package for your system from [the most recent release on GitHub](https://github.com/TecharoHQ/anubis/releases).
|
||||
|
||||
Install the Anubis package using your package manager of choice:
|
||||
|
||||
<Tabs>
|
||||
@@ -129,3 +131,8 @@ curl http://localhost:8240/metrics
|
||||
```
|
||||
|
||||
Then set up your reverse proxy (Nginx, Caddy, etc.) to point to the Anubis port. Anubis will then reverse proxy all requests that meet the policies in `/etc/anubis/gitea.botPolicies.json` to the target service.
|
||||
|
||||
For more details on particular reverse proxies, see here:
|
||||
|
||||
- [Apache](./environments/apache.mdx)
|
||||
- [Nginx](./environments/nginx.mdx)
|
||||
|
||||
@@ -26,3 +26,19 @@ Anubis is a bit of a nuclear response. This will result in your website being bl
|
||||
If you run into any issues running Anubis, please [open an issue](https://github.com/TecharoHQ/anubis/issues/new?template=Blank+issue) and include all the information I would need to diagnose your issue.
|
||||
|
||||
For live chat, please join the [Patreon](https://patreon.com/cadey) and ask in the Patron discord in the channel `#anubis`.
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://www.star-history.com/#TecharoHQ/anubis&Date)
|
||||
|
||||
## Packaging Status
|
||||
|
||||
[](https://repology.org/project/anubis-anti-crawler/versions)
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/TecharoHQ/anubis/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=TecharoHQ/anubis" />
|
||||
</a>
|
||||
|
||||
Made with [contrib.rocks](https://contrib.rocks).
|
||||
|
||||
31
docs/docs/user/known-instances.md
Normal file
31
docs/docs/user/known-instances.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: List of known websites using Anubis
|
||||
---
|
||||
|
||||
This page contains a non-exhaustive list with all websites using Anubis.
|
||||
|
||||
* <details>
|
||||
<summary>The Linux Foundation</summary>
|
||||
|
||||
* https://git.kernel.org/
|
||||
* https://lore.kernel.org/
|
||||
</details>
|
||||
* https://gitlab.gnome.org/
|
||||
* https://scioly.org/
|
||||
* https://bugs.winehq.org/
|
||||
* https://svnweb.freebsd.org/
|
||||
* https://trac.ffmpeg.org/
|
||||
* https://git.sr.ht/
|
||||
* https://xeiaso.net/
|
||||
* https://source.puri.sm/
|
||||
* https://git.enlightenment.org/
|
||||
* https://superlove.sayitditto.net/
|
||||
* https://linktaco.com/
|
||||
* https://jaredallard.dev/
|
||||
* https://dev.sanctum.geek.nz/
|
||||
* https://canine.tools/
|
||||
* <details>
|
||||
<summary>The United Nations</summary>
|
||||
|
||||
* https://policytoolbox.iiep.unesco.org/
|
||||
</details>
|
||||
@@ -125,10 +125,6 @@ const config: Config = {
|
||||
{
|
||||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'Blog',
|
||||
to: '/blog',
|
||||
},
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/TecharoHQ/anubis',
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #2e8555;
|
||||
--ifm-color-primary-dark: #29784c;
|
||||
--ifm-color-primary-darker: #277148;
|
||||
--ifm-color-primary-darkest: #205d3b;
|
||||
--ifm-color-primary-light: #33925d;
|
||||
--ifm-color-primary-lighter: #359962;
|
||||
--ifm-color-primary-lightest: #3cad6e;
|
||||
--ifm-color-primary: #ff5630;
|
||||
--ifm-color-primary-dark: #ad422a;
|
||||
--ifm-color-primary-darker: #8f3521;
|
||||
--ifm-color-primary-darkest: #592115;
|
||||
--ifm-color-primary-light: #ff7152;
|
||||
--ifm-color-primary-lighter: #ff9178;
|
||||
--ifm-color-primary-lightest: #ffb09e;
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||
--code-block-diff-add-line-color: #ccffd8;
|
||||
|
||||
13
go.mod
13
go.mod
@@ -1,16 +1,16 @@
|
||||
module github.com/TecharoHQ/anubis
|
||||
|
||||
go 1.24.2
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/a-h/templ v0.3.857
|
||||
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
github.com/playwright-community/playwright-go v0.5001.0
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/playwright-community/playwright-go v0.5101.0
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
|
||||
github.com/yl2chen/cidranger v1.0.2
|
||||
golang.org/x/net v0.38.0
|
||||
golang.org/x/net v0.39.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -30,7 +30,6 @@ require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
|
||||
github.com/go-stack/stack v1.8.1 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
@@ -42,9 +41,9 @@ require (
|
||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
honnef.co/go/tools v0.6.1 // indirect
|
||||
)
|
||||
|
||||
|
||||
28
go.sum
28
go.sum
@@ -38,10 +38,10 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
@@ -55,13 +55,13 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
|
||||
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
|
||||
github.com/playwright-community/playwright-go v0.5001.0 h1:EY3oB+rU9cUp6CLHguWE8VMZTwAg+83Yyb7dQqEmGLg=
|
||||
github.com/playwright-community/playwright-go v0.5001.0/go.mod h1:kBNWs/w2aJ2ZUp1wEOOFLXgOqvppFngM5OS+qyhl+ZM=
|
||||
github.com/playwright-community/playwright-go v0.5101.0 h1:gVCMZThDO76LJ/aCI27lpB8hEAWhZszeS0YB+oTxJp0=
|
||||
github.com/playwright-community/playwright-go v0.5101.0/go.mod h1:kBNWs/w2aJ2ZUp1wEOOFLXgOqvppFngM5OS+qyhl+ZM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
@@ -92,8 +92,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -109,8 +109,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -129,8 +129,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -23,8 +23,8 @@ func (c *OGTagCache) GetOGTags(url *url.URL) (map[string]string, error) {
|
||||
if errors.Is(err, syscall.ECONNREFUSED) {
|
||||
slog.Debug("Connection refused, returning empty tags")
|
||||
return nil, nil
|
||||
} else if errors.Is(err, ErrNotFound) {
|
||||
// not even worth a debug log...
|
||||
} else if errors.Is(err, ErrOgHandled) {
|
||||
// Error was handled in fetchHTMLDocument, return empty tags
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("page not found") /*todo: refactor into common errors lib? */
|
||||
emptyMap = map[string]string{} // used to indicate an empty result in the cache. Can't use nil as it would be a cache miss.
|
||||
ErrOgHandled = errors.New("og: handled error") // used to indicate that the error was handled and should not be logged
|
||||
emptyMap = map[string]string{} // used to indicate an empty result in the cache. Can't use nil as it would be a cache miss.
|
||||
)
|
||||
|
||||
func (c *OGTagCache) fetchHTMLDocument(urlStr string) (*html.Node, error) {
|
||||
@@ -31,7 +31,7 @@ func (c *OGTagCache) fetchHTMLDocument(urlStr string) (*html.Node, error) {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
slog.Debug("og: received non-OK status code", "url", urlStr, "status", resp.StatusCode)
|
||||
c.cache.Set(urlStr, emptyMap, c.ogTimeToLive) // Cache empty result for non-successful status codes
|
||||
return nil, ErrNotFound
|
||||
return nil, fmt.Errorf("%w: page not found", ErrOgHandled)
|
||||
}
|
||||
|
||||
// Check content type
|
||||
@@ -43,11 +43,13 @@ func (c *OGTagCache) fetchHTMLDocument(urlStr string) (*html.Node, error) {
|
||||
mediaType, _, err := mime.ParseMediaType(ct)
|
||||
if err != nil {
|
||||
// Malformed Content-Type header
|
||||
return nil, fmt.Errorf("invalid Content-Type '%s': %w", ct, err)
|
||||
slog.Debug("og: malformed Content-Type header", "url", urlStr, "contentType", ct)
|
||||
return nil, fmt.Errorf("%w malformed Content-Type header: %w", ErrOgHandled, err)
|
||||
}
|
||||
|
||||
if mediaType != "text/html" && mediaType != "application/xhtml+xml" {
|
||||
return nil, fmt.Errorf("unsupported Content-Type: %s", mediaType)
|
||||
slog.Debug("og: unsupported Content-Type", "url", urlStr, "contentType", mediaType)
|
||||
return nil, fmt.Errorf("%w unsupported Content-Type: %s", ErrOgHandled, mediaType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,24 @@ var (
|
||||
realIP: placeholderIP,
|
||||
userAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/120.0.6099.28 Safari/537.36",
|
||||
},
|
||||
{
|
||||
name: "Amazonbot",
|
||||
action: actionDeny,
|
||||
realIP: placeholderIP,
|
||||
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)",
|
||||
},
|
||||
{
|
||||
name: "Amazonbot",
|
||||
action: actionDeny,
|
||||
realIP: placeholderIP,
|
||||
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)",
|
||||
},
|
||||
{
|
||||
name: "PerplexityAI",
|
||||
action: actionDeny,
|
||||
realIP: placeholderIP,
|
||||
userAgent: "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)",
|
||||
},
|
||||
{
|
||||
name: "kagiBadIP",
|
||||
action: actionChallenge,
|
||||
@@ -80,7 +98,7 @@ const (
|
||||
actionChallenge action = "CHALLENGE"
|
||||
|
||||
placeholderIP = "fd11:5ee:bad:c0de::"
|
||||
playwrightVersion = "1.50.1"
|
||||
playwrightVersion = "1.51.1"
|
||||
)
|
||||
|
||||
type action string
|
||||
@@ -101,6 +119,9 @@ func doesNPXExist(t *testing.T) {
|
||||
}
|
||||
|
||||
func run(t *testing.T, command string) string {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration smoke testing in short mode")
|
||||
}
|
||||
t.Helper()
|
||||
|
||||
shPath, err := exec.LookPath("sh")
|
||||
|
||||
@@ -263,21 +263,21 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
lg.Debug("cookie not found", "path", r.URL.Path)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
if err := ckie.Valid(); err != nil {
|
||||
lg.Debug("cookie is invalid", "err", err)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
if time.Now().After(ckie.Expires) && !ckie.Expires.IsZero() {
|
||||
lg.Debug("cookie expired", "path", r.URL.Path)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil || !token.Valid {
|
||||
lg.Debug("invalid token", "path", r.URL.Path, "err", err)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok {
|
||||
lg.Debug("invalid token claims type", "path", r.URL.Path)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
||||
@@ -311,7 +311,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
if claims["challenge"] != challenge {
|
||||
lg.Debug("invalid challenge", "path", r.URL.Path)
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
lg.Debug("invalid response", "path", r.URL.Path)
|
||||
failedValidations.Inc()
|
||||
s.ClearCookie(w)
|
||||
s.RenderIndex(w, r)
|
||||
s.RenderIndex(w, r, cr, rule)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -337,21 +337,36 @@ func (s *Server) MaybeReverseProxy(w http.ResponseWriter, r *http.Request) {
|
||||
s.next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr CheckResult, rule *policy.Bot) {
|
||||
lg := slog.With(
|
||||
"user_agent", r.UserAgent(),
|
||||
"accept_language", r.Header.Get("Accept-Language"),
|
||||
"priority", r.Header.Get("Priority"),
|
||||
"x-forwarded-for",
|
||||
r.Header.Get("X-Forwarded-For"),
|
||||
"x-real-ip", r.Header.Get("X-Real-Ip"),
|
||||
)
|
||||
|
||||
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
||||
|
||||
var ogTags map[string]string = nil
|
||||
if s.opts.OGPassthrough {
|
||||
var err error
|
||||
ogTags, err = s.OGTags.GetOGTags(r.URL)
|
||||
if err != nil {
|
||||
slog.Error("failed to get OG tags", "err", err)
|
||||
lg.Error("failed to get OG tags", "err", err)
|
||||
ogTags = nil
|
||||
}
|
||||
}
|
||||
handler := internal.NoStoreCache(
|
||||
templ.Handler(
|
||||
web.BaseWithOGTags("Making sure you're not a bot!", web.Index(), ogTags),
|
||||
),
|
||||
)
|
||||
|
||||
component, err := web.BaseWithChallengeAndOGTags("Making sure you're not a bot!", web.Index(), challenge, rule.Challenge, ogTags)
|
||||
if err != nil {
|
||||
lg.Error("render failed", "err", err)
|
||||
templ.Handler(web.Base("Oh noes!", web.ErrorPage("Other internal server error (contact the admin)", s.opts.WebmasterEmail)), templ.WithStatus(http.StatusInternalServerError)).ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
handler := internal.NoStoreCache(templ.Handler(component))
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ import (
|
||||
func loadPolicies(t *testing.T, fname string) *policy.ParsedConfig {
|
||||
t.Helper()
|
||||
|
||||
policy, err := LoadPoliciesOrDefault("", anubis.DefaultDifficulty)
|
||||
anubisPolicy, err := LoadPoliciesOrDefault("", anubis.DefaultDifficulty)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return policy
|
||||
return anubisPolicy
|
||||
}
|
||||
|
||||
func spawnAnubis(t *testing.T, opts Options) *Server {
|
||||
|
||||
471
package-lock.json
generated
471
package-lock.json
generated
@@ -1,22 +1,448 @@
|
||||
{
|
||||
"name": "@xeserv/xess",
|
||||
"name": "@techaro/anubis",
|
||||
"version": "1.0.0-see-VERSION-file",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@xeserv/xess",
|
||||
"name": "@techaro/anubis",
|
||||
"version": "1.0.0-see-VERSION-file",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"cssnano": "^7.0.6",
|
||||
"cssnano-preset-advanced": "^7.0.6",
|
||||
"esbuild": "^0.25.2",
|
||||
"postcss-cli": "^11.0.1",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-import-url": "^7.2.0",
|
||||
"postcss-url": "^10.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
|
||||
"integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
|
||||
"integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
|
||||
"integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
|
||||
"integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
|
||||
"integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
|
||||
"integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
|
||||
"integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
|
||||
"integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
|
||||
"integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
|
||||
"integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
|
||||
"integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
|
||||
"integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -617,6 +1043,47 @@
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.25.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
|
||||
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.25.2",
|
||||
"@esbuild/android-arm": "0.25.2",
|
||||
"@esbuild/android-arm64": "0.25.2",
|
||||
"@esbuild/android-x64": "0.25.2",
|
||||
"@esbuild/darwin-arm64": "0.25.2",
|
||||
"@esbuild/darwin-x64": "0.25.2",
|
||||
"@esbuild/freebsd-arm64": "0.25.2",
|
||||
"@esbuild/freebsd-x64": "0.25.2",
|
||||
"@esbuild/linux-arm": "0.25.2",
|
||||
"@esbuild/linux-arm64": "0.25.2",
|
||||
"@esbuild/linux-ia32": "0.25.2",
|
||||
"@esbuild/linux-loong64": "0.25.2",
|
||||
"@esbuild/linux-mips64el": "0.25.2",
|
||||
"@esbuild/linux-ppc64": "0.25.2",
|
||||
"@esbuild/linux-riscv64": "0.25.2",
|
||||
"@esbuild/linux-s390x": "0.25.2",
|
||||
"@esbuild/linux-x64": "0.25.2",
|
||||
"@esbuild/netbsd-arm64": "0.25.2",
|
||||
"@esbuild/netbsd-x64": "0.25.2",
|
||||
"@esbuild/openbsd-arm64": "0.25.2",
|
||||
"@esbuild/openbsd-x64": "0.25.2",
|
||||
"@esbuild/sunos-x64": "0.25.2",
|
||||
"@esbuild/win32-arm64": "0.25.2",
|
||||
"@esbuild/win32-ia32": "0.25.2",
|
||||
"@esbuild/win32-x64": "0.25.2"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
"devDependencies": {
|
||||
"cssnano": "^7.0.6",
|
||||
"cssnano-preset-advanced": "^7.0.6",
|
||||
"esbuild": "^0.25.2",
|
||||
"postcss-cli": "^11.0.1",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-import-url": "^7.2.0",
|
||||
"postcss-url": "^10.1.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
pkgs/cryptography/techaro-pkgs.pub.asc
Normal file
14
pkgs/cryptography/techaro-pkgs.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU/hRYJKwYBBAHaRw8BAQdANg5d753IR7Q3NxfE+vVgpBx9w66HSzx74zEz
|
||||
2djVqZm0NlRlY2hhcm8gUGFja2FnZXMgU2lnbmF0dXJlcyA8Z3BnK3BhY2thZ2Vz
|
||||
QHRlY2hhcm8ubG9sPoiZBBMWCgBBFiEEgz9kFhFntQEFjDlHVjddot8Cq/8FAmgF
|
||||
P4UCGwMFCRLMAwAFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQVjddot8C
|
||||
q/8PYwEAk1B1r8cBZi54fTOpMnkKUJnbk9wnmNLdUkRADlPRCcIBAN3Zgsjb/SXw
|
||||
nWINVPKvodwUVanDwl5uZuXtROv1mQ8GuDgEaAU/hRIKKwYBBAGXVQEFAQEHQLqY
|
||||
3RXQiv/4d7y+eGs+YE4BymAguYG44jRtHHwFERZEAwEIB4h+BBgWCgAmFiEEgz9k
|
||||
FhFntQEFjDlHVjddot8Cq/8FAmgFP4UCGwwFCRLMAwAACgkQVjddot8Cq/8WXgEA
|
||||
lMjj013kuKsSCrczDxCSH0boW6xSTfyjnC2SQ4VDj78A/i6JrmkMq0wUSevgxlGw
|
||||
ZIoXIS4aVdSnfY9LMcnklKcL
|
||||
=zIdk
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
14
pkgs/cryptography/techaro-root.pub.asc
Normal file
14
pkgs/cryptography/techaro-root.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU+KxYJKwYBBAHaRw8BAQdAroyz8ysjSTBcQgfN+StN6WAfNzPDwiTF1LvS
|
||||
bVRSu0a0KlRlY2hhcm8gUm9vdCBTaWduaW5nIEtleSA8Z3BnQHRlY2hhcm8ubG9s
|
||||
PoiZBBMWCgBBFiEEia0uWmNauBlpQAXmU41NIwnMwuwFAmgFPisCGwMFCRLMAwAF
|
||||
CwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQU41NIwnMwuxKFQD/ZovOrWC3
|
||||
DKcrYYKpCrX30iWDd+U2hqlPFFvRKhFx52UA+gO+UYeCBy/dnxc0GrNPE84yWQqr
|
||||
9eas/yEf1rsMInIEuDgEaAU+KxIKKwYBBAGXVQEFAQEHQAaSsoWAStlNTHgN9xuW
|
||||
aVsxZ9DQzPlD2osWHuvXCwknAwEIB4h+BBgWCgAmFiEEia0uWmNauBlpQAXmU41N
|
||||
IwnMwuwFAmgFPisCGwwFCRLMAwAACgkQU41NIwnMwuxs+AEAijEEHvssBYt80YZW
|
||||
/jCrp3vuD6aTFzb5NzvdQafPH5AA/0dt5ayS/vu31z2YTfSg5WNGWKvOvyGAG6jz
|
||||
TS5tWMYJ
|
||||
=uI7D
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
2
pkgs/cryptography/var/.gitignore
vendored
Normal file
2
pkgs/cryptography/var/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
29
pkgs/cryptography/yeetfile.js
Normal file
29
pkgs/cryptography/yeetfile.js
Normal file
@@ -0,0 +1,29 @@
|
||||
rpm.build({
|
||||
name: "techaro-repo-keys",
|
||||
description: "Public keys for techaro.lol RPM packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
version: "1.0.0",
|
||||
|
||||
build: (out) => {
|
||||
yeet.run(`mkdir`, `-p`, `${out}/etc/pki/rpm-gpg/techaro.lol-keys`);
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-root.asc`);
|
||||
},
|
||||
});
|
||||
|
||||
deb.build({
|
||||
name: "techaro-repo-keys",
|
||||
description: "Public keys for techaro.lol RPM packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
version: "1.0.0",
|
||||
|
||||
build: (out) => {
|
||||
yeet.run(`mkdir`, `-p`, `${out}/usr/share/keyrings`);
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/usr/share/keyrings/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/usr/share/keyrings/techaro-root.asc`);
|
||||
},
|
||||
});
|
||||
14
pkgs/repos/techaro-pkgs.pub.asc
Normal file
14
pkgs/repos/techaro-pkgs.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU/hRYJKwYBBAHaRw8BAQdANg5d753IR7Q3NxfE+vVgpBx9w66HSzx74zEz
|
||||
2djVqZm0NlRlY2hhcm8gUGFja2FnZXMgU2lnbmF0dXJlcyA8Z3BnK3BhY2thZ2Vz
|
||||
QHRlY2hhcm8ubG9sPoiZBBMWCgBBFiEEgz9kFhFntQEFjDlHVjddot8Cq/8FAmgF
|
||||
P4UCGwMFCRLMAwAFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQVjddot8C
|
||||
q/8PYwEAk1B1r8cBZi54fTOpMnkKUJnbk9wnmNLdUkRADlPRCcIBAN3Zgsjb/SXw
|
||||
nWINVPKvodwUVanDwl5uZuXtROv1mQ8GuDgEaAU/hRIKKwYBBAGXVQEFAQEHQLqY
|
||||
3RXQiv/4d7y+eGs+YE4BymAguYG44jRtHHwFERZEAwEIB4h+BBgWCgAmFiEEgz9k
|
||||
FhFntQEFjDlHVjddot8Cq/8FAmgFP4UCGwwFCRLMAwAACgkQVjddot8Cq/8WXgEA
|
||||
lMjj013kuKsSCrczDxCSH0boW6xSTfyjnC2SQ4VDj78A/i6JrmkMq0wUSevgxlGw
|
||||
ZIoXIS4aVdSnfY9LMcnklKcL
|
||||
=zIdk
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
14
pkgs/repos/techaro-root.pub.asc
Normal file
14
pkgs/repos/techaro-root.pub.asc
Normal file
@@ -0,0 +1,14 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEaAU+KxYJKwYBBAHaRw8BAQdAroyz8ysjSTBcQgfN+StN6WAfNzPDwiTF1LvS
|
||||
bVRSu0a0KlRlY2hhcm8gUm9vdCBTaWduaW5nIEtleSA8Z3BnQHRlY2hhcm8ubG9s
|
||||
PoiZBBMWCgBBFiEEia0uWmNauBlpQAXmU41NIwnMwuwFAmgFPisCGwMFCRLMAwAF
|
||||
CwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQU41NIwnMwuxKFQD/ZovOrWC3
|
||||
DKcrYYKpCrX30iWDd+U2hqlPFFvRKhFx52UA+gO+UYeCBy/dnxc0GrNPE84yWQqr
|
||||
9eas/yEf1rsMInIEuDgEaAU+KxIKKwYBBAGXVQEFAQEHQAaSsoWAStlNTHgN9xuW
|
||||
aVsxZ9DQzPlD2osWHuvXCwknAwEIB4h+BBgWCgAmFiEEia0uWmNauBlpQAXmU41N
|
||||
IwnMwuwFAmgFPisCGwwFCRLMAwAACgkQU41NIwnMwuxs+AEAijEEHvssBYt80YZW
|
||||
/jCrp3vuD6aTFzb5NzvdQafPH5AA/0dt5ayS/vu31z2YTfSg5WNGWKvOvyGAG6jz
|
||||
TS5tWMYJ
|
||||
=uI7D
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
6
pkgs/repos/techaro-stable.repo
Normal file
6
pkgs/repos/techaro-stable.repo
Normal file
@@ -0,0 +1,6 @@
|
||||
[techaro-stable]
|
||||
name=Techaro Packages (stable)
|
||||
baseurl=https://pkgs.techaro.lol/rpm/stable
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc
|
||||
6
pkgs/repos/techaro-unstable.repo
Normal file
6
pkgs/repos/techaro-unstable.repo
Normal file
@@ -0,0 +1,6 @@
|
||||
[techaro-unstable]
|
||||
name=Techaro Packages (unstable)
|
||||
baseurl=https://pkgs.techaro.lol/rpm/unstable
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc
|
||||
2
pkgs/repos/var/.gitignore
vendored
Normal file
2
pkgs/repos/var/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
29
pkgs/repos/yeetfile.js
Normal file
29
pkgs/repos/yeetfile.js
Normal file
@@ -0,0 +1,29 @@
|
||||
rpm.build({
|
||||
name: "techaro-repos-stable",
|
||||
description: "Repo definitions for stable Techaro packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
version: "1.0.0",
|
||||
|
||||
build: (out) => {
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-root.asc`);
|
||||
file.install("./techaro-stable.repo", `${out}/etc/yum.repos.d/techaro-stable.repo`);
|
||||
},
|
||||
});
|
||||
|
||||
rpm.build({
|
||||
name: "techaro-repos-unstable",
|
||||
description: "Repo definitions for unstable Techaro packages",
|
||||
homepage: "https://techaro.lol",
|
||||
license: "MIT",
|
||||
goarch: "all",
|
||||
version: "1.0.0",
|
||||
|
||||
build: (out) => {
|
||||
file.install("./techaro-pkgs.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-pkgs.asc`);
|
||||
file.install("./techaro-root.pub.asc", `${out}/etc/pki/rpm-gpg/techaro.lol-keys/techaro-root.asc`);
|
||||
file.install("./techaro-stable.repo", `${out}/etc/yum.repos.d/techaro-stable.repo`);
|
||||
},
|
||||
});
|
||||
34
run/anubis.freebsd
Normal file
34
run/anubis.freebsd
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
# PROVIDE: anubis
|
||||
# REQUIRE: NETWORKING
|
||||
# KEYWORD: shutdown
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name=anubis
|
||||
rcvar=anubis_enable
|
||||
|
||||
load_rc_config ${name}
|
||||
|
||||
: ${anubis_enable="NO"}
|
||||
: ${anubis_user="anubis"}
|
||||
: ${anubis_bin="/usr/local/bin/anubis"}
|
||||
: ${anubis_environment_file="/etc/anubis.env"}
|
||||
|
||||
command=/usr/sbin/daemon
|
||||
procname=${anubis_bin}
|
||||
pidfile=/var/run/anubis.pid
|
||||
logfile=/var/log/anubis.log
|
||||
command_args="-c -f -p ${pidfile} -o ${logfile} ${procname}"
|
||||
start_precmd=anubis_precmd
|
||||
|
||||
anubis_precmd () {
|
||||
export $(xargs < ${anubis_environment_file})
|
||||
if [ ! -f ${logfile} ]; then
|
||||
install -o anubis /dev/null ${logfile}
|
||||
fi
|
||||
install -o anubis /dev/null ${pidfile}
|
||||
}
|
||||
|
||||
run_rc_command "$1"
|
||||
14
web/index.go
14
web/index.go
@@ -2,14 +2,22 @@ package web
|
||||
|
||||
import (
|
||||
"github.com/a-h/templ"
|
||||
|
||||
"github.com/TecharoHQ/anubis/lib/policy/config"
|
||||
)
|
||||
|
||||
func Base(title string, body templ.Component) templ.Component {
|
||||
return base(title, body, nil)
|
||||
return base(title, body, nil, nil)
|
||||
}
|
||||
|
||||
func BaseWithOGTags(title string, body templ.Component, ogTags map[string]string) templ.Component {
|
||||
return base(title, body, ogTags)
|
||||
func BaseWithChallengeAndOGTags(title string, body templ.Component, challenge string, rules *config.ChallengeRules, ogTags map[string]string) (templ.Component, error) {
|
||||
return base(title, body, struct {
|
||||
Challenge string `json:"challenge"`
|
||||
Rules *config.ChallengeRules `json:"rules"`
|
||||
}{
|
||||
Challenge: challenge,
|
||||
Rules: rules,
|
||||
}, ogTags), nil
|
||||
}
|
||||
|
||||
func Index() templ.Component {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/TecharoHQ/anubis/xess"
|
||||
)
|
||||
|
||||
templ base(title string, body templ.Component, ogTags map[string]string) {
|
||||
templ base(title string, body templ.Component, challenge any, ogTags map[string]string) {
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -42,10 +42,8 @@ templ base(title string, body templ.Component, ogTags map[string]string) {
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
margin: 1rem 0 2rem;
|
||||
outline-color: #b16286;
|
||||
outline-offset: 2px;
|
||||
outline-style: solid;
|
||||
outline-width: 4px;
|
||||
outline: #b16286 solid 4px;
|
||||
}
|
||||
|
||||
.bar-inner {
|
||||
@@ -56,6 +54,9 @@ templ base(title string, body templ.Component, ogTags map[string]string) {
|
||||
}
|
||||
</style>
|
||||
@templ.JSONScript("anubis_version", anubis.Version)
|
||||
if challenge != nil {
|
||||
@templ.JSONScript("anubis_challenge", challenge)
|
||||
}
|
||||
|
||||
</head>
|
||||
<body id="top">
|
||||
|
||||
26
web/index_templ.go
generated
26
web/index_templ.go
generated
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/TecharoHQ/anubis/xess"
|
||||
)
|
||||
|
||||
func base(title string, body templ.Component, ogTags map[string]string) templ.Component {
|
||||
func base(title string, body templ.Component, challenge any, ogTags map[string]string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -104,6 +104,12 @@ func base(title string, body templ.Component, ogTags map[string]string) templ.Co
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if challenge != nil {
|
||||
templ_7745c5c3_Err = templ.JSONScript("anubis_challenge", challenge).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</head><body id=\"top\"><main><center><h1 id=\"title\" class=\".centered-div\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@@ -111,7 +117,7 @@ func base(title string, body templ.Component, ogTags map[string]string) templ.Co
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 64, Col: 52}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 67, Col: 52}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -162,7 +168,7 @@ func index() templ.Component {
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
||||
anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 88, Col: 18}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 91, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -176,7 +182,7 @@ func index() templ.Component {
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" +
|
||||
anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 94, Col: 18}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 97, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -190,7 +196,7 @@ func index() templ.Component {
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(
|
||||
"/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 98, Col: 84}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 101, Col: 84}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -232,7 +238,7 @@ func errorPage(message string, mail string) templ.Component {
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/reject.webp?cacheBuster=" + anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 138, Col: 102}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 141, Col: 102}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -245,7 +251,7 @@ func errorPage(message string, mail string) templ.Component {
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(message)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 140, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 143, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -272,7 +278,7 @@ func errorPage(message string, mail string) templ.Component {
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(mail)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 144, Col: 9}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 147, Col: 9}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -325,7 +331,7 @@ func bench() templ.Component {
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
||||
anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 175, Col: 22}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 178, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@@ -339,7 +345,7 @@ func bench() templ.Component {
|
||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(
|
||||
"/.within.website/x/cmd/anubis/static/js/bench.mjs?cacheBuster=" + anubis.Version)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 179, Col: 89}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 182, Col: 89}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
||||
@@ -133,19 +133,7 @@ function showContinueBar(hash, nonce, t0, t1) {
|
||||
}
|
||||
}
|
||||
|
||||
const { challenge, rules } = await fetch("/.within.website/x/cmd/anubis/api/make-challenge", { method: "POST" })
|
||||
.then(r => {
|
||||
if (!r.ok) throw new Error("Failed to fetch config");
|
||||
return r.json();
|
||||
})
|
||||
.catch(err => {
|
||||
ohNoes({
|
||||
titleMsg: "Internal error!",
|
||||
statusMsg: `Failed to fetch challenge config: ${err.message}`,
|
||||
imageSrc: imageURL("reject", anubisVersion),
|
||||
});
|
||||
throw err;
|
||||
});
|
||||
const { challenge, rules } = JSON.parse(document.getElementById('anubis_challenge').textContent);
|
||||
|
||||
const process = algorithms[rules.algorithm];
|
||||
if (!process) {
|
||||
|
||||
@@ -24,6 +24,7 @@ var (
|
||||
func init() {
|
||||
Mount(http.DefaultServeMux)
|
||||
|
||||
//goland:noinspection GoBoolExpressions
|
||||
if anubis.Version != "devel" {
|
||||
URL = filepath.Join(filepath.Dir(URL), "xess.min.css")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user