config: Add --whitelist support.
This commit is contained in:
parent
42b969a827
commit
a2085c68f8
4 changed files with 79 additions and 2 deletions
34
config.go
34
config.go
|
@ -103,6 +103,7 @@ type config struct {
|
|||
DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"`
|
||||
BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"`
|
||||
BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."`
|
||||
Whitelists []string `long:"whitelist" description:"Add an IP network or IP that will not be banned. (eg. 192.168.1.0/24 or ::1)"`
|
||||
RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"`
|
||||
RPCPass string `short:"P" long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
|
||||
RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"`
|
||||
|
@ -163,6 +164,7 @@ type config struct {
|
|||
addCheckpoints []chaincfg.Checkpoint
|
||||
miningAddrs []btcutil.Address
|
||||
minRelayTxFee btcutil.Amount
|
||||
whitelists []*net.IPNet
|
||||
}
|
||||
|
||||
// serviceOptions defines the configuration options for the daemon as a service on
|
||||
|
@ -630,6 +632,38 @@ func loadConfig() (*config, []string, error) {
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Validate any given whitelisted IP addresses and networks.
|
||||
if len(cfg.Whitelists) > 0 {
|
||||
var ip net.IP
|
||||
cfg.whitelists = make([]*net.IPNet, 0, len(cfg.Whitelists))
|
||||
|
||||
for _, addr := range cfg.Whitelists {
|
||||
_, ipnet, err := net.ParseCIDR(addr)
|
||||
if err != nil {
|
||||
ip = net.ParseIP(addr)
|
||||
if ip == nil {
|
||||
str := "%s: The whitelist value of '%s' is invalid"
|
||||
err = fmt.Errorf(str, funcName, addr)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
var bits int
|
||||
if ip.To4() == nil {
|
||||
// IPv6
|
||||
bits = 128
|
||||
} else {
|
||||
bits = 32
|
||||
}
|
||||
ipnet = &net.IPNet{
|
||||
IP: ip,
|
||||
Mask: net.CIDRMask(bits, bits),
|
||||
}
|
||||
}
|
||||
cfg.whitelists = append(cfg.whitelists, ipnet)
|
||||
}
|
||||
}
|
||||
|
||||
// --addPeer and --connect do not mix.
|
||||
if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 {
|
||||
str := "%s: the --addpeer and --connect options can not be " +
|
||||
|
|
6
doc.go
6
doc.go
|
@ -35,10 +35,12 @@ Application Options:
|
|||
(default all interfaces port: 8333, testnet: 18333)
|
||||
--maxpeers= Max number of inbound and outbound peers (125)
|
||||
--nobanning Disable banning of misbehaving peers
|
||||
--banthreshold= Maximum allowed ban score before disconnecting and
|
||||
banning misbehaving peers.
|
||||
--banduration= How long to ban misbehaving peers. Valid time units
|
||||
are {s, m, h}. Minimum 1 second (24h0m0s)
|
||||
--banthreshold= Maximum allowed ban score before disconnecting and
|
||||
banning misbehaving peers.
|
||||
--whitelist= Add an IP network or IP that will not be banned.
|
||||
(eg. 192.168.1.0/24 or ::1)
|
||||
-u, --rpcuser= Username for RPC connections
|
||||
-P, --rpcpass= Password for RPC connections
|
||||
--rpclimituser= Username for limited RPC connections
|
||||
|
|
|
@ -114,6 +114,13 @@
|
|||
; banduration=24h
|
||||
; banduration=11h30m15s
|
||||
|
||||
; Add whitelisted IP networks and IPs. Connected peers whose IP matches a
|
||||
; whitelist will not have their ban score increased.
|
||||
; whitelist=127.0.0.1
|
||||
; whitelist=::1
|
||||
; whitelist=192.168.0.0/24
|
||||
; whitelist=fd00::/16
|
||||
|
||||
; Disable DNS seeding for peers. By default, when btcd starts, it will use
|
||||
; DNS to query for available peers to connect with.
|
||||
; nodnsseed=1
|
||||
|
|
34
server.go
34
server.go
|
@ -223,6 +223,7 @@ type serverPeer struct {
|
|||
relayMtx sync.Mutex
|
||||
disableRelayTx bool
|
||||
sentAddrs bool
|
||||
isWhitelisted bool
|
||||
filter *bloom.Filter
|
||||
knownAddresses map[string]struct{}
|
||||
banScore connmgr.DynamicBanScore
|
||||
|
@ -315,6 +316,11 @@ func (sp *serverPeer) addBanScore(persistent, transient uint32, reason string) {
|
|||
if cfg.DisableBanning {
|
||||
return
|
||||
}
|
||||
if sp.isWhitelisted {
|
||||
peerLog.Debugf("Misbehaving whitelisted peer %s: %s", sp, reason)
|
||||
return
|
||||
}
|
||||
|
||||
warnThreshold := cfg.BanThreshold >> 1
|
||||
if transient == 0 && persistent == 0 {
|
||||
// The score is not being increased, but a warning message is still
|
||||
|
@ -1590,6 +1596,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
|
|||
// for disconnection.
|
||||
func (s *server) inboundPeerConnected(conn net.Conn) {
|
||||
sp := newServerPeer(s, false)
|
||||
sp.isWhitelisted = isWhitelisted(conn.RemoteAddr())
|
||||
sp.Peer = peer.NewInboundPeer(newPeerConfig(sp))
|
||||
sp.AssociateConnection(conn)
|
||||
go s.peerDoneHandler(sp)
|
||||
|
@ -1609,6 +1616,7 @@ func (s *server) outboundPeerConnected(c *connmgr.ConnReq, conn net.Conn) {
|
|||
}
|
||||
sp.Peer = p
|
||||
sp.connReq = c
|
||||
sp.isWhitelisted = isWhitelisted(conn.RemoteAddr())
|
||||
sp.AssociateConnection(conn)
|
||||
go s.peerDoneHandler(sp)
|
||||
s.addrManager.Attempt(sp.NA())
|
||||
|
@ -2599,6 +2607,32 @@ func dynamicTickDuration(remaining time.Duration) time.Duration {
|
|||
return time.Hour
|
||||
}
|
||||
|
||||
// isWhitelisted returns whether the IP address is included in the whitelisted
|
||||
// networks and IPs.
|
||||
func isWhitelisted(addr net.Addr) bool {
|
||||
if len(cfg.whitelists) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(addr.String())
|
||||
if err != nil {
|
||||
srvrLog.Warnf("Unable to SplitHostPort on '%s': %v", addr, err)
|
||||
return false
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
srvrLog.Warnf("Unable to parse IP '%s'", addr)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, ipnet := range cfg.whitelists {
|
||||
if ipnet.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkpointSorter implements sort.Interface to allow a slice of checkpoints to
|
||||
// be sorted.
|
||||
type checkpointSorter []chaincfg.Checkpoint
|
||||
|
|
Loading…
Reference in a new issue