主页 > 苹果商城可以直接下载imtoken吗 > 以太坊如何抵御 Eclipse 攻击

以太坊如何抵御 Eclipse 攻击

什么是日蚀攻击

一、eclipse攻击简介

以太坊的节点发现机制基于Kademlia,但目的不同。 Kademlia 旨在成为一种在分布式对等网络中存储和查找内容的方式,而以太坊仅用于发现新节点。 由于以太坊的节点由公钥表示,不受IP限制,一台机器上可以同时存在多个节点。 攻击者在少数服务器上创建多个节点并主动 ping 受害者的服务器。 通过 Kademlia 协议,攻击者的节点信息将被存储并填充到受害者节点列表中。 接下来就是让受害者重启机器,包括断电、ddos攻击等等。 重启后,攻击者不断ping受害者的节点,建立tcp连接。 一旦受害者的所有tcp连接都被攻击者建立起来,就达到了将受害者与正常网络隔离的目的。 当然,最大的目的应该还是为了双花。

网上关于eclipse攻击的详细介绍很多,这里不再赘述。

在刚才的论文中,提到了以太坊的geth1.8.0解决了eclipse攻击,所以笔者对比了1.8.0和1.7.3来阐明以太坊是如何解决这个问题的。

直接看代码。

以太坊启动时加载p2p网络的过程如下,

cmd/geth/main.go 初始化方法 -> geth -> startNode() -> uTIls.StartNode() -> stack.Start() -> running.Start()

这个running.Start()调用了p2p/server.go中的Start()方法,看看这个方法做了什么:

// Start 开始运行服务器。

// 服务器停止后不能重新使用。

func (srv *Server) Start() (err 错误) {

srv.loopWG.Add(1)

去srv.run(拨号器)

srv.running = true

返回零

}

本文主要解决eclipse攻击相关代码,其他不再介绍。

以太坊和以太经典是什么关系_以太坊年底结束pow挖矿_以太坊pow重启

上面的go srv.run(dialer)连接池管理协程负责维护TCP连接列表,监听各种信号以太坊pow重启,处理peer的增删改查

func(srv *Server) run(dialstate dialer) {

. ..

跑步:

为了 {

调度任务()

选择 {

. ..

case c := "-srv.posthandshake:

// 一个连接已经通过了加密握手所以

// 远程身份已知(但尚未验证)。

如果可信[c.id] {

// 确保在检查 MaxPeers 之前设置可信标志。

c.flags |= trustedConn

}

// TODO:跟踪进行中的入站节点 ID(Peer-Peer)以避免拨打它们。

选择 {

以太坊和以太经典是什么关系_以太坊pow重启_以太坊年底结束pow挖矿

case c.cont "- srv.encHandshakeChecks(peers, inboundCount, c):

案例“-srv.quit:

休息跑步

}

case c := "-srv.addpeer:

// 此时连接已通过协议握手。

// 它的能力是已知的,并且远程身份已经过验证。

错误:= srv.protoHandshakeChecks(同行,inboundCount,c)

如果错误 == 无 {

// 握手完成并通过所有检查。

p := newPeer(c, srv.协议)

// 如果启用了消息事件,则传递 peerFeed

// 对等体

如果 srv。 EnableMsgEvents {

p.events = &srv.peerFeed

}

名称:=截断名称(c.name)

以太坊pow重启_以太坊年底结束pow挖矿_以太坊和以太经典是什么关系

srv.log.Debug("Adding p2p peer", "name", name, "addr", c.fd.RemoteAddr(), "peers", len(peers)+1)

去 srv.runPeer(p)

同行[c.id] = p

如果 p.Inbound() {

入站计数++

}

}

. ..

case pd := "-srv.delpeer:

// 对等点断开连接。

d := common.PrettyDuration(mclock.Now() - pd.created)

pd.log.Debug("移除 p2p peer", "duration", d, "peers", len(peers)-1, "req", pd.requested, "err", pd.err)

删除(同行,pd.ID())

如果PD。 入站(){

inboundCount--

}

}

以太坊年底结束pow挖矿_以太坊和以太经典是什么关系_以太坊pow重启

}

. ..

}

注意加粗的代码,里面有一个inboundCount的操作,当有posthandshake,addpeer message的时候,会先检查,如果add或者del一个peer,会有对应的inboundCount++或者inboundCount--。 查看选中的内容:

protoHandshakeChecks 最终调用 encHandshakeChecks:

func (srv *Server) encHandshakeChecks(peers map [discover.NodeID] *Peer, inboundCount int, c *conn) error {

转变 {

案件! c.is(trustedConn|staticDialedConn) && len(peers) "= srv.MaxPeers:

返回 DiscTooManyPeers

案件! c.is(trustedConn) && c.is(inboundConn) && inboundCount 》= srv.maxInboundConns():

返回 DiscTooManyPeers

案例同行[c.id]! = 无:

返回 DiscAlreadyConnected

案例 c.id == srv.Self().ID:

返回 DiscSelf

默认:

返回零

以太坊和以太经典是什么关系_以太坊pow重启_以太坊年底结束pow挖矿

}

}

inboundConn 指示连接类型是活动连接。

看黑体部分的逻辑:如果连接可信且主动连接,且主动连接的节点数大于srv.maxInboundConns(),则拒绝连接。

可以看出,以太坊通过限制活跃连接数来防止eclipse攻击。 我们顺便看看这个数字是多少:

func(srv *Server) maxInboundConns() int {

返回 srv.MaxPeers - srv.maxDialedConns()

}

func(srv *Server) maxDialedConns() int {

如果 srv.NoDiscovery || srv.NoDial {

返回 0

}

r := srv.DialRatio

如果 r == 0 {

r = defaultDialRatio

}

返回 srv.MaxPeers /r

}

MaxPeers默认为25,defaultDialRatio表示可以接受活跃连接的比例。 默认值为 3以太坊pow重启,因此允许的最大传入 tcp 连接数为 25/3 = 8