Add documentation for ipblocklist

This commit is contained in:
9seconds
2021-04-05 16:09:21 +03:00
parent 04b88cc864
commit 0274b3436a
6 changed files with 82 additions and 28 deletions
+11 -2
View File
@@ -30,9 +30,18 @@ func (s *stableBloomFilter) SeenBefore(digest []byte) bool {
// hardcore math which proves that if you choose this P correctly, you // hardcore math which proves that if you choose this P correctly, you
// can maintain the same error rate for a stream of elements. // can maintain the same error rate for a stream of elements.
// //
// byteSize is the number of bytes you want to give to a bloom filter . // byteSize is the number of bytes you want to give to a bloom filter.
// errorRate is desired false-positive error rate . // errorRate is desired false-positive error rate. If you want to use
// default values, please pass 0 for byteSize and <0 for errorRate.
func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache { func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
if byteSize == 0 {
byteSize = DefaultStableBloomFilterMaxSize
}
if errorRate < 0 {
errorRate = DefaultStableBloomFilterErrorRate
}
sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd
sf.SetHash(xxhash.New64()) sf.SetHash(xxhash.New64())
+1 -1
View File
@@ -133,7 +133,7 @@ func (c *Proxy) setupIPBlocklist(opts *mtglib.ProxyOpts) error {
return err // nolint: wrapcheck return err // nolint: wrapcheck
} }
go firehol.Run(c.Config.Defense.Blocklist.UpdateEach.Value(ipblocklist.DefaultUpdateEach)) go firehol.Run(c.Config.Defense.Blocklist.UpdateEach.Value(ipblocklist.DefaultFireholUpdateEach))
opts.IPBlocklist = firehol opts.IPBlocklist = firehol
+50 -23
View File
@@ -27,6 +27,19 @@ const (
var fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`) var fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`)
// Firehol is IPBlocklist which uses lists from FireHOL:
// https://iplists.firehol.org/
//
// It can use both local files and remote URLs. This is not necessary
// that blocklists should be taken from this website, we expect only
// compatible formats here.
//
// Example of the format:
//
// # this is a comment
// # to ignore
// 127.0.0.1 # you can specify an IP
// 10.0.0.0/8 # or cidr
type Firehol struct { type Firehol struct {
ctx context.Context ctx context.Context
ctxCancel context.CancelFunc ctxCancel context.CancelFunc
@@ -44,6 +57,12 @@ type Firehol struct {
treeV6 *bool_tree.TreeV6 treeV6 *bool_tree.TreeV6
} }
// Shutdown stop a background update process.
func (f *Firehol) Shutdown() {
f.ctxCancel()
}
// Contains is given IP list can be found in FireHOL blocklists.
func (f *Firehol) Contains(ip net.IP) bool { func (f *Firehol) Contains(ip net.IP) bool {
if ip == nil { if ip == nil {
return true return true
@@ -61,27 +80,15 @@ func (f *Firehol) Contains(ip net.IP) bool {
return f.containsIPv6(ip.To16()) return f.containsIPv6(ip.To16())
} }
func (f *Firehol) containsIPv4(addr net.IP) bool { // Run starts a background update process.
ip := patricia.NewIPv4AddressFromBytes(addr, 32) //
// This is a blocking method so you probably want to run it in a
if ok, _, err := f.treeV4.FindDeepestTag(ip); ok && err == nil { // goroutine.
return true
}
return false
}
func (f *Firehol) containsIPv6(addr net.IP) bool {
ip := patricia.NewIPv6Address(addr, 128)
if ok, _, err := f.treeV6.FindDeepestTag(ip); ok && err == nil {
return true
}
return false
}
func (f *Firehol) Run(updateEach time.Duration) { func (f *Firehol) Run(updateEach time.Duration) {
if updateEach == 0 {
updateEach = DefaultFireholUpdateEach
}
ticker := time.NewTicker(updateEach) ticker := time.NewTicker(updateEach)
defer func() { defer func() {
@@ -113,8 +120,24 @@ func (f *Firehol) Run(updateEach time.Duration) {
} }
} }
func (f *Firehol) Shutdown() { func (f *Firehol) containsIPv4(addr net.IP) bool {
f.ctxCancel() ip := patricia.NewIPv4AddressFromBytes(addr, 32)
if ok, _, err := f.treeV4.FindDeepestTag(ip); ok && err == nil {
return true
}
return false
}
func (f *Firehol) containsIPv6(addr net.IP) bool {
ip := patricia.NewIPv6Address(addr, 128)
if ok, _, err := f.treeV6.FindDeepestTag(ip); ok && err == nil {
return true
}
return false
} }
func (f *Firehol) update() error { // nolint: funlen, cyclop func (f *Firehol) update() error { // nolint: funlen, cyclop
@@ -302,6 +325,10 @@ func (f *Firehol) updateAddToTrees(ip net.IP, cidr uint,
return nil return nil
} }
// NewFirehol creates a new instance of FireHOL IP blocklist.
//
// This method does not start an update process so please execute Run
// when it is necessary.
func NewFirehol(logger mtglib.Logger, network mtglib.Network, func NewFirehol(logger mtglib.Logger, network mtglib.Network,
downloadConcurrency uint, downloadConcurrency uint,
remoteURLs []string, remoteURLs []string,
@@ -326,7 +353,7 @@ func NewFirehol(logger mtglib.Logger, network mtglib.Network,
} }
if downloadConcurrency == 0 { if downloadConcurrency == 0 {
downloadConcurrency = DefaultDownloadConcurrency downloadConcurrency = DefaultFireholDownloadConcurrency
} }
workerPool, _ := ants.NewPool(int(downloadConcurrency)) workerPool, _ := ants.NewPool(int(downloadConcurrency))
+12 -2
View File
@@ -1,8 +1,18 @@
// Package ipblocklist contains default implementation of the
// IPBlocklist for mtg.
//
// Please check documentation for mtglib.IPBlocklist interface to get an
// idea of this abstraction.
package ipblocklist package ipblocklist
import "time" import "time"
const ( const (
DefaultDownloadConcurrency = 1 // DefaultFireholDownloadConcurrency defines a default max number of
DefaultUpdateEach = 12 * time.Hour // concurrent downloads of ip blocklists for Firehol.
DefaultFireholDownloadConcurrency = 1
// DefaultFireholUpdateEach defines a default time period when
// Firehol requests updates of the blocklists.
DefaultFireholUpdateEach = 6 * time.Hour
) )
+2
View File
@@ -10,6 +10,8 @@ type noop struct{}
func (n noop) Contains(ip net.IP) bool { return false } func (n noop) Contains(ip net.IP) bool { return false }
// NewNoop returns a dummy ipblocklist which allows all incoming
// connections.
func NewNoop() mtglib.IPBlocklist { func NewNoop() mtglib.IPBlocklist {
return noop{} return noop{}
} }
+6
View File
@@ -69,6 +69,12 @@ type AntiReplayCache interface {
SeenBefore(data []byte) bool SeenBefore(data []byte) bool
} }
// IPBlocklist filters requests based on IP address.
//
// If this filter has an IP address, then mtg closes a request without
// reading anything from a socket. It also does not give such request to
// a worker pool, so in worst cases you can expect that you invoke this
// object more frequent than defined proxy concurrency.
type IPBlocklist interface { type IPBlocklist interface {
Contains(net.IP) bool Contains(net.IP) bool
} }