aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/discv5/net.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2016-11-22 01:11:54 +0800
committerFelix Lange <fjl@twurst.com>2016-11-23 05:21:18 +0800
commita98d1d67d6192df0bd57f608921a82cc508eee18 (patch)
tree49eb8ce8813e8f53cf7d949b2d7dd0ef575713e8 /p2p/discv5/net.go
parentba2884f3431312c616e21f57deeb03a7c4374d57 (diff)
downloaddexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar.gz
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar.bz2
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar.lz
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar.xz
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.tar.zst
dexon-a98d1d67d6192df0bd57f608921a82cc508eee18.zip
p2p/discover, p2p/discv5: prevent relay of invalid IPs and low ports
The discovery DHT contains a number of hosts with LAN and loopback IPs. These get relayed because some implementations do not perform any checks on the IP. go-ethereum already prevented relay in most cases because it verifies that the host actually exists before adding it to the local table. But this verification causes other issues. We have received several reports where people's VPSs got shut down by hosting providers because sending packets to random LAN hosts is indistinguishable from a slow port scan. The new check prevents sending random packets to LAN by discarding LAN IPs sent by Internet hosts (and loopback IPs from LAN and Internet hosts). The new check also blacklists almost all currently registered special-purpose networks assigned by IANA to avoid inciting random responses from services in the LAN. As another precaution against abuse of the DHT, ports below 1024 are now considered invalid.
Diffstat (limited to 'p2p/discv5/net.go')
-rw-r--r--p2p/discv5/net.go19
1 files changed, 12 insertions, 7 deletions
diff --git a/p2p/discv5/net.go b/p2p/discv5/net.go
index 7ad6f1e5b..b7e4a0bee 100644
--- a/p2p/discv5/net.go
+++ b/p2p/discv5/net.go
@@ -45,6 +45,7 @@ const (
bucketRefreshInterval = 1 * time.Minute
seedCount = 30
seedMaxAge = 5 * 24 * time.Hour
+ lowPort = 1024
)
const testTopic = "foo"
@@ -684,16 +685,19 @@ func (net *Network) internNodeFromDB(dbn *Node) *Node {
return n
}
-func (net *Network) internNodeFromNeighbours(rn rpcNode) (n *Node, err error) {
+func (net *Network) internNodeFromNeighbours(sender *net.UDPAddr, rn rpcNode) (n *Node, err error) {
if rn.ID == net.tab.self.ID {
return nil, errors.New("is self")
}
+ if rn.UDP <= lowPort {
+ return nil, errors.New("low port")
+ }
n = net.nodes[rn.ID]
if n == nil {
// We haven't seen this node before.
- n, err = nodeFromRPC(rn)
- n.state = unknown
+ n, err = nodeFromRPC(sender, rn)
if err == nil {
+ n.state = unknown
net.nodes[n.ID] = n
}
return n, err
@@ -1095,7 +1099,7 @@ func (net *Network) handleQueryEvent(n *Node, ev nodeEvent, pkt *ingressPacket)
net.conn.sendNeighbours(n, results)
return n.state, nil
case neighborsPacket:
- err := net.handleNeighboursPacket(n, pkt.data.(*neighbors))
+ err := net.handleNeighboursPacket(n, pkt)
return n.state, err
case neighboursTimeout:
if n.pendingNeighbours != nil {
@@ -1182,17 +1186,18 @@ func rlpHash(x interface{}) (h common.Hash) {
return h
}
-func (net *Network) handleNeighboursPacket(n *Node, req *neighbors) error {
+func (net *Network) handleNeighboursPacket(n *Node, pkt *ingressPacket) error {
if n.pendingNeighbours == nil {
return errNoQuery
}
net.abortTimedEvent(n, neighboursTimeout)
+ req := pkt.data.(*neighbors)
nodes := make([]*Node, len(req.Nodes))
for i, rn := range req.Nodes {
- nn, err := net.internNodeFromNeighbours(rn)
+ nn, err := net.internNodeFromNeighbours(pkt.remoteAddr, rn)
if err != nil {
- glog.V(logger.Debug).Infof("invalid neighbour from %x: %v", n.ID[:8], err)
+ glog.V(logger.Debug).Infof("invalid neighbour (%v) from %x@%v: %v", rn.IP, n.ID[:8], pkt.remoteAddr, err)
continue
}
nodes[i] = nn