diff options
author | Felix Lange <fjl@twurst.com> | 2016-11-22 01:11:54 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-11-23 05:21:18 +0800 |
commit | a98d1d67d6192df0bd57f608921a82cc508eee18 (patch) | |
tree | 49eb8ce8813e8f53cf7d949b2d7dd0ef575713e8 /p2p/discover/udp.go | |
parent | ba2884f3431312c616e21f57deeb03a7c4374d57 (diff) | |
download | dexon-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/discover/udp.go')
-rw-r--r-- | p2p/discover/udp.go | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go index b48f16229..6a2c91317 100644 --- a/p2p/discover/udp.go +++ b/p2p/discover/udp.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/rlp" ) @@ -126,8 +127,13 @@ func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint { return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort} } -func nodeFromRPC(rn rpcNode) (*Node, error) { - // TODO: don't accept localhost, LAN addresses from internet hosts +func nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*Node, error) { + if rn.UDP <= 1024 { + return nil, errors.New("low port") + } + if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil { + return nil, err + } n := NewNode(rn.ID, rn.IP, rn.UDP, rn.TCP) err := n.validateComplete() return n, err @@ -281,9 +287,12 @@ func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node reply := r.(*neighbors) for _, rn := range reply.Nodes { nreceived++ - if n, err := nodeFromRPC(rn); err == nil { - nodes = append(nodes, n) + n, err := nodeFromRPC(toaddr, rn) + if err != nil { + glog.V(logger.Detail).Infof("invalid neighbor node (%v) from %v: %v", rn.IP, toaddr, err) + continue } + nodes = append(nodes, n) } return nreceived >= bucketSize }) @@ -595,6 +604,9 @@ func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte // Send neighbors in chunks with at most maxNeighbors per packet // to stay below the 1280 byte limit. for i, n := range closest { + if netutil.CheckRelayIP(from.IP, n.IP) != nil { + continue + } p.Nodes = append(p.Nodes, nodeToRPC(n)) if len(p.Nodes) == maxNeighbors || i == len(closest)-1 { t.send(from, neighborsPacket, p) |