middleware: added IP blacklist/whitelist middlewares

This commit is contained in:
Leo Balduf 2016-02-19 12:08:04 +01:00 committed by Jimmy Zelinskie
parent 0b250779b3
commit 50192d45c1
4 changed files with 126 additions and 0 deletions

View file

@ -15,6 +15,7 @@ import (
"github.com/chihaya/chihaya/server"
"github.com/chihaya/chihaya/tracker"
_ "github.com/chihaya/chihaya/server/store/middleware/ip"
_ "github.com/chihaya/chihaya/server/http"
)

View file

@ -0,0 +1,32 @@
## IP Blacklisting/Whitelisting Middlewares
This package provides the announce middlewares `IPBlacklist` and `IPWhitelist` for blacklisting or whitelisting IP addresses and networks for announces.
### `IPBlacklist`
The `IPBlacklist` middleware uses all IP addresses and networks stored in the `IPStore` to blacklist, i.e. block announces.
Both the IPv4 and the IPv6 addresses contained in the announce are matched against the `IPStore`.
If one or both of the two are contained in the `IPStore`, the announce will be rejected _completely_.
### `IPWhitelist`
The `IPWhitelist` middleware uses all IP addresses and networks stored in the `IPStore` to whitelist, i.e. allow announces.
If present, both the IPv4 and the IPv6 addresses contained in the announce are matched against the `IPStore`.
Only if all IP address that are present in the announce are also present in the `IPStore` will the announce be allowed, otherwise it will be rejected _completely_.
### Important things to notice
Both middlewares operate on announce requests only.
The middlewares will check the IPv4 and IPv6 IPs a client announces to the tracker against an `IPStore`.
Normally the IP address embedded in the announce is the public IP address of the machine the client is running on.
Note however, that a client can override this behaviour by specifying an IP address in the announce itself.
_This middleware does not (dis)allow announces coming from certain IP addresses, but announces containing certain IP addresses_.
Always keep that in mind.
Both middlewares use the same `IPStore`.
It is therefore not advised to have both the `IPBlacklist` and the `IPWhitelist` middleware running.
(If you add an IP address or network to the `IPStore`, it will be used for blacklisting and whitelisting.
If your store contains no addresses, no announces will be blocked by the blacklist, but all announces will be blocked by the whitelist.
If your store contains all addresses, no announces will be blocked by the whitelist, but all announces will be blocked by the blacklist.)

View file

@ -0,0 +1,49 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package ip
import (
"net"
"github.com/chihaya/chihaya"
"github.com/chihaya/chihaya/config"
"github.com/chihaya/chihaya/errors"
"github.com/chihaya/chihaya/server/store"
"github.com/chihaya/chihaya/tracker"
)
func init() {
tracker.RegisterAnnounceMiddleware("IPBlacklist", blacklistAnnounceIP)
}
// ErrBlockedIP is returned by an announce middleware if any of the announcing
// IPs is disallowed.
var ErrBlockedIP = errors.NewMessage("disallowed IP address")
// blacklistAnnounceIP provides a middleware that only allows IPs to announce
// that are not stored in an IPStore.
func blacklistAnnounceIP(next tracker.AnnounceHandler) tracker.AnnounceHandler {
return func(cfg *config.TrackerConfig, req *chihaya.AnnounceRequest, resp *chihaya.AnnounceResponse) (err error) {
blacklisted := false
storage := store.MustGetStore()
// We have to check explicitly if they are present, because someone
// could have added a <nil> net.IP to the store.
if req.IPv6 != nil && req.IPv4 != nil {
blacklisted, err = storage.HasAnyIP([]net.IP{req.IPv4, req.IPv6})
} else if req.IPv4 != nil {
blacklisted, err = storage.HasIP(req.IPv4)
} else {
blacklisted, err = storage.HasIP(req.IPv6)
}
if err != nil {
return err
} else if blacklisted {
return ErrBlockedIP
}
return next(cfg, req, resp)
}
}

View file

@ -0,0 +1,44 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package ip
import (
"net"
"github.com/chihaya/chihaya"
"github.com/chihaya/chihaya/config"
"github.com/chihaya/chihaya/server/store"
"github.com/chihaya/chihaya/tracker"
)
func init() {
tracker.RegisterAnnounceMiddleware("IPWhitelist", whitelistAnnounceIP)
}
// whitelistAnnounceIP provides a middleware that only allows IPs to announce
// that are stored in an IPStore.
func whitelistAnnounceIP(next tracker.AnnounceHandler) tracker.AnnounceHandler {
return func(cfg *config.TrackerConfig, req *chihaya.AnnounceRequest, resp *chihaya.AnnounceResponse) (err error) {
whitelisted := false
storage := store.MustGetStore()
// We have to check explicitly if they are present, because someone
// could have added a <nil> net.IP to the store.
if req.IPv4 != nil && req.IPv6 != nil {
whitelisted, err = storage.HasAllIPs([]net.IP{req.IPv4, req.IPv6})
} else if req.IPv4 != nil {
whitelisted, err = storage.HasIP(req.IPv4)
} else {
whitelisted, err = storage.HasIP(req.IPv6)
}
if err != nil {
return err
} else if !whitelisted {
return ErrBlockedIP
}
return next(cfg, req, resp)
}
}