动态 帖子 3 评论 9 短评 0 收到的赞 送出的赞
  1. 差生文具多   在小组 国家局域网研究所 发表文章

    Arti: 一个用内存安全语言Rust实现的Tor节点程序

    大多数情况下提到Tor,指的是用C语言实现的Tor。说起Tor大家会想到安全、隐私,然而事实上,C语言实现的Tor经过十多年的开发迭代,代码已经变成了屎山。

    你没看错,用Tor团队的说法,目前C语言实现的Tor的情况是

    What's more, our existing C implementation has grown over the years to have a not-so-modular design: nearly everything is connected to everything else, which makes it even more difficult to analyze the code and make safe improvements. One thing that we found, however, was that our existing C code was not modular enough to be easily rewritten. (Rust's security guarantees depend on Rust code interacting with other Rust code, so to get any benefit, you need to rewrite a module at a time rather than just one function at a time.) The parts of the code that were isolated enough to replace were mostly trivial, and seemed not worth the effort—whereas the parts that most needed replacement were to intertwined with each other to practically disentangle. We tried to disentangle our modules, but it proved impractical to do so without destabilizing the codebase.

    简单来说,Tor开发团队试着用Rust语言向Tor代码中添加一些新功能,结果发现旧代码耦合在一起,修改一处,其它地方就要出乱子,不得已只好彻底推翻重写。

    从前年(2020)开始,Tor开发团队就开始着手用内存安全语言Rust重写Tor,重写后的Tor叫做Arti,架构设计更合理,开发语言Rust当然也更安全。目前Arti已经推出了1.0,可以用于生产环境。

    有人会问,Go或Java不也是内存安全语言吗?这个Arti不能用Go或者Java重写吗?

    先不谈性能问题,只就语言设计来说,Rust语言的不止有内存安全的特点,它还有很多非常严谨的代码防呆设计来阻止你写错代码,除非你编程思路有问题,或者故意写错代码,否则很难出错。Tor开发团队也有相同的感慨:

    At every stage, we've encountered way fewer bugs than during comparable C development. The bugs that we have encountered have almost all been semantic/algorithmic mistakes (real programming issues), not mistakes in using the Rust language and its facilities. Rust has a reputation for being a difficult language with a picky compiler - but the pickiness of the compiler has been a great boon. Generally speaking, if our Rust code compiles and passes its tests, it is much likelier to be correct than our C code under the same conditions.

    (在开发过程的每个阶段,我们遇到的错误都比用C语言开发的对应阶段少得多。我们遇到的 bug几乎都是语义/算法错误(即真正的编程问题),而不是使用Rust语言本身和开发设施的错误。Rust以复杂的语言和挑剔的编译器而著称——但是挑剔的编译器是一个很大的优点。一般来说,只要我们的Rust代码编译并通过了测试,那么比起C代码,相同条件下Rust代码就更可能正确。)

    除此之外,Arti还在Tor的基础上,添加了很多新的安全特性,例如对流量分析的抵抗能力。

    目前安装Arti需要电脑上有Rust编译器,如果你已经安装了Rust编译套件(Cargo),可以运行以下指令安装Arti:

    cargo install arti
    

    如果没有安装Rust,可以参考Rust官网的指南安装Rust编译套件

  2. 差生文具多   在小组 国家局域网研究所 发表文章

    谈谈thphd的《对养猫君对葱爆的分析的分析》一文的错误之处

    对养猫君对葱爆的分析的分析

    我最近翻站里的旧文章,发现这篇一年以前的文章里充斥着大量的IT常识错误,作者的语气还颇为自信,气势很能唬住一些外行读者。这样一篇充满低级错误的文章以贵站(前)站长的身份发在站里,实属拉低了贵站技术的上限。不知那些专业的IT人士看到这样一篇文章,会对2047的技术水平作何感想?因此,我认为有必要写一篇文章,指出《葱爆的分析的分析》的错误之处。

    thphd在这篇文章中的技术分析有很多错误。我不清楚是他自己一知半解就信口开河,还是自己清楚但故意误导读者。比如,技术分析部分的第二段就是如此:

    MySQL遇到磁盘已满的情况,并不会返回DISK_FULL错误并拒绝服务,而会直接当场卡死,除非非常了解mysql工作原理,否则只能强行重启:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

    我很疑惑thphd是否真的看过这个链接里的内容,这个链接里讲的是MySQL如何处理磁盘写满的情况。根据MySQL文档的说明,在磁盘写满时,MySQL并不会“卡死”,而只是每隔一分钟检查一下是否有足够的空间写入,如果有空间就写入,没有空间就不写入,就好像什么都没发生一样(it continues as if nothing had happened)。

    就算不去读MySQL的文档,凭常识也可以推断出,MySQL作为一款全世界最流行的数据库系统,背后又有Oracle这样的公司支持,必然会考虑到磁盘写满这样的常见情况。所谓MySQL“卡死”纯属缺乏计算机常识的臆测。

    这篇文章里更有一些极度缺乏常识的观点,例如:

    因为开机过程也是需要写入磁盘的,磁盘空间不足可能导致开机卡死。而云服务器无法开机就连不上,也就无法进行远程操作

    我不知道thphd是否有操作Linux系统的经验。Linux系统非常可靠,这和我们日常使用windows电脑的经验不同,即使硬盘写满,内存占满,CPU使用率100%,也不会影响正常使用,当然也不影响远程连接。事实上在商业环境中,操作系统满负荷重载运行是很正常的事情(包括偶尔写满硬盘),否则公司投资了昂贵的IT基础设施又不能跑满,岂不是严重的浪费。

    下面的分析更是看似有理,实则是满篇的胡说八道:

    所以另一种情况是,品葱站长强行重启了服务器,开启了数据库,数据库尝试从上一次强行重启的地方开始恢复。由于几乎所有数据库都依赖某种b+tree,而b+tree最流行的实现是leveldb(myrocks),leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

    常见的数据库管理系统由存储引擎和外部的“wrapper”构成。存储引擎是数据库的核心,其本质是一棵查找树(B树、B+树、LSM树),通过查找树可以高效地完成数据读写等数据库基本功能。外部的“wrapper”负责解析命令、查询规划、用户认证等功能。

    要查看mysql的存储引擎,可以在MySQL控制台输入show engines。下图所示列出了MySQL使用的存储引擎,可见其中并没有thphd提到的“leveldb/myrocks”

    事实上,MySQL最常用的存储引擎的是InnoDB和MyISAM。InnoDB是芬兰公司Innobase在2005年开发的一款存储引擎,MyISAM是MySQL团队基于IBM ISAM开发的存储引擎。而LevelDB是谷歌公司在2011年发布的一款嵌入式数据库,和MySQL风马牛不相及。

    再进一步,thphd对LevelDB存储特性的分析,也是完全错误的:

    leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

    从技术角度说,leveldb并不依赖底层磁盘的写入特性。确实,LevelDB对底层存储设备做了“顺序写入速度大于随机写入速度”的假设,这是为了优化写入性能。这种实现叫做LSM树(Log Structured Merge Tree,日志结构合并树),而不是thphd所说的B+树。好了,这里thphd又犯了一个知识性错误。

    LSM树会把对数据的修改变化缓存在内存中,达到一定的大小限制后,将这些变化批量写入磁盘。确实,在LSM树把数据写入磁盘之前,断电会导致数据丢失,然而LevelDB中数据缓存-写入的间隔非常短,仅为几百毫秒。换句话说,如果你在1秒的时间内,向LevelDB写入数据然后断电,那么这1秒内写入的数据确实会丢失,但是只要超过1秒,数据就会永久写入磁盘,不管怎么断电都不会影响数据,除非磁盘本身损坏。

    再退一步说,LevelDB的作者是谷歌首席程序员Jeffrey Dean,并且在开发过程中得到了谷歌的大力支持。就算你对我或thphd说的一切表示怀疑,你应该可以相信谷歌顶级程序员的实力——LevelDB经过了无数苛刻环境的考验,重启电脑并不会丢失大半年的数据,否则谷歌首席程序员就不要混了。

    至于看了《对养猫君对葱爆的分析的分析》信以为真的网友,这不是大家的错,毕竟术业有专攻,不能要求每个人都是IT专家。但是贵站的前站长thphd暗示自己是“IT从业人士”,却发表这样一篇错误百出的文章,我想只有两种可能:要么是 1) 拉大旗扯虎皮,用专业名词忽悠外行,证明自己对“葱爆”的原因推测正确,进而达到污蔑其它网站的目的。要么就是 2) 没有基本的网络常识,被抓迟早的事。

    相关资料:

    [1] MySQL存储引擎:https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html

    [2] MySQL磁盘满的行为:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

    [3] LevelDB:https://github.com/google/leveldb

    [4] LSM-tree: https://en.wikipedia.org/wiki/Log-structured_merge-tree

  3. 差生文具多   在小组 国家局域网研究所 发表文章

    《连线》杂志报道rust:接管技术的安全编程语言

    https://www.wired.com/story/rust-secure-programming-language-memory-safe/

    Rust 被称为“内存安全”语言,因为它旨在使程序不可能意外地从计算机内存中提取意外数据。当程序员使用不具备此属性的强大语言(包括 C 和 C++)时,他们必须仔细检查程序将请求哪些数据以及如何请求的参数——即使是最熟练和最有经验的开发人员也会偶尔执行这项任务拙劣。通过使用 Rust 编写新软件,即使是业余程序员也可以确信他们没有在代码中引入任何内存安全漏洞。

    很少见到大众媒体报道这样专业的领域。