mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-11 02:58:49 +00:00
Compare commits
8 Commits
Xe/thoth
...
v1.19.0-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa1f2355ea | ||
|
|
0a56194825 | ||
|
|
93e2447ba2 | ||
|
|
51f875ff6f | ||
|
|
555a188dc3 | ||
|
|
6f08bcb481 | ||
|
|
11081aac08 | ||
|
|
c78d830ecb |
3
.github/actions/spelling/expect.txt
vendored
3
.github/actions/spelling/expect.txt
vendored
@@ -178,6 +178,7 @@ selfsigned
|
|||||||
setsebool
|
setsebool
|
||||||
sitemap
|
sitemap
|
||||||
sls
|
sls
|
||||||
|
sni
|
||||||
Sourceware
|
Sourceware
|
||||||
Spambot
|
Spambot
|
||||||
sparkline
|
sparkline
|
||||||
@@ -210,7 +211,7 @@ webmaster
|
|||||||
webpage
|
webpage
|
||||||
websecure
|
websecure
|
||||||
websites
|
websites
|
||||||
workaround
|
Workaround
|
||||||
workdir
|
workdir
|
||||||
xcaddy
|
xcaddy
|
||||||
Xeact
|
Xeact
|
||||||
|
|||||||
@@ -20,9 +20,6 @@
|
|||||||
# https://twitter.com/nyttypos/status/1898844061873639490
|
# https://twitter.com/nyttypos/status/1898844061873639490
|
||||||
#\([A-Z][a-z]{2,}(?: [a-z]+){3,}\)\.\s
|
#\([A-Z][a-z]{2,}(?: [a-z]+){3,}\)\.\s
|
||||||
|
|
||||||
# Complete sentences shouldn't be in the middle of another sentence as a parenthetical.
|
|
||||||
(?<!\.)\.\),
|
|
||||||
|
|
||||||
# Complete sentences in parentheticals should not have a space before the period.
|
# Complete sentences in parentheticals should not have a space before the period.
|
||||||
\s\.\)(?!.*\}\})
|
\s\.\)(?!.*\}\})
|
||||||
|
|
||||||
|
|||||||
4
.github/actions/spelling/patterns.txt
vendored
4
.github/actions/spelling/patterns.txt
vendored
@@ -128,3 +128,7 @@ go install(?:\s+[a-z]+\.[-@\w/.]+)+
|
|||||||
|
|
||||||
# ignore long runs of a single character:
|
# ignore long runs of a single character:
|
||||||
\b([A-Za-z])\g{-1}{3,}\b
|
\b([A-Za-z])\g{-1}{3,}\b
|
||||||
|
|
||||||
|
# hit-count: 1 file-count: 1
|
||||||
|
# microsoft
|
||||||
|
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]*
|
||||||
@@ -56,6 +56,7 @@ var (
|
|||||||
redirectDomains = flag.String("redirect-domains", "", "list of domains separated by commas which anubis is allowed to redirect to. Leaving this unset allows any domain.")
|
redirectDomains = flag.String("redirect-domains", "", "list of domains separated by commas which anubis is allowed to redirect to. Leaving this unset allows any domain.")
|
||||||
slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)")
|
slogLevel = flag.String("slog-level", "INFO", "logging level (see https://pkg.go.dev/log/slog#hdr-Levels)")
|
||||||
target = flag.String("target", "http://localhost:3923", "target to reverse proxy to, set to an empty string to disable proxying when only using auth request")
|
target = flag.String("target", "http://localhost:3923", "target to reverse proxy to, set to an empty string to disable proxying when only using auth request")
|
||||||
|
targetSNI = flag.String("target-sni", "", "if set, the value of the TLS handshake hostname when forwarding requests to the target")
|
||||||
targetHost = flag.String("target-host", "", "if set, the value of the Host header when forwarding requests to the target")
|
targetHost = flag.String("target-host", "", "if set, the value of the Host header when forwarding requests to the target")
|
||||||
targetInsecureSkipVerify = flag.Bool("target-insecure-skip-verify", false, "if true, skips TLS validation for the backend")
|
targetInsecureSkipVerify = flag.Bool("target-insecure-skip-verify", false, "if true, skips TLS validation for the backend")
|
||||||
healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis")
|
healthcheck = flag.Bool("healthcheck", false, "run a health check against Anubis")
|
||||||
@@ -136,7 +137,7 @@ func setupListener(network string, address string) (net.Listener, string) {
|
|||||||
return listener, formattedAddress
|
return listener, formattedAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeReverseProxy(target string, targetHost string, insecureSkipVerify bool) (http.Handler, error) {
|
func makeReverseProxy(target string, targetSNI string, targetHost string, insecureSkipVerify bool) (http.Handler, error) {
|
||||||
targetUri, err := url.Parse(target)
|
targetUri, err := url.Parse(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse target URL: %w", err)
|
return nil, fmt.Errorf("failed to parse target URL: %w", err)
|
||||||
@@ -158,10 +159,14 @@ func makeReverseProxy(target string, targetHost string, insecureSkipVerify bool)
|
|||||||
transport.RegisterProtocol("unix", libanubis.UnixRoundTripper{Transport: transport})
|
transport.RegisterProtocol("unix", libanubis.UnixRoundTripper{Transport: transport})
|
||||||
}
|
}
|
||||||
|
|
||||||
if insecureSkipVerify {
|
if insecureSkipVerify || targetSNI != "" {
|
||||||
slog.Warn("TARGET_INSECURE_SKIP_VERIFY is set to true, TLS certificate validation will not be performed", "target", target)
|
transport.TLSClientConfig = &tls.Config{}
|
||||||
transport.TLSClientConfig = &tls.Config{
|
if insecureSkipVerify {
|
||||||
InsecureSkipVerify: true,
|
slog.Warn("TARGET_INSECURE_SKIP_VERIFY is set to true, TLS certificate validation will not be performed", "target", target)
|
||||||
|
transport.TLSClientConfig.InsecureSkipVerify = true
|
||||||
|
}
|
||||||
|
if targetSNI != "" {
|
||||||
|
transport.TLSClientConfig.ServerName = targetSNI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +219,7 @@ func main() {
|
|||||||
// when using anubis via Systemd and environment variables, then it is not possible to set targe to an empty string but only to space
|
// when using anubis via Systemd and environment variables, then it is not possible to set targe to an empty string but only to space
|
||||||
if strings.TrimSpace(*target) != "" {
|
if strings.TrimSpace(*target) != "" {
|
||||||
var err error
|
var err error
|
||||||
rp, err = makeReverseProxy(*target, *targetHost, *targetInsecureSkipVerify)
|
rp, err = makeReverseProxy(*target, *targetSNI, *targetHost, *targetInsecureSkipVerify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't make reverse proxy: %v", err)
|
log.Fatalf("can't make reverse proxy: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- name: "ai-robots-txt"
|
- name: "ai-robots-txt"
|
||||||
user_agent_regex: >-
|
user_agent_regex: >-
|
||||||
AI2Bot|Ai2Bot-Dolma|aiHitBot|Amazonbot|anthropic-ai|Applebot|Applebot-Extended|Brightbot 1.0|Bytespider|CCBot|ChatGPT-User|Claude-Web|ClaudeBot|cohere-ai|cohere-training-data-crawler|Cotoyogi|Crawlspace|Diffbot|DuckAssistBot|FacebookBot|Factset_spyderbot|FirecrawlAgent|FriendlyCrawler|Google-Extended|GoogleOther|GoogleOther-Image|GoogleOther-Video|GPTBot|iaskspider/2.0|ICC-Crawler|ImagesiftBot|img2dataset|imgproxy|ISSCyberRiskCrawler|Kangaroo Bot|meta-externalagent|Meta-ExternalAgent|meta-externalfetcher|Meta-ExternalFetcher|NovaAct|OAI-SearchBot|omgili|omgilibot|Operator|PanguBot|Perplexity-User|PerplexityBot|PetalBot|QualifiedBot|Scrapy|SemrushBot-OCOB|SemrushBot-SWA|Sidetrade indexer bot|TikTokSpider|Timpibot|VelenPublicWebCrawler|Webzio-Extended|YouBot
|
AI2Bot|Ai2Bot-Dolma|aiHitBot|Amazonbot|anthropic-ai|Applebot|Applebot-Extended|Brightbot 1.0|Bytespider|CCBot|ChatGPT-User|Claude-SearchBot|Claude-User|Claude-Web|ClaudeBot|cohere-ai|cohere-training-data-crawler|Cotoyogi|Crawlspace|Diffbot|DuckAssistBot|FacebookBot|Factset_spyderbot|FirecrawlAgent|FriendlyCrawler|Google-CloudVertexBot|Google-Extended|GoogleOther|GoogleOther-Image|GoogleOther-Video|GPTBot|iaskspider/2.0|ICC-Crawler|ImagesiftBot|img2dataset|imgproxy|ISSCyberRiskCrawler|Kangaroo Bot|meta-externalagent|Meta-ExternalAgent|meta-externalfetcher|Meta-ExternalFetcher|MistralAI-User/1.0|NovaAct|OAI-SearchBot|omgili|omgilibot|Operator|PanguBot|Perplexity-User|PerplexityBot|PetalBot|QualifiedBot|Scrapy|SemrushBot-OCOB|SemrushBot-SWA|Sidetrade indexer bot|TikTokSpider|Timpibot|VelenPublicWebCrawler|Webzio-Extended|wpbot|YouBot
|
||||||
action: DENY
|
action: DENY
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## v1.19.0: Jenomis cen Lexentale
|
||||||
|
|
||||||
|
- Record if challenges were issued via the API or via embedded JSON in the challenge page HTML ([#531](https://github.com/TecharoHQ/anubis/issues/531))
|
||||||
- Ensure that clients that are shown a challenge support storing cookies
|
- Ensure that clients that are shown a challenge support storing cookies
|
||||||
- Encode challenge pages with gzip level 1
|
- Encode challenge pages with gzip level 1
|
||||||
- Add `check-spelling` for spell checking
|
- Add `check-spelling` for spell checking
|
||||||
@@ -22,11 +25,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Ensure cookie renaming is consistent across configuration options
|
- Ensure cookie renaming is consistent across configuration options
|
||||||
- Add Bookstack app in data
|
- Add Bookstack app in data
|
||||||
- Add `--target-host` flag/envvar to allow changing the value of the Host header in requests forwarded to the target service.
|
- Add `--target-host` flag/envvar to allow changing the value of the Host header in requests forwarded to the target service.
|
||||||
- Bump AI-robots.txt to version 1.30 (add QualifiedBot)
|
- Bump AI-robots.txt to version 1.31
|
||||||
- Add `RuntimeDirectory` to systemd unit settings so native packages can listen over unix sockets
|
- Add `RuntimeDirectory` to systemd unit settings so native packages can listen over unix sockets
|
||||||
- Added SearXNG instance tracker whitelist policy
|
- Added SearXNG instance tracker whitelist policy
|
||||||
- Added Qualys SSL Labs whitelist policy
|
- Added Qualys SSL Labs whitelist policy
|
||||||
- Fixed cookie deletion logic ([#520](https://github.com/TecharoHQ/anubis/issues/520), [#522](https://github.com/TecharoHQ/anubis/pull/522))
|
- Fixed cookie deletion logic ([#520](https://github.com/TecharoHQ/anubis/issues/520), [#522](https://github.com/TecharoHQ/anubis/pull/522))
|
||||||
|
- Add `--target-sni` flag/envvar to allow changing the value of the TLS handshake hostname in requests forwarded to the target service.
|
||||||
|
- Fixed CEL expression matching validator to now properly error out when it receives empty expressions
|
||||||
|
|
||||||
## v1.18.0: Varis zos Galvus
|
## v1.18.0: Varis zos Galvus
|
||||||
|
|
||||||
|
|||||||
39
docs/docs/admin/frameworks/wordpress.mdx
Normal file
39
docs/docs/admin/frameworks/wordpress.mdx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Wordpress
|
||||||
|
|
||||||
|
Wordpress is the most popular blog engine on the planet.
|
||||||
|
|
||||||
|
## Using a multi-site setup with Anubis
|
||||||
|
|
||||||
|
If you have a multi-site setup where traffic goes through Anubis like this:
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
Wordpress may not realize that the underlying connection is being done over HTTPS. This could lead to a redirect loop in the `/wp-admin/` routes. In order to fix this, add the following to your `wp-config.php` file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
||||||
|
$_SERVER['HTTPS'] = 'on';
|
||||||
|
$_SERVER['SERVER_PORT'] = 443;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will make Wordpress think that your connection is over HTTPS instead of plain HTTP.
|
||||||
@@ -84,6 +84,7 @@ If you don't know or understand what these settings mean, ignore them. These are
|
|||||||
|
|
||||||
| Environment Variable | Default value | Explanation |
|
| Environment Variable | Default value | Explanation |
|
||||||
| :---------------------------- | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| :---------------------------- | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `TARGET_SNI` | unset | If set, overrides the TLS handshake hostname in requests forwarded to `TARGET`. |
|
||||||
| `TARGET_HOST` | unset | If set, overrides the Host header in requests forwarded to `TARGET`. |
|
| `TARGET_HOST` | unset | If set, overrides the Host header in requests forwarded to `TARGET`. |
|
||||||
| `TARGET_INSECURE_SKIP_VERIFY` | `false` | If `true`, skip TLS certificate validation for targets that listen over `https`. If your backend does not listen over `https`, ignore this setting. |
|
| `TARGET_INSECURE_SKIP_VERIFY` | `false` | If `true`, skip TLS certificate validation for targets that listen over `https`. If your backend does not listen over `https`, ignore this setting. |
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ sudo install -D ./run/anubis@.service /etc/systemd/system
|
|||||||
Install the default configuration file to your system:
|
Install the default configuration file to your system:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
sudo install -D ./run/default.env /etc/anubis
|
sudo install -D ./run/default.env /etc/anubis/default.env
|
||||||
```
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@@ -77,6 +77,13 @@ Install Anubis with `rpm`:
|
|||||||
sudo rpm -ivh ./anubis-$VERSION.$ARCH.rpm
|
sudo rpm -ivh ./anubis-$VERSION.$ARCH.rpm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="distro" label="Package managers">
|
||||||
|
|
||||||
|
Some Linux distributions offer Anubis [as a native package](https://repology.org/project/anubis-anti-crawler/versions). If you want to install Anubis from your distribution's package manager, consult any upstream documentation for how to install the package. It will either be named `anubis`, `www-apps/anubis` or `www/anubis`.
|
||||||
|
|
||||||
|
If you use a systemd-flavoured distribution, then follow the setup instructions for Debian or Red Hat Linux.
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
challengesIssued = promauto.NewCounter(prometheus.CounterOpts{
|
challengesIssued = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||||
Name: "anubis_challenges_issued",
|
Name: "anubis_challenges_issued",
|
||||||
Help: "The total number of challenges issued",
|
Help: "The total number of challenges issued",
|
||||||
})
|
}, []string{"method"})
|
||||||
|
|
||||||
challengesValidated = promauto.NewCounter(prometheus.CounterOpts{
|
challengesValidated = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
Name: "anubis_challenges_validated",
|
Name: "anubis_challenges_validated",
|
||||||
@@ -260,7 +260,7 @@ func (s *Server) MakeChallenge(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
lg.Debug("made challenge", "challenge", challenge, "rules", rule.Challenge, "cr", cr)
|
lg.Debug("made challenge", "challenge", challenge, "rules", rule.Challenge, "cr", cr)
|
||||||
challengesIssued.Inc()
|
challengesIssued.WithLabelValues("api").Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, rule *polic
|
|||||||
s.respondWithError(w, r, "Client Error: Please ensure your browser is up to date and try again later.")
|
s.respondWithError(w, r, "Client Error: Please ensure your browser is up to date and try again later.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
challengesIssued.WithLabelValues("embedded").Add(1)
|
||||||
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
|
||||||
|
|
||||||
var ogTags map[string]string = nil
|
var ogTags map[string]string = nil
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ func (is *ImportStatement) open() (fs.File, error) {
|
|||||||
func (is *ImportStatement) load() error {
|
func (is *ImportStatement) load() error {
|
||||||
fin, err := is.open()
|
fin, err := is.open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't open %s: %w", is.Import, err)
|
return fmt.Errorf("%w: %s: %w", ErrInvalidImportStatement, is.Import, err)
|
||||||
}
|
}
|
||||||
defer fin.Close()
|
defer fin.Close()
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ func (eol *ExpressionOrList) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (eol *ExpressionOrList) Valid() error {
|
func (eol *ExpressionOrList) Valid() error {
|
||||||
|
if eol.Expression == "" && len(eol.All) == 0 && len(eol.Any) == 0 {
|
||||||
|
return ErrExpressionEmpty
|
||||||
|
}
|
||||||
if len(eol.All) != 0 && len(eol.Any) != 0 {
|
if len(eol.All) != 0 && len(eol.Any) != 0 {
|
||||||
return ErrExpressionCantHaveBoth
|
return ErrExpressionCantHaveBoth
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ func TestExpressionOrListUnmarshal(t *testing.T) {
|
|||||||
}`,
|
}`,
|
||||||
validErr: ErrExpressionCantHaveBoth,
|
validErr: ErrExpressionCantHaveBoth,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "expression-empty",
|
||||||
|
inp: `{
|
||||||
|
"any": []
|
||||||
|
}`,
|
||||||
|
validErr: ErrExpressionEmpty,
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var eol ExpressionOrList
|
var eol ExpressionOrList
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@techaro/anubis",
|
"name": "@techaro/anubis",
|
||||||
"version": "1.18.0",
|
"version": "1.19.0-pre1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@techaro/anubis",
|
"name": "@techaro/anubis",
|
||||||
"version": "1.18.0",
|
"version": "1.19.0-pre1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cssnano": "^7.0.7",
|
"cssnano": "^7.0.7",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@techaro/anubis",
|
"name": "@techaro/anubis",
|
||||||
"version": "1.18.0",
|
"version": "1.19.0-pre1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ User-agent: Brightbot 1.0
|
|||||||
User-agent: Bytespider
|
User-agent: Bytespider
|
||||||
User-agent: CCBot
|
User-agent: CCBot
|
||||||
User-agent: ChatGPT-User
|
User-agent: ChatGPT-User
|
||||||
|
User-agent: Claude-SearchBot
|
||||||
|
User-agent: Claude-User
|
||||||
User-agent: Claude-Web
|
User-agent: Claude-Web
|
||||||
User-agent: ClaudeBot
|
User-agent: ClaudeBot
|
||||||
User-agent: cohere-ai
|
User-agent: cohere-ai
|
||||||
@@ -21,6 +23,7 @@ User-agent: FacebookBot
|
|||||||
User-agent: Factset_spyderbot
|
User-agent: Factset_spyderbot
|
||||||
User-agent: FirecrawlAgent
|
User-agent: FirecrawlAgent
|
||||||
User-agent: FriendlyCrawler
|
User-agent: FriendlyCrawler
|
||||||
|
User-agent: Google-CloudVertexBot
|
||||||
User-agent: Google-Extended
|
User-agent: Google-Extended
|
||||||
User-agent: GoogleOther
|
User-agent: GoogleOther
|
||||||
User-agent: GoogleOther-Image
|
User-agent: GoogleOther-Image
|
||||||
@@ -37,6 +40,7 @@ User-agent: meta-externalagent
|
|||||||
User-agent: Meta-ExternalAgent
|
User-agent: Meta-ExternalAgent
|
||||||
User-agent: meta-externalfetcher
|
User-agent: meta-externalfetcher
|
||||||
User-agent: Meta-ExternalFetcher
|
User-agent: Meta-ExternalFetcher
|
||||||
|
User-agent: MistralAI-User/1.0
|
||||||
User-agent: NovaAct
|
User-agent: NovaAct
|
||||||
User-agent: OAI-SearchBot
|
User-agent: OAI-SearchBot
|
||||||
User-agent: omgili
|
User-agent: omgili
|
||||||
@@ -55,6 +59,7 @@ User-agent: TikTokSpider
|
|||||||
User-agent: Timpibot
|
User-agent: Timpibot
|
||||||
User-agent: VelenPublicWebCrawler
|
User-agent: VelenPublicWebCrawler
|
||||||
User-agent: Webzio-Extended
|
User-agent: Webzio-Extended
|
||||||
|
User-agent: wpbot
|
||||||
User-agent: YouBot
|
User-agent: YouBot
|
||||||
Disallow: /
|
Disallow: /
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user