演讲稿:
大家好,今天分享的是智能合约安全分析与闪电贷攻击,我将从以下几个方面来讲解,可能里面有不对的地方,请多多指正。
首先我们知道区块链大致上可以分为以下几层:从最底层的数据层,这一块大部分来说是用的 LevelDB 数据库,然后是从中间的 P2P 协议层,以及最后的应用层,纵观这些范围来讲,其实每一个地方都存在着安全风险。不管是比特币,还是以太坊,在历史上都出现过很多的漏洞。
这里就给大家举两个例子,一个是比特币在 2018 年的 CVE,,可以造成拒绝式攻击,严重的话可以造成通胀,就是地址余额变多了,相当于是超发了,这个也算是比较严重的漏洞了,那它是怎么造成的呢?这里主要是在 CheckBlock() 函数,该函数在节点接收到新的区块时被调用。CheckTransaction() 函数对于传入的交易消息进行检测,其中包括了检测一笔交易是否发生双花。如果发现 utxo 被重复记录了两次,就会返回处理失败的信息。可以看出,这段检测代码在被 CheckBlock() 函数的调用过程中被认为是费时的,并通过将函数的第三个参数设置为 False 的方式,使其跳过。利用的话,如果通过 p2p 传播交易,就会被检查出来,但是如果是有一个恶意区块,里面的双花交易是没有经过内存池的,所以就会被绕过校验,从而形成一种增发的现象,并且也会造成 DoS,形成恐慌。
另一个例子的话,可能大家都有经历过,就是前段时间,以太坊出的那个关于 EVM 的漏洞,同样的话,攻击者如果构造一个恶意合约,可以将节点直接打崩溃,危害其实也很大的,配合上做空机制,攻击者同样也能赚到很多钱,那它是怎么造成的呢?大家可以看一下这块的代码,在 staticCall 的时候,被重复覆盖了数据。导致前后不一致,这个时候没有更新代码的节点就会崩溃。这里的 staticCall 其实只是读取一个合约,然后读取相关的信息,而攻击者提供的参数正好是一个预编译合约,0x4,这个合约也很简单,就是返回原有的内容。然后传递的参数中,正好输入和输出的产生了重叠,而 staticCall 处理的时候,是按指针处理的,正好影响到了输出,于是产生了不一致,就无法通过,实际造成了链的分叉。
不管是底层服务,还是中间的协议,应用层,基础设施,其实很需要注重安全的,尤其是那些和钱打交道的一些服务,比如说交易所,比如说钱包,很多攻击者,就一直盯着这些服务,如果是中心化的,那么就会更加的容易被攻击。之前交易所被攻击的太多了,数不过来,之前币安有一次都被盗了八千多个 BTC,讨论矿工去强行逆转那笔交易,当然最后没有实行,损失如果算起来的话,也很严重的。
不知道大家有没有想过一件事情,如果从一个地址或者公钥可以反推出私钥,或者是破解了这个私钥,那么不就可以把钱转走,或者通过量子计算机去破解,那就可以很有钱了。这也说明了密码学对于虚拟货币的重要性,基础的话基本上是数学的基本推理,前段时间,有人发了一个关于门限 ECDSA 的两种安全攻击,里面影响了 zcash,Binance,Anyswap 等用到这个协议的,这个发现大概价值 50 万美金,所以说,底层的安全影响也很大的。关于这个攻击就不给大家讲了,主要我也不会,不是密码学博士,里面要求数学和密码学的功底还是很高的。
区块链最直接的,跟我们联系最紧密的还是应用层,像一些 defi 项目,或者是 Dapp,在这两年经历了很多攻击,其中也不乏一些没有审计过的应用。在这个过程中,只有黑客是获利最大的,项目方尽可能地挽回损失然后跑路,直接造成投资者的损失。并且之前还出过很多比较简单的漏洞,造成几十亿的损失,之后会详细讲一下。
大家大致了解了区块链安全以后,接下来一起来看一下智能合约。
讲 solidity 的话,先得讲一下脚本语言在比特币上的实现,中本聪其实很早地就在比特币上留下了脚本语言的模型,利用 utxo,我们可以往里存放一些脚本,比方说,在某一高度的时候进行转账,或者是一个简单点的,2 + 4 = 6,在比特币中是怎么实现的呢,具体的代码的话,是 2 4 ADD 6 EQUAL ,执行的时候,是以栈的方式来实现的,栈的大小是有限的,先将 2 和 4 压栈,然后 ADD,就变成 6,再将 6 进行压栈,然后最后通过 EQUAL 就可以得到结果 True 了。但这种方式实现的脚本编程是非图灵完备的,复杂性受限,也没有循环等,执行的次数有限。
这个时候,以太坊横空出世,号称下一代智能合约和去中心化应用平台,就用了 solidity 语言,现在用这个实现的技术越来越多,从最早的 DAO,到 Dapp,再到 Defi 等。它实现了图灵完备,有循环,合约之间也可以互相调用,甚至可以跨链调用,这个时候就有一个问题,比方说有个合约,它写了一个死循环,然后又发了一个激活这个合约的交易,矿工受到打包执行这笔交易的时候,也就在跑这一段代码,那么就让矿工和节点一直卡在那里,为了解决这个问题呢,以太坊一开始就设计了 gas 这个概念,合约每进行一个操作,就消耗一定的 gas,然后设置一个 gas limit,不能超过这个上限,然后消耗的 gas 再乘以当时设置的 gas price 就是最终的手续费,由矿工打包。这块详细的可以参考文档。
那么以太坊合约是在哪里执行的,像 java 有 java 虚拟机,有些语言有运行时,以太坊这边的话,是在 evm 上执行的,这里画了一张图吧,就是代表 evm 的结构,evm 也是一种基于栈的虚拟机,在存储上主要分为几部分,一类是,code 和 storage,这种是持久化的,code 用来保存合约的二进制,storage 的话,用来保存合约执行的全局变量。其他还有就是 stack 用来保存局部变量,最多有 16 个。memory 的话,就类似之前讲的内存一样,存储临时数据。还有 evm 是如何执行的,这里不是基于寄存器的,通过不断地压栈和弹栈,然后去取内存的内容,通过程序计数器记录当前的指令,不断地执行。
在讲指令之前,我想先介绍一下这个东西,ABI,全名的话是,应用二进制接口,可以通俗的理解为合约的接口说明,接口文档。当合约被编译后,那么它的 abi 也就确定了。当合约被调用的时候,会指定函数名和参数,这个在 web3.py 里或者是其他调用合约的代码,是根据 abi 来找到对应的函数,然后执行,生成编译码,传到交易的 data 字段。
我们在算 gas 的时候,不可避免的要和这个打交道,opcode,大家学过汇编的时候,应该要学一些指令,像什么 JMP,EIP,ESP,在 evm 里也不例外,最多只能有 256 条指令,就对合约这块做了更多的优化,尽可能的简单,每条指令消耗多少 gas 也比较清楚。所以说,大致的流程是这样的,开发人员写 solidity 代码,然后编译器会编译成字节码的形式,同时生成 abi 文件,然后将字节码和 abi 文件打包成合约,然后发布到以太坊上,然后用户可以通过以太坊的浏览器,查看合约的信息。节点收到交易的时候,对应的就会部署这个合约,有交易如果要打到这个合约地址上时,也会执行这个合约,通过字节码的形式。
那么 evm 是如何执行的,这里一般和电脑上的软件一样,也会分静态和动态,静态的话,会直接去反编译字节码,这里举两种方式,一种是通过在线反编译器,网址的话是这个,可以直接对链上的合约进行反编译,https://ethervm.io/decompile ,另一种的话,使用一些常见的工具,加一些插件,比如说 IDA 神器,反编译完成之后,就可以看到指令的具体内容,这样就可以更加直观的看到合约的执行过程和数据流了。这样有什么好处呢,比如说有一个没有开源的合约,我们想要去找它有没有问题,通过这样的分析手段,了解它的执行流程,分析其可能存在的问题吧。
现在有人应该有个问题,我们如何收集链上的合约呢,总不能每次都要自己写吧,这里提几个思路,一种是查浏览器,有些浏览器会有个地方是合约列表,去爬这个列表,另一种的话是调用节点,通过 getCode 这个方法,传地址的参数,先爬一遍创建合约的地址,然后通过这个方法,获取合约的字节码什么的。但是这几种都有缺陷,现在合约有自毁的功能,比如有个合约不用了,然后它调一个 selfdestruct,那么这个合约就会自动被销毁,这个时候,我们就不能获取到这个合约的字节码了。还有一个思路就是修改节点,在相关地方插桩,hook 相关的地方,将合约信息保存下来,这样几天同步节点的时间就可以得到全部的合约了。
接下来的话,会讲一下,智能合约开发和分析当中,会遇到什么样的问题,之前有些机构排过智能合约风险前十大排名,可以简单了解一下,具体会详细的讲其中几个。
一个的话是溢出,这个可能有些人听过,在安全方面,溢出也很常见吧,在这里主要还是整形的溢出,分为上溢和下溢,上溢的话,给大家举个例子,比如说一个 4 位的数字,那么它就是从 0x0,到 0xFFFF,这个时候,如果 0x2 + 0xFFFF 如果不加以判断的话,就会造成一种溢出,或者是 0x01 - 0xFFFF,这个时候又会是另一种结果。这种也有实际例子,之前美图有一个链就是因为这个问题,损失了好几十亿,这种的话,挖掘需要判断输入的是否可控,传进的参数是否进行校验,是否使用了安全的库。
另一个是重入,之前 ETH 有一次很重要的分叉,就因为这个,分出了 ETC 这个币种,这个漏洞大致的原理是这样的,合约之间可以互相调用嘛,这里认为合约中所有的外部调用都是不安全的,都有可能存在重入漏洞。例如:如果外部调用的目标是一个攻击者可以控制的恶意的合约,那么当被攻击的合约在调用恶意合约的时候,攻击者可以执行恶意的逻辑然后再重新进入到被攻击合约的内部,通过这样的方式来发起一笔非预期的外部调用,从而影响被攻击合约正常的执行逻辑。
再给大家介绍一种情况,条件竞争。这个漏洞主要是这个 approve 函数,该函数的主要功能是授权给第三方让其代替当前账户转账给其他账户,但是在这个函数当中却存在“事务顺序依赖性问题”,假设有两个用户:用户A,用户B,首先用户A 通过调用 approve 函数允许用户B代其转账的数量为 N(N>0),经过一段时间后,用户A决定将 N 改为 M(M>0),所以再次调用 approve 函数;用户B在第二次调用被矿工处理之前迅速调用 transferFrom 函数转账 N 数量的 token;用户A对 approve 的第二次调用成功后,用户B便可再次获得M的转账额度,即用户B通过交易顺序攻击获得了 N+M 的转账额度。
其他的一些风险,没那么广泛,需要一定的利用条件,这里再简单列一下,有兴趣的话,下来可以继续讲一下。
在了解了这些安全问题以后,就会问了,我们怎么去利用他们,这里有几种利用方式,目前我还没有找到一些自动化利用框架,应该还处在科研阶段,一种是直接发交易,构造特殊的交易到这个合约地址上,另一种的话,是再部署一个恶意合约,这个合约去调用正常的合约,达到一些特殊的目的。这些可以通过起一个本地的测试链,加上一些合约部署工具来实现测试。
之前讲的基本上是以太坊平台的,其他平台其实或多或少地都有一定的问题,这里举几个攻击的例子,比如 BSC 上就遭遇过类似的攻击,按照原理上来说,这些风险都是差不多的。
休息时间。
接下来的话,就是讲一下闪电贷这个东西,我们知道有一个是原子性的东西,这个时候 Defi 出现了一种项目,如果你在同一个交易里完成了借款和还款的操作,那么是不用抵押东西的,也就是几乎没有成本,举个例子,比如说,有两家去中心化交易所有价差,这个时候我们怎么套利呢,比如一个交易所的交易对是另一个的一半价格,当然实际不会这么夸张,这个时候,我们可以走闪电贷,借点钱出来,在这两个交易所之间搬砖,先去这个交易所买点币,然后直接链上去另一个交易所卖掉,然后归还之前借的闪电贷,中间的收入减去手续费就是利润了。但这种现在比较少了,更多的是黑客进行攻击一些协议,之前这个协议就被攻击过,过程是这样的,首先从闪电贷借点 eth,然后去另一个借贷协议抵押一部分 eth 借到 wbtc,然后这个时候去 dZx 这里做保证金交易,开了一个 eth/btc 的做空,这个时候拿一部分钱去另一个交易所大量的用 eth 买入 btc,这个时候做空不是算亏损嘛,但是价格达到一个高点的时候,就在刚才的保证金交易进行抛售 btc,赚 eth,之前做空开了 5 倍,然后把钱还给闪电贷,中间的收入减去手续费就是利润了,这次赚了大概几十个 eth。
所以说闪电贷是一种致富思路和财富密码吧,如果发现某个 defi 协议有漏洞,就可以这样攻击,然后进行获利,这些协议都是开源的,这样的攻击也可以使得系统更加健全,之前的中心化金融就没有这么多应用了。
讲完这些问题以后,接下来讲一下,如何去分析出这些问题,当然有一种方式是找相关公司进行审计,花钱嘛,没有花钱办不到的事情,这里主要讲一下通过工具来进行分析的一些思路。这里主要分为几种,静态分析,动态,机器学习。
静态分析的话,目前业界主要是有两种思路,一种是生成控制流图,通过生成的控制流执行流,利用之前写的插件规则,校验对应的问题。缺点的话,就是需要维护规则,依赖生成的路径。
另一种的话是形式化验证,这个相对来说是有一定的技术门槛的。这里就不讲了。
动态分析的话,顾名思义,就是将这个合约跑起来,利用虚拟机提供的特性,进行模糊测试等。以及动态污点分析,其实也算是一种跟踪技术。这块实现业界还比较少,要么是论文,要么是公司产品。
机器学习。有一篇论文思路是通过 GNN 模型,来进行智能合约漏洞的检测,这种算是卷积神经网络和图的一种结合和升级。为什么要用这种,还是由于虚拟货币的一些特性,我们相互转账的行为,在分析上可以用图数据库的方式。具体可以看 《Smart Contract Vulnerability Detection Using Graph Neural Networks》这篇论文。总体来说,是将合约源代码特征化为合约图,然后规范化突出节点,用神经网络结合专家知识库进行检测。
最后一个内容的话,是如何去防御,这里简单提几点,一个是保持良好的编码习惯,尽可能地避免常见的漏洞,一个是找相关公司审计合约,然后就是多看之前人总结的经验,形成的一种官方库。
可能有些人想要了解一下,这个合约如何进行升级,比如临时发现了问题,想升级版本去解决,这个不像传统应用,直接发布到链上就不可更改的,但还是有一些升级的方式,目前升级的策略主要有以下两种,一种是数据分离,另一种是通过代理的方式。数据分离的意思是这样的,我们将逻辑和数据分开,部署成两个合约,然后升级的时候,数据合约修改逻辑合约的地址。代理的方式,主要是利用了 call 和 delegatecall 的上下文的不同,一个是上一个账户的,一个是外部账户的,在合约和账户中间,还会部署一个 proxy 代理合约,相当于传递数据给最终的合约,当合约升级的时候,proxy 合约的地址就会发生变化,指向升级后的合约。
未来的话,我觉得还是有很多可以值得思考的,但这里加密货币的特殊性,代码即法律,不像传统应用,会尽可能地隐藏代码,反调试,在智能合约领域,谁可以更快地找到或者避免这些问题,谁将更占优势。
谢谢大家。
具体 ppt 需要联系获取。
]]>大家好,今天的话,主要是分享一些 eth 相关的东西,之前的话,我记得也有同事分享类似的一些内容,这次主要是一些补充和扩展,以及一些最新的一些动态。
总的话,会分为以下几个内容,扩容,pos,eth2.0,以及我们可能会遇到的一些机遇与挑战。
为什么要讲扩容呢,这个有点避不开的话题,主要也和手续费有关。
不知道大家有没有注意过,最近 NFT 特别火,包括腾讯也推出了自己的 NFT 平台幻核,以及现在各式各样的链游,币安也推出了自己的 NFT 平台,最近还有个头像作为 NFT 商品,然后来卖的 CryptoPunk,一件商品卖个几十万美元,这不仅刷热点,而且还将以太坊的 gas 费推高,有个项目叫 Space Poggers,直接当时一度飙升到 600 多 GWei,当然现在基本正常了,中间的交易手续费因为 eip - 1559 的原因,也大部分被燃烧掉了。
之前有没有类似的拥堵的情况呢,今年也有, 5 月 19 日那天,可以说是今年的一个黑天鹅事件,那一天币价大跌,很多人当时就在进行一些 Defi 提款操作,当时有些人有一些恐慌情绪,当然也有人去进行抄底,在长期看来,当时的价格应该算是底部,于是链上的交易就很频繁,导致手续费推高,交易变得更拥堵,然后于是也就有了一些 mev 的机会。
拥堵的话,会导致用户体验变差,尤其是现在 Defi 和 NFT 热门的情况,比方说,之前 2017 年有一个应用,加密猫,其实就是现在的一种 NFT,但当时引起了巨大的轰动,导致正常交易不得不提高手续费,来尽快的确认,甚至可以影响到矿池,矿池每天打款的时候,实际上手续费是自己出的,所以拥堵情况会造成额外的一些支出。
为什么会这么拥堵呢?其实说到底的话,还是由于 tps 的问题。在区块链里面,有一个不可能三角,去中心化、安全和高性能。很少能同时满足的,一般越中心化,它的交易性能就越好,币安就是会比一些去中心化交易所要交易快,所以去中心化交易所必须自己自动去做市。比特币的话,是实现了去中心化,和安全,但性能实际不太好,以太坊也差不多,所以为了提升性能,有了扩容的一些方案,来提升 tps。
社区里面也提了很多方案,也有不少比较有代表性的。这里 Layer2 过渡性方案,最终还要过渡到 eth2.0 分片技术。
第一种是状态通道,第二种是侧链,侧链的话,就是在主链旁边,映射一种新的资产,并且把主链的账户锁住,交易完成以后,然后再返回主链,提交最终的结果,当然如何保证这种安全,有一种方案就出现了,就是 Plasma(帕拉斯马),就是子链,这个其实后来发现不太好走,于是有一种新的方案出现了,就是 Rollup,后来 v 神把 Rollup 和零知识证明结合起来,搞了个 Zk Rollup,后来,Plasma 研究组,提出了一种 Optimistic Rollup,这个方案需要实现质押一些资产,然后提款的时候,会有一定的观察期,这个时间里如果没有人反对,那就提取成功。
那么这么多方案 v 神是怎么说的呢?他说目前Layer2可行性最高的方案,应该还是 Rollup 这个方案,它集合了状态通道、侧链、Plasma 等解决方案的优势,他觉得最好的方案还是这个 Arbitrum。
Arbitrum,大概今年 8 月份会上线主网,现在也有很多 Defi 项目支持这个。
但是这些 Rollup 扩容方案,有个问题,那就是上线太慢了,于是币安,ok,这些交易所,就复制了以太坊的代码,搞了个 bsc 的公链,直接复制了很多应用过去,并且牺牲去中心化,提高了性能。其他公链的话,也有很多方案,比方说,直接大区块,闪电网络,Segwit。
当然有些公链,直接通过 PoS 来实现一定的扩容,虽然效果有限,之前有号称 eth 2.0 的 EOS,还有 Ada 币,甚至还有 eos 这种 DPoS 的共识,上半年还有很火的 Solana 公链也是用的 PoS。
大家也听说了,以后以太坊也要转 PoS,最近看到一个 EIP,就是讨论这件事情的,EIP - 3675,这个 eip 主要内容呢,讲,将现在的 PoW 的共识转变成 PoS 共识,当然现在还是草稿阶段,中间可能还会有一定的变化,现在大部分人预计的时间在明年的2,3月份,在今年的上海分叉升级完,应该就会集中到这个里面。
那么在转之前,PoW 的老矿工怎么办,其实长远看来,以太坊抛弃 PoW 的挖矿是趋势,eth 2.0 也只有 PoS,而且今年的 12 月份还会有难度炸弹,最近的 1559 也减少了一部分收益,到时候这些矿工也只能去切到其他币种了。
eth 2.0 可以说是近几年比较大的变革的事情了,之前也讲现在越来越堵,而且跑全节点占用的资源越来越大,为了提高性能,因此就开始规划这个 eth 2.0。
2.0 的话,主要分为以下几个阶段,阶段 0 的话,去年 12 月份上线了,一种信标链,也就是当时说的,需要 32 个 eth 才能成为验证人,这 32 个 eth 相当于质押在那里,有一定的锁仓时间,现在的话是取也取不出来的,锁仓最后也会有一定的收益。这个信标链,主要是为以后的 PoS 打基础,管理验证者,以及为第二个阶段分片提供一种方向,
第二阶段基本上就是分片了,现在的话,是要分 64 个切片,并且基本互不影响,验证可以是独立的,直接提升了很多的性能,这个还是值得期待的。
直到第三阶段,也就是阶段2,这个时候才可以拿到之前抵押的那些 eth 以及收益,这个时候基本上第一阶段和第二阶段都完了,基本上现在这个主链也合并到 eth 2.0 了,就基本上是一个分布式计算平台,然后执行一些智能合约基本上也不会有什么压力。
到阶段3以后,社区就会有更多的一些优化,优化性能部分,到时候会有更好的轻客户端实现,形成一个高性能的分布式计算平台。那个时候,就基本上是每秒上万笔交易的级别,有更多的应用。
那么以太坊1.0 这个版本的链怎么办,
在信标链阶段质押 eth 里面也有一个经济模型,目前的话,大概质押了 600 万的 eth,目前年化在 6 %,这个收益是根据质押量在变化的,其实现在每年的增发率也在不断地降低,现在很多 Defi 项目也在锁仓,然后再加上 eip-1559 的销毁,基本上以太坊是一种通缩的状态。
大概流动性的话,现在 2.0 质押了大概 600 万的 eth,可以占总的 5% 左右,Defi 项目做市和锁仓的现在也差不多也有 5%,然后每天销毁大概几百个 ETH,并且之前主要的 eth 在基金会和交易所比较多,实际现在的流通量会越来越少,价格上也会更多。
当然这里有个问题,用户是选择这种质押收益呢还是选择 Defi 借贷那种锁仓收益更好,其实我目前觉得,可能没有更多的比较,质押收益的话,锁仓的时间会更长,Defi 项目的话,会有一定的风险,质押收益的话,也会追求一定的在线率,保证节点的可用性,当然现在也有很多托管钱包可以帮别人做这些事情,然后收取一定的收益。
当然最后的收益也是通过 eth 去返还的,如果按法币本位的话,也有可能到时候收益降低,总之是收益和风险都会存在的。
在 eth 2.0 的这一些生态里面,有哪些机遇呢?这里主要有以下几类吧,可能不一定全。
一类的话,是做数据分析,这方面比较成功的例子是这个 Nansen,之前融资融了大概有千万美元级别,其他的也做的不错。oklink 最近也推出了一个链上大师,专门去做一些数据分析的聚合。
也可以做一些基础服务的建设,比如说一些 eth 2.0 节点的建设,信标链浏览器的建设,可以增加一些流量。
在业务上的话,可以和一些相关的初创公司做合作,大概是今年年初的时候,有一个 eth2.0 相关的合作,主要是bison 公司的,
现在也有很多托管中心化钱包可以做相关的一些质押,然后中间抽取10%左右的利润,当然也会有一定的风险,考验一些技术能力,要保证节点一直在线,大概这个锁仓时间估计有两年左右的时间,所以是一种相对比较长期的事情。
最近还有看到一个非托管式的一个质押平台,Lido,去年开始开发的,今年上线的,基本上是通过智能合约的形式,将 eth 映射成另一种资产,然后通过这个平台获取对应的收益,当然实际上也会有风险,包括智能合约风险,验证者风险,密钥管理风险,生态风险。
最近元宇宙也比较热门,但觉得目前还算比较早期,当 eth 2.0 成熟了以后,就会有更多实际落地性的应用,而且性能提升了以后,支付的成本会变得很低,实现更多的区块链 3.0 的应用。
另外就是推出一些专题,然后增加一些 eth 2.0 相关的,相当于是跟随热度,增加流量吧。
具体 ppt 需要联系获取。
]]>这几天有在看到一篇文章(玩 DeFi 流动性挖矿巨亏83万,比特币期权1小时让我恢复元气),里面讲的是一个炒币者,15 年进入币圈,17 年遇上 ico 和大牛市,赚到第一桶金,然后在 2020 年八九月份的时候,关注到了 Defi,看到了后来很出名的 SushiSwap 项目,于是就将自己手中的 87 万投入了 Sushi 的流动性挖矿,后来的故事大概也都知道了,创始人,套现出局,然后引发 sushi 社群不满,市场出现暴跌,虽然后来道歉了,归还了一些 ETH,但是当时还是对他来说跌了许多,当时的 87 万变成了 4 万,整个人都不一样了。
当然重点可能不是在于他亏了那么多钱,而是币圈当时开始流行一些新的内容,比如说流动性挖矿,AMM(自动化市商),Defi 借贷,闪电贷,机枪池,甚至于当时,传奇的 v 神认为,Defi 热潮可能会推动下一次牛市的到来(具体可以参阅当时的专访)。
其实论核心或者是要点来说,加密货币行业不可绕过的就是去中心化,这既是原则,也是初衷,相对来说,行业目前更加趋近于去中心化,还没有绝对性的垄断。逐渐地也可以看到,去中心化,在渐渐影响着世界,在影响着一些规则的运行,在这个世界里,没有中心化的黑盒,人们可以使用稳定币来进行各方面的交易借贷,并且通过这种去中心化的区块链,让其应用场景更加稳定,有用。
Defi,维基百科是这样讲的:
Decentralized finance (commonly referred to as DeFi) is a blockchain-based form of finance that does not rely on central financial intermediaries such as brokerages, exchanges, or banks to offer traditional financial instruments, and instead utilizes smart contracts on blockchains, the most common being Ethereum.
我们可以理解,Defi 出生于 Dapps,实现了很多金融相关的功能或者业务,是一种智能合约的形式的实现,它相对于传统的中心化交易所或者借贷提供商,不需要相关的 KYC,代码更多的是开源的,链上信息是公开的,任何人都可以访问且透明。
展望未来,必先回顾历史。实际上,Defi 已经有一定的发展时间了,早在 2018 年的时候,就出现了 MakerDAO,Aave 等协议,当时大多集中在抵押借贷方面,Aave 这个项目也是吭哧吭哧的发展了很久,才形成了规模。然后 19 年基本上算是熊市,项目也是不温不火,远不如 18 年出现的 Fomo3D 的昙花一现的样子。
可能都比较了解,2020 年可以认为成真正 defi 开始爆发的元年,这一年涌现了不少项目,比如Uniswap,Sushiswap,Compound 等,持仓量有着爆发式的增长,从十几亿美元,达到年底的数百亿美元。
可其真的去中心化吗?也未必,按目前来说,有很多一些新型的项目,比如 BDP,也有更多更小的项目,都会想往这里分一杯羹,但论水平和规模上都有差异,里面的套利手段也并不是没有风险,既要相信项目方,也要相信智能合约代码没有漏洞,还要避免一些闪电贷的攻击,在架构上,依托于以太坊等公链,交易速度和性能都有限制,在政治上,目前大多数依赖相关组织,相关项目方,在这方面很难实现完全的去中心化。
但为什么还是要发展 Defi,现在 Defi 算是起步的阶段,Defi 有一些是稳定币,而世界上有一些国家,货币体制的不完善,导致了恶性的通货膨胀,导致社会一定的混乱,这时在 Defi 上,有一些比较新颖的算力稳定币的实现,甚至可以幻想一些国家用稳定币来进行交易。
最近有看到一句话,深感认同:
安全是 DeFi 的必备基础,社区和治理是发展的方向,那么可持续性一定是 DeFi 项目的长期目标。
从去年到现在,Defi 也更多进入了黑客的视野,在印象中,去年发生了大概几十次攻击事件,很多就与 Defi 有关,安全是区块链领域很重要很重要的一环,历史上发生了太多因为不重视安全,导致极大规模的损失的事情,甚至一些 erc20 币种直接退市。
论发展来看,感觉 Defi 是抓住了机遇,甚至于引领了市场,在以前,上个牛市的时候,也有很多去中心化交易所(Dex)的项目,实际上,它们不管是链上挂单,链下撮合,然后将撮合结果放到链上,都有着很多的缺点,比方说,交易慢,缺乏对手方等的致命缺陷。而以 Uniswap,Sushiswap 等项目,就提供了一些不一样的思路,结合流动性挖矿,提供流动性提供者,简称 LP,我们可以称之为老婆,当然和现实可能不太一样,在流动性挖矿里,是 LP 老婆,将他 / 她的抵押代币资产提供到 Defi 的智能合约里面(称之为流动性池),因此,他们会获得代币形式的奖励,而这个收益在当时是很可观,甚至可以年化达到 2000 %,当然项目难免会有风险,投资需要很了解项目。有些项目的高利率是不可持续的,甚至项目方有套现跑路的风险。
实际上,拉长时间来看,是错过这一波机遇的,尽管当时还有很多大佬喊单,日亦繁荣,对应的币种,从上线初期,到现在大多数都有百倍的涨幅。而且这次很多也算是从国外传入国内,由老外带动的项目。
因此如何更好地错过类似的机遇呢,那就是更多发现一些好项目,深入了解项目方,然后就不投,看着它翻倍,或者是成长。
还有是对变化不要那么太敏感,有可能过一段时间,看的项目出现了安全风险,然后被攻击,损失很多,错过了这样的机遇。
在 Defi 方面,提供了太多的机遇,包括抵押借贷,流动性挖矿,机枪池,各种稳定币,撮合系统,去中心化交易所,预言机,合成资产,与 NFT 的结合,锁仓收益,0x协议,代币交换,贷款等等。
前段时间,有一句流行的话:
凭运气赚的钱,都会被实力亏掉。
其实感觉很多投资领域,大多数都是这样的,在自我意识方面,很重要的一部分便是认知,不管是韭菜也好,构建认知也罢,都会有共同的地方。
总结币圈的很多项目来说,一切还是市场和用户的选择,并不是单纯技术决定的。对 Defi 来说,更多的是一种双边市场,其中借贷是双方,AMM 里的市商和用户是双方,清算套利者是双方,在项目里,更多是如何平衡各方面的关系,同时维持系统的稳定。
前几天还有看到一个有意思的项目,应该是特别小众,SuperNova,一种算力稳定币,当然这种项目感觉刚开始会赚到一些,之后就主要是抵押借贷方面了,当时正好是,都在讲财富密码,感觉正好押韵,所以改了个状态,“财富密码,SuperNova”,按照白皮书上的来说,思路比较新颖,SuperNova 包含了两种稳定币的设计模式,之后可以阅读源码去更多的了解一下。项目早期的年化都在几百上千(官方人员说的)
如何更好的错过类似的项目,避免赚钱?
我觉得可能有以下几点:
NFT 也比较火,之后可能会写如何错过 NFT,以及 NFT 的前世今生。
大概不仅错过 Defi,还会错过 NFT,也会错过 SuperNova。
意难平。
最后是最近循环的一首歌,愿你决定,愿你决定如何错过。
参考资料:
https://defipulse.com/
https://charts.coinmetrics.io/
https://en.wikipedia.org/wiki/Decentralized_finance
专访V神 :DeFi热潮可能会推动下一次牛市到来
https://finance.sina.com.cn/blockchain/coin/2020-07-09/doc-iircuyvk2879363.shtml
关于流动性挖矿
https://www.jianshu.com/p/ba0d294dd6f1
对话王玮:从第一性原理的角度重新理解DeFi
https://www.weiyangx.com/378068.html
我想世界上只有两种人,一种是接受比特币的,视比特币为投机也好,信仰也罢,心底上“信任”比特币,尊重比特币的机制;而另一种是不接受比特币的,对比特币还持有一种固执的执念,传销也好,骗局也罢。
意识是进化的一部分,我们在意识到效率的落后,从而开启了工业革命,从而不断地探索、思考现在与未来。
比特币和其他东西一样,也充满着缺点,比如价格波动大,不能快速变现,在保值上还需要成长。但正如我们有包容心一样,意识到了法币的缺陷,面对中心化的银行运作,加以密码学先前的发展,进行了巧妙的结合,发现了比特币,并从极客走到了大众。
实际上,到现如今,比特币依然解决不了大多数金融问题,但是就像开源文化一样,众人的智慧是无穷的,依然有很多人,在比特币的基础上,不断地做着实验,比如开发一些跨链应用,去描绘心中去中心化更多的解决方案,因此将比特币称之为区块链的成熟应用并不为过。
当然,有些人就疑惑了,比特币是否存在价值,价值这种事情,也是见仁见智的,有些观点认为,它既然有价格,那么价格就代表了价值,说明这是一种共识,认为目前就应该这么多;但还有些认为,它只是一种虚拟的东西,当受到全世界的监管时,自然没有价值。不想争论错与对,随着四年一牛市的周期,势必关注也是一种周期性的行为,而投机也好,信仰也罢,面对这样的形态,依然需要做好风险控制。
现如今,大多数行业早已经不是单打独斗式的小作坊,而成立了群体,拥有了资本,通过资本的力量和方式,将原本简单的事情,复杂化,在百余年间,比如借贷变得越来越普遍,成为了一种司空见惯的方式。资本的正向操作会让资本越来越有钱,这也就是,马斯克不断地为比特币喊单,从而投资回报率要超过可认为是实业的特斯拉。
依然比特币属于早期,还没有特别完善的应用,无法避免投机者的存在,依然会可能触发危机,但我依然相信那句话,它是一个一些人的社会实验,面对货币的不断贬值、不断的印刷钞票,在长期来看,依然是那个最避险的资产。
当然,在现如今,它还是一种早期意识形态,国家也很早的开始了对其的观察,严禁投机炒币,禁止非法集资,鼓励区块链应用,就是国家的态度。
比特向左,以太向右。
在去年以及今年,在家乡之时,闲暇时间也聊起了比特币,顿时那人便放起了光芒,说到,噢,那个传销币吧,在这骗了不少钱呢,实际上在一些人眼里,就是一种传销的味道,和其他币没有区别。
但是作为市值占比最高的虚拟加密货币,其有着很多不可代替性,但艺术是百花齐放的,不是永远一枝独秀。
以太坊,从名字上看来就不是一种币,这就是 v 神的独到之处,对其的理解,这是一个平台级的应用,可以执行任意 Dapp 的虚拟机,认为是区块链 2.0 时代。
在初期也经历了不少质疑的声音,而以太坊团队也没有去关心,依然是探索自己的实践,当然面对以太坊的扩容问题,我们需要给一定的时间,分片也好,2.0 也罢,之后也会在 4 月 14 日进行柏林硬分叉,会有各种优化,为之后转为 pos 提供了道路。
defi 从去年到现在,我想是很火的,甚至没有研究过 defi 的,都不一定算币圈有经验的。它算是泡沫还是价值,这个每个人我想有自己的理解吧,和比特币一样,也是一种不成熟的东西,缺乏更好的安全机制,一旦不慎,就会被造成用户的损失,同样,它也不需要 kyc 传统的验证,便可进行更多的去中心化的理财应用。
当其去中心化了以后,实际上也更加利于攻击,我们可以看到更多的攻击手法是,通过智能合约等的闪电贷的方式,最大化攻击利益。
论原因来讲,不仅是没有做好安全审计,更是缺乏一种高效的追踪方式。有利有弊,如此而已。
正如林夕歌中所讲的那样,爱情是一种飘渺的感觉,纵然雪中飞花,不过是一种你情我愿的纠缠。
最美好的投资方式,我想是,用不影响自己的一部分钱,投资自己熟悉的东西,涨了不为所动,跌了不为其流泪,穿越牛熊,看淡这些。
实际上,没有人可以做到每次投资必是成功的,心态上,要保持坦然自若,短期里的价格是无法预测的。只要当保持就算都失去了也无所谓的心态,这样便不会影响到很多。
个人的力量是永远无法和资本抗衡的,谁会知道顶部最终会到哪里,都不知道,预测也只是心理价位以及一些信仰。通过这些去吸引,去传销的那些人,尤其是去通过各种途径,手段引诱中老年人去参加什么投资,承诺什么回报,之后跑路的,特别可耻,现在还出台了各种防范非法集资的政策,望谨记。
实际上《富士山下》不是只讲爱情,而且里面也有一种佛法的味道,看淡了人生,放下了思想,这种歌,我想每次听都会有新感觉,新理解吧。
当然还是希望大家的币都成为十倍百倍,万币顺意。
币圈有风险,投资需谨慎。
原文便是比特币白皮书链接。
]]>在前不久,比特币 Core 开发者将实现 BIP-340 Schnorr 签名的提交合并到了 Secp256k1,而 Bitcoin 代码也在 10 月 15 日时合并了相关提交,这将意味着会在 12 月份发布 0.21 的版本中,有相关的实现。并且按照 BIP 9 的软分叉规范,大概在近几年内,会进行实际投票通过软分叉的形式激活这些特性。
在比特币上实现 Schnorr 签名具体可以追溯到 BIP340,其中讨论了 Bitcoin Schnorr 的相关标准与实现,讲了一些特性,包括与之前的 ECDSA 的对比,以及具体的标准规范,具体的分析在下面 Schnorr 实现一节参阅。
在 2017 年 8 月份,比特币激活了隔离见证(SegWit),解决了之前遗留的延展性问题,将签名部分的数据移到了见证部分,进一步节省了区块体积。
Schnorr 签名算法由 Claus Schnorr 于 1991 年申请专利,在 2008 年到期,在专利到期以后,该算法就可以免费使用。在 2019 年 5 月份,BCH 正式发布新版本,其中实现了 Schnorr 签名。在今年 7 月的时候,Zcash 基金会发布了新的 FROST (Flexible Round-Optimized Schnorr Threshold),具体参阅https://www.zfnd.org/blog/frost-update/,相类似的签名优化方案有 Two-Round,在之后的系列会有相关介绍。
在以前,比特币签名方案一直是 ECDSA,签名方案的选择,要有公开,隐私性强,破解难度高,体积小等优点,在当时 RSA 和 ECDSA 的选择下,最后选择了 ECDSA,不得不说这是正确的决定,相对来说,ECDSA 和 RSA 相比之下,密钥更短,计算更快,安全性更强。在研究区块体积和验证速度上,出现了 Schnorr 签名方案,这种方案和传统的 ECDSA 相比,公钥体积可以更小,并且支持线性,不需要每个输入都对应一个公钥,类似于叠加的方式,签名时组合出最终的公钥,而验证的时候,也极大的节省了时间和空间。
在加密算法上,Schnorr 签名同样可以使用椭圆曲线,甚至可以使用和比特币同样的椭圆曲线secp256k1,这意味着,切换的成本降低了许多。
那么具体什么是 Schnorr 签名,如何验证 Schnorr 签名?如何在 Schnorr 签名上实现 m-n 多重签名。
首先我们的私钥可以认为成一个特别大随机的数字 x,乘以在椭圆曲线上的 G 点,而这个过程是不可逆的,最后结果在大量的运算下是无法推到出之前的特别大随机的数字即私钥,这将是我们讨论的基础,而数字签名的过程中,某个人想要对一段信息做签名,如何验证其的合法性,确保其拥有一定的承诺。这里这一段消息称之为 m,m 和 x 之间使用乘法进行组合,再进行椭圆曲线函数的计算。如果这样推导公钥的话,很有可能会反推出私钥,通过进行相约,会有暴露私钥的风险,所以在签名的过程中,引入了一个每次都不同的随机值k,进行组合。其中我们将椭圆曲线计算称之为 G,因此可得以下公式:
1 | (k + m*x)*G = k*G + (m*x)*G |
按上面公式进行扩展:
这里将 k*G
称之为 R,在之后会称之为签名的一部分,x*G
称之为 P,可以理解为私钥对应的椭圆曲线公钥。
这里 H(R,m)
为对消息 m 进行哈希处理时,使用 R,有时也写成 H(R||m)
,以表达追加。
1 | R = k * G |
以此计算出了 R,s 两值,这将作为签名的 R、S 。在比特币中,这对(R,s)使用64个字节进行编码,其中前32个字节表示R,后32个字节表示s。
在验证时,会提供 R,s,P。P 为私钥 x 对应的公钥,且无法反推出私钥。
主要检查:
由 s 值的定义:
1 | s = k + H(R,m)* x |
等式两边同时乘以椭圆曲线 G:
1 | s * G = k * G + H(R,m)* x * G |
那么可得:
1 | s * G = R + H(R,m)* P |
这个显然当提供 R,s,P 且正确的时候,是可以成立的。
但是这个时候,是容易受到 “related-key attacks”(相关密钥差分攻击) 的影响,第三方会有替换的思路,利用信息输入上的差别对输出结果变化的影响,从而破解相关的密钥。
于是提出了将公钥也参与哈希运算,那么最终的 s 和证明公式会变成:
1 | s * G = R + H(R || P || m)* P |
在介绍的 Schnorr 签名的过程以后,不可避免的会被其独有的特性而感兴趣,它是如何实现线性的呢。
当消息 m 相同时,Schnorr 可以做合并的操作,可以在验证时,仅做一次,而之前的 ECDSA,需要进行每一个签名的验证。
用公式表达如下:
1 | SchnorrSign(x 1,k 1,m)+ SchnorrSign(x 2,k 2,m)= SchnorrSign(x 1 + x 2,k 1 + k 2,m) |
推导过程如下:
1 | SchnorrSign(x 1,k 1,m)+ SchnorrSign(x 2,k 2,m) |
比特币使用的 ECDSA 签名(DER编码)的长度为 70 或 71 个字节,而 Schnorr 签名仅为 64 个字节(R,s 各 32 字节)。
在近期,签名导致的事故也有所发生。
总所周知,多重签名方案需要一组多个签名密钥(X 1,X 2,…,X n),这些签名密钥共同为消息生成签名。最常见的就是 Pay to Script Key Hash,P2SH。按照 btc.com 的脚本统计,类似的交易也在不断增长中。
那么 Schnorr 如何实现多重签名呢?
这时,提出了 MuSig 的方案。
Schnorr 的核心内容是其线性,根据其特性,多重签名的过程主要包括以下内容:
多签名的核心问题,是如何更好地进行密钥聚合(Key Aggregation)。
一开始的方案是各方每一方都有对应的公钥,这些公钥都在椭圆曲线的点上,因此可以进行加法运算进行聚合,那么根据椭圆曲线的加法之后,是一个新点,并且也将签名的 R,s 也做累加,然后进行验证。
但是这种方案,容易受到 Rogue Key Attack 类似的攻击,一些 CTF 比赛甚至有类似的题目,和上面的差分攻击不同,这个思路是攻击者去欺骗别人一起聚合,那么可以得到一个最终的聚合点,这时,攻击者再减去自己的点,也可以正常广播出符合签名校验的内容。
于是在这个过程中进行了升级,将中间的过程也进行公开,然后可以各方进行验证,引入随机数nonce,先发布承诺(对随机数的哈希运算的值),而并不会直接得到最终的聚合密钥。
具体过程可以详细查阅论文。
这个过程整体用了三轮,而在最近,Blockstream 研究人员发表了一篇新论文《MuSig2: Simple Two-Round Schnorr Multi-Signatures》(https://eprint.iacr.org/2020/1261),有兴趣的可以简单看看,具体会在之后的系列进行相关分析。
在 2019 年 5 月,BCH 常规硬分叉升级中,支持了 Schnorr 签名,而在当年 11 月的升级中,更是直接对 OP_CHECKMULTISIG 支持了 Schnorr 签名,@checksum0,发布了利用 Schnorr 签名的多重签名的示例:https://gist.github.com/checksum0/47d5ee7ee513a9d2e9fcb0b2761c7c73
目前来说,BCH 是不支持 Schnorr 和 ECDSA 混合进行多签名的,在未来大多数钱包和应用支持 Schnorr 签名,这样在区块体积和验证速度上会有一定的效果和提升。
以 2b5fe26f6f903021b343da52d8d8b316c88986c480cfd6fc80ffbc027cbd2039 这笔交易为例:
将 bitcoincash:qr2n5jt6sfnd06ts25l9dqg2sycc8q6qvv6eyk65lq 的输出进行了花费。
构造出的验证脚本如下:
1 | OP_DUP |
通过示例中的私钥公钥,最后构造出以下原始交易:
1 | 01000000016377d5d92f7244deddab0c3cf0268d2005eee238491fa6c8cb40e43b0e98245e010000006441f7f9f9ca507031b26c972fc23ab9b052843f7c3b3ee4e29acdd4dc09dbc03addf9f07e069d52009f5ded90a741c5223b90b20e39ebf9af37b0ca3ef1010959c0412102ff08fda3ea73d50eb7c52f82b55d7883e1843c7e6c80ba0daf08032f2e88692efeffffff020000000000000000866a4c834243482069732061626f757420676976696e672070656f706c65207468652066726565646f6d20746f206d616b65207468656972206f776e2063686f696365732c20746f20707572737565207468656972206f776e2068617070696e6573732c20686f7765766572207468657920696e646976696475616c6c7920736565206669742e3a9598000000000017a914785ca29645c56f51ff2581dd29e812764fe79636871ae60800 |
并且在第一个输出里,opreturn 对 BCH is about giving people the freedom to make their own choices, to pursue their own happiness, however they individually see fit.
消息进行了编码。
Schnorr Signatures for secp256k1:https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
隐私加密系列|MuSig Schnorr签名方案:https://www.qukuaiwang.com.cn/news/147169.html
MuSig2: Simple Two-Round Schnorr Multi-Signatures:https://www.chainnode.com/doc/4807
MuSig:一个新的多重签名标准:https://blockstream.com/2019/02/18/zh-musig-a-new-multisignature-standard/
Simple Schnorr Multi-Signatures with Applications to Bitcoin:https://eprint.iacr.org/2018/068.pdf
Key Aggregation for Schnorr Signatures:https://blockstream.com/2018/01/23/en-musig-key-aggregation-schnorr-signatures/
https://bch.btc.com/2b5fe26f6f903021b343da52d8d8b316c88986c480cfd6fc80ffbc027cbd2039
]]>高正炎,BTC.com
整理:赵宇彤(Apache Flink China 社区志愿者), 苗文婷(Apache Flink China 社区志愿者)
摘要:本文主要介绍BTC.com团队,在实时 OLAP 方面的技术演进,主要包括5个方面:业务背景:BTC.com主要做比特币或者以及区块链相关的一些业务;机遇挑战:原有架构存在的挑战;架构演进:从技术选型,到整个架构搭建;架构优化:基于 Flink 和 ClickHouse 做优化;未来展望;
首先介绍一下我们的业务。总结来说就是ABCD, A是人工智能机器学习,B是区块链,C代表云,D是数据。这些模块不是独立的,是可以结合起来的。为什么这几年人工智能,区块链这么热门呢?因为大数据给了他们很好的支持。
区块链是一个不可逆的分布式账本,我们的作用是让大家能更好的浏览账本。挖掘账本背后的信息数据。目前比特币的数据量级大概在几十亿到百亿,数据量大概在数10T,当然我们也有其他的一些货币,包括一些以太坊等的货币,还有智能合约分析的服务。
总的来说我们是一家区块链技术方案的提供商。俗话说得好,炒币毁一生,挖矿富三代。所以我们也提供挖矿的服务,跟其他做金融的银行一样,我们也有很多的 OLAP 需求,比方说黑客攻击了一些交易所,或者是一些供应链上的攻击,他想把钱转走。这时需要经过链上的操作,包括洗钱,在链上我们可以对它进行分析,分析他去了你的交易所进行洗钱,以及交易上的跟踪,统计数据。
2.1 之前的架构
大概2018年的时候,竞争对手比较少,我们整体的架构就是上图。底层是区块链的节点,通过 Parser 不断的解析到 MySQL ,再从 MySQL 抽取到 Hive 或者 Presto ,从 Spark 跑各种定时任务分析数据,再通过可视化的查询,得到报表或者数据。架构的问题也是显而易见的:
2.2 遇到的需求与挑战
2.3 技术选型我们需要考虑什么
在技术选型的时候我们需要考虑什么呢?首先是缩容。今年(2020年)行情不太好,大家都在尽力缩减成本,更好的活下去。在成本有限的情况下,我们如何能做更多的东西,必须提高自身的效率,同时也要保证质量。所以我们需要找到一种平衡,在成本效率还有质量这三者之间进行一定的平衡。
俗话说的好,工具选的好,下班下的早,关于是否引入 Flink,我们想了很久,它和 Spark 相比优势在哪里?我们实际调研以后,发现 Flink 还是有很多优势,比方说灵活的窗口,精准的语义,低延迟,支持秒级的,实时的数据处理。
因为团队本身更熟练 Python ,所以我们当时就选择了 PyFlink ,有专业的开发团队支撑,近几个版本变化比较大,实现了很多功能。在实时 OLAP 方面,数据库我们采用了 ClickHouse 。
为什么要使用 ClickHouse ?首先是快,查询的效率高。字节跳动,腾讯,快手等大公司都在用,老板觉得靠谱。同时我们也有 C++方面的技术积累,使用起来比较容易,成本不是太高。
于是我们就形成了上图的架构,底层是数据源,包括区块链的节点,右边的这些,通过 Parser 解析到 Kafka ,Kafka 负责对接 Flink 和 Spark 任务,Flink 把数据输出到 MySQL 和 ClickHouse 。支持报表导出,数据统计,数据同步,OLAP 统计。我们的基础架构,比较适合中小公司,大公司比较复杂,中间会加很多 Kafka 。
数据治理方面,我们参考了业界的分层,分成了原始层、明细层、汇总层以及应用层。
我们还有机器学习的任务,也在这上面跑的。这些都部署在 k8s 平台上。
我们的架构演进过程如上图,从2018年的 Spark 和 Hive ,到后来的 Tableau 可视化,今年接触了 Flink ,下半年开始使用 ClickHouse ,后来 Flink 任务比较多了,我们开发了简易的调度平台,开发者只需要上传任务,就会定时或者实时的跑任务。
为什么演进这么慢,因为区块链的发展还没有达到一定量级,不可能像某些大公司,有上亿 B 级别或者 PB 级别的数据量。我们的数据量没有那么大,区块链是一个新鲜的事物,没有一定的历史。另外的问题就是钱不够,能用钱解决的问题都不是问题。我们的人员不足,人员成本上也有所控制。
刚才讲的架构,我们总结了它适合怎样的企业。首先是有一定的数据规模,比方说某个企业 MySQL 只有几千万的数据,用 MySQL , Redis , MongoDB 都可以,就不适合这套架构。其次是需要一定的成本控制,这一整套成本算下来比 Spark 那一套会低很多。要有技术储备,要开发了解相关的东西。
区块链数据的特点。数据量比较多,历史数据基本上是不变的,实时数据相对来说是更有价值的,数据和时间是有一定的关联的。
Flink 和 ClickHouse 之间有一些联动,我们自定义了三个工作。
我们也在做一些开源方面的跟进,做一些补丁方面的尝试,把我们业务上,技术上常用的 UDF ,集合在一起。
比方说导入某一个东西失败了,我们如何更好的发现这些东西,以前+ 话,只能去人肉监控。
他上面一条链是一个重组并且分叉的一条链,比方说有一个攻击者或者是有一个矿工,他去挖了上面那一条链,最终的结果是他这一条链被废弃掉了,拿不到任何奖励,
如果超过51%的算力,就会达到这样的效果,成为最长的链,这个是累计难度比较高的,这个时候我们会认为导入失败,在实时数据中导入失败,是一个不完整的分叉。
比方说是上一部分,我们是可以认为从导入失败的一种情况,我们会利用回撤的功能,不断的把它回滚回去,进行重组,直到他满足最完整的那一条链。当然我们也会设置一些记录和 CheckPoint ,这里的 CheckPoint 和 Flink 的 CheckPoint 的概念是不太一样的。
它是区块链方面的 CheckPoint ,区块链有一个币种叫 bch ,会定义 CheckPoint,当满足一定的长度的时候,它无法再回滚回去,这正好就避免了攻击者去攻击他。我们主要是利用 CheckPoint 记录信息,防止它回滚,同时我们还会按照级别/表记录,批量插入的失败或者成功,如果失败就会进行重试,进行报警回滚等操作。
ClickHouse 不支持 Upsert ,主要在 sdk 方面做兼容,之前是直接往 Mysql 写数据,目标就是 sql 语句,修改对应的 sdk 增加临时小表的 join ,通过 join 临时小表,进行 Upsert 的操作。
给大家举个例子,区块链地址账户余额,就像银行的账户余额,必须非常的精确。
Kubernetes 方面的优化。Kubernetes 是一个很完整的平台。
使用Prometheus作为监控工具。使用方便,成本较低。
总的来说的话,路漫漫其修远兮,使用 Flink 真不错。谢谢大家。
大家好,我们是 BTC.com 团队。 2020 年,我们有幸接触到了 Flink 和 PyFlink 生态,从团队自身需求出发,完善了团队内实时计算的任务和需求,搭建了流批一体的计算环境。
在实现实时计算的过程中,我们在实践中收获了一些经验,在此分享一些这方面的心路历程。
作为工程师,我们每天都在不断地了解需求,研发业务。
有一天,我们被拉到了一次团队总结会议上,收到了以下的需求:
销售总监 A:
我们想要知道销售的历史和实时转化率、销售额,能不能统计一下实时的 TOP5 的商品,还有就是大促时候,用户实时访问、商品实时浏览量 TOP5 的情况呢,可以根据他历史访问的记录实时推荐相关的吗。
市场总监 B:
我们想要知道市场推广的效果,每次活动的实时数据,不然我们的市场投放无法准确评估效果,及时反馈啊。
研发总监 C:
有些用户的 bug 无法复现,日志可以再实时一点吗?传统日志分析,需要一定的梳理,可不可以直接清洗 / 处理相关的数据?
采购总监 D:
这些年是不是流行数字化,采购这边想预测采购需求,做一下实时分类和管理支出,预测未来供应来源,完善一下成本。这个有办法做吗?还有有些供应商不太稳定啊,能监控到他们的情况吗?
运维总监 E:
网站有时候访问比较慢,没有地方可以看到实时的机器情况,搞个什么监控大屏,这个有办法解决吗?
部门领导 F:
可以实现上面的人的需求吗。
做以上的了解之后,才发现,大家对于数据需求的渴望程度,使用方不仅需要历史的数据,而且还需要实时性的数据。
在电商、金融、制造等行业,数据有着迅猛的增长,诸多的企业面临着的新的挑战,数据分析的实时处理框架,比如说做一些实时数据分析报表、实时数据处理计算等。
和大多数企业类似,在此之前,我们是没有实时计算这方面的经验和积累的。这时,就开始困惑了,怎样可以更好地做上面的需求,在成本和效果之间取得平衡,如何设计相关的架构。
穷则思变,在有了困惑以后,我们就开始准备梳理已有的条件和我们到底需要什么。
首先我们的业务范围主要在区块链浏览器与数据服务、区块链矿池、多币种钱包等。在区块链浏览器的业务里,BTC.com 目前已是全球领先的区块链数据服务平台,矿池业务在业内排行第一,区块链浏览器也是全球前三大浏览器之一。
首先,我们通过 parser 解析区块链上的数据,得到各方面的数据信息,可以分析出每个币种的地址活跃度、地址交易情况、交易流向、参与程度等内容。目前,BTC.com 区块链浏览器与行业内各大矿池和交易所等公司都有相关合作,可以更好地实现一些数据的统计、整理、归纳、输出等。
面向的用户,不仅有专业的区块链开发人员,也有各样的 b 端和 c 端用户,c 端用户可以进行区块链地址的标注,智能合约的运行,查看智能合约相关内容等,以及链上数据的检索和查看。b 端用户则有更专业的支持和指导,提供 API、区块链节点等一些的定制以及交易加速、链上的业务合作、数据定制等。
从数据量级来讲,截至目前,比特币大概有 5 亿笔交易,3000 多万地址,22 亿输出(output:每笔交易的输出),并且还在不断增长中。以太坊的话,则更多。而 BTC.com 的矿池和区块链浏览器都支持多币种,各币种的总数据量级约为几十 T。
矿池是矿工购买矿机设备后连接到的服务平台,矿工可以通过连接矿池从而获取更稳定的收益。这是一个需要保证 7 * 24 小时稳定的服务,里面有矿机不断地提交其计算好的矿池下发的任务的解,矿池将达到网络难度的解进行广播。这个过程也可以认为是近乎是实时的,矿机通过提交到服务器,服务器内部再提交到 kafka 消息队列,同时有一些组件监听这些消息进行消费。而这些提交上来的解可以从中分析出矿机的工作状态、算力、连接情况等。
在业务上,我们需要进行历史数据和实时数据的计算。
历史数据要关联一些币价,历史交易信息,而这些交易信息需要一直保存,是一种典型的批处理任务。
每当有新区块的确认,就有一些数据可以得到处理和分析,比如某个地址在这个区块里发生了一笔交易,那么可以从其交易流向去分析是什么样的交易,挖掘交易相关性。或者是在这个区块里有一些特殊的交易,比如 segwit 的交易、比如闪电网络的交易,就是有一些这个币种特有的东西可以进行解析分析和统计。并且在新区块确认时的难度预测也有所变化。
还有就是大额交易的监控,通过新区块的确认和未确认交易,锁定一些大额交易,结合地址的一些标注,锁定交易流向,更好地进行数据分析。
还有是一些区块链方面的 OLAP 方面的需求。
总结了在数据统计方面的需求和问题以后,我们就开始进行思考:什么是最合适的架构,如何让人员参与少,成本低。
解决问题,无非就是提出假设,通过度量,然后刷新认知。
在浏览了一些资料以后,我们认为,大部分的计算框架都是通过输入,进行处理,然后得到输出。首先,我们要获取到数据,这里数据可以从 MySQL 也可以从 Kafka,然后进行计算,这里计算可以是聚合,也可以是 TOP 5 类型的,在实时的话,可能还会有窗口类型的。在计算完之后,将结果做下发,下发到消息渠道和存储,发送到微信或者钉钉,落地到 MySQL 等。
团队一开始尝试了 spark,搭建了 yarn,使用了 airflow 作为调度框架,通过做 MySQL 的集成导入,开发了一些批处理任务,有着离线任务的特点,数据固定,量大,计算周期长,需要做一些复杂操作。
在一些批处理任务上,这种架构是稳定的,但是随着业务的发展,有了越来越多的实时的需求,并且实时的数据并不能保证按顺序到达,按时间戳排序,消息的时间字段是允许前后有差距的。在数据模型上,需求驱动式的开发,成本相对来说,spark 的方式对于当时来说较高,对于状态的处理不是很好,导致影响一部分的效率。
其实在 2019 年的时候,就有在调研一些实时计算的事情,关注到了 Flink 框架,当时还是以 java 为主,整体框架概念上和 spark 不同,认为批处理是一种特殊的流,但是因为团队没有 java 方面的基因和沉淀,使用 Flink 作为实时计算的架构,在当时就暂告一个段落。在 2020 年初的时候,不管是阿里云还是 infoq,还是 b 站,都有在推广 PyFlink,而且当时尤其是程鹤群和孙金城的视频以及孙金城老师的博客的印象深刻。于是就想尝试 PyFlink,其有着流批一体的优势,而且还支持 Python 的一些函数,支持 pandas,甚至以后还可以支持 tensorflow、keras,这对我们的吸引力是巨大的。在之后,就在构思我们的在 PyFlink 上的流批一体的架构。
首先我们要梳理数据,要清楚数据从哪里来。在以 spark 为主的时期,数据是定期从数据源加载(增量)数据,通过一定的转换逻辑,然后写入目的地,由于数据量和业务需要,延迟通常在小时级别,而实时的话,需要尽可能短的延迟,因此将数据源进行了分类,整体分成了几部分,一部分是传统的数据我们存放在 MySQL 持久化做保存,这部分之后可以直接作为批处理的计算,也可以导入 hive,做进一步的计算。实时的部分,实际上是有很多思路,一种方式是通过 MySQL 的 binlog 做解析,还有就是 MySQL 的 cdc 功能,在多方考量下,最后我们选择了 Kafka,不仅是因为其是优秀的分布式流式平台,而且团队也有对其的技术沉淀。
并且实际上在本地开发的时候,安装 Kafka 也比较方便,只需要 brew install kafka
,而且通过 conduktor 客户端,也可以方便的看到每个 Topic 的情况。于是就对现有的 Parser 进行改造,使其支持 Kafka,在当收到新的区块时,会立即向 Kafka 发送一个消息,然后进行处理。
大概是在 2018 年的时候,团队将整体的业务迁移到了 kubernetes 上,在业务不断发展的过程中,其对开发和运维上来说,减轻了很多负担,所以建议有一定规模的业务,最好是迁移到 kubernetes,其对成本的优化,DevOps,以及高可用的支持,都是其他平台和传统方式无法比拟的。
在开发作业的过程中,我们在尽可能的使用 Flink SQL,同时结合一些 Java 、Python 的 UDF,UDAF,UDTF。每个作业通过初始化类似于以下的语句,形成一定的模式:
1 | self.source_ddl = ''' |
在未来的话,会针对性地将数据进行分层,按照业界通用的 ODS、DWD、DWS、ADS,分出原始层,明细层和汇总层,进一步做好数据的治理。
最终我们团队基于 PyFlink 开发快速地完成了已有的任务,部分是批处理作业,处理过去几天的数据,部分是实时作业,根据 Kafka 的消息进行消费,目前还算比较稳定。
部署时选择了kubernetes,具体下面会进行分享。在 k8s 部署了 jobmanager 和 taskmanager,并且使用 kubernetes 的 job 功能作为批处理作业的部署,之后考虑接入一些监控平台,比如 Prometheus 之类的。
在成本方面,由于是使用的 kubernetes 集群,因此在机器上只有扩展主机的成本,在这种方式上,成本要比传统的 yarn 部署方式要低,并且之后 kuberntes 会支持原生部署,在扩展 jobmanager 和 taskmanager 上面会更加方便。
Zeppelin 是我们用来进行数据探索和逻辑验证,有些数据在本地不是真实数据,利用 Zeppelin 连接实际的链上数据,进行计算的逻辑验证,当验证完成后,便可转换成生产需要的代码进行部署。
一、kubernetes 上搭建 PyFlink 和 Zeppelin
1). flink-conf.yaml
1 | taskmanager.numberOfTaskSlots: 10 |
这里可以调整 Taskmanager 可运行的的 job 的数量
2). zeppelin-site.xml
1 | cp conf/zeppelin-site.xml.template conf/zeppelin-site.xml; \ |
1 | nginx.ingress.kubernetes.io/configuration-snippet: | |
Zeppelin 在浏览器需要和 server 端建立 socket 连接,需要在 ingress 添加 websocket 配置。
1 | - mountPath: /opt/flink/lib |
1). 本地安装 PyFlink
1 | $ pip3 install apache-flink==1.11.1 |
2). 测试 demo
1 | def word_count(): |
或者是实时处理的 Demo:
1 | def handle_kafka_message(): |
1 | $ flink run -m localhost:8081 -py word_count.py |
1 | $ zip -r flinkdemo.zip ./* |
随着区块链技术的越来越成熟,应用越来越多,行业标准化、规范化的趋势也开始显现,也越来越依赖于云计算、大数据,毕竟是数字经济的产物。BTC.com 也在扎根于区块链技术基础设施,为各类公司各类应用提供数据和业务上的支持。
近些年,有个词火遍了 IT 业界,中台,不管是大公司还是创业公司,都喜欢扯上这个概念,号称自己业务中台,数据中台等。我们的理解中,中台是一种整合各方面资源的能力,从传统的单兵作战,到提升武器装备后勤保障,提升作战能力。在数据上打破数据孤岛,在需求快速变化的前台和日趋稳定的后台中取得平衡。而中台更重要的是服务,最终还是要回馈到客户,回馈到合作伙伴。
在区块链领域,BTC.com 有着深厚的行业技术积累,可以提供各方面数据化的能力。比如在利用机器学习进行链上数据的预估,预估 eth 的 gas price,还有最佳手续费等,利用 keras 深度学习的能力,进行一些回归计算,在之后也会将 Flink、机器学习和区块链结合起来,对外提供更多预测类和规范化分类的数据样本,之前是在用定时任务不断训练模型,与 Flink 结合之后,会更加实时。在这方面,以后也会提供更多的课题,比如币价与 Defi,舆情,市场等的关系,区块链地址与交易的标注和分类。甚至于将机器学习训练的模型,放于 IPFS 网络中,通过去中心化的代币进行训练,提供方便调用样本和模型的能力。
在目前,BTC.com 推出了一些通过数据挖掘实现的能力,包括交易推送、OLAP 链上分析报表等,改善和提升相关行业和开发者实际的体验。我们在各种链上都有监控节点,监控各区块链网络的可用性、去中心化程度,监控智能合约。在接入一些联盟链、隐私加密货币,可以为联盟链、隐私加密货币提供这方面的数据能力。BTC.com 将为区块链产业生态发展做出更多努力,以科技公司的本质,以技术发展为第一驱动力,以市场和客户为导向,开发创新和融合应用,做好基础设施。
从实时计算的趋势,到流批一体的架构,通过对 PyFlink 和 Flink 的学习,稳定在线上运行了多种作业任务,对接了实际业务需求。并且搭建了 Zeppelin 平台,使得业务开发上更加方便。在计算上尽可能地依赖 SQL,方便各方面的集成与调试。
在社区方面,PyFlink 也是没有令我们失望的,较快的响应能力,不断完善的文档。在 Confluence 上也可以看到一些 Flink Improvement Proposals,其中也有一些是 PyFlink 相关的,在不远的将来,还会支持 Pandas UDAF,DataStream API,ML API,也期望在之后可以支持 Joblistener,总之,在这里也非常感谢相关团队。
未来的展望,总结起来就是,通过业务实现数据的价值化。而数据中台的终局,是将数据变现。
当学习久了以后,就会意识到效率的重要性。计算机行业日新月异,作为一名计算机爱好者,同时也关注效率的人来说,需要不断的学习,才能跟得上发展。
Personal Knowledge Management,个人知识管理,可以参照维基百科。
我觉得个人知识管理主要分为输入、处理、输出、分享几个部分,如思维导图所示。
同时打造闭环,并且还在不断的补充中。
现在已经是信息大爆炸的时代了,无处不存在信息,好多都已经是大数据的级别了,我们可以通过各种方式去获得信息,但是获取到的信息,往往是需要脱敏,过滤,分类的。
在人工智能和推荐系统越来越流行的今天,如何获取到对自己有效的信息,才是这个阶段需要考虑的,最近也在思考如何构建一个 chatbot platform,将自己想要的信息进行整合推荐。
一方面使用 feedly 订阅自己技术相关的RSS,如下图所示。然后 ipad、mac 上客户端使用 Reeder 工具,相类似的RSS订阅器还有 inoreader 。
微博/推特关注牛人以及行业相关,及时了解技术动态,感受技术的风向标。
总结一些专业方向好的信息汇总,比如码农周刊,腾讯玄武实验室,SecWiki等。
当然知识并不一定只有文章的形式,也可以通过各种公开课获取知识,以及播客等等。因此可以将输入的知识按获取的形式进行分类。
当然信息的输入并不只有技术相关的,比如文学方面,做人以及工作方面,以及兴趣爱好等等,都有相关的获取方式。
可以通过利器不断地找到自我提升的工具,比如利用种子习惯去让自己养成习惯。
比如发现人生中的美好事物可以在堆糖,可以在 mindstore 获得一些灵感及想法。
1.稍后阅读 Pocket,以及instapaper,Pocket主要放一些自我感觉质量比较高,值得反复去阅读的文章。而instapaper会放一些平时可以得到一些启示,或者值得去实践的文章。
2.开始试用一下 TheBrain。
workflowy 作为自己的知识 wiki,并对外分享,evernote作为学习和整理的笔记。
mybase 作为自己的摘抄知识库。
1.分享在博客这类的自我空间,做自我整理与思考。
2.简书类的平台。
1.workflowy 作为自己的计算机知识 wiki,其特有的树状结构还是可以弄清楚相互的关系的。
2.Evernote 作为自己的整理与学习的笔记,在最初的时候也用过有道云笔记,那会还是不知道该如何记笔记,
3.mybase 作为摘抄,如何快速的进行摘抄,这就成了一个问题,当然文件的话,按坚果云同步。
4.boostnote 作为代码管理工具
1.在试用了一段时间的番茄土豆以后,感觉对自己的工作提升还是有一定的作用的,尤其是任务比较小而碎的情况下,这也许是工作效率的提升。
2.在试用了一段时间的滴答清单以后,感觉还比较满意,以前也用过很多的TODO软件,(包括高效Todo等),那会在录入的过程中觉得繁琐。
3.在试用了一段时间的种子习惯以后,发现自己没有对其的执行力,也许是自我感觉在忙,觉得滴答清单上的东西总是有些没做,建立了几个习惯,但是没有很好的执行。
4.是不是应该引入一种优先级的策略,通过设定一个优先级,然后低于某个值,可以暂时不做,可是又感觉是在给自己找了个借口,人类总是自我矛盾体。
这篇文章想了很久,一方面自我总是会拖延,缺乏执行力,另一方面总是在想一些毫无边际的事情,比如智慧大脑,自动化机器人,而没有太多专门的时间去思考自我的效率。
人生总是聚少离别多,我们又有多少的奈何。
记于2017年4月29日。
]]>本文从 DevOps 的角度去浅显地探讨软件安全开发周期,而建设软件安全开发周期任重而道远,而面对大多数公司的安全性问题,能否使用软件安全开发周期解决。并且 DevOps 作为周期很重要的一环,如何推动公司的安全体系建设。当然 SDL 并不是银弹,只是能大量减少软件安全缺陷。
现如今,DevOps 的概念已经对于互联网公司来说不是陌生了,随着诸多大公司的推进,越来越多的公司用上了 DevOps,有些公司从中体验到了快捷之处,也有公司感觉到了复杂性。不像其他方面,DevOps 至今都没有一个完整的标准或者是实现方案,大多数都是一些大公司的实践。
而中小企业或者创业公司,需不需要 DevOps 呢?大多数创业公司还是需要一种敏捷性,追求快速迭代开发,希望早点上线,早点运营,抢占用户。在公司里规划 DevOps 团队,自然就显得比较重要,可以提高产品的交付能力与效率。近几年,Docker,Kubernetes 的出现,极大地增加了我们对于 DevOps 的渴望。
通过 Docker 进行持续集成,极大地提升了我们持续交付的能力。并且它可以达到开发与生产环境一致的效果,从原来的一天部署一次,通过它的可持续可以一天构建几十次之多。使得 Dev 和 Ops 的关系从原来的相互独立变成了相互融合,实际上还可以引入 QA 等人员。
当熟悉了 DevOps 的最佳实践了以后,运用一些自动化工具,改变传统的开发部署流程,提高部署速度,构建可扩展的技术架构,
提升软件交付的效率。从下图也可以看出,企业对于 DevOps 的重视程度在不断增加。
近几年,政府与各大公司在不断地推进网络安全的发展,但是还是每天有很多应急,数据泄露事件的发生。有数据表明,大多数网络安全问题是由 SQL 注入、网站后门、代码注入、未授权访问、弱口令等造成的。
像这些问题是如何造成的呢,有很大一部分是由于开发上的不完善,导致有些地方可以利用,比如 SQL 注入,XSS 之类的,在代码上没有做好过滤,或者是进行参数化查询,而这些问题在开发的过程中就有能力去解决,可以使用一些代码审计或者代码检查服务。而中小公司,创业公司并没有配备专业的安全团队,而这些安全问题往往是致命的,可以被拿到权限,或者关键数据库等,而安全对于用户的影响也是很重要的。
如何去解决这些问题呢?有一种方法是采用一些安全测试,使用专门的人员进行黑盒测试,而这种的并不能找到所有的问题,还是会有一些问题遗漏,并且这种成本较高,普通小公司初期往往不能接受,如果领导层面不重视安全的话,必然会出现很多问题。而中小公司的安全问题如何去解决,大多数普通开发者对于安全审计的知识了解尚浅,所以需要一个自动化,在开发过程中进行代码检查的工具,使开发者了解到其危害,并定期做一些科普性的交流。这样可以减少一定的风险,而成本不会投入太多。
中小公司、创业公司,在业务的不断成长的情况下,总是会遇到很多安全性,以及开发上的部署,测试等流程上的问题。如何去面对这种问题呢?
微软在最初的时候,也有开发周期上的不完善,导致出现了很多安全问题,比如缺少安全设计,缺少安全编程规范,开发者安全意识不足等,并且当时 IIS 引发了不少安全 bug,导致当时安全不容乐观。而微软在推动软件安全开发生命周期(SDL)以后,如同“微软:引领软件安全趋势”给我们带来了这样的印象。实际说明了 SDL 带来的效果。
软件安全开发周期包括什么呢?包括安全编码培训、安全威胁建模、安全设计、安全应急响应、安全配置、安全测试、安全部署等。它只是一个体系,具体实施的时候,还得看实际情况。
安全编码培训就是提供不同的开发语言的安全规范,与安全团队或者安全负责人进行课程的建立,增强开发人员的安全意识。开发人员需要遵循安全编码规范,定期做一些代码检查之类的。在有些产品中,在设计阶段就应该引入安全部分。创建一些恶意的输入进行安全测试,并且把引用到的第三方开源控件也应该记录下来,及时升级新版本。并且对安全事件进行应急响应,规范修补漏洞的流程。
而现如今的敏捷开发方式,是争取早日上线,抢占用户,从漏洞报告的情况可得知,有很多不应该出现的安全缺陷。而安全开发周期这种体系,也许是因为领导的不重视,或许是没人进行推进,导致各种安全事件的发生。所以需要在项目管理的时候,引入安全开发周期的概念,建立相关模板,定期进行代码审计,规范环境配置,做好安全应急响应。
其实在开发与测试过程中,很多安全开发周期需要规范的地方,在 DevOps 部分可以体现。所以作为 DevOps。有必要协助进行 SDL 的建设。
在随着持续集成与持续交付建立好的情况下,发布会越来越频繁,而其中需要安全团队或者安全负责人进行定期的代码审查,而 DevOps 配置好一些自动化审计工具以后,会降低一些工作量,并且 DevOps 进行规范化配置,定期和运维去检查一些弱口令或者未授权访问的情况。提醒开发禁止使用一些危险可能造成漏洞的 API 或者函数。并且通过使用 Docker 统一环境,进行隔离,降低了由环境带来的安全风险。
在做安全应急响应的时候,有一部分事件是与部署或者环境有关的,比如 Docker 或者 etcd 未授权访问、弱口令、一些常见组件的安全漏洞(struts、脏牛、ImageMagick 等),这一部分由于是线上环境,所以需要 DevOps 去关注相关的动态,定期做一些培训或者检查,在有相关组件的安全漏洞时及时构建镜像进行升级,避免受到攻击。
对 CVE 进行关注,列出应用依赖的组件,避免通过组件拿到权限。并且与运维配置好相关防火墙,WAF,监控服务。做好身份校验。
由于业务的不同,每个公司的情况都不可能一致,所以需要 DevOps 和安全部门或者负责安全的人员进行共同做对应的配置及优化。
在小型的创业公司里,以上最好是可以弄在项目管理里,而常见的项目管理软件或者网站,并没有相关功能,而华为企业云在这块开发了软件开发云模块,里面提供了各种完善的管理机制,而对于软件园区、孵化器、互联网企业、软件外包行业、高校、培训机构这些应用场景来说,完整的软件管理周期就显得有核心竞争力。并且它有代码检查的功能,还可以自定义检查规则,其中提供了以下的服务
这是其他同类网站所没有的。并且相比较而言,以前得使用很多服务,比如 bugly,Jenkins,bugclose 或者 bugtags,trello 或者 tower,git 等。
实际上,软件安全开发周期还有很多内容,限于篇幅,不能一一列举探讨,而其他的比如安全培训,需求分析,测试,系统设计,发布,应急响应时候的安全规范,这个每个公司情况不尽相同,不能一概而论,并且 SDL 也不是银弹,不能解决全部的问题,但是对整体的安全性会有很大的提升,所以也希望大部分公司可以建设起自己的安全体系,建设属于自己的 SDL,解决大部分的安全问题,一起对安全作出自己的贡献。
]]>最近 android UI 布置了期末作业,以前总是不写作业,总觉得那些作业重复性太强,浪费太多时间。还不如将写作业的时间用在思考上面。不过自己还是喜欢那种课程设计的作业,课程设计的作业较普通作业来说,可以学到不少知识,可以整理出很多东西。几个人做出一个课设总觉得是一件很酷的事情,不过哪有几个人,很多时间都是一个人在做。不仅是对以往知识的掌握的练习,还可以自由地进行一定的扩展。
本次的试题总共有四个题目,分别代表了不同的应用,后面会尽量使用谷歌官方的组件来进行实现。
首先是模拟去哪儿网风格的卡片式手机客户端界面。
通过截图我们可以看到整体界面基本由三部分组成(第三幅图的标题栏可自行实现),底部由底部选项卡组成,上面是一个轮播图片组件,中间是一个类似于Win8的Merto风格的磁贴式风格。(题目上说下标签页,滑动导航,卡片式是什么鬼),这些基本就是这个试题的组成部分了,其他都是一些不重要或者很简单的东西了。
第二个是一个点菜应用界面设计。
看风格总像是一个在 iPad 上的应用,其中主要是以下几点:
1.设计成平板电脑横向应用(不可以旋转界面嘛)
2.界面实现左边菜谱分类导航,右边就是其分类下的菜品。这个就是意思是左边是一个 ListView,右边还是一个 ListView 或者 GridView,(当然都是 RecyclerView 也不反对),实际上截图上面左边是一个可扩展的ListView,这些不重要,重要的是右边内容是跟着左边的选项变化的。
3.关于详情介绍界面这个,把那个菜品对象传到另一个详情界面的 Activity,然后显示即可。以及选菜功能的话,这个其实有一点点复杂的,主要是选菜界面的部分,首先每个菜品上面需要有个单选框,来标记是否选择此菜品,选了以后,存到sharedprefences也好,数据库也罢,或者放到缓存里面,然后在我的已点菜界面可以查到相关信息。以及应该有个计算总价或者购物车的功能。
第三个是一个模拟手机QQ的界面,给出的截图也应该是5.x的版本,在以后的版本里,已经改回了侧滑菜单,不再有缩放效果。
上方的消息电话的切换效果,以前是用两张图片来切换的,然后中间内容是一个ViewPager控制下的Fragment,然后滑动一下,切换界面的时候,更改标题栏的图片。
这个题目需要有一个侧滑菜单,点击头像或者在左侧边缘部分向右滑动,可像抽屉似的出现一个菜单。
其他就是一些底部选项卡的,以及圆角头像,以及圆角头像的角标,弹出菜单的一些常规的东西了。
最后一个是一个新闻客户端,截图给了一个网易和凤凰视频的,两者结构上很相似,基本上是以下情况。
除去标题栏以后,一个顶部选项卡,(当然网易的还有沉浸式状态栏),然后一个轮播图片组件,一个ListView的新闻列表,(当然网易的还有一个垂直跑马灯效果的新闻组件),底部选项卡。
整体的这次课程设计就是这样子,实际上谷歌官方并不推荐这样布局的,谷歌有自己的设计语言Material Design,在5.0以后会越来越多的应用采用这个(当然国内大厂没遵循规范,其实他们也做过相关实践的),比如一些知乎、Youtube类似的应用,早已开始了这种风格的实践,并且谷歌官方推出了不少关于它的组件,让一个不懂设计的开发,也能做出一个好看的界面,而传统的风格是碎片化的,有些应用借鉴了iOS的设计,形成了自己的风格,需要美工和开发者的不断配合。
对于现在来说,个人开发者对Material Design熟悉一点比较好,不仅可以快速做出一些界面,还可以改善自己博客的风格。
底部选项卡,在2.3时期,采用了TabHost和TabActivity的方式(即课本采用的方式),现在早已不是2.3时期了,TabActivity也已经过期了。在引入了Fragment以后,底部选项卡的设计也有所变化。
在Material Design里,也对底部导航栏进行了统一设计规范,该规范明确给出了 BottomNavigation在设计,使用,交互,风格和尺寸等的使用。
实现Tab功能的几种方式也有人总结过,在Android学习笔记:TabHost 和 FragmentTabHost这篇文章也叙述了五种方法。
其中有种就是利用FragmentTabHost实现底部导航栏,在Activity里初始化的代码:
1 | fragmentTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); |
其中fragments是一个Fragment的数组,里面包含了标签卡的class。其中底部的按钮采用了RadioGroup的组件,标识其只能按下一个。并且实现其的选择改变的接口(OnCheckedChangeListener),然后里面需要使fragmentTabHost.setCurrentTab(0);
设置对应的标签页。
1 | private Class[] fragments = {HomeFragment.class, HomeFragment.class, |
布局代码:
1 | <android.support.v4.app.FragmentTabHost |
当然利用ViewPagerIndicator和PagerSlidingTabStrip也可以完成此功能,这里用了RadioButton。
1 | //style.xml |
1 | //selector_main_tab_home.xml |
效果图如下:
莫名地总想测一下时间,利用TraceView
测试initView()
(即初始化fragmentTabHost的代码)的结果如下:
这个轮播图片,这个好多大牛都自己实现过一次,如果时间不够,或者水平没达到一定程度,也可以借鉴一些开源组件,例如Kanner,PictureCarousel等。当然Trinea大牛也出过一篇名为Android自动滚动 轮播循环的ViewPager的分析。 限于篇幅,不能详细地分析了。
事实上,截图里的风格趋近于磁贴,真正的卡片式设计谷歌也早已在应用。但是这种交互性没有那么强,只有几个块状元素,应该触感上不如磁贴的。
因为没有什么特效,可以直接使用ImageView构建类似的风格,即如下图所示。
直接使用xml代码即可。
1 | //activity_main.xml |
#####0x05 Fragment平板电脑适配
以及如何禁止旋转呢。
在新建项目的时候,选择Master/Detail Flow
,然后运行到横向布局的平板上面,即是下图的效果。
它这里主要通过建立了layout-w900dp文件夹,来进行屏幕的适配,以及在java代码里面,通过以下判断,在Adapter里设定一个标志变量,以求响应不同的屏幕。
1 | if (findViewById(R.id.item_detail_container) != null) { |
禁止旋转的话,只需要在AndroidManifest.xml将对应的Activity的android:screenOrientation属性设为定值即可,比如纵向”portrait”,横向”landscape”。
#####0x06 左右ListView实现
这个以前也做过类似的,类似于外卖平台的商家界面,左边是分类,而右边是该分类对应下的商品。当时做的是网络应用,分类和商品都是网络获取的,当然现在这个自己生成一些数据就好。
主要是有两个Adapter,一个分类的Adapter,即左边的Adapter,一个右边的Adapter。Adapter和传统的写法一致。
布局xml代码:
1 | <LinearLayout |
其中ListView和GridView是在一个LinearLayout里,响应listView的点击事件,然后加载不同的数据源,配置Adapter。
1 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
关于QQ的侧滑界面,网上也有解析,使用了ViewDragHelper来进行手势的处理。
这个在新建项目的时候,我们就会发现一个名为Navigation Drawer Activity的选项。
我们可以选择它,一路Next。
然后运行应用,可以看到以下的效果。
分析这个应用的xml,整个界面的xml如下:
1 | <android.support.v4.widget.DrawerLayout> |
整体不难理解,是由一个DrawerLayout包含了整体的布局,然后CoodinatorLayout是界面的布局,而NavigationView是侧边栏导航的布局。其中DrawerLayout的文档里也说明了需要将primary content view作为第一个子节点,并且高度和宽度均为match_parent并且没有设置Layout_gravity,而抽屉需要在这个view之后,并设置layout_gravity,如果设置成start,即为从左向右滑动。
在java代码里,这个示例主要做了以下几件事情。
初始化并设置Toolbar
设置浮动按钮(FloatingActionButton)。
初始化DrawerLayout。由于ActionBarDrawerToggle实现了DrawerLayout.DrawerListener,所以直接使用其可以将DrawerLayout和ActionBar进行监听器的绑定。
初始化并配置NavigationView,其是谷歌标准的侧滑出来的布局,当然也可以自己实现一个布局,然后在Activity的xml布局里,在主内容之后添加。
其中menu也声明了是在activity_main_drawer.xml
文件里,可以修改其,以进行一些侧滑菜单项的配置。
我们在侧滑界面实现的那个Demo或者Base Activity
里面,其实已经实现了点击弹出菜单的样式,即官方实现,当然这个各自有各自的实现,我们当然也可以使用PopupMenu、PopupWindow之类的去实现这些效果,此次简要写一下官方实现Menu。
1 | //MainActivity.java |
1 | //main.xml |
#####0x09 顶部选项卡实现
在build.gradle
里引入
1 | compile 'com.android.support:design:24.0.0' |
1 | //xml代码 |
1 | //Activity代码 |
具体可以参考简书上的这篇Android开发之TabLayout实现顶部菜单的文章。如果要实现内容不是View,而是一个Fragment的话,只需要重写一下Adapter
,将对应的Fragment返回即可,具体可以查看FragmentStatePagerAdapter
的源码,以及以前写过类似的东西。
斜阳无限,无奈只一息间灿烂。
曾遇上几多风雨翻,编织我交错梦幻。
曾遇你真心的臂弯,伴我走过患难。
夕阳虽美,但却近黄昏。
梅艳芳曾经讲过,《夕阳之歌》是她一生的写照。也许在死亡面前,才能真正感悟。
各位都应珍惜时间,别到了最后,令自己后悔;珍惜眼前人,也许明日就是离别之时;珍惜身边的一切,经历过大风大浪才知,平淡美好的生活才是所向往的。未来怎样,无法预料,可是我们也得有面对未来的准备啊。扪心自问,问心无愧,足以。
]]>这里findViewById作用以及用法就不再叙述了,接触过Android开发的都明白其怎么用,这次主要分析如何提高其性能,并且使用TraceView分析,如何改善或者节省代码,使开发人员变得更懒。
环境:
1 | Mac 10.11 |
如何使用TraceView监测代码呢,在想要根据的代码片段之间使用以下两句代码,注意添加SD卡权限。当然也可以直接在DDMS中的面板里的Start Method Profiling
来监测方法。此次就将代码放置在initView()
方法里,以示区别。并且都是启动一次,再结束activity,然后再启动Activity去比较运行时间。
1 | Debug.startMethodTracing("debug_test"); |
这里采用的xml文件是这样的,其中包含了几个TextView,ImageView。
1 |
|
string.xml
1 | <resources> |
常规的即使用findViewById方法。即:
1 | textView1 = (TextView) findViewById(R.id.tv_demo1); |
测试结果如下:
如何使用注解这种的避免传统的findViewById
呢。
很多开源框架已经支持注解了,就以Android Annotations框架为例。
View注解也分运行时注解和编译时注解。
注解利用的原理也不一样,有的是利用反射,比如KJFrameForAndroid, xUtils, afinal, thinkAndroid,有的是利用aapt资源打包。反射自然效率比较低,在反射部分举例分析。
ButterKnife处理注解是在编译的时候,处理了@Bind、@OnClick等这些注解,所以效率比较高。
即:
1 |
|
结果如下:
1 | private <T extends View> T $(int resId) { |
1 | textView1 = $(R.id.tv_demo1); |
测试结果:
#####0x04 反射
前面也说过,有些注解框架实现视图注入是利用的反射机制,反射执行的效率是很低的。以xutils为例,测试代码:
1 |
|
在DDMS的测试结果如下。
Convert your Android XML layouts into a set of declarations and binds to save you all that manual typing. Enter a prefix for your fields, choose the scope paste in your XML and hit generate. Select “verbose” to find out why any fields are skipped.
http://android.lineten.net/layout.php
生成的结果如图所示。
DataBinding是谷歌官方推出的一款数据绑定框架。
使用起来比较方便,只需要在build.gradle文件里添加以下代码片段。
1 | android { |
具体的使用方法,网上也有很多,比如精通 Android Data Binding,以及官方文档。
1 | <layout xmlns:android="http://schemas.android.com/apk/res/android"> |
然后Activity里可以使用MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
进行数据绑定。
前面的类即是根据xml文件名自动生成的。
其中可以实现单向数据绑定。
想了那么多避免传统的findViewById的方法,有的性能差不多,有的性能比较低,但是官方基础实现永远是性能最快的。
1 | public final View findViewById(int id) { |
其中调用了findViewTraversal()
方法。
1 | protected View findViewTraversal(int id) { |
我们通常是在Activity里findViewById()
,所以需要看Activity代码。
1 | public View findViewById(int id) { |
getWindow()
的对象是继承ViewGroup的,在ViewGroup里,重写了findViewTraversal()
方法:
1 | protected View findViewTraversal(int id) { |
其中维护了一个View数组,然后从中遍历匹配,从而找到View对象。
]]>首先在逆向领域,有一个是需要区别的。就是反汇编和反编译。
反汇编把程序的原始机器码,翻译成较便于阅读理解的汇编代码。比如IDA、OD等。
反编译,通常是将机器码(汇编语言)转换为高级编程语言。
由于Java、.net这样的基于虚拟机技术的语言都是采用了ByteCode的二进制结构,因此很容易将ByteCode转化为“抽象语法树”(简称AST,《编译原理》这门课中的概念),然后采用反编译器就可以将AST转换为代码了。
详细可以参考乌云上的文章反编译系列教程(上)
#####0x02 无混淆无加密无加壳
一个Android程序,如果没有进行混淆,加密,加壳等行为时,如果进行反编译的话,是可以逆向到Java源码的。
先通过Dex2Jar软件将classes.dex
转换为jar文件,然后再通过Java反编译工具JD-GUI将jar文件转换成JAVA源文件。
总之这是通过dex转jar,然后再转java源代码的思路。其中dex转jar也可以选择一些其他软件,例如谷歌官方的enjarify。
下载Dex2Jar和Jd-gui的地址:
Dex2Jar:https://github.com/pxb1988/dex2jar/releases
JD-GUI:http://jd.benow.ca/
使用Dex2Jar和Jd-gui的命令:
1 | dex2jar <file0> |
以下即为反汇编出来的结果。
2.APK改之理、APKDB、Android逆向助手、Android Killer之类软件
实际本质上还是通过Dex2jar或者apktool工具的封装。
还有一个Jadx的软件也比较好用。
3.在线反编译网站
地址:http://www.decompileandroid.com/
地址:http://www.ludaima.cn/android.html
只需要上传需要反编译的apk,稍等片刻,即可下载源码。
4.smali和Baksmali以及Smali Viewer
smali是将smali文件转换成dex。
Baksmali和smali相反,将dex转换成smali。
在Quora的一篇问答中,介绍了smali和baksmali的作用。
1 | Smali/Baksmali is an assembler/disassembler for the dex format used by dalvik, |
通常Android混淆方法,有ProGuard、DexGuard和APKfuscator等。
怎样使用ProGuard对Android项目源码进行混淆保护,在Android Studio中build.gradle,修改以下代码片段
1 | release { |
将minifyEnabled
改为true。去除无效资源的话需要添加shrinkResources true
。
然后在proguard-rules.pro
文件中,编写一些特定框架的混淆规则。
1 | # ProGuard configurations for Bugtags |
并且混淆时需要对使用的框架进行混淆,或者是避免混淆一些类。这时就对框架的文档进行阅读,分析需要增加的混淆规则。
混淆的效果如下图所示。
以及加速gradle编译的配置:
1 | org.gradle.daemon=true |
如何对抗这种混淆呢?这种混淆仅仅是增大了阅读难度,在反汇编之后,类名变成了a,b,c之类的。
dex2jar作者在Android混淆技巧与反混淆中谈到,ProGuard有Shrinking、Optimization、Name Obfuscation、Removal of logging code等功能。在面对名字替换时,有阅读源代码、JEB、ProGuard分析等方法,Flanker大牛也分享过利用JEB API编写插件分析。
默认的混淆规则在proguard-android.txt。
可以使用Proguard再混淆一次,利用自己写的规则Mapping文件。
这里以一个文件为例。进行Proguard的混淆以及反混淆。
在Proguard配置文件中,添加如下语句,可打印出默认混淆规则的Mapping文件。
1 | -printmapping mapping.txt |
在修改好对应的值以后,利用以下语句,应用Mapping文件,再建一个项目,分析对应的代码。
1 | -applymapping mapping.txt |
最后结果如下:
这样反混淆了以后,降低了代码阅读的难度,增加了应用被破解的风险。
加密方式有很多种,本文不能面面俱到,只能找出一些典型的。比如有流程混排加密、代码内部字符串加密,对so源码、so函数名称以及接口调用进行加密隐藏,对classes.dex中的所有函数功能代码进行提取,然后加密单独存放等。
当然如果面面俱到,文章篇幅就比较长了,并且实践、研究花费的时间也比较多。这里就举比较简单的例子。
Android签名校验:
在android程序中,可以使用以下代码进行签名的获取。
1 | public int getSignature(String packageName) { |
可以在APP每次访问服务器的时候,携带上当前APP的签名,服务端做个签名验证,如果不对,直接不通过,返回客户端信息,然后客户端进行一定的处理。当然这样的话破解者也可以通过抓包的方式,抓取到签名验证的包,然后每次通信时修改对应的包即可。
so加壳,upx是最为so加壳的首选,以前在PC端也做过upx的脱壳。
这里做个示例,加壳so。
在前一篇文章里,涉及到了如何在so里打log文件。在写好jni代码了以后,将so文件复制出来。
然后添加到文件夹里,如下图所示。
准备UPX壳编译环境:
1 | zlib-1.2.8.tar.gz |
编译安装:
1 | cd ucl-1.03 |
设置环境变量。
1 | export UPX_UCLDIR=/Users/qingfeng/software/upx/libs/ucl-1.03 |
查看环境变量的命令env,应用环境变量的命令source .bash_profile
。
然后在编译make all
的过程中,遇到了以下的错误。
1 | ./bele_policy.h:156:9: error: unused typedef 'acc_cta_t__39' [-Werror,-Wunused-local-typedef] |
无论是upx是3.9.1,还是最新版,无论lzma是443版本还是最新版1610,编译的时候都会出现这个问题
然后试着升级了一下g++的版本,mac自带的是4.2版本,用brew升级到了4.8,然后用zsh的alias功能(vi .zshrc)将自带的替换掉,然后再编译还是不行,最后还是使用ubuntu进行编译吧。
然后就下了一个16.04的镜像,然后跑起了虚拟机,下载并编译那些依赖,然后在upx目录下make all
的过程中,出现了以下的问题:
1 | compress.cpp:32:18: fatal error: zlib.h: No such file or directory |
没找到zlib.h
,可是自己在zlib那也make
了啊,在查找资料的过程中,试着在zlib目录make install
了一下,然后就编译完成了,在src目录下也有./upx.out
了,版本是3.9.2。
这个时候就应该考虑so的init段的问题了。据这篇文章说,加壳的文件中需要有INIT段,添加init段的代码如下:
1 | void _init(void){} \\c++ |
然后加壳的命令如下:
1 | ./upx.out -f -o libdemo_upx.so libdemo.so |
然后脱壳自然-d参数即可,需要判断标志是否为UPX!,以及处理变形等问题,脱完壳就可以使用IDA进行android的so分析了。
如何实现一些自动化脚本,进行反汇编的还原工作。
当然网上已经有人实现过相关内容,比如Mac下的AndroidDecompiler,或者是easy-android-decompiler。
DEX转jar:
app调试器:
代码混淆软件:
对抗混淆:
当然实际情况是混淆,加密,加壳综合起来的,实际情况要具体分析。
参考链接:
]]>#####0x01 原理
常见的一些打Log的语句
1 | Log.i(TAG, ""); |
Log给开发者开放了6种级别(分别对应info,debug,error,verbose,warning,assert),隐藏了两种级别:
1 | F — Fatal |
通过阅读Log的代码,里面说明了通过println_native(LOG_ID_MAIN, Priority, tag, msg);
代码进行输出了日志。并声明了LOG_ID_MAIN、LOG_ID_RADIO、LOG_ID_EVENTS、LOG_ID_SYSTEM、LOG_ID_CRASH五个缓冲区。
而println_native()
的代码在frameworks/base/core/jni/android_util_log.cpp
,其中判断了msg是否为空,如果为空,抛出空指针异常。
其中levels_t是一个结构体,其中包括了那六种级别,其中assert
,查阅代码可得知,如果利用Log.wtf()方法,就会打印一个标志成ASSERT的错误。
并通过以下函数进行了打印操作。即__android_log_buf_write。在__android_log_buf_write
函数里通过调用write_to_log
函数进行打印。
1 | int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg); |
然后write_to_log
是怎样的情况呢,在文件45行有以下信息。
1 | static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init; |
然后追溯到__write_to_log_init
这个函数里,这个函数其中有一些打开文件等的操作,然后__write_to_log_kernel
这个就写入到文件里。
具体底层Log设备Logger机制,就不再阐述,如果细研下去,就是另一篇文章了,并且嵌入式的同学还学到了ioctl
函数,这需要一些Linux驱动方面的知识。
LogCat是如何获取Log的?通过logcat.cpp
,可以知道,定义了一个Log文件目录,即#define LOG_FILE_DIR "/dev/log/"
。具体读取log的过程,可以参考田海立的文章-解读Android LOG机制的实现:(5)获取LOG的应用程序LogCat。
如何去修改logcat的显示颜色呢,可以通过android studio的设置,也可以安装一个logcat-color直接改变颜色,通过以下命令。
1 | $ logcat-color -e | egrep '(Tag1|Tag2)' |
通过以下命令,进行apktool反编译
1 | apktool d xxx.apk |
在合适位置插入以下语句,其中v0为寄存器,尽量不要随意添加寄存器。
1 | invoke-static {v0, v0}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I |
然后进行打包
1 | apktool b xxx -o xxx.apk |
打包完安装需要签名,由于已经有了android.keystore ,这里使用jarsigner进行签名。
1 | jarsigner -verbose -keystore android.keystore -signedjar android_signed.apk app.apk android.keystore |
运行即可看到Log信息。
如何在手机上读取其他应用的log并可以导出呢,谷歌在4.1以后禁止了相关权限,改为了signature|system|development
权限。就算有android.PREMISSION.READ_LOGS,也读取不到其他应用的log了。只能root以后查看。
在谷歌Android Developer论坛里也有相关讨论。在4.1之后,禁止了去阅读其他应用log的权限。
并且在google play商店上也有几款手机上查看log的软件,需要root权限。比如CatLog - Logcat Reader!,aLogcat (free) - logcat等。aLogCat也开源了,地址在GitHub上。
如何在so文件,即jni开发中里打log呢
这里如何配置NDK就不再叙述。详细可参考ndk官网
需要在cpp文件中添加以下语句:
1 |
|
然后在build.gradle文件里,修改成以下片段:
1 | ndk { |
引入liblog.h
,或者通过自定义Android.mk
进行导入。
可以通过一些宏定义定义:
1 |
一种方法是通过添加一个Log辅助类,配置级别,或者通过变量控制显示。
1 | public class Log { |
使用时直接使用这个Log类打印方法。
release版屏蔽log输出,另外一种方法是,可以通过ProGuard的方式,将log语句删除。
ProGuard是Android SDK的一部分。只需要开启即可。
在android studio中,编辑build.gradle文件,配置如下代码:
1 | android { |
后来gradle的runProguard更名为minifyEnabled,所以直接改为true即可。
1 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
注意这段位置,本来按默认的配置一直没有消除成功,直到看了一篇文章以后,改为了proguard-android-optimize.txt
,才屏蔽输出成功。即:
1 | release { |
修改Proguard的配置文件proguard-rules.pro
,添加以下配置:
1 | -assumenosideeffects class android.util.Log { |
即结果。然后打包签名输出就不会有log日志了。
1 | ./adb shell |
dmesg是内核中的一个命令,可以查看内核日志,当然,也可以用cat/proc/kmsg
。两者不同的是,dmesg只读取缓冲区中的内核日志,而cat /proc/kmsg
则可以原始的、完整的日志文件。
]]>
作为开发者或者安全研究员,开发或分析一些与网络相关的程序时,必然要涉及到 HTTP 协议,而了解信息的传输,是非常必要的。所以我们需要抓取并控制到网路流量,并且需要对中间人攻击有一定的认识。
TOC:
需要一些nc、wireshark、tcpdump for Android软件。
wireshark可通过以下代码进行安装:
1 | brew cask install wireshark |
netcat可通过以下代码进行安装;
1 | brew install netcat |
然后下载好TCPdump for android,注意是可执行文件,不是文件扩展名为bin的。
然后usb线连接好设备,或者启动虚拟机。
进入platform-tools文件夹,输入以下的命令:
1 | 查看连接的设备: |
通过数据线或者其他adb push的方式,将tcpdump复制到设备的**/data/tcpdump/**文件夹。
在android设备里执行以下命令:
1 | ./adb shell |
然后确认一下android设备中是否安装有netcat,可以通过nc命令来判断是否安装。
以下是:在android端转发流量的命令
1 | ./data/tcpdump/tcpdump -w - | nc -l -p 31337 |
需要配置adb的端口转发:
1 | ./adb forward tcp:12345 tcp:31337 |
然后pc端需要nc转发流量,然后wireshark进行分析。
1 | netcat 127.0.0.1 12345 | wireshark -k -S -i - |
安装配置好捕捉流量,wireshark分析:
安装并配置Charles。
1 | brew cask install charles |
捕捉HTTP流量:
手机上设置代理,如下所示:
捕捉HTTPS流量:
安装证书:
下载Charles证书http://www.charlesproxy.com/getssl/,输入文件名进行安装。
在Charles的工具栏上点击设置按钮,选择SSL Proxy Settings;选项卡的Locations表单可以填写要抓包的域名和端口,点击Add按钮,在弹出的表单中Host填写域名,比如填*,Port填443。默认的空值表示应用于所有地址。
0x04 利用ettercap进行中间人
ettercap是linux上常用的一种中间人工具,作为网上的一种sniffer,曾经利用其接收到机房的广播出来的数据包。
MAC系统上如何利用其进行中间人攻击呢?
ettercap安装与配置:
1 | sudo brew install ettercap --with-gtk+ |
而driftnet是一款简单而使用的图片捕获工具,可以很方便的在网络数据包中抓取图片。可以利用其和ettercap进行抓取局域网中的图片。
ARP欺骗:
1 | ettercap -i eth0 -T -M arp:remote /10.0.0.1/ // 欺骗局域网内所有主机 |
常见的有dSploit,zANTI。
android设备使用dSploit进行中间人攻击:
当成为中间人了以后,就可以进行各种利用了,比如查看流量,网页劫持,提取密码,会话劫持等。
以弹对话框为例:
热爱互联网,对操作系统和网络安全有狂热的追求,专业不限;熟悉漏洞挖掘、网络安全攻防技术,了解常见黑客攻击手法;掌握基本开发能力,熟练使用C/C++语言;对数据库、操作系统、网络原理有较好掌握;具有软件逆向,网络安全攻防或安全系统开发经验者优先。
]]>drozer 是一个 android 渗透与测试比较出名的一个框架,其源码托管在 GitHub。我们可以利用其进行一些自动化测试工作,以及测试一些拒绝式服务,写一些 exploit 等。
TOC:
mac10.11 系统:
安装配置好 python,然后使用下面的命令,或者 pip 安装也可以。
1 | sudo easy_install --allow-hosts pypi.python.org protobuf==2.4.1 |
遇到了如下的问题:
1 | error: Setup script exited with error: command 'clang' failed with exit status 1 |
然后在github上的仓库上寻找方案。其中ISSUE#155叙述了这个问题。但是官网的2.3.4并没有修复依赖。
于是应该clone这个仓库进行安装。然后修复更新的是develop分支,就是clone这个分支的事情了。
1 | sudo easy_install pyopenssl==0.15 |
然后sudo python setup.py install即可
并且**/usr/local/lib/python2.7/site-packages/drozer-2.3.4-py2.7.egg/drozer/lib/aapt**这个需要配置好755权限。
1 | sudo chmod 755 /usr/local/lib/python2.7/site-packages/drozer-2.3.4-py2.7.egg/drozer/lib/aapt |
配置drozer,需要在android端也安装好对应的agent
连接上android设备,并打开调试,允许安装未知来源的应用。
然后adb install drozer.apk,或者在官网下载apk包,传到android设备上安装。
之后打开drozer应用,并且设备通过USB线连接上,并设置好端口转发:
1 | adb forward tcp:31415 tcp:31415 |
然后启动drozer应用上的嵌入式服务,Embedded Server,然后按一下Embedded Server滑块,再将Disabled滑块拖到右边。
然后计算机设备上就可以通过下面这条命令连接到drozer console了。
1 | drozer console connect |
可以进行一些常见的命令:
1 | 枚举已安装的包: |
打开drozer console,执行以下命令:
1 | module repository create [path-to-your-module-dir] |
其中为pach-to-your-module-dir存放编写的模块的目录的路径。
官方文档里说明了需要书写的一些属性:
name、description、examples、author、date、license、path
如果增加参数可使用add_arguments()**方法,其利用argparse**的原理。
模块一:
枚举所有的可导出的activity、content provider、service、broadcast receiver:
1 | from drozer.modules import common, Module |
在模块一的基础上实现自动启动可导出的activity,以测试是否产生拒绝式服务。
1 | try: |
QA:
1.drozer 模块存放在哪,从哪寻找那些模块?
用户自定义的模块,在当前目录下面会生成如下图所示的结构,当删除这个目录后,模块也被删除。并且 drozer 会在模块目录,存在一个名为 .drozer_repository 的文件。
并且 drozer 的文件中说明了寻找模块的方法。
1 | def __locate(self): |
主要就是爬虫下载apk,然后自动安装apk,然后drozer去分析利用。
爬虫下载apk的思路,曾经利用scrapy去下载一些apk网站上的排行apk。托管在了Coding。
如何自动安装apk呢?利用adb install -r xxx.apk?
所以是爬虫下载apk,然后分开不同的目录,再利用脚本adb安装到设备上,并将包名输出到一个文件里,然后模块里在读取文件,然后进行检查package,或者拒绝服务的检测。
drozer 是利用 protobuf 协议作为通信的,如果这个协议出现了问题,又会怎么样呢?这是以后思考的方向吧。
当然 drozer 的可利用范围是比较广的,可以测试 SQL 注入,以及各种组件的漏洞,或者配合 nc 进行 shell 的获取。以后再整理一些利用思路,或者一些 exploit 的编写。
最近在看 XSS 的相关内容,也有很多需要注意的东西。在平时的开发及设计当中,不可避免的会遇到XSS,于是就有了设计一些filter的想法,以前也在phithon的github上看到过Python的XSS filter,毕竟自己动手实现一个对于理解XSS,以及过滤的相关事情是很有帮助的。因此设计一些简单的filter,以备自己使用,并且这些filter是不安全的,不要放在生产环境,毕竟没有经过一些专业的检测,以及自己的JavaScript和XSS水平有待提高。以及以后可能还会写一些如何attack 这个filter的文章。
TOC:
首先需要过滤<>”()/script等字符(“>_<script123”),在PHP里可以使用preg_replace函数去过滤,并且通过htmlspecialchars函数转换为HTML实体编码。即:
1 | function safe_replace($content){ |
这里可以采用zicai的XSS-learn代码进行实验。
java可以使用:
1 | string = string.replaceAll("<", "<"); |
当有了过滤以后,测试<>”(号时,发现<>被转义成<
和>
,而”(等的并没有转义,当时怀疑是被实体编码了。当看到实际代码时,发现是字符串正则替换,后来一想,如果是类似于httpspecialchars那种的实体编码的话,引号也应该转义才对。当时还想着怎么绕过实体编码转义,于是又有了一个问题,关于java里的escapeHtml的底层实现是怎样的?以及实体编码是怎样的过程,似乎这个有点偏离主题了,这个完了再思考去写一篇总结编码的文章。
而在Python里可以使用
1 | import cgi |
以上都是一些正则过滤和escape编码的手段,当然不会过滤掉所有的XSS,仅可以防御一些小白。
还是会有人去寻找其他的可控点,或者想办法去绕过过滤。
当然这可以过滤**’;alert(String.fromCharCode(88,83,83))**这种的攻击向量么,如果可控点在JavaScript代码里呢,或者javascript伪协议,例如
1 | <img src="javascript:alert('xss');"> |
以及如果使用黑名单去过滤javascript伪协议的XSS,可以使用一些空格或者回车Tab等的绕过。即:
1 | <img src="javas |
如何去过滤这种的呢?
将换行符换成\n,将回车符换成\r,将制表符换成\t,空格可以遍历去除。
当过滤完这种的以后呢,又会出现一些大小写混淆或者十进制十六进制编码或者注释的示例:
1 | <img src="JavaScRiPt:alert('xss');"> |
面对这些,如果过滤/*&#javascript\;
,不如采取一些白名单的形式,仅允许执行特定形式的,去正则匹配结果。例如:仅允许<img src="http://">
这种的。
可以构造正则语句:”/^((http|ftp|https)://)?[\w-.]+(/[\w-]+)*/?$/“
如果单纯地过滤一些常见的<script>
标签或者onerror、onResume
等事件,还是可能会利用<link>
引入一个内容为如下的CSS进行hack。
1 | @import 'javascript:alert("XSS")'; |
当然还是要记得去判断变量类型,数字型的直接判断是否是数字,字符型的限定一些长度,并且不能有特殊字符,还有不能有拆分跨站法(疯狂的跨站之行)的出现。
如果一直针对绕过的方法,去不断过滤,未免有点麻烦,应该设计一个统一的filter,加强防御。
#####0x03 Python filter设计
一些用户的输入都是不可信的。
基础的过滤就得使用一些函数或者开源库:
1 | //基础的过滤 |
富文本过滤类的一种思路:
1.解析HTML节点
2.过滤白名单标签,删除不在白名单的标签,并且判断属性及属性值。
以及一些框架的处理策略:
tornado:
Tornado框架原则上所有输出在模板里的变量都会经过”HTML实体化”,并且官方文档也给出了一篇文章的链接,说明了仅过滤&, <, >, “, 和 ‘ 这些字符是不够的。
tornado都会自动执行xhtml_escape方法,将<, >, “, ‘, 和&进行了转义。
但是也需要针对特殊情况去过滤,关注一些输出在JavaScript代码的地方,进行特定形式的转义、正则匹配。
《XSS跨站脚本与防御》的第242页给出了一个通用的过滤XSS的函数,贴到了gist。
PHP在处理$_GET
、$_POST
、$_REQUEST
等变量时需过滤一次。
需要使用一些filter_var(),filter_input()函数来进行构造一些规则,进行一些模式的匹配,过滤。
网上的一个防止基本的XSS函数:
1 | function transform_HTML($string, $length = null) { |
从代码可以看到,期间过滤的一些空格,Unicode转码的问题,一些十进制十六进制的编码,并且限定了长度,进行了HTML实体编码,针对基础的XSS问题足够了。可以设计一个函数,获取GET、POST、REQUEST参数的时候,可以进行XSS的防护。
以及可以使用一些类似于HTML Purifier,或者一些富文本过滤类。
Java Web方面,通过过滤一些Request请求,在GET或者POST请求层面进行过滤。
Java里面本来就有一个Filter类,继承这个Filter类,然后可以通过构造一个XSSRequestWrapper,过滤一些HttpServletRequest,配置好Web.xml,使这个继承后的Filter类全局有效,进行自动的anti一些xss,过滤掉所有请求里的恶意脚本。
在XSSRequestWrapper这个类里,需要重写一些getParameterValues(), getParameter() 和 getHeader()方法,期间实现一些过滤xss的函数,通过一些HTML实体编码的手段,以及正则匹配替换掉一些关键词,或者直接replaceAll去替换。
Web.xml的配置方法:
1 | <!-- XSS过滤器 --> |
也可以使用一些类似于Lucy-XSS : XssFilter, XssPreventer的模块去处理。
这里的系统层面,侧重于WAF方面。
WAF可以是硬件层面,也可以是软件层面,ngx_lua_waf就提供了一种基于nginx_lua的思路。
通常会定义一些过滤规则,就像下面这样的正则匹配规则:
1 | \.\./ |
当然有些WAF还是联网获取这些规则的,它们采用的一些正则表达式匹配的方法,比较容易被绕过的,也有人提出了主动防御的概念。
当学习地渐渐深入的时候,会越来越发现其的神奇,不断的过滤,不断的绕过,以及还有二哥和长短短的一些猥琐的思路,并且也有很多人教导学习XSS时候,一定要注意JavaScript基础,毕竟好的一名跨站师,xsser都是JavaScript很厉害。
当然防御XSS,不只有建立filter,也需要一些HttpOnly,Noscript,WAF,CSP的配合,更需要加强安全意识。
以后探索的方向:
自动化挖掘XSS漏洞,自动化防御,CVE里的XSS,以及总结一些好的XSS思路,新型XSS,自动化利用框架,浏览器Filter策略,防御XSS,机器学习等。。。
在国内的大环境下,一些软件使用官方源会有很大的延迟,而使用国内搭建的同步官方源的话,速度会提升很多的,因此,本文总结一些常用的软件源,并不定期更新。
以ubuntu为例,需要编辑**/etc/apt/sources.list**文件
配置:
1 | $ gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/ |
配置:
1 | 例1:修改 composer 的全局配置文件(推荐方式) |
#####0x07 NodeJs npm
配置:
1 | 可以使用我们定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm: |
使用方法
1 | 安装模块: |
1 | sudo pip install -i http://pypi.douban.com/simple/ xxx |
1 | 在maven的settings.xml 文件里配置mirrors的子节点,添加如下mirror |
1 | 本地配置文件: |
写在Bugtags上线Crash发生趋势之际,以及英语四级前夜。仅感触,无其他。
在9月份的时候,开学之际,随着Codekk微信号推送了一条名为“移动应用Bug快速反馈利器”的消息,工欲善其事,必先利其器。看完介绍了以后,不禁感觉眼前一亮,和以前接触的crash收集工具有点不一样,并且也听说过一些摇一摇进行反馈的功能。
这个主要是一个类似于外包的项目,应用内容是大学内app社交、社区等形式,其中整体APP需要一个良好的架构,以及完善的测试(然而并没有测试),只好在边开发边测试。
最初我们在应用开发上,采用的git版本控制,主要两个人进行开发,并没有测试妹纸。(最初找了一个“设计师”同学),在经理提出项目需求和改进时,往往通过经理去告诉给另外一个人,然后另一个人进行评估,直接在代码里进行修改,并且没有记录,整个过程并不透明。后来经理会找张纸记录一些问题,解决了打个对勾,但是这还是不好管理,并且对于机型的不确定性,以及Bug的难复现,降低了一些效率。
此处应该有图片:
在公众号信息里,展示了提交Bug的流程,然后试着集成了一下sdk,整体集成的过程并不麻烦,很快感受到了效果,并推荐给了另一位开发。
在接入以后,熟悉了提交Bug的方式,感觉相见恨晚,很适合经理在提哪有问题,哪需要改进。
在接入应用以后,效率上感觉到了一些方便,但是就发现了一些问题,比如那会会一直邮件收到提醒,并提了工单,在QQ群里也进行了咨询,并且收到了这个问题正在解决中,会在下周上线。
并且Bugtags提交Bug时,整体流程并不麻烦。
令人感到欣慰的是,Bugtags团队的迭代,使得Bugtags不断的完善,随着使用中,逐渐上线了以下几个特性:
增加几种标签状态和类型。
区别了开发人员和提交Bug人员
可以批量修改状态和删除标签
Crash可以抓到截图
支持了导出功能
增加匿名提交
添加了批量邀请成员等功能
……
在团队的不断迭代开发应用的过程中,收到了很多经理的提的标签,经常一天提十几条,如果按照往常的列出清单,然后一个一个去解决,会浪费很多时间和效率。
应用也在fir.im内测,不断的去完善,提高着自己的开发技能,奔溃影响机型数从最初的少量的几台手机在逐渐增加。
此处应该有图片:
在使用的过程中,提交的问题越来越多,收到的标签也越来越多,毕竟是一个APP应用,从0.1到0.9的过程(0.1指接入时已经开发了一个简单原型)。
一张现在的统计,标签已经不少了,此处继续应该有图片:
问题界面:
随着不断的使用,发觉提高了不少效率,在这将近三个月的相处之中,感受到了Bugtags团队的不懈努力,感受到了对开发与测试的关注。
并且现在也提供了一些可视化的数据,来表达测试的效果,以及应用的完善程度。
在上线以后,我们也重点关注了一些Crash,并且Crash相对于以前来说,更加好复现,并且对其进行了改进,优化应用的性能,提升了一些用户体验。
因为机型和系统不同,作为一个android开发者,不可避免地会遇到很多Crash,当用户遇到了以后,作为开发也很无奈,毕竟比较难复现,有了Bugtags了以后,可以及时地统计机型,系统版本,以及用户所执行的步骤,现在最近又上线了Crash的发生趋势,可以让开发专注于近期发生频率高的Crash进行改进。
此处应该有图片:
在今年的华北五省计算机应用大赛的答辩现场,也给评委们简单介绍了一下这个 Bug 管理平台,提高了一些开发效率。
你们的测试妹子、霸道产品、老板肯定需要它很久了,爱他恨他就转给他。
在Bugtags之前,并不知道有相关的Bug管理平台,作为一名开发者,Bugtags是值得推荐的。
最后提几点意见(其中有些不知道中肯与否):
]]>开发android studio插件,实现可以收到紧急标签会提醒。
开发android客户端,实现可以移动管理标签状态。
开放一些api,实现自定义配置
希望可以提供一些移动应用测试,例如monkey之类的实践。
如果是非Wi-Fi环境下,提供一些流量方面的统计。
作为容器技术的发展,自认为是互联网技术公司的基础设施架构的不可或缺的一部分,并且好多公司都在实践,并且创业公司也可以利用其加快开发,缩短构建部署等消耗的时间。
很少有像docker这样才推出两年多就很火的样子,并且拿到了好多投资,😃,作为变化很快的IT行业,不掌握点新技术,很难在竞争中生存下来。
并且Docker也适合进行弹性计算,毕竟一个容器启动是秒级别的,还可以作为持续集成等实践,统一开发和部署环境。(只需要一个Dockerfile或者yaml)
此次CNUTCon容器技术大会,聚集了像谷歌,百度,阿里,腾讯,360,京东等大公司,也不乏像Daocloud,灵雀云,时速云这类的创业公司。
不仅有像谷歌,RedHat这类的公司分享Docker容器技术的演化,以及还有Daocloud给的一些实践。
这些对于一些架构师,技术官,云平台工程师都是不容错过的,各大平台分享自己的平台演化之路,毕竟互联网公司需要的更多的是基础设施的稳定性,相互借鉴,互相交流。
晚上坐硬卧去北京,期间感受了硬卧的滋味,然后28号早上晚点了几十分钟到达了北京,然后乘地铁,倒到了十号线,在太阳宫,然后在周围找了半天,期间地图出现了些许问题,耽误了几十分钟,将近八点才到会场,然后在赞助商展演的地方刷了点小礼品。
开场是由InfoQ官方的负责人员,郭蕾,霍泰稳(极客邦科技,InfoQ中国创始人兼CEO),介绍了 InfoQ 的发展,与 InfoQ 和 Docker 的关系,毕竟整个大会大部分是在说docker及其相关,InfoQ很早的时候就推出了Docker专栏,并且推广过很多系列文章,以及还介绍了为什么举办此次会议。
首先是RedHat公司的副总裁,一种印度味的英语根本听不懂,也只能拍拍Slides,去感受RedHat对于Docker发展的贡献了。其中的软件定义一切,让想起了软件定义网络,都是一些不知所云的名词,需要学习的太多太多。
然后是CoreOS产品负责人,对于CoreOS的印象是版本号太奇葩,更新太快,会议第二天听了林帆的CoreOS实战以后,才有其他印象,想起来6月份,林帆还做过浏览器的镜像,一块还在灵雀云的发布会上见过。
他讲了K8S,这又是较新的名词了,听说是谷歌出的,谷歌出的大部分都是好东西,并且感觉有技术含量,其他的还是回去看PPT吧。
上午最后一个京东的分享容器之路,分享了一个秒杀的例子,秒杀在那几天的时候很消耗资源,但平时也用不着那么多资源,于是京东开始实践容器,并且说有10000+容器在线上运行,并且还在建设数据中心。
并且也讲述了在网络和存储两大问题上的解决方案。
28日下午就去了解决方案专场,分会场,开始听灵雀云CTO陈恺分享微服务架构的演变,从单片到三层结构,再到最近的微服务架构,一个应用的架构在不断的发生演变,以电商网站作为例子,并且最后宣传了下灵雀云,作为持续交付,容器托管的创业公司。
微服务作为近年流行的应用架构,重新定义了应用开发运维的方法。
时速云王磊分享了 k8s 打造容器云平台实践,也是作为国内CAAS创业的一部分。
华为梁辰晔分享了关于OCT容器开放测试项目的实践,是一套针对不同容器产品的统一测试框架,包含了容器标准测试、容器功能测试和容器性能测试。
七牛的联合创始人徐立,曾经写过go语言编程还是什么的书,听得听的睡着了,中午吃完饭就没睡觉,『不要为了Docker而Docker、为了微服务而微服务』,毕竟Docker在网络和存储方面并不是长处。
最后是SpeedyCloud,之前并没有听说过这个公司,在展台上打听的这是做云主机的一家公司,不过分享的大部分还是听不懂,回去慢慢啃PPT吧。
并且在群里说TAE的分享不错,阿里的容器实践,回去看视频和ppt吧。
首先是首日期待很久了的谷歌Dawn Chen讲 k8s 和 borg 设计哲学,还是一名女讲师呢,她讲了在谷歌有20亿+的容器在运行,并且早在很久以前(大概十年前开始)就已经实践了容器相关技术,并且将了k8s作为容器管理的发展,分享了 Kubernetes 的架构,设计等内容。
相对来说,更对她的IT职场发展更感兴趣,作为一名女性,怎么在谷歌里成长的,这个完了可以作为例子,来激励或者鼓励自己罢。
然后是华为的线超博讲 swarm,swarm 又是啥,毕竟没有接触过,作为 swarm 的 Maintainer,并且也在分享里说了 swarm 并不适合直接作为生产环境,目前还在开发测试当中。
最后是百度云平台负责人谢广军的分享百度云架构演化过程,从一开始的私有云实践到后来的公有云,开放云,如何支撑大量的资源进行调度。
中午遇到了几位灵雀云的工程师,并且在那讨论了关于灵雀云和容器docker的事,毕竟是作为开发者,总希望云平台对开发者便利,还有很多开发者对docker不了解或者是没听说过,记得灵雀云的用户群体是创业公司的,开发者还得有很多的学习docker的成本,并且在学习中还会遇到不少的坑,所以无论阿里云这类也好新浪云这类,又或是daocloud,灵雀云,时速云这种也罢,简化对于开发者上面的运维工作也很重要。
下午的培训专场首先是林帆的CoreOS应用实战,从CoreOS讲到了Rkt,也说了Docker与CoreOS之间的关系,听了会出来吃茶点,然后又去主会场正好Daocloud进行分布式云平台微服务实践,如何快速部署一些服务,并且用Daocloud作为演示。
最后是张磊的 Kubernetes 实战,作为浙大的科研人员,讲的感觉很深入浅出,并且也很有意思,值得分享。分享了关于集群管理的性能和利用率,如何进行大规模容器集群管理,以及Pod:容器化思维下的设计模式,k8s的原理。
令人印象很深的是好几个讲师分享完了以后,都有好多人在其旁边去问问题也好,交流也罢,感觉气氛很好,在分会场也看到好多人在认真的做笔记,又或是拿着笔记本去实践,并且在浙大的张磊讲的时候还有好多人站的,第一天会议的时候也有很多人在后面站的。
感觉有些讲师的分享干货不少,一下很难全消化掉。尤其是TAE的,谷歌的,张磊的令人印象深,TAE作为阿里的,分享阿里云在容器方面要做的一些事,并且看上去也很厉害,这些是创业公司不可比拟的额。
张磊讲的深入浅出,(毕竟是受过高等教育的人,逃),并且其中也进行了答疑,作为浙大SEL实验室,并且也有新书要发售,Daocloud的孙宏亮也写了一本书《Docker源码分析》。
传统的虚拟化技术,会在不知不觉中被容器技术替代,在互联网公司里首先会普及容器技术,然后逐渐往非互联网行业渗透,虽然觉得这个时间会很长很长,但是不可不知的是容器技术不仅在现在,在未来都会是重点发展的一部分。
在设置界面的开发时,以前往往通过自己写界面,在没有合适美工时,比较费时费力,尤其是以前需要兼容Android2.3的时候。当3.0以后出现了PreferenceFragment,可以快速地完成一个类似于系统设置的偏好设定界面。
在android3.0以后,官方推荐使用PreferenceFragment去替代PreferenceActivity。
以及一些配置。
PreferenceFragment是继承于Fragment,实现了PreferenceManager.OnPreferenceTreeClickListener这些接口。
1 | /** |
通过新建项目的方式:
在android-studio里,新建一个项目:PreferenceFragmentDemo
选择Blank Activity With Fragment,填写activity为SettingActivity。
修改fragment继承PreferenceFragment。
新建一个xml文件,建立/res/xml/preferences.xml
1 | <PreferenceScreen |
在SettingFragment中,通过addPreferencesFromResource(R.xml.preferences);加载上述的xml文件。
1 |
|
设置项保存到哪了?SharedPreferences。在/data/data/应用包名/shared_prefs/应用包名_preferences.xml文件中,android:key即为键值名。
如何读取设置?通过SharedPreferences
1 | SharedPreferences mySharedPreferences = PreferenceManager |
列表设置项的ListPreferences类:
1 | <ListPreference |
entries和entryValues从哪来?/res/values/array.xml或者/res/values/strings.xml
1 | <resources> |
preference-headers类
前几天在SIMS(学生信息管理系统)项目中,涉及到了Preference这个类,当时可以通过输入输出流进行与文件的交互。
在Java里可以利用这个类进行一些配置信息的保存等。
详情可参考PropertiesUtils的实现。
其PreferenceFragment文件源码地址在:GoogleSource,其中利用了ListView进行界面绘制。另外grepcode.com这个网站是个不错的查看android源代码(AOSP)的网站。以及还有一些示例代码。
并且文档里还介绍了android3.0以前如果想用PreferenceFragment怎么办,详细参考这个链接。