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"`
|
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"`
|
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."`
|
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"`
|
RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"`
|
||||||
RPCPass string `short:"P" long:"rpcpass" default-mask:"-" description:"Password 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"`
|
RPCLimitUser string `long:"rpclimituser" description:"Username for limited RPC connections"`
|
||||||
|
@ -163,6 +164,7 @@ type config struct {
|
||||||
addCheckpoints []chaincfg.Checkpoint
|
addCheckpoints []chaincfg.Checkpoint
|
||||||
miningAddrs []btcutil.Address
|
miningAddrs []btcutil.Address
|
||||||
minRelayTxFee btcutil.Amount
|
minRelayTxFee btcutil.Amount
|
||||||
|
whitelists []*net.IPNet
|
||||||
}
|
}
|
||||||
|
|
||||||
// serviceOptions defines the configuration options for the daemon as a service on
|
// 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
|
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.
|
// --addPeer and --connect do not mix.
|
||||||
if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 {
|
if len(cfg.AddPeers) > 0 && len(cfg.ConnectPeers) > 0 {
|
||||||
str := "%s: the --addpeer and --connect options can not be " +
|
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)
|
(default all interfaces port: 8333, testnet: 18333)
|
||||||
--maxpeers= Max number of inbound and outbound peers (125)
|
--maxpeers= Max number of inbound and outbound peers (125)
|
||||||
--nobanning Disable banning of misbehaving peers
|
--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
|
--banduration= How long to ban misbehaving peers. Valid time units
|
||||||
are {s, m, h}. Minimum 1 second (24h0m0s)
|
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
|
-u, --rpcuser= Username for RPC connections
|
||||||
-P, --rpcpass= Password for RPC connections
|
-P, --rpcpass= Password for RPC connections
|
||||||
--rpclimituser= Username for limited RPC connections
|
--rpclimituser= Username for limited RPC connections
|
||||||
|
|
|
@ -114,6 +114,13 @@
|
||||||
; banduration=24h
|
; banduration=24h
|
||||||
; banduration=11h30m15s
|
; 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
|
; Disable DNS seeding for peers. By default, when btcd starts, it will use
|
||||||
; DNS to query for available peers to connect with.
|
; DNS to query for available peers to connect with.
|
||||||
; nodnsseed=1
|
; nodnsseed=1
|
||||||
|
|
34
server.go
34
server.go
|
@ -223,6 +223,7 @@ type serverPeer struct {
|
||||||
relayMtx sync.Mutex
|
relayMtx sync.Mutex
|
||||||
disableRelayTx bool
|
disableRelayTx bool
|
||||||
sentAddrs bool
|
sentAddrs bool
|
||||||
|
isWhitelisted bool
|
||||||
filter *bloom.Filter
|
filter *bloom.Filter
|
||||||
knownAddresses map[string]struct{}
|
knownAddresses map[string]struct{}
|
||||||
banScore connmgr.DynamicBanScore
|
banScore connmgr.DynamicBanScore
|
||||||
|
@ -315,6 +316,11 @@ func (sp *serverPeer) addBanScore(persistent, transient uint32, reason string) {
|
||||||
if cfg.DisableBanning {
|
if cfg.DisableBanning {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if sp.isWhitelisted {
|
||||||
|
peerLog.Debugf("Misbehaving whitelisted peer %s: %s", sp, reason)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
warnThreshold := cfg.BanThreshold >> 1
|
warnThreshold := cfg.BanThreshold >> 1
|
||||||
if transient == 0 && persistent == 0 {
|
if transient == 0 && persistent == 0 {
|
||||||
// The score is not being increased, but a warning message is still
|
// The score is not being increased, but a warning message is still
|
||||||
|
@ -1590,6 +1596,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
|
||||||
// for disconnection.
|
// for disconnection.
|
||||||
func (s *server) inboundPeerConnected(conn net.Conn) {
|
func (s *server) inboundPeerConnected(conn net.Conn) {
|
||||||
sp := newServerPeer(s, false)
|
sp := newServerPeer(s, false)
|
||||||
|
sp.isWhitelisted = isWhitelisted(conn.RemoteAddr())
|
||||||
sp.Peer = peer.NewInboundPeer(newPeerConfig(sp))
|
sp.Peer = peer.NewInboundPeer(newPeerConfig(sp))
|
||||||
sp.AssociateConnection(conn)
|
sp.AssociateConnection(conn)
|
||||||
go s.peerDoneHandler(sp)
|
go s.peerDoneHandler(sp)
|
||||||
|
@ -1609,6 +1616,7 @@ func (s *server) outboundPeerConnected(c *connmgr.ConnReq, conn net.Conn) {
|
||||||
}
|
}
|
||||||
sp.Peer = p
|
sp.Peer = p
|
||||||
sp.connReq = c
|
sp.connReq = c
|
||||||
|
sp.isWhitelisted = isWhitelisted(conn.RemoteAddr())
|
||||||
sp.AssociateConnection(conn)
|
sp.AssociateConnection(conn)
|
||||||
go s.peerDoneHandler(sp)
|
go s.peerDoneHandler(sp)
|
||||||
s.addrManager.Attempt(sp.NA())
|
s.addrManager.Attempt(sp.NA())
|
||||||
|
@ -2599,6 +2607,32 @@ func dynamicTickDuration(remaining time.Duration) time.Duration {
|
||||||
return time.Hour
|
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
|
// checkpointSorter implements sort.Interface to allow a slice of checkpoints to
|
||||||
// be sorted.
|
// be sorted.
|
||||||
type checkpointSorter []chaincfg.Checkpoint
|
type checkpointSorter []chaincfg.Checkpoint
|
||||||
|
|
Loading…
Reference in a new issue