您正在查看: EOS-优秀转载 分类下的文章

EOS bp nodes security checklist(EOS超级节点安全执行指南)

EOS bp nodes security checklist(EOS超级节点安全执行指南)

by 慢雾安全团队 & Joinsec Team

感谢 IMEOS.ONE, EOS Asia, EOS Store 倾力相助

English

超级节点安全审计方案

目录

架构核心目标

  1. 保护出块服务器正常通信与运行
  2. 增强初始主网整体抗攻击能力
  3. 保护节点安全

面临的主要问题

  1. 对初始状态主网进行 DDoS
  2. RPC 功能滥用
  3. 通信故障

架构核心设计

  1. BP 服务器隔离
  2. 多跳转节点(小节点流量转发,大节点高防护)
  3. 多链路高可用

核心防御

  1. 默认关闭 RPC。必须打开时,混淆端口,并架设高防等保护
  2. BP 通信多链路设计
    • BP 服务器不在公网上暴露,通过跳板服务器(跳板服务器数量要大)进行通信;
    • 在外网公布的跳板服务器大面积瘫痪时,通过私有网络(1.私有秘密节点 2.私有 VPN 链路)来同步区块
  3. 防止全网扫描定位高防后的服务器,修改同步端口 9876(同理 RPC 的 8888)至全网最大存活数量的端口 80、443 或 22,这样可以有效抬高攻击者定位成本。

推荐总架构

架构说明:

为了应对可能的 DDoS 攻击,节点应准备多条链路,在攻击到来后,可以随时通过备用链路进行通信,确保主网顺利启动,并持续出块。

首先,每个节点应至少准备 2 个公开 full node、2 个私密 full node,公开 full node 的 IP 可以对外公开,以供 Dapp 和主网正常通信。另 2 个私密 full node 的 IP 只告知被选中的其他超级节点,不对外公开,以避免同时遭遇 DDoS 攻击。

假如私密 full node 的 IP 也被攻击者获知(例如扫描全网所有 IPv4 地址)并遭遇 DDoS 攻击导致节点间无法正常通信,此时可通过 VPN 加密链路连接到虚拟内网,确保 21 个超级节点之间不间断的正常通信。

架构各部分设计说明

1. 公开节点(对外公开在社区节点列表里)

在没有攻击情况下,外围节点通过对外公布的公开节点进行通信。

2. 私密节点(只对其他可信BP节点私密分享的通信节点)

当攻击者通过公开的节点列表攻击公开节点造成公开节点不可用时,则可通过私密节点进行通信。(私密节点可被全网扫描发现,所以并不是完全安全)

3. VPN 加密节点(各可信节点间最后的秘密的通信信道)

当公网节点都被发现,并且攻击者进行攻击导致对公网 full node 服务器全部阻塞,最后则由私有 VPN 网络在隔离的虚拟内网内进行通信,保证最基础的出块正常。

4. RPC API 节点

查询用 RPC 所在 full node 与 BP 完全隔离并架设防御,保证外网对 RPC 的攻击不能影响到 BP。

安全加固方案

1. RPC 安全

1.1 屏蔽 RPC

如无必要,建议禁止 RPC 对外访问,config.ini配置内容如下:

  • 配置为空值http-server-address =
  • 注释https-server-address

1.2 开启 SSL

如果确实需要对外提供 RPC 服务,建议禁用 HTTP 协议,使用 HTTPS,config.ini配置内容如下:

  • 注释http-server-address,或者配置为127.0.0.1:8888
  • 配置https-server-address0.0.0.0:443
  • 配置https-certificate-chain-filehttps-private-key-file 为证书链文件路径和私钥文件路径,注意两个文件格式必须为 PEM
  • 配置证书链文件和私钥文件权限为 600

1.3 禁用 wallet_pluginwallet_api_plugin

在对外提供 RPC 服务的场景下,一定不要加载 wallet_pluginwallet_api_plugin。如果加载了wallet_pluginwallet_api_plugin,攻击者就可以通过 RPC API /v1/wallet/list_keys 获取已解锁账户的私钥。此外,攻击者还可以恶意循环调用/v1/wallet/lock_all使节点上的账户无法解锁。

1.4 禁用producer_api_plugin

在对外提供 RPC 服务的场景下,一定不要加载 producer_api_plugin。如果加载了producer_api_plugin,攻击者就可以通过 RPC API /v1/producer/pause 远程控制节点停止生产。

2. 配置安全

2.1 生成 Active 多签密钥

由于超级节点账户的公私钥明文配置在config.ini中,存在较大的风险,建议对这个账户生成 Active 多签,提高资产转出门槛。举例如下:

授予 shrimp2 和 shrimp3 拥有 shrimp1 的权限

cleos set account permission shrimp1 active '{"threshold":2,"keys":[{"key":"EOS6tjMy84SYqQEUcUXQeMLmeBo99aakJCbieu2TSMk2Agn6nTwmX","weight":2}],"accounts":[{"permission":{"actor":"shrimp2","permission":"active"},"weight":1},{"permission":{"actor":"shrimp3","permission":"active"},"weight":1}],"waits":[]}' owner

2.2 开启日志记录

在配置文件中配置logconf参数,记录必要的 RPC 请求日志。

2.3 Docker 默认参数优化

官方仓库https://github.com/EOSIO/eos/blob/master/Docker/config.ini中的配置过于宽泛,加载了wallet_api_plugin等插件,存在较大风险(官方已优化),建议在docker build之前修改配置。

2.4 max-clients参数优化

在配置文件中配置max-clients = 0 提升 P2P 端口并发连接数为无限制,同时优化ulimit系统参数和内核参数,增强恶意连接攻击承受能力。

官方在 这个提交中修复了P2P单节点恶意连接的问题,并新增了默认配置max_nodes_per_host = 1。所以max-clients不需要设置为0,可以根据节点性能酌情配置。

2.5 非 root 启动 nodeos

建议编译完成后,创建普通用户账号,并使用该账号启动 nodeos,避免使用 root,降低风险。

2.6 监听随机端口

  • p2p-listen-endpoint = ip:
  • http-server-address = ip:

每次启动会随机监听一个端口,如果是对外服务的,建议采用 主机安全 中的配置方法

3. 网络安全

3.1 网络架构

为应对可能的 DDoS 攻击导致节点主网络阻塞的问题,建议提前配置备份网络,例如私密 VPN 网络。具体可参考 EOS Asia 的架构图:

3.2 云服务商

经慢雾安全团队测试,Google Cloud、AWS 及 UCloud 等具有更好的抗 DDoS 攻击的性能,并且在 DDoS 攻击过后服务商不会临时封锁服务器,可以极为快速的恢复网络访问,推荐超级节点使用。(请谨慎选择云服务商,许多云服务商在遭遇 DDoS 等攻击时会直接关闭服务器)

3.3 DDoS 防御

为应对可能发生的 DDoS 攻击,建议超级节点提前配置 Cloudflare、AWS Shield 等 DDoS 高防服务。

4. 主机安全

  • 防止全网扫描定位高防后的服务器,修改同步端口 9876 (同理 RPC 的 8888)至全网最大存活数量的端口 80、443 或 22,这样可以有效抬高攻击者定位成本。
  • 关闭不相关的其他服务端口,并在 AWS 或 Google Cloud 上定制严格的安全规则。
  • 更改 SSH 默认的 22 端口,配置 SSH 只允许用 key (并对 key 加密)登录,禁止密码登录,并限制访问 SSH 端口的 IP 只能为我方运维 IP。
  • 在预算充足的情况下,推荐部署优秀的 HIDS(或者强烈建议参考开源的 OSSEC 相关做法),及时应对服务器被入侵。

5. 威胁情报

  • 强烈建议做好相关重要日志的采集、储存与分析工作,这些日志包括:RPC 与 P2P 端口的完整通信日志、主机的系统日志、节点相关程序的运行日志等。储存与分析工作可以选择自建类似 ELK(ElasticSearch, Logstash, Kibana) 这样的开源方案,也可以购买优秀的商业平台。
  • 如果使用了成熟的云服务商,他们的控制台有不少威胁情报相关模块可重点参考,以及时发现异常。
  • 当节点出现重大漏洞或相关攻击情报,第一时间启动应急预案,包括灾备策略与升级策略。
  • 社区情报互通有无。

致谢

在此非常感谢

  • HelloEOS
  • EOS Asia
  • EOSBIXIN
  • EOS Pacific
  • UnlimitedEOS
  • EOS Cannon
  • EOSpace
  • Blockgenic
  • EOSeco
  • EOSLaoMao
  • OneChain

等社区节点参与到节点安全测试中,为社区安全积累了宝贵的数据。
转载自 https://github.com/slowmist/eos-bp-nodes-security-checklist

EOS资源系统

EOS资源系统由RAM,CPU,NET组成。数据存储需要消耗RAM,账号交易需要使用CPU和NET。一个EOS账号创建的时候可以通过购买和抵押来获取资源,费用由主账号支付。如果创建账号时并未购买资源,则需要通过其他账号购买或者进行抵押,因为购买和抵押本身就是一种交易行为需要消耗资源。

RAM

RAM是运行时的内存。在EOSIO系统中,数据存储在区块链中要消耗该资源,是DApp开发时必须的资源。

RAM的交易方式
  1. RAM 的买卖,实质上是抵押 eos 到系统账户,而不是买方和卖方直接的交易。
  2. 不论是购买ram(即抵押eos,获取ram),还是卖出ram(即取回抵押的eos,释放ram),都是参与者与系统账户之间的交互,该过程将会收取1%的手续费。
  3. 买入RAM有两种计价方式: 买多少字节的RAM;买多少EOS的RAM。
  4. 卖出RAM只有一种方式:多少字节的RAM。
    RAM相关网站
  5. RMA价格实时查询:https://eosmeta.io/statisticsram,https://eos.feexplorer.io/
  6. RAM购买:https://eostoolkit.io/account/undelegate

NET 带宽

网络带宽以过去3天的平均消耗量为单位进行测量,单位是字节如KB。每次发送操作或事务时都会暂时消耗网络带宽,但随着时间的推移会减少到0。抵押的EOS越多,网络带宽可以使用得越多。 可以随时赎回EOS,但是有三天左右的赎回期。

CPU 带宽

CPU带宽以过去3天的平均消耗(以微秒ms为单位)来衡量。 当您发送操作或事务时,CPU带宽会暂时消耗,但随着时间的推移会减少到0。事务运行时间越长,它将消耗的CPU带宽就越多。 可以随时赎回EOS,但是有三天左右的赎回期。

三者区别

  1. RAM是自由市场买卖模式,由市场价格来决定。CPU、NET是抵押模式,抵押多少取消多少。
  2. RAM是随时可以交易,但CPU、NET有三天等待期。
  3. CPU和NET可用于出租给其他账户,取消抵押后,EOS可以回到自己的账户。RAM可帮助其他账户购买,但卖出时的EOS归其他账户所有。

资源操作

//账号资源查看
cleos get account ${account}

//${account1}为支付账号,${account2}获得账号
//ram购买
cleos system buyram ${account1} ${account2}  "0.0001 EOS" 
//ram销售,最多能售出的数量limit - used
cleos system sellram ${account1} 68718 -p ${account1}

//抵押EOS,获得CPU带宽和NET带宽
cleos system delegatebw ${account1} ${account2} '0.1000 EOS'  '0.1000 EOS'  -p ${account1}
//取消抵押
cleos system undelegatebw ${account1} ${account2} '1 EOS' '1 EOS' -p ${account1}

转载自:blockflow.net

cleos create account创建账号失败源码分析

我们知道在部署eosio.system合约之前,cleos new account都是可以好好使用的,一旦eosio.system部署完成,再执行该命令就会报如下错误。

$cleos create account eosio itleaks EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvt
Error 3080001: account using more than allotted RAM usage

这时必须使用如下命令创建对象

$cleos system newaccount eosio itleaks EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvt —stake-net-bandwidth xxx

其实system newaccount也是调用createaccount命令来创建账号,只不过又多执行一个buyram action

也就是通过新增一个buyram action来解决RAM不够问题,那这里就存在一个问题了?为啥eosio.system部署前不报这个ram不够的错呢?
这个是因为newaccount这个action有两个执行者,一个是native handler函数create_native_account,一个是eosio.system的newaccount函数(原理具体可看我的博文【EOS特殊智能合约eosio】)。create_native_account函数负责创建账号,初始化账号数据。经过create_native_account函数处理后,账号的cpu_resource_limit中的cpu,ram, net都是-1,意味着账号拥有无限的ram, cpu, net, 所以不会报错。而eosio.system部署后,“newaccount”这个action还会执行eosio.system的newaccount函数,这个函数做了一个很重要的事,就是将账号的cpu_resource_limit中的ram,cpu, net都赋值为0,这样该账号就没有任何资源了,因而在后面的检测阶段因为ram不够而报错。

源码分析

"newaccount"的两个处理函数逻辑如下:

native handler的处理函数


eosio.system的处理函数newaccount


转载自:http://blog.csdn.net/itleaks

EOS零手续费免费?你不知道的EOS收费细节

EOS是收取手续费的,主要体现在ram上。cpu和net也是收费的,但是是一种临时抵押冻结方式,一段时间后会自动解冻, 所以从一定程度上说cpu, net资源是免费的。这个其实也是合理的,因为ram是物理资产,不随时间的增长而增长。而cpu, net资产是一种虚拟资产,它的量是跟时间相关的。时间越长,它的量越大。1个月的cpu计算量肯定是1天cpu计算量的30倍。

账号的资源拥有状态保存在账号的resource_limits_object对象里,而使用情况保存在账号的resource_usage_object对象里。购买资源就是通过set_resource_limits更新resource_limits_object对象,记录资源消耗就是通过add_ram_usage更新ram使用状态和add_transaction_usage更新cpu, net使用状态。余额检测的逻辑就是比较resource_limits_object中的资源量和resource_usage_object里对应的资源使用量。接下来就来分析EOS收费具体细节。

ram收费逻辑

只要action中执行了持久化存储相关的逻辑就需要收取ram使用费,比如系统合约的newaccount ,updateauth, setcode, setabi, schedule_deferred_transaction, eosio.token的transfer

ram购买

ram购买通过eosio.system合约的buyram action来操作的,具体命令如下:

$./cleos.sh system buyram itleakstoken tokenitleaks "1 EOS" -p itleakstoken

ram购买的量是一个绝对值,是根据购买时市场内EOS和ram的汇率计算出来的。一般来说在ram总量不增加的情况下,ram会越来越贵。所以如果早期你购买了ram,然后过段时间后通过sellram卖掉ram可能还能挣钱。

汇率计算公式如下

ram消耗记录过程

我们以newaccount为例来说明:

智能合约里对table的修改其实会回调到eos的db相关函数,比如新增一个对象,就对应db_store_i64函数

ram余额检验

交易执行结束的时候,会检测ram 余额是否足够,即检测账号对应的ram量和消耗量的大小

cpu, net收费逻辑

cpu, net的消耗量是绝对值,以kb计量,而cpu, net的拥有量不是以kb计量的,而是以抵押的EOS计量保存在resource_limits_object对象里,在余额检测时才实时转为具体的绝对kb值进行比较,实时绝对量计算由get_account_net_limit, get_account_cpu_limit实现。

可见全网的网络抵押的EOS越多,账号能用的网络带宽就越少,即和抵押的CPU EOS总量相关,而不是和全部发行的EOS量相关。

cpu, net购买

购买cpu, net资源是通过抵押EOS实现的,具体命令如下:

$./cleos.sh system delegatebw itleakstoken tokenitleaks "2.0000 EOS" "2.000 EOS" -p itleakstoken

cpu, net消耗量记录过程


cpu, net的消耗量记录在resource_usage_object里,通过usage_accumulator记录

struct resource_usage_object : 
    usage_accumulator net_usage;
    usage_accumulator cpu_usage;

    uint64_t ram_usage = 0;
};
using usage_accumulator = impl::exponential_moving_average_accumulator<>;

最开始有提到过,cpu, net的消耗量是临时的,过一段时间可以清空,可以继续使用。这个具体实现逻辑由exponential_moving_average_accumulator的add函数实现

比如下图我使用itleakstoken账号执行一次转账后,cpu used反而变小了就是这个原因

cpu, net余额检测

余额检测也是在transaction_context.finalize函数

转载自:http://blog.csdn.net/itleaks