135 lines
4.7 KiB
Markdown
135 lines
4.7 KiB
Markdown
# go-away
|
|
|
|
Self-hosted abuse detection and rule enforcement against low-effort mass AI scraping and bots.
|
|
|
|
[](https://ci.gammaspectra.live/git/go-away)
|
|
[](https://pkg.go.dev/git.gammaspectra.live/git/go-away)
|
|
|
|
This documentation is a work in progress. For now, see policy examples under [examples/](examples/).
|
|
|
|
## Setup
|
|
|
|
It is recommended to have another reverse proxy above (for example [Caddy](https://caddyserver.com/), nginx, HAProxy) to handle HTTPs or similar.
|
|
|
|
go-away for now only accepts plaintext connections, although it can take _HTTP/2_ / _h2c_ connections if desired over the same port.
|
|
|
|
### Binary / Go
|
|
|
|
Requires Go 1.22+. Builds statically without CGo
|
|
|
|
```shell
|
|
git clone https://git.gammaspectra.live/git/go-away.git && cd go-away
|
|
|
|
CGO_ENABLED=0 go build -pgo=auto -v -trimpath -o ./go-away ./cmd/go-away
|
|
|
|
# Run on port 8080, forwarding matching requests on git.example.com to http://forgejo:3000
|
|
./go-away --bind :8080 \
|
|
--backend git.example.com=http://forgejo:3000 \
|
|
--policy examples/forgejo.yml \
|
|
--challenge-template forgejo --challenge-template-theme forgejo-dark
|
|
|
|
```
|
|
|
|
### Dockerfile
|
|
|
|
Available under [Dockerfile](Dockerfile). See the _docker compose_ below for the environment variables.
|
|
|
|
### docker compose
|
|
|
|
```yaml
|
|
services:
|
|
go-away:
|
|
image: git.gammaspectra.live/git/go-away:latest
|
|
restart: always
|
|
ports:
|
|
- "3000:8080"
|
|
networks:
|
|
- forgejo
|
|
depends_on:
|
|
- forgejo
|
|
volumes:
|
|
- "./examples/forgejo.yml:/policy.yml:ro"
|
|
environment:
|
|
#GOAWAY_BIND: ":8080"
|
|
#GOAWAY_BIND_NETWORK: "tcp"
|
|
#GOAWAY_SOCKET_MODE: "0770"
|
|
|
|
# default is WARN, set to INFO to also see challenge successes and others
|
|
#GOAWAY_SLOG_LEVEL: "INFO"
|
|
|
|
# this value is used to sign cookies and challenges. by default a new one is generated each time
|
|
# set to generate to create one, then set the same value across all your instances
|
|
#GOAWAY_JWT_PRIVATE_KEY_SEED: ""
|
|
|
|
# HTTP header that the client ip will be fetched from
|
|
# Defaults to the connection ip itself, if set here make sure your upstream proxy sets this properly
|
|
# Usually X-Forwarded-For is a good pick
|
|
GOAWAY_CLIENT_IP_HEADER: "X-Real-Ip"
|
|
|
|
GOAWAY_POLICY: "/policy.yml"
|
|
|
|
# Template, and theme for the template to pick. defaults to an anubis-like one
|
|
# An file path can be specified. See embed/templates for a few examples
|
|
GOAWAY_CHALLENGE_TEMPLATE: forgejo
|
|
GOAWAY_CHALLENGE_TEMPLATE_THEME: forgejo-dark
|
|
|
|
# specify a DNSBL for usage in conditions. Defaults to DroneBL
|
|
# GOAWAY_DNSBL: "dnsbl.dronebl.org"
|
|
|
|
GOAWAY_BACKEND: "git.example.com=http://forgejo:3000"
|
|
|
|
# additional backends can be specified via more command arguments
|
|
# command: ["--backend", "ci.example.com=http://ci:3000"]
|
|
|
|
```
|
|
|
|
|
|
## Example policies
|
|
|
|
### Forgejo
|
|
|
|
The policy file at [examples/forgejo.yml](examples/forgejo.yml) provides a ready template to be used on your own Forgejo instance.
|
|
|
|
Important notes:
|
|
* Edit the `homesite` rule, as it's targeted to common users or orgs on the instance. A better regex might be possible in the future.
|
|
* Edit the `http-cookie-check` challenge, as this will fetch the listed backend with the given session cookie to check for user login.
|
|
* Adjust the desired blocked networks or others. A template list of network ranges is provided, feel free to remove these if not needed.
|
|
* Check the conditions and base rules to change your challenges offered and other ordering.
|
|
|
|
|
|
## Development
|
|
|
|
### Compiling WASM runtime challenge modules
|
|
|
|
Custom WASM runtime modules follow the WASI `wasip1` preview syscall API.
|
|
|
|
It is recommended using TinyGo to compile / refresh modules, and some function helpers are provided.
|
|
|
|
If you want to use a different language or compiler, enable `wasip1` and the following interface must be exported:
|
|
|
|
```
|
|
// Allocation is a combination of pointer location in WASM memory and size of it
|
|
type Allocation uint64
|
|
|
|
func (p Allocation) Pointer() uint32 {
|
|
return uint32(p >> 32)
|
|
}
|
|
func (p Allocation) Size() uint32 {
|
|
return uint32(p)
|
|
}
|
|
|
|
|
|
// MakeChallenge MakeChallengeInput / MakeChallengeOutput are valid JSON.
|
|
// See lib/challenge/interface.go for a definition
|
|
func MakeChallenge(in Allocation[MakeChallengeInput]) Allocation[MakeChallengeOutput]
|
|
|
|
// VerifyChallenge VerifyChallengeInput is valid JSON.
|
|
// See lib/challenge/interface.go for a definition
|
|
func VerifyChallenge(in Allocation[VerifyChallengeInput]) VerifyChallengeOutput
|
|
|
|
func malloc(size uint32) uintptr
|
|
func free(size uintptr)
|
|
|
|
```
|
|
|
|
Modules will be recreated for each call, so there is no state leftover |