bunnypop

package module
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

BunnyPoP: check if client is really a bunny 🐇

Hey, a badge! Go project version License

This middleware checks if the incoming request is really from BunnyCDN 🐰, or something that you want to allow.

Features

  • Bunny PoP Verification: checks if the client address belongs to BunnyCDN
  • Header validation: checks if the correct BunnyCDN headers are present in the request
  • IPv4, IPv6, or both: someday only IPv6 will be needed
  • Allow private or custom CIDR: private IPs (RFC 1918) or IPs from known CIDRs (/32 or /128 work too)
  • Bunnies: 🐰🐇

Flowchart

---
title: Default configuration
---
flowchart LR;
  user["Request 🐺"] --> headers;
  subgraph bunny["BunnyPoP 🐇"];
    headers{{areHeadersValid}} --> ip{{isAllowedIP}};
  end;
  ip --> |allowed|Service;
  headers --> |rejected|user;
  ip --> |rejected|user;

Usage

Traefik configuration:

experimental:
  plugins:
    bunnypop:
      moduleName: code.dataslut.pet/mewsse/bunnypop
      version: v1.2.2

Kubernetes middleware:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: checkremote
spec:
  plugin:
    bunnypop:
      checkHeader: true
      checkAddr: true
      updateInterval: 24h
      LogRejectedRequests: true

Configuration

argument type description default
silentStartup bool Suppresses startup logging noise false
silentUpdate bool Suppresses background PoP list refresh logs false
logRejectedRequests bool Log rejected requests true
logAllowedRequests bool Log allowed requests false
checkHeaders bool Validates the request headers true
checkAddr bool Validates the RemoteAddr against allowed values true
onlyIPV4 bool Allow only IPv4 requests false
onlyIPV6 bool Allow only IPv6 requests false
onlyLog bool Operates in a logging-only mode false
httpStatusCodeDeniedRequest int Status code for rejected requests 403
allowedCidr []string List of explicit CIDR ranges allowed via IP check []
allowPrivateIPs bool Allows private/reserved IPs false
updateInterval time.Duration Cache refresh interval for the PoP IP list 12h

Licences

Documentation

Overview

Package bunnypop provides HTTP middleware for verifying incoming requests against validity criteria derived from BunnyCDN PoP source checks or required headers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error)

Types

type BunnyPoP

type BunnyPoP struct {
	http.Handler

	AllowedCidr    []*net.IPNet
	UpdateInterval time.Duration
	Cache          *Cache
	Logger         *slog.Logger
	Config         *Config
	Fetcher        IPFetcher
	// contains filtered or unexported fields
}

func (*BunnyPoP) ServeHTTP

func (a *BunnyPoP) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Cache added in v1.2.1

type Cache struct {
	sync.RWMutex
	Entries    []net.IP
	Expiration time.Time
}

func (*Cache) Read added in v1.2.1

func (m *Cache) Read() ([]net.IP, error)

func (*Cache) Update added in v1.2.1

func (m *Cache) Update(ips []net.IP, expiration time.Time)

type Config

type Config struct {
	SilentStartup               bool     `yaml:"silentStartup"`               // Suppresses startup logging noise
	SilentUpdate                bool     `yaml:"silentUpdate"`                // Suppresses background PoP list refresh logs
	LogRejectedRequests         bool     `yaml:"logRejectedRequests"`         // Log rejected requests
	LogAllowedRequests          bool     `yaml:"logAllowedRequests"`          // Log allowed  requests
	CheckHeaders                bool     `yaml:"checkHeaders"`                // Validates the request headers
	CheckAddr                   bool     `yaml:"checkAddr"`                   // Validates the RemoteAddr against allowed values
	OnlyIPV4                    bool     `yaml:"onlyIPV4"`                    // Allow only IPv4 requests
	OnlyIPV6                    bool     `yaml:"onlyIPV6"`                    // Allow only IPv6 requests
	OnlyLog                     bool     `yaml:"onlyLog"`                     // Operates in a logging-only mode
	HTTPStatusCodeDeniedRequest int      `yaml:"httpStatusCodeDeniedRequest"` // Status code for rejected requests
	AllowedCidr                 []string `yaml:"allowedCidr"`                 // List of explicit CIDR ranges allowed via IP check
	AllowPrivateIPs             bool     `yaml:"allowPrivateIPs"`             // Allows private/reserved IPs
	UpdateInterval              string   `yaml:"updateInterval"`              // Cache refresh interval for the PoP IP list
}

func CreateConfig

func CreateConfig() *Config

type HTTPClientFetcher added in v0.0.2

type HTTPClientFetcher struct {
	Client *http.Client
	Config *Config
	Logger *slog.Logger
	Cache  *Cache
}

func (*HTTPClientFetcher) GetPoPList added in v0.0.2

func (f *HTTPClientFetcher) GetPoPList(api string) ([]net.IP, error)

func (*HTTPClientFetcher) UpdatePoPList added in v1.2.2

func (f *HTTPClientFetcher) UpdatePoPList() ([]net.IP, error)

type IPFetcher added in v0.0.2

type IPFetcher interface {
	GetPoPList(api string) ([]net.IP, error)
	UpdatePoPList() ([]net.IP, error)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL