ban

package
v0.0.0-...-0bf38da Latest Latest
Warning

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

Go to latest
Published: Nov 21, 2021 License: GPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package ban provides an IP ban service, based on the Banner interface. Expected usage is as a http server middleware.

To use the service:

  • create a Banner implementation. Bundled implementations include:
  • Memory, recommended for single-instance services not needing persistence.
  • SQL, recommended for multi-instance services or those needing persistence. All implementations support concurrent operation.
  • On request handling, check the IP with Banner.IsBanned.
  • To ban an IP, use Banner.Ban
  • To unban an IP, use Banner.UnBan
  • Management UIs/debugging can list bans with Banner.FindAll ad Banner.FindByID
  • Close the instance when done using it, probably with a defer.

Index

Constants

View Source
const (
	// DefaultBanListSize is a heuristic for storage sizing only.
	DefaultBanListSize = 50
)
View Source
const DefaultTableName = `ban`

DefaultTableName is the default name for the table used as the storage for the SQL Flooder implementation.

Variables

View Source
var (
	// ErrAlreadyBanned is a logic error, but without consequences. It may be ignored.
	ErrAlreadyBanned = errors.New("already banned")

	// ErrInvalidID  is a severe error, meaning data corruption.
	// Program should stop, or at the very least reset the Banner instance.
	ErrInvalidID = errors.New("ID is invalid")

	// ErrInvalidIP  is a severe error, meaning data corruption.
	// Program should stop, or at the very least reset the Banner instance.
	ErrInvalidIP = errors.New("IP is invalid")

	// ErrNonExistentBan is a logic error, but without consequences. It may be ignored.
	ErrNonExistentBan = errors.New("non-existent ban")

	// ErrStorageInconsistency  is a severe error, meaning data corruption.
	// Program should stop, or at the very least reset the Banner instance.
	ErrStorageInconsistency = errors.New("storage inconsistency")
)

Functions

This section is empty.

Types

type Ban

type Ban struct {
	ID
	net.IP
}

func (Ban) String

func (b Ban) String() string
type Banner interface {
	// Closer allows closing the Banner instance.
	//
	// The interface does not define persistence considerations on a closed instance:
	// some implementations may persist (e.g. SQL), while others will not (e.g. Memory).
	io.Closer

	// Ban adds an IP to the ban list.
	//
	// Although it is idempotent at the storage level, repeated calls for the
	// same IP will return ErrAlreadyBanned, and should be seen as a logic error.
	Ban(ctx context.Context, ip net.IP) (ID, error)

	// FindAll may return large slices, and is very inefficient in the general case:
	// because of the concurrent access property, it only represents a crawl through
	// the ban storage, which may not represent an actual snapshot of that storage at any time.
	//
	// As such, it is considered an unstable function, mostly be seen as a debugging tool,
	// which could be used for admin UIs on sites with smaller ban lists.
	FindAll(ctx context.Context) ([]Ban, error)

	// FindByID is an administrative operation, which should not be used in the
	// hot path, as it may be highly inefficient (O(n) by number of IPs).
	//
	// For most situations, access the storage using IsBanned instead.
	FindByID(ctx context.Context, id ID) (net.IP, error)

	// IsBanned is the only operation meant for the hot path, and is expected to
	// the most used one, by far.
	IsBanned(ctx context.Context, ip net.IP) (bool, error)

	// UnBan removes an IP from the ban list.
	//
	// Although it is idempotent at the storage level, repeated calls for the
	// same IP will return ErrNonExistentBan, and should be seen as a logic error.
	UnBan(ctx context.Context, ip net.IP) error
}

Banner is the interface defining the ability to ban IPs.

It has nothing to do with advertising banners or the IAB.

type ID

type ID uint64

type Memory

type Memory struct {
	// Map is used here because each entry is expected to be written only once,
	// when banning (and deleted one when unbanning) but read ofte to check access.
	// Keys are IPs in string format (because net.IP cannot he hashed), values are IDs.
	sync.Map
	// contains filtered or unexported fields
}

Memory is an in-memory non-persistent implementation of ban.Banner. The blank value is a ready-to-use instance.

There is no guarantee that a once-Closed instance may be reused, although this is the case in the current implementation.

func (*Memory) Ban

func (m *Memory) Ban(_ context.Context, ip net.IP) (ID, error)

func (*Memory) Close

func (m *Memory) Close() error

func (*Memory) FindAll

func (m *Memory) FindAll(ctx context.Context) ([]Ban, error)

func (*Memory) FindByID

func (m *Memory) FindByID(ctx context.Context, id ID) (net.IP, error)

func (*Memory) IsBanned

func (m *Memory) IsBanned(ctx context.Context, ip net.IP) (bool, error)

func (*Memory) UnBan

func (m *Memory) UnBan(ctx context.Context, ip net.IP) error

type SQL

type SQL struct {
	*sql.DB

	TableName string
	// contains filtered or unexported fields
}

SQL is a RDBMS-backed Banner implementation. See NewSQL. In the current version, it only supports SQLIte > 3. TODO support other engines.

func NewSQL

func NewSQL(ctx context.Context, db *sql.DB, tableName string) *SQL

NewSQL creates a RDBMS-backed Banner instance.

  • db is an opened sql.DB pool
  • tableName is the name of the table which the service will use. If set to the empty string, it will use DefaultTableName.

func (*SQL) Ban

func (s *SQL) Ban(ctx context.Context, ip net.IP) (ID, error)

Ban upserts an IP to the ban list.

func (*SQL) Close

func (s *SQL) Close() error

Close is only present to override the promoted DB.Close and avoid closing the underlying DB pool.

It explicitly does not drop or truncate the associated storage, as other instances sharing the same storage may still be using it.

func (*SQL) FindAll

func (s *SQL) FindAll(ctx context.Context) ([]Ban, error)

func (*SQL) FindByID

func (s *SQL) FindByID(ctx context.Context, id ID) (net.IP, error)

func (*SQL) IsBanned

func (s *SQL) IsBanned(ctx context.Context, ip net.IP) (bool, error)

func (*SQL) UnBan

func (s *SQL) UnBan(ctx context.Context, ip net.IP) error

Jump to

Keyboard shortcuts

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