Compare commits

...

12 Commits

Author SHA1 Message Date
Xe Iaso
e05d8bd65b chore: fix spelling
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 12:05:25 -05:00
Xe Iaso
c84a414570 docs: add iplist2rule docs
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:58:11 -05:00
Xe Iaso
ad41bc7a25 feat(iplist2rule): add comment describing how rule was generated
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:31:53 -05:00
Xe Iaso
c5815f3be7 chore: fix spelling again
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:28:46 -05:00
Xe Iaso
2dc0719556 chore: fix spelling
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:20:44 -05:00
Xe Iaso
9ccfdf37ef docs: update CHANGELOG
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:18:31 -05:00
Xe Iaso
b592aaf656 feat: iplist2rule utility command
Assisted-By: GLM 4.7 via Claude Code
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-29 10:16:39 -05:00
Xe Iaso
1d8e98c5ec test(nginx): fix tests to work in GHA (#1372)
* test(nginx): fix tests to work in GHA

Closes: #1371
Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(test): does this work lol

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(test): does this other thing work lol

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(test): pki folder location

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Signed-off-by: Jason Cameron <git@jasoncameron.dev>
Co-authored-by: Jason Cameron <git@jasoncameron.dev>
2025-12-28 23:59:48 -05:00
Jason Cameron
880020095c fix(test): remove interactive flag from nginx smoke test docker run command (#1371) 2025-12-29 03:14:50 +00:00
dependabot[bot]
f5728e96a1 build(deps-dev): bump esbuild from 0.27.1 to 0.27.2 in the npm group (#1368)
Co-authored-by: Jason Cameron <git@jsn.cam>
2025-12-28 22:07:44 -05:00
dependabot[bot]
bcf525dbcf build(deps): bump the github-actions group with 3 updates (#1369)
Co-authored-by: Jason Cameron <git@jasoncameron.dev>
2025-12-28 22:04:16 -05:00
Xe Iaso
d748dc9da8 test: basic nginx smoke test (#1365)
* docs: split nginx configuration files to their own directory

Signed-off-by: Xe Iaso <me@xeiaso.net>

* test: add nginx config smoke test based on the config in the docs

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-12-28 23:18:25 +00:00
31 changed files with 802 additions and 270 deletions

View File

@@ -18,3 +18,8 @@ clampip
pseudoprofound
reimagining
iocaine
admins
fout
iplist
NArg
blocklists

View File

@@ -68,7 +68,7 @@ jobs:
SLOG_LEVEL: debug
- name: Generate artifact attestation
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0
with:
subject-name: ${{ env.IMAGE }}
subject-digest: ${{ steps.build.outputs.digest }}

View File

@@ -22,7 +22,7 @@ jobs:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Log into registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0

View File

@@ -18,7 +18,7 @@ jobs:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Docker meta
id: meta

View File

@@ -23,6 +23,7 @@ jobs:
- healthcheck
- i18n
- log-file
- nginx
- palemoon/amd64
#- palemoon/i386
- robots_txt
@@ -35,10 +36,10 @@ jobs:
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: '24.11.0'
node-version: "24.11.0"
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version: '1.25.4'
go-version: "1.25.4"
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9

View File

@@ -30,7 +30,7 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Build and push
run: |
cd ./test/ssh-ci

View File

@@ -29,7 +29,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
with:
sarif_file: results.sarif
category: zizmor

View File

@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Add iplist2rule tool that lets admins turn an IP address blocklist into an Anubis ruleset.
- Add Polish locale ([#1292](https://github.com/TecharoHQ/anubis/pull/1309))
<!-- This changes the project to: -->

View File

@@ -1,5 +1,7 @@
# Nginx
import CodeBlock from "@theme/CodeBlock";
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
@@ -36,110 +38,26 @@ These examples assume that you are using a setup where your nginx configuration
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
import anubisTest from "!!raw-loader!./nginx/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;
listen [::]:443 ssl;
http2 on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Http-Version $server_protocol;
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;
# Get the visiting IP from the TLS termination server
set_real_ip_from unix:;
real_ip_header X-Real-IP;
# Your normal configuration can go here
# location .php { fastcgi...} etc.
}
```
<CodeBlock language="nginx">{anubisTest}</CodeBlock>
:::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
import anubisInclude from "!!raw-loader!./nginx/conf-anubis.inc";
# Forward to anubis
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://anubis;
}
```
<CodeBlock language="nginx">{anubisInclude}</CodeBlock>
Then in a server block:
<details>
<summary>Full nginx config</summary>
```nginx
# /etc/nginx/conf.d/server-mimi-techaro-lol.conf
import mimiTecharoLol from "!!raw-loader!./nginx/server-mimi-techaro-lol.conf";
server {
# Listen on 443 with SSL
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# 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;
port_in_redirect off;
root "/srv/http/mimi.techaro.lol";
index index.html;
# Your normal configuration can go here
# location .php { fastcgi...} etc.
}
```
<CodeBlock language="nginx">{mimiTecharoLol}</CodeBlock>
</details>
@@ -147,24 +65,9 @@ server {
Create an upstream for Anubis.
```nginx
# /etc/nginx/conf.d/upstream-anubis.conf
import anubisUpstream from "!!raw-loader!./nginx/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 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;
}
```
<CodeBlock language="nginx">{anubisUpstream}</CodeBlock>
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.

View File

@@ -0,0 +1,8 @@
# /etc/nginx/conf-anubis.inc
# Forward to anubis
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://anubis;
}

View File

@@ -0,0 +1,50 @@
# /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;
listen [::]:443 ssl;
http2 on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Http-Version $server_protocol;
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;
# Get the visiting IP from the TLS termination server
set_real_ip_from unix:;
real_ip_header X-Real-IP;
# Your normal configuration can go here
# location .php { fastcgi...} etc.
}

View File

@@ -0,0 +1,29 @@
# /etc/nginx/conf.d/server-mimi-techaro-lol.conf
server {
# Listen on 443 with SSL
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# 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;
port_in_redirect off;
root "/srv/http/mimi.techaro.lol";
index index.html;
# Your normal configuration can go here
# location .php { fastcgi...} etc.
}

View File

@@ -0,0 +1,16 @@
# /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 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;
}

View File

@@ -0,0 +1,50 @@
---
title: iplist2rule CLI tool
---
The `iplist2rule` tool converts IP blocklists into Anubis challenge policies. It reads common IP block list formats and generates the appropriate Anubis policy file for IP address filtering.
## Installation
Install directly with Go
```bash
go install github.com/TecharoHQ/anubis/utils/cmd/iplist2rule@latest
```
## Usage
Basic conversion from URL:
```bash
iplist2rule https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml
```
Explicitly allow every IP address on a list:
```bash
iplist2rule --action ALLOW https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml
```
Add weight to requests matching IP addresses on a list:
```bash
iplist2rule --action WEIGH --weight 20 https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml
```
## Options
| Flag | Description | Default |
| :------------ | :----------------------------------------------------------------------------------------------- | :-------------------------------- |
| `--action` | The Anubis action to take for the IP address in question, must be in ALL CAPS. | `DENY` (forbids traffic) |
| `--rule-name` | The name for the generated Anubis rule, should be in kebab-case. | (not set, inferred from filename) |
| `--weight` | When `--action=WEIGH`, how many weight points should be added or removed from matching requests? | 0 (not set) |
## Using the Generated Policy
Save the output and import it in your main policy file:
```yaml
bots:
- import: "./filter-tor.yaml"
```

View File

@@ -12,6 +12,7 @@ Install directly with Go:
```bash
go install github.com/TecharoHQ/anubis/cmd/robots2policy@latest
```
## Usage
Basic conversion from URL:
@@ -35,8 +36,8 @@ robots2policy -input robots.txt -action DENY -format json
## Options
| Flag | Description | Default |
|-----------------------|--------------------------------------------------------------------|---------------------|
| `-input` | robots.txt file path or URL (use `-` for stdin) | *required* |
| --------------------- | ------------------------------------------------------------------ | ------------------- |
| `-input` | robots.txt file path or URL (use `-` for stdin) | _required_ |
| `-output` | Output file (use `-` for stdout) | stdout |
| `-format` | Output format: `yaml` or `json` | `yaml` |
| `-action` | Action for disallowed paths: `ALLOW`, `DENY`, `CHALLENGE`, `WEIGH` | `CHALLENGE` |
@@ -47,6 +48,7 @@ robots2policy -input robots.txt -action DENY -format json
## Example
Input robots.txt:
```txt
User-agent: *
Disallow: /admin/
@@ -57,6 +59,7 @@ Disallow: /
```
Generated policy:
```yaml
- name: robots-txt-policy-disallow-1
action: CHALLENGE
@@ -77,8 +80,8 @@ Generated policy:
Save the output and import it in your main policy file:
```yaml
import:
- path: "./robots-policy.yaml"
bots:
- import: "./robots-policy.yaml"
```
The tool handles wildcard patterns, user-agent specific rules, and blacklisted bots automatically.

100
docs/package-lock.json generated
View File

@@ -14,6 +14,7 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
@@ -161,6 +162,7 @@
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.29.0.tgz",
"integrity": "sha512-cZ0Iq3OzFUPpgszzDr1G1aJV5UMIZ4VygJ2Az252q4Rdf5cQMhYEIKArWY/oUjMhQmosM8ygOovNq7gvA9CdCg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@algolia/client-common": "5.29.0",
"@algolia/requester-browser-xhr": "5.29.0",
@@ -308,6 +310,7 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.3",
@@ -2145,6 +2148,7 @@
}
],
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18"
},
@@ -2167,6 +2171,7 @@
}
],
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18"
}
@@ -2247,6 +2252,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"license": "MIT",
"peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -2610,6 +2616,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"license": "MIT",
"peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -3523,6 +3530,7 @@
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz",
"integrity": "sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@docusaurus/core": "3.8.1",
"@docusaurus/logger": "3.8.1",
@@ -4246,6 +4254,7 @@
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz",
"integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/mdx": "^2.0.0"
},
@@ -4558,6 +4567,7 @@
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
@@ -5200,6 +5210,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz",
"integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -5539,6 +5550,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -5594,6 +5606,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -5639,6 +5652,7 @@
"resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.29.0.tgz",
"integrity": "sha512-E2l6AlTWGznM2e7vEE6T6hzObvEyXukxMOlBmVlMyixZyK1umuO/CiVc6sDBbzVH0oEviCE5IfVY1oZBmccYPQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@algolia/client-abtesting": "5.29.0",
"@algolia/client-analytics": "5.29.0",
@@ -6092,6 +6106,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001737",
"electron-to-chromium": "^1.5.211",
@@ -6375,6 +6390,7 @@
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz",
"integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@chevrotain/cst-dts-gen": "11.0.3",
"@chevrotain/gast": "11.0.3",
@@ -7079,6 +7095,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"license": "MIT",
"peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -7398,6 +7415,7 @@
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.32.0.tgz",
"integrity": "sha512-5JHBC9n75kz5851jeklCPmZWcg3hUe6sjqJvyk3+hVqFaKcHwHgxsjeN1yLmggoUc6STbtm9/NQyabQehfjvWQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10"
}
@@ -7819,6 +7837,7 @@
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">=12"
}
@@ -8977,6 +8996,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -13596,6 +13616,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -14170,6 +14191,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -15073,6 +15095,7 @@
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"license": "MIT",
"peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -15845,6 +15868,76 @@
"node": ">= 0.8"
}
},
"node_modules/raw-loader": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
"integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
"license": "MIT",
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/raw-loader/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/raw-loader/node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"license": "MIT",
"peerDependencies": {
"ajv": "^6.9.1"
}
},
"node_modules/raw-loader/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"license": "MIT"
},
"node_modules/raw-loader/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -15874,6 +15967,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -15883,6 +15977,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.25.0"
},
@@ -15938,6 +16033,7 @@
"resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz",
"integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/react": "*"
},
@@ -15966,6 +16062,7 @@
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz",
"integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.13",
"history": "^4.9.0",
@@ -17804,6 +17901,7 @@
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -18151,6 +18249,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -18398,6 +18497,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
"integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.6",

View File

@@ -21,6 +21,7 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},

220
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@techaro/anubis",
"version": "1.24.0-pre1",
"version": "1.24.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@techaro/anubis",
"version": "1.24.0-pre1",
"version": "1.24.0",
"license": "ISC",
"dependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
@@ -15,7 +15,7 @@
"devDependencies": {
"cssnano": "^7.1.2",
"cssnano-preset-advanced": "^7.0.10",
"esbuild": "^0.27.1",
"esbuild": "^0.27.2",
"playwright": "^1.52.0",
"postcss-cli": "^11.0.1",
"postcss-import": "^16.1.1",
@@ -62,9 +62,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz",
"integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
"integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
"cpu": [
"ppc64"
],
@@ -79,9 +79,9 @@
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz",
"integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
"integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
"cpu": [
"arm"
],
@@ -96,9 +96,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz",
"integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
"integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
"cpu": [
"arm64"
],
@@ -113,9 +113,9 @@
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz",
"integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
"integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
"cpu": [
"x64"
],
@@ -130,9 +130,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz",
"integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
"integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
"cpu": [
"arm64"
],
@@ -147,9 +147,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz",
"integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
"integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
"cpu": [
"x64"
],
@@ -164,9 +164,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz",
"integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
"integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
"cpu": [
"arm64"
],
@@ -181,9 +181,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz",
"integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
"integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
"cpu": [
"x64"
],
@@ -198,9 +198,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz",
"integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
"integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
"cpu": [
"arm"
],
@@ -215,9 +215,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz",
"integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
"integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
"cpu": [
"arm64"
],
@@ -232,9 +232,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz",
"integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
"integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
"cpu": [
"ia32"
],
@@ -249,9 +249,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz",
"integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
"integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
"cpu": [
"loong64"
],
@@ -266,9 +266,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz",
"integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
"integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
"cpu": [
"mips64el"
],
@@ -283,9 +283,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz",
"integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
"integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
"cpu": [
"ppc64"
],
@@ -300,9 +300,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz",
"integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
"integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
"cpu": [
"riscv64"
],
@@ -317,9 +317,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz",
"integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
"integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
"cpu": [
"s390x"
],
@@ -334,9 +334,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz",
"integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
"integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
"cpu": [
"x64"
],
@@ -351,9 +351,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz",
"integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
"integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
"cpu": [
"arm64"
],
@@ -368,9 +368,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz",
"integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
"integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
"cpu": [
"x64"
],
@@ -385,9 +385,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz",
"integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
"integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
"cpu": [
"arm64"
],
@@ -402,9 +402,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz",
"integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
"integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
"cpu": [
"x64"
],
@@ -419,9 +419,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz",
"integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
"integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
"cpu": [
"arm64"
],
@@ -436,9 +436,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz",
"integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
"integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
"cpu": [
"x64"
],
@@ -453,9 +453,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz",
"integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
"integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
"cpu": [
"arm64"
],
@@ -470,9 +470,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz",
"integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
"integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
"cpu": [
"ia32"
],
@@ -487,9 +487,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz",
"integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
"integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
"cpu": [
"x64"
],
@@ -1156,9 +1156,9 @@
}
},
"node_modules/esbuild": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz",
"integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
"integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -1169,32 +1169,32 @@
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.1",
"@esbuild/android-arm": "0.27.1",
"@esbuild/android-arm64": "0.27.1",
"@esbuild/android-x64": "0.27.1",
"@esbuild/darwin-arm64": "0.27.1",
"@esbuild/darwin-x64": "0.27.1",
"@esbuild/freebsd-arm64": "0.27.1",
"@esbuild/freebsd-x64": "0.27.1",
"@esbuild/linux-arm": "0.27.1",
"@esbuild/linux-arm64": "0.27.1",
"@esbuild/linux-ia32": "0.27.1",
"@esbuild/linux-loong64": "0.27.1",
"@esbuild/linux-mips64el": "0.27.1",
"@esbuild/linux-ppc64": "0.27.1",
"@esbuild/linux-riscv64": "0.27.1",
"@esbuild/linux-s390x": "0.27.1",
"@esbuild/linux-x64": "0.27.1",
"@esbuild/netbsd-arm64": "0.27.1",
"@esbuild/netbsd-x64": "0.27.1",
"@esbuild/openbsd-arm64": "0.27.1",
"@esbuild/openbsd-x64": "0.27.1",
"@esbuild/openharmony-arm64": "0.27.1",
"@esbuild/sunos-x64": "0.27.1",
"@esbuild/win32-arm64": "0.27.1",
"@esbuild/win32-ia32": "0.27.1",
"@esbuild/win32-x64": "0.27.1"
"@esbuild/aix-ppc64": "0.27.2",
"@esbuild/android-arm": "0.27.2",
"@esbuild/android-arm64": "0.27.2",
"@esbuild/android-x64": "0.27.2",
"@esbuild/darwin-arm64": "0.27.2",
"@esbuild/darwin-x64": "0.27.2",
"@esbuild/freebsd-arm64": "0.27.2",
"@esbuild/freebsd-x64": "0.27.2",
"@esbuild/linux-arm": "0.27.2",
"@esbuild/linux-arm64": "0.27.2",
"@esbuild/linux-ia32": "0.27.2",
"@esbuild/linux-loong64": "0.27.2",
"@esbuild/linux-mips64el": "0.27.2",
"@esbuild/linux-ppc64": "0.27.2",
"@esbuild/linux-riscv64": "0.27.2",
"@esbuild/linux-s390x": "0.27.2",
"@esbuild/linux-x64": "0.27.2",
"@esbuild/netbsd-arm64": "0.27.2",
"@esbuild/netbsd-x64": "0.27.2",
"@esbuild/openbsd-arm64": "0.27.2",
"@esbuild/openbsd-x64": "0.27.2",
"@esbuild/openharmony-arm64": "0.27.2",
"@esbuild/sunos-x64": "0.27.2",
"@esbuild/win32-arm64": "0.27.2",
"@esbuild/win32-ia32": "0.27.2",
"@esbuild/win32-x64": "0.27.2"
}
},
"node_modules/escalade": {

View File

@@ -20,7 +20,7 @@
"devDependencies": {
"cssnano": "^7.1.2",
"cssnano-preset-advanced": "^7.0.10",
"esbuild": "^0.27.1",
"esbuild": "^0.27.2",
"playwright": "^1.52.0",
"postcss-cli": "^11.0.1",
"postcss-import": "^16.1.1",

View File

@@ -14,7 +14,7 @@ services:
ports:
- 3004:3004
volumes:
- ../pki/registry.local.cetacean.club:/etc/techaro/pki/registry.local.cetacean.club
- ./pki/registry.local.cetacean.club:/etc/techaro/pki/registry.local.cetacean.club
anubis:
image: ko.local/anubis

View File

@@ -1,53 +1,56 @@
REPO_ROOT=$(git rev-parse --show-toplevel)
(cd $REPO_ROOT && go install ./utils/cmd/...)
mkdir -p pki
echo '*' >>./pki/.gitignore
function cleanup() {
set +e
set +e
pkill -P $$
pkill -P $$
if [ -f "docker-compose.yaml" ]; then
docker compose down -t 1 || :
docker compose rm -f || :
fi
if [ -f "docker-compose.yaml" ]; then
docker compose down -t 1 || :
docker compose rm -f || :
fi
}
trap cleanup EXIT SIGINT
function build_anubis_ko() {
(
cd $REPO_ROOT && npm ci && npm run assets
)
(
cd $REPO_ROOT &&
VERSION=devel ko build \
--platform=all \
--base-import-paths \
--tags="latest" \
--image-user=1000 \
--image-annotation="" \
--image-label="" \
./cmd/anubis \
--local
)
(
cd $REPO_ROOT && npm ci && npm run assets
)
(
cd $REPO_ROOT &&
VERSION=devel ko build \
--platform=all \
--base-import-paths \
--tags="latest" \
--image-user=1000 \
--image-annotation="" \
--image-label="" \
./cmd/anubis \
--local
)
}
function mint_cert() {
if [ "$#" -ne 1 ]; then
echo "Usage: mint_cert <domain.name>"
fi
if [ "$#" -ne 1 ]; then
echo "Usage: mint_cert <domain.name>"
fi
domainName="$1"
domainName="$1"
# If the transient local TLS certificate doesn't exist, mint a new one
if [ ! -f "${REPO_ROOT}/test/pki/${domainName}/cert.pem" ]; then
# Subshell to contain the directory change
(
cd ${REPO_ROOT}/test/pki &&
mkdir -p "${domainName}" &&
go tool minica -domains "${domainName}" &&
cd "${domainName}" &&
chmod 666 *
)
fi
# If the transient local TLS certificate doesn't exist, mint a new one
if [ ! -f "./pki/${domainName}/cert.pem" ]; then
# Subshell to contain the directory change
(
cd ./pki &&
mkdir -p "${domainName}" &&
go tool minica -domains "${domainName}" &&
cd "${domainName}" &&
chmod 666 *
)
fi
}

View File

@@ -0,0 +1,8 @@
# /etc/nginx/conf-anubis.inc
# Forward to anubis
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://anubis;
}

View File

@@ -0,0 +1,29 @@
# /etc/nginx/conf.d/server-mimi-techaro-lol.conf
server {
# Listen on 443 with SSL
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# Slipstream via Anubis
include "conf-anubis.inc";
server_name mimi.techaro.lol;
ssl_certificate /techaro/pki/mimi.techaro.lol/cert.pem;
ssl_certificate_key /techaro/pki/mimi.techaro.lol/key.pem;
}
server {
listen unix:/tmp/nginx.sock;
server_name mimi.techaro.lol;
port_in_redirect off;
root "/srv/http/mimi.techaro.lol";
index index.html;
# Your normal configuration can go here
# location .php { fastcgi...} etc.
}

View File

@@ -0,0 +1,17 @@
# /etc/nginx/conf.d/upstream-anubis.conf
upstream anubis {
zone anubis_zone 64k;
# 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 anubis:3000 resolve;
# 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;
}

View File

@@ -0,0 +1,99 @@
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/avif avif;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;
application/vnd.openxmlformats-officedocument.presentationml.presentation
pptx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlsx;
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/wasm wasm;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}

View File

@@ -0,0 +1,32 @@
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
resolver 169.254.42.1 valid=300s ipv6=on;
resolver_timeout 10s;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

17
test/nginx/test.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
source ../lib/lib.sh
export KO_DOCKER_REPO=ko.local
set -euo pipefail
mint_cert mimi.techaro.lol
docker run --rm \
-v $PWD/conf/nginx:/etc/nginx:ro \
-v $PWD/pki:/techaro/pki:ro \
nginx \
nginx -t
exit 0

View File

@@ -26,7 +26,7 @@ services:
KEY_FNAME: key.pem
PROXY_TO: http://anubis:3000
volumes:
- ../../pki/relayd:/techaro/pki:ro
- ./pki/relayd:/techaro/pki:ro
# novnc:
# image: geek1011/easy-novnc
@@ -42,7 +42,7 @@ services:
environment:
DISPLAY: display:0
volumes:
- ../../pki:/usr/local/share/ca-certificates/minica:ro
- ./pki:/usr/local/share/ca-certificates/minica:ro
- ../scripts:/hack/scripts:ro
depends_on:
- anubis

View File

@@ -24,7 +24,7 @@ services:
KEY_FNAME: key.pem
PROXY_TO: http://anubis:3000
volumes:
- ../../pki/relayd:/techaro/pki:ro
- ./pki/relayd:/techaro/pki:ro
# novnc:
# image: geek1011/easy-novnc
@@ -40,5 +40,5 @@ services:
environment:
DISPLAY: display:0
volumes:
- ../../pki:/usr/local/share/ca-certificates/minica:ro
- ./pki:/usr/local/share/ca-certificates/minica:ro
- ../scripts:/hack/scripts:ro

View File

@@ -0,0 +1,57 @@
package main
import (
"bufio"
"fmt"
"io"
"net/http"
"net/netip"
"strings"
)
// FetchBlocklist reads the blocklist over HTTP and returns every non-commented
// line parsed as an IP address in CIDR notation. IPv4 addresses are returned as
// /32, IPv6 addresses as /128.
//
// This function was generated with GLM 4.7.
func FetchBlocklist(url string) ([]string, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP request failed with status: %s", resp.Status)
}
var lines []string
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
// Skip empty lines and comments (lines starting with #)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
addr, err := netip.ParseAddr(line)
if err != nil {
// Skip lines that aren't valid IP addresses
continue
}
var cidr string
if addr.Is4() {
cidr = fmt.Sprintf("%s/32", addr.String())
} else {
cidr = fmt.Sprintf("%s/128", addr.String())
}
lines = append(lines, cidr)
}
if err := scanner.Err(); err != nil && err != io.EOF {
return nil, err
}
return lines, nil
}

View File

@@ -0,0 +1,103 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/TecharoHQ/anubis/lib/config"
"github.com/facebookgo/flagenv"
"sigs.k8s.io/yaml"
)
type Rule struct {
Name string `yaml:"name" json:"name"`
Action config.Rule `yaml:"action" json:"action"`
RemoteAddr []string `json:"remote_addresses,omitempty" yaml:"remote_addresses,omitempty"`
Weight *config.Weight `json:"weight,omitempty" yaml:"weight,omitempty"`
}
func init() {
flag.Usage = func() {
fmt.Printf(`Usage of %[1]s:
%[1]s [flags] <blocklist-url> <filename>
Grabs the contents of the blocklist, converts it to an Anubis ruleset, and writes it to filename.
Flags:
`, filepath.Base(os.Args[0]))
flag.PrintDefaults()
}
}
var (
action = flag.String("action", "DENY", "Anubis action to take (ALLOW / DENY / WEIGH)")
manualRuleName = flag.String("rule-name", "", "If set, prefer this name over inferring from filename")
weight = flag.Int("weight", 0, "If set to any number, add/subtract this many weight points when --action=WEIGH")
)
func main() {
flagenv.Parse()
flag.Parse()
if flag.NArg() != 2 {
flag.Usage()
os.Exit(2)
}
blocklistURL := flag.Arg(0)
foutName := flag.Arg(1)
ruleName := strings.TrimSuffix(foutName, filepath.Ext(foutName))
if *manualRuleName != "" {
ruleName = *manualRuleName
}
ruleAction := config.Rule(*action)
if err := ruleAction.Valid(); err != nil {
log.Fatalf("--action=%q is invalid: %v", *action, err)
}
result := &Rule{
Name: ruleName,
Action: ruleAction,
}
if *weight != 0 {
if ruleAction != config.RuleWeigh {
log.Fatalf("used --weight=%d but --action=%s", *weight, *action)
}
result.Weight = &config.Weight{
Adjust: *weight,
}
}
ips, err := FetchBlocklist(blocklistURL)
if err != nil {
log.Fatalf("can't fetch blocklist %s: %v", blocklistURL, err)
}
result.RemoteAddr = ips
fout, err := os.Create(foutName)
if err != nil {
log.Fatalf("can't create output file %q: %v", foutName, err)
}
defer fout.Close()
fmt.Fprintf(fout, "# Generated by %s on %s from %s\n\n", filepath.Base(os.Args[0]), time.Now().Format(time.RFC3339), blocklistURL)
data, err := yaml.Marshal([]*Rule{result})
if err != nil {
log.Fatalf("can't marshal yaml")
}
fout.Write(data)
}