chaff

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2021 License: Apache-2.0 Imports: 9 Imported by: 2

README

Go Chaff Tracker / Generator

GoDoc Go

This package provides the necessary tools to allow for your server to handle chaff (fake) requests from clients. This technique can be used when you want to guard against the fact that clients are connecting to your server is meaningful.

The tracker automatically captures metadata like average request time and response size, with the aim of making a chaff request indistinguishable from a real request. This is useful in situations where someone (e.g. server operator, network peer) should not be able to glean information about the system from requests, their size, or their frequency.

Clients periodically send "chaff" requests. They denote the request is chaff via a header or similar identifier. If one of your goals is to obfuscate server logs, a dedicated URL is not recommended as this will be easily distinguisable in logs.

There are two components:

  • a middleware function that implements tracking
  • an http.Handler that serves the chaff requests

Usage

  1. Option 1 - use a single handler, detect chaff based on a request property like a header. This is most useful when you don't trust the server operator and can have the performance hit of the branching logic in a single handler:

    mux := http.NewServeMux()
    mux.Handle("/", tracker.HandleTrack(chaff.HeaderDetector("X-Chaff"), myHandler))
    

    In this example, requests to / are served normally and the tracker generates heuristics automatically. When a request includes an X-Chaff header, the handler sends a chaff response.

  2. Option 2 - create the tracker on specific routes and provide a dedicated chaff endpoint. This is useful when you trust the server operator, but not the network observer:

    r := mux.NewRouter()
    tracker := chaff.New()
    defer tracker.Close()
    
    mux := http.NewServeMux()
    mux.Handle("/", tracker.Track())
    mux.Handle("/chaff", tracker.HandleChaff())
    

Documentation

Overview

Package chaff provides useful primitives for enabling chaff requests on your http servers.

One might want to employ chaff requests to obscure which clients are and are not communicating with your server by allowing all clients to periodically communicate with the server.

Request size and latencies are tracked on a rolling basis so that responses to chaff requests are similar to real traffic in terms of latency and response size.

Index

Constants

View Source
const (
	Header          = "X-Chaff"
	DefaultCapacity = 100
	MaxRandomBytes  = 1000000
)

Variables

This section is empty.

Functions

func PaddingWriterFn added in v0.4.0

func PaddingWriterFn(randomData string) interface{}

The default ProduceJSONFn

func RandomData added in v0.4.0

func RandomData(size uint64) string

RandomData generates size bytes of random base64 data.

Types

type BasicPadding added in v0.4.0

type BasicPadding struct {
	Padding string `json:"padding"`
}

The default JSON object that is returned.

type Detector added in v0.3.0

type Detector interface {
	IsChaff(r *http.Request) bool
}

func HeaderDetector added in v0.3.0

func HeaderDetector(h string) Detector

HeaderDetector is a detector that searches for the header's presence to mark a request as chaff.

type DetectorFunc added in v0.3.0

type DetectorFunc func(r *http.Request) bool

func (DetectorFunc) IsChaff added in v0.3.0

func (d DetectorFunc) IsChaff(r *http.Request) bool

type JSONResponder added in v0.4.0

type JSONResponder struct {
	// contains filtered or unexported fields
}

JSONResponder implements the Responder interface and allows you to reply to chaff reqiests with a custom JSON object.

To use a function that will be given the heuristically sized payload so you can transform it into the struct that you want to serialize.

func (*JSONResponder) Write added in v0.4.0

func (j *JSONResponder) Write(headerSize, bodySize uint64, w http.ResponseWriter, r *http.Request) error

type Option added in v0.6.0

type Option func(*Tracker)

Option defines a method for applying options when configuring a new tracker.

func WithMaxLatency added in v0.6.0

func WithMaxLatency(maxLatencyMs uint64) Option

WithMaxLatency puts a cap on the tunnel latency.

type PlainResponder added in v0.4.0

type PlainResponder struct {
}

func (*PlainResponder) Write added in v0.4.0

func (pr *PlainResponder) Write(headerSize, bodySize uint64, w http.ResponseWriter, r *http.Request) error

type ProduceJSONFn added in v0.2.0

type ProduceJSONFn func(string) interface{}

ProduceJSONFn is a function for producing JSON responses.

type Responder added in v0.4.0

type Responder interface {
	// Writes the appropriately sized header and body in the desired format.
	Write(headerSize, bodySize uint64, w http.ResponseWriter, r *http.Request) error
}

Responder allows you to extend the chaff library with custom responders.

func DefaultJSONResponder added in v0.4.0

func DefaultJSONResponder() Responder

func NewJSONResponder added in v0.4.0

func NewJSONResponder(fn ProduceJSONFn) Responder

NewJSONResponse creates a new JSON responder Requres a ProduceJSONFn that will be given the random data payload and is responsible for putting it into a struct that can be marshalled as the JSON response.

type Tracker

type Tracker struct {
	// contains filtered or unexported fields
}

Tracker represents the status of a latency and request size tracker. It contains middleware that can be injected to automate keeping a rolling history of requests.

It also implements http.Handler and can be used to server the chaff request handler.

Response details are sent through a buffered channel. If the channel is full (i.e. this library is falling behind or requests volumes are too large), then some individual requests will be dropped.

func New

func New(opts ...Option) *Tracker

New creates a new tracker with the `DefaultCapacity`.

func NewTracker

func NewTracker(resp Responder, cap int, opts ...Option) (*Tracker, error)

NewTracker creates a tracker with custom capacity. Launches a goroutine to update the request metrics. To shut this down, use the .Close() method. The Responder parameter is used to write the output. If non is specified, the tracker will default to the "PlainResponder" which just writes the raw chaff bytes.

func (*Tracker) CalculateProfile

func (t *Tracker) CalculateProfile() *request

CalculateProfile takes a read lock over the source data and returns the current average latency and request sizes.

func (*Tracker) ChaffHandler added in v0.4.0

func (t *Tracker) ChaffHandler(responder Responder) http.Handler

func (*Tracker) Close

func (t *Tracker) Close()

Close will stop the updating goroutine and closes all channels.

func (*Tracker) HandleChaff added in v0.3.0

func (t *Tracker) HandleChaff() http.Handler

HandleChaff is the chaff request handler. Based on the current request profile the requst will be held for a certian period of time and then return approximate size random data.

func (*Tracker) HandleTrack added in v0.3.0

func (t *Tracker) HandleTrack(d Detector, next http.Handler) http.Handler

HandleTrack wraps the given http handler and detector. If the request is deemed to be chaff (as determined by the Detector), the system sends a chaff response. Otherwise it returns the real response and adds it to the tracker.

func (*Tracker) ServeHTTP

func (t *Tracker) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler. See HandleChaff for more details.

func (*Tracker) Track

func (t *Tracker) Track(next http.Handler) http.Handler

Track wraps a http handler and collects metrics about the request for replaying later during a chaff response. It's suitable for use as a middleware function in common Go web frameworks.

Directories

Path Synopsis
example module

Jump to

Keyboard shortcuts

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