mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-09 18:18:49 +00:00
Compare commits
4 Commits
Xe/fix-pre
...
json/add-b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
978af9d5ff | ||
|
|
57c0b2b22c | ||
|
|
186ffeb744 | ||
|
|
ff87aac4e7 |
1
.github/actions/spelling/allow.txt
vendored
1
.github/actions/spelling/allow.txt
vendored
@@ -23,3 +23,4 @@ fout
|
|||||||
iplist
|
iplist
|
||||||
NArg
|
NArg
|
||||||
blocklists
|
blocklists
|
||||||
|
rififi
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
# - Claude-User: No published IP allowlist
|
# - Claude-User: No published IP allowlist
|
||||||
- name: "ai-clients"
|
- name: "ai-clients"
|
||||||
user_agent_regex: >-
|
user_agent_regex: >-
|
||||||
ChatGPT-User|Claude-User|MistralAI-User
|
ChatGPT-User|Claude-User|MistralAI-User|Perplexity-User
|
||||||
action: DENY
|
action: DENY
|
||||||
|
|||||||
12
data/clients/perplexity-user.yaml
Normal file
12
data/clients/perplexity-user.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Acts on behalf of user requests
|
||||||
|
# https://docs.perplexity.ai/guides/bots
|
||||||
|
- name: perplexity-user
|
||||||
|
user_agent_regex: Perplexity-User/.+; \+https\://perplexity\.ai/perplexity-user
|
||||||
|
action: ALLOW
|
||||||
|
# https://www.perplexity.com/perplexity-user.json
|
||||||
|
remote_addresses: [
|
||||||
|
"44.208.221.197/32",
|
||||||
|
"34.193.163.52/32",
|
||||||
|
"18.97.21.0/30",
|
||||||
|
"18.97.43.80/29",
|
||||||
|
]
|
||||||
@@ -4,5 +4,5 @@
|
|||||||
# - Claude-SearchBot: No published IP allowlist
|
# - Claude-SearchBot: No published IP allowlist
|
||||||
- name: "ai-crawlers-search"
|
- name: "ai-crawlers-search"
|
||||||
user_agent_regex: >-
|
user_agent_regex: >-
|
||||||
OAI-SearchBot|Claude-SearchBot
|
OAI-SearchBot|Claude-SearchBot|PerplexityBot
|
||||||
action: DENY
|
action: DENY
|
||||||
|
|||||||
16
data/crawlers/perplexitybot.yaml
Normal file
16
data/crawlers/perplexitybot.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Indexing for search, does not collect training data
|
||||||
|
# https://docs.perplexity.ai/guides/bots
|
||||||
|
- name: perplexitybot
|
||||||
|
user_agent_regex: PerplexityBot/.+; \+https\://perplexity\.ai/perplexitybot
|
||||||
|
action: ALLOW
|
||||||
|
# https://www.perplexity.com/perplexitybot.json
|
||||||
|
remote_addresses: [
|
||||||
|
"107.20.236.150/32",
|
||||||
|
"3.224.62.45/32",
|
||||||
|
"18.210.92.235/32",
|
||||||
|
"3.222.232.239/32",
|
||||||
|
"3.211.124.183/32",
|
||||||
|
"3.231.139.107/32",
|
||||||
|
"18.97.1.228/30",
|
||||||
|
"18.97.9.96/29",
|
||||||
|
]
|
||||||
@@ -3,5 +3,7 @@
|
|||||||
- import: (data)/bots/ai-catchall.yaml
|
- import: (data)/bots/ai-catchall.yaml
|
||||||
- import: (data)/crawlers/ai-training.yaml
|
- import: (data)/crawlers/ai-training.yaml
|
||||||
- import: (data)/crawlers/openai-searchbot.yaml
|
- import: (data)/crawlers/openai-searchbot.yaml
|
||||||
|
- import: (data)/crawlers/perplexitybot.yaml
|
||||||
- import: (data)/clients/openai-chatgpt-user.yaml
|
- import: (data)/clients/openai-chatgpt-user.yaml
|
||||||
- import: (data)/clients/mistral-mistralai-user.yaml
|
- import: (data)/clients/mistral-mistralai-user.yaml
|
||||||
|
- import: (data)/clients/perplexity-user.yaml
|
||||||
|
|||||||
@@ -2,5 +2,7 @@
|
|||||||
- import: (data)/bots/ai-catchall.yaml
|
- import: (data)/bots/ai-catchall.yaml
|
||||||
- import: (data)/crawlers/openai-searchbot.yaml
|
- import: (data)/crawlers/openai-searchbot.yaml
|
||||||
- import: (data)/crawlers/openai-gptbot.yaml
|
- import: (data)/crawlers/openai-gptbot.yaml
|
||||||
|
- import: (data)/crawlers/perplexitybot.yaml
|
||||||
- import: (data)/clients/openai-chatgpt-user.yaml
|
- import: (data)/clients/openai-chatgpt-user.yaml
|
||||||
- import: (data)/clients/mistral-mistralai-user.yaml
|
- import: (data)/clients/mistral-mistralai-user.yaml
|
||||||
|
- import: (data)/clients/perplexity-user.yaml
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Add iplist2rule tool that lets admins turn an IP address blocklist into an Anubis ruleset.
|
- 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))
|
- Add Polish locale ([#1292](https://github.com/TecharoHQ/anubis/pull/1309))
|
||||||
|
- Fix honeypot and imprint links missing `BASE_PREFIX` when deployed behind a path prefix ([#1402](https://github.com/TecharoHQ/anubis/issues/1402))
|
||||||
|
|
||||||
<!-- This changes the project to: -->
|
<!-- This changes the project to: -->
|
||||||
|
|
||||||
|
|||||||
@@ -51,9 +51,8 @@ If you are using Kubernetes, you will need to create an image pull secret:
|
|||||||
kubectl create secret docker-registry \
|
kubectl create secret docker-registry \
|
||||||
techarohq-botstopper \
|
techarohq-botstopper \
|
||||||
--docker-server ghcr.io \
|
--docker-server ghcr.io \
|
||||||
--docker-username your-username \
|
--docker-username any-username \
|
||||||
--docker-password your-access-token \
|
--docker-password <your-access-token> \
|
||||||
--docker-email your@email.address
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then attach it to your Deployment:
|
Then attach it to your Deployment:
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import "time"
|
|||||||
|
|
||||||
// Challenge is the metadata about a single challenge issuance.
|
// Challenge is the metadata about a single challenge issuance.
|
||||||
type Challenge struct {
|
type Challenge struct {
|
||||||
IssuedAt time.Time `json:"issuedAt"`
|
IssuedAt time.Time `json:"issuedAt"` // When the challenge was issued
|
||||||
Metadata map[string]string `json:"metadata"`
|
Metadata map[string]string `json:"metadata"` // Challenge metadata such as IP address and user agent
|
||||||
ID string `json:"id"`
|
ID string `json:"id"` // UUID identifying the challenge
|
||||||
Method string `json:"method"`
|
Method string `json:"method"` // Challenge method
|
||||||
RandomData string `json:"randomData"`
|
RandomData string `json:"randomData"` // The random data the client processes
|
||||||
PolicyRuleHash string `json:"policyRuleHash,omitempty"`
|
PolicyRuleHash string `json:"policyRuleHash,omitempty"` // Hash of the policy rule that issued this challenge
|
||||||
Difficulty int `json:"difficulty,omitempty"`
|
Difficulty int `json:"difficulty,omitempty"` // Difficulty that was in effect when issued
|
||||||
Spent bool `json:"spent"`
|
Spent bool `json:"spent"` // Has the challenge already been solved?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ templ base(title string, body templ.Component, impressum *config.Impressum, chal
|
|||||||
@templ.JSONScript("anubis_public_url", anubis.PublicUrl)
|
@templ.JSONScript("anubis_public_url", anubis.PublicUrl)
|
||||||
</head>
|
</head>
|
||||||
<body id="top">
|
<body id="top">
|
||||||
@honeypotLink(fmt.Sprintf("%shoneypot/%s/init", anubis.APIPrefix, uuid.NewString()))
|
@honeypotLink(anubis.BasePrefix + fmt.Sprintf("%shoneypot/%s/init", anubis.APIPrefix, uuid.NewString()))
|
||||||
<main>
|
<main>
|
||||||
<h1 id="title" class="centered-div">{ title }</h1>
|
<h1 id="title" class="centered-div">{ title }</h1>
|
||||||
@body
|
@body
|
||||||
@@ -79,7 +79,7 @@ templ base(title string, body templ.Component, impressum *config.Impressum, chal
|
|||||||
if impressum != nil {
|
if impressum != nil {
|
||||||
<p>
|
<p>
|
||||||
@templ.Raw(impressum.Footer)
|
@templ.Raw(impressum.Footer)
|
||||||
-- <a href={ templ.SafeURL(fmt.Sprintf("%simprint", anubis.APIPrefix)) }>Imprint</a>
|
-- <a href={ templ.SafeURL(anubis.BasePrefix + fmt.Sprintf("%simprint", anubis.APIPrefix)) }>Imprint</a>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
<p>{ localizer.T("version_info") } <code>{ anubis.Version }</code>.</p>
|
<p>{ localizer.T("version_info") } <code>{ anubis.Version }</code>.</p>
|
||||||
|
|||||||
6
web/index_templ.go
generated
6
web/index_templ.go
generated
@@ -137,7 +137,7 @@ func base(title string, body templ.Component, impressum *config.Impressum, chall
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = honeypotLink(fmt.Sprintf("%shoneypot/%s/init", anubis.APIPrefix, uuid.NewString())).Render(ctx, templ_7745c5c3_Buffer)
|
templ_7745c5c3_Err = honeypotLink(anubis.BasePrefix+fmt.Sprintf("%shoneypot/%s/init", anubis.APIPrefix, uuid.NewString())).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@@ -245,9 +245,9 @@ func base(title string, body templ.Component, impressum *config.Impressum, chall
|
|||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var13 templ.SafeURL
|
var templ_7745c5c3_Var13 templ.SafeURL
|
||||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("%simprint", anubis.APIPrefix)))
|
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(anubis.BasePrefix + fmt.Sprintf("%simprint", anubis.APIPrefix)))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 82, Col: 78}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 82, Col: 98}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
|
|||||||
81
web/index_test.go
Normal file
81
web/index_test.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/TecharoHQ/anubis"
|
||||||
|
"github.com/TecharoHQ/anubis/lib/config"
|
||||||
|
"github.com/TecharoHQ/anubis/lib/localization"
|
||||||
|
"github.com/a-h/templ"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBasePrefixInLinks(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
basePrefix string
|
||||||
|
wantInLink string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no prefix",
|
||||||
|
basePrefix: "",
|
||||||
|
wantInLink: "/.within.website/x/cmd/anubis/api/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with rififi prefix",
|
||||||
|
basePrefix: "/rififi",
|
||||||
|
wantInLink: "/rififi/.within.website/x/cmd/anubis/api/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with myapp prefix",
|
||||||
|
basePrefix: "/myapp",
|
||||||
|
wantInLink: "/myapp/.within.website/x/cmd/anubis/api/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// Save original BasePrefix and restore after test
|
||||||
|
origPrefix := anubis.BasePrefix
|
||||||
|
defer func() { anubis.BasePrefix = origPrefix }()
|
||||||
|
|
||||||
|
anubis.BasePrefix = tt.basePrefix
|
||||||
|
|
||||||
|
// Create test impressum
|
||||||
|
impressum := &config.Impressum{
|
||||||
|
Footer: "<p>Test footer</p>",
|
||||||
|
Page: config.ImpressumPage{
|
||||||
|
Title: "Test Imprint",
|
||||||
|
Body: "<p>Test imprint body</p>",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create localizer using a dummy request
|
||||||
|
req := httptest.NewRequest("GET", "/", nil)
|
||||||
|
localizer := &localization.SimpleLocalizer{}
|
||||||
|
localizer.Localizer = localization.NewLocalizationService().GetLocalizerFromRequest(req)
|
||||||
|
|
||||||
|
// Render the base template to a buffer
|
||||||
|
var buf strings.Builder
|
||||||
|
component := base(tt.name, templ.NopComponent, impressum, nil, nil, localizer)
|
||||||
|
err := component.Render(context.Background(), &buf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to render template: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
|
||||||
|
// Check that honeypot link includes the base prefix
|
||||||
|
if !strings.Contains(output, `href="`+tt.wantInLink+`honeypot/`) {
|
||||||
|
t.Errorf("honeypot link does not contain base prefix %q\noutput: %s", tt.wantInLink, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that imprint link includes the base prefix
|
||||||
|
if !strings.Contains(output, `href="`+tt.wantInLink+`imprint`) {
|
||||||
|
t.Errorf("imprint link does not contain base prefix %q\noutput: %s", tt.wantInLink, output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user