middleware: added IP blacklist/whitelist middlewares
This commit is contained in:
parent
0b250779b3
commit
50192d45c1
4 changed files with 126 additions and 0 deletions
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
32
server/store/middleware/ip/README.md
Normal file
32
server/store/middleware/ip/README.md
Normal 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.)
|
49
server/store/middleware/ip/blacklist.go
Normal file
49
server/store/middleware/ip/blacklist.go
Normal 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)
|
||||
}
|
||||
}
|
44
server/store/middleware/ip/whitelist.go
Normal file
44
server/store/middleware/ip/whitelist.go
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue