Pages

Friday, 24 February 2017

为何 shadowsocks 要弃用一次性验证 (OTA)

前些天,shadowsocks 提出了 SIP004 草案,旨在使用 AEAD 算法 取代原先的不安全的 流加密 + OTA,并弃用了一次性验证 (OTA)。
新协议的提出对于 shadowsocks 是一个非常非常重大的改进,因此我写了这篇博文为看不懂洋文的友们科普一下「为什么 OTA 会被这么快被弃用」以及「为什么应该使用新协议」。

一、OTA 是什么

OTA(One Time Auth,一次性验证),是之前 shadowsocks 为了增强安全性,抵抗 CCA(Chosen-ciphertext Attack,选择密文攻击)而加入的实验性功能。
我觉得应该很多人都听过这玩意 —— 就算不知道 OTA 是啥好歹也在 shadowsocks 各分支的客户端上看到过「一次性验证」的开关吧?虽然这个名字确实起得有点让人不明所以就是了(笑)。
那么下面我来科普下当初为什么要加入 OTA 功能。

二、原协议的弱点

原 shadowsocks 协议的这个漏洞其实早在 2015 年就被 @breakwa11 提出了。当时正值 @clowwindy被喝茶之际,此 issue下,闹得沸沸扬扬,撕逼不断,过了好一段时间后才开始有正经的技术讨论。
如果你想要了解一下当时的情况可以去看看 这个 issue,我这里简略概括一下当时提出的漏洞。

2.1 shadowsocks 协议

原 shadowsocks 协议 的 TCP 握手包(加密后)的格式是这样的:
+-------+----------+
|  IV   | Payload  |
+-------+----------+
| Fixed | Variable |
+-------+----------+
其中的 IV(Initialization Vector, 初始化向量)是使用随机数生成器生成的一个固定长度的输入值。通过引入 IV 能够使相同的明文和相同的密钥产生不同的密文,让攻击者难以对同一把密钥的密文进行破解。
shadowsocks 服务端会用这个 IV 和 pre-shared key(预共享密钥,通常是用户设置的密码)来解密 TCP 数据包中的 payload
解密后的内容格式如下:
+--------------+---------------------+------------------+----------+
| Address Type | Destination Address | Destination Port |   Data   |
+--------------+---------------------+------------------+----------+
|      1       |       Variable      |         2        | Variable |
+--------------+---------------------+------------------+----------+
其中 Address Type (ATYP) 是地址类型,占一个字节,有三个可能的取值:010304,分别对应 IPv4hostnameIPv6 类型的地址。这些都是 RFC1928 中定义的标准,有兴趣可以去看看。
握手完成后 shadowsocks 中继就会工作在流模式下,后续的所有 TCP 数据包不会再带上 IV,而是使用握手时协商的那个 IV
说完了原 shadowsocks 协议的内容,下面说说该协议的不足之处。

2.2 原协议的缺陷

正如上表所示,原始 shadowsocks 协议 TCP 握手包中的 IV 字段是 Fixed(定长)的。不同的加密算法 IV 长度不同,对于 rc4-md5 和 aes 系列等常用算法,这个长度是 16 字节。各加密算法的详细信息可以在 官方文档 - Cipher 查看。
而服务端为了判断数据是否有效,会检查数据包中表示地址信息的那个字节,看它是不是上面提到的三个可能取值。如果是,就尝试解析后面的地址和端口进行连接;如果不是,立即断开连接。
正是 shadowsocks 服务器的这个行为使得主动探测成为可能。

2.2.1 主动探测的原理

该方法由 @breakwa11 提供
一般来讲,「表示地址类型的那个字节」是被加密后发送的,所以第三方无法精确的修改它。但是不巧的是,shadowsocks 所有的加密方式都是 stream cipher流加密),而这种加密方式的特点就是「明文数据流与密钥数据流一一对应」
通俗地讲,即对应修改了某个位置的密文(根据加密模式的不同,可能影响到后面其他密文块的解密,也可能影响不到,但在这里这个性质并不重要),如果预先知道了明文的模式,虽然无法解密还原出内容,但可以修改密文中的特定字节,起到修改解密后的明文的效果。
根据流加密的这个特性,坏东西们就可以通过伪造 TCP 数据包来主动探测 shadowsocks 服务器了。攻击者只要暴力尝试修改加密后的数据包中 IV 之后紧接着的那个字节(如果使用的加密算法 IV 长度为 16 字节,那么就修改第 17 个字节),穷举 2^8 = 256 种可能性,如果被测试的服务器有一种到三种情况下没有立即关闭连接,就可以判断出这台机子的这个端口开放的是 shadowsocks 服务。
或许这种主动探测方法正在被 GFW 大规模应用,谁知道呢?你正在使用的原版 shadowsocks 代理随时有可能被封锁。

2.2.2 防范主动探测

经过讨论后上述漏洞被证明是 确实存在 的,所以现在大部分的 shadowsocks 分支都已经加入了针对这种探测方法的对抗措施(e.g. shadowsocks-libev v2.5.5+),即「随机超时抵抗」而不是立即断开连接,配合自动黑名单等机制可以有效减少被探测到的风险。
但是这种方法总归不是长久之计,要怎么办呢? 

三、OTA 闪亮登场

上述情况下主动探测能够得逞的原因是服务器没有对收到的数据包进行校验,随便哪个阿猫阿狗发来的数据包,不管有没有被恶意篡改过,原来的 shadowsocks 服务器都会做出同样的反应。
这时 @madeye(现在的 shadowsocks 维护者)提出了 One Time Auth 即「一次性验证」的提案,给原 shadowsocks 协议加上了数据包验证。

3.1 OTA 协议

开启了 OTA 后的 shadowsocks 握手包(加密前)是这样的:
+------+---------------------+------------------+-----------+
| ATYP | Destination Address | Destination Port | HMAC-SHA1 |
+------+---------------------+------------------+-----------+
|  1   |       Variable      |         2        |    10     |
+------+---------------------+------------------+-----------+
可以看到它添加了一个 HMAC-SHA1 字段,这个字段是将除了 DATA 通过 HMAC-SHA1 算法(以 IV + PSK 作为 key)生成的。并且数据包头部的 ATYP 添加了一个标志位用于指示 OTA 是否开启(ATYP & 0x10 == 0x10)。
+----------+-----------+----------+----
| DATA.LEN | HMAC-SHA1 |   DATA   | ...
+----------+-----------+----------+----
|     2    |     10    | Variable | ...
+----------+-----------+----------+----
握手完成后,接下来的 TCP 数据包均在原始协议的包上添加了 DATA.LEN(包长度)和 HMAC-SHA1 字段。这样,服务器就可以对数据包进行完整性校验,也就可以识别出被篡改过的数据包了。

3.2 OTA 的缺陷

OTA 增强了安全性,可以防范 CCA,也解决了原版协议数据包容易被篡改的问题,听起来很美好,不是吗?
但是,对于这个协议的实现,shadowsocks-libev 及其它大部分分支均假定第一个数据包必须包含整个带了 SHA1-MAC 的头部,否则断开连接。
OK,又一个可以通过服务器行为进行主动探测的地方。不过这种主动探测也可以通过上面提到的「随机超时抵抗」来进行防范,真正可怕的在下面:
该方法由 @breakwa11 提供
还记得我们上面提到的 stream cipher(流加密)的特点吗?攻击者可是使用同样的套路修改数据包中的 DATA.LEN 字段,然后通过观察服务器的反应来判断这是否是一个 shadowsocks 服务器。
举个栗子,如果攻击者恶意构造 DATA.LEN 的高位字节密文,使得解密后 DATA.LEN 的数值变得特别大(但是后面的 DATA 的大小并没有改变),shadowsocks 服务器就会继续等待那些实际上并不存在的数据传输完成直到超时。因此只要在发送恶意数据包后观察服务器是不是「不会断开连接且至少等待 1 分钟无任何数据包」即可确定该服务器是否开启了 shadowsocks 服务。
没错,这样的检测方法比检测原版协议还要神不知鬼不觉,甚至不会在服务端留下任何可疑的痕迹。OTA 当初是为了给原版协议的流加密加上一个认证以增强安全性,殊不知这带来了更大的隐患,这也是为什么 shadowsocks-org 要急急忙忙弃用 OTA 的原因。

四、新协议 AEAD

4.1 之前协议的缺陷汇总分析

原版 shadowsocks 协议最大的缺陷就是未对数据包完整性进行校验,再加上流加密的特点,导致了攻击者可以通过穷举的方式修改密文进行基于服务器行为的主动探测。
OTA 协议虽然通过在数据包尾部附上 HMAC-SHA1 字段对 DATA 的完整性进行了验证,但是包首部的 DATA.LEN 用于计算偏移的指示 DATA 长度的字段并没有经过验证。这导致了攻击者可以通过构建高位的 DATA.LEN 密文进行更隐蔽的主动探测。
因此,在这次新协议草案的讨论过程中参照了 shadowsocksR 协议的一个重要改进 —— 对 DATA.LEN 进行单独校验,参见:ShadowsocksR 协议插件文档

4.2 AEAD 是啥

在通常的密码学应用中,Confidentiality(保密)用加密实现,消息认证用 MAC(Message Authentication Code,消息验证码)实现。这两种算法的配合方式,引发了很多安全漏洞,过去曾经有 3 种方法:
  1. Encrypt-and-MAC (E&M)
  2. MAC-then-Encrypt (MtE) <- 即 OTA 的做法
  3. Encrypt-then-MAC (EtM) <- 新协议的做法
然而后来人们发现,E&M 和 MtE 都是有安全问题的,所以 2008 年起, 逐渐提出了「用一个算法在内部同时实现加密和认证」的 idea,称为 AEAD (Authenticated Encryption with Associated Data)。在 AEAD 这种概念里,cipher + MAC 的模式被一个 AEAD 算法替换。
使用了 AEAD 算法的新协议本质上就是更完善的 stream cipher + authentication,虽然它依然使用的是流加密,但是通过更完善的数据包完整性验证机制杜绝了上面所述的可被篡改密文的可能性。
注:截至本文发布时新协议都是使用的 流加密 + 认证,不过 AEAD 的设计使得它能够使用块加密,因此上面说的并不是绝对的。
而为了实现认证加密(Authenticated Encryption),新协议必须要将 TCP 流分割成不同的 chunk 并分别验证。如对新协议的数据包定义有兴趣可以查阅 官方文档 - AEAD,本文不再深入。

4.3 新协议支持的 AEAD 算法

目前 shadowsocks-libev 已经支持 如下的 AEAD 算法,其他分支也正在跟进中:
  • AES-128-GCM
  • AES-192-GCM
  • AES-256-GCM
  • ChaCha20-IETF-Poly1305
  • XChaCha20-IETF-Poly1305
这些新的加密算法本质上就是 流加密 + 验证,原先的其他单纯的流加密算法均不适用于新协议。

4.4 新协议的优缺点

使用了 AEAD 算法的新协议能够解决上面描述的 Original/OTA 协议的所有问题,可以有效防范 CCA 和中间人攻击,减少被主动探测的风险。我能想到的唯一的缺点大概就是性能了,但是它又能影响多少呢?Benchmark 参考在 这里
shadowsocks 原本就不是为「加速网络」而生的项目,它的初衷是「突破网络审查并提供安全的加密访问」。是继续使用很可能会被 GFW 封锁的原协议呢,还是选择使用更安全的新协议呢,相信各位看官心中自有定夺 。

五、写在后面

写这篇文章之前我对密码学的了解也就是一点皮毛程度而已,所以这篇文章也是我边查资料边写出来的。为了不让自己误人子弟,我非常谨慎查阅了相关资料并向他人请教(衷心感谢 @breakwa11 和 @madeye 对本文的审阅和提出的建议!)
但是所谓「金无足赤,人无完人」,如果文章中仍有什么错误的地方,欢迎在下方评论区批评指正。
大家都不容易,谨以此文敦促 shadowsocks 用户 / 开发者们尽快使用 / 支持新协议。

六、参考链接

phpDocumentor2

Documentation Generator for PHP.

What is phpDocumentor?

phpDocumentor an application that is capable of analyzing your PHP source code and DocBlock comments to generate a complete set of API Documentation.
Inspired by phpDocumentor 1 and JavaDoc it continues to innovate and is up to date with the latest technologies and PHP language features.

Features

phpDocumentor supports the following:
  • PHP 5.3 compatible, full support for Namespaces, Closures and more is provided.
  • Shows any tag, some tags add additional functionality to phpDocumentor (such as @link).
  • Processing speed, Zend Framework experienced a significant reduction in processing time compared to phpDocumentor 1.
  • Low memory usage, peak memory usage for small projects is less than 20MB, medium projects 40MB and large frameworks 100MB.
  • Incremental parsing, if you kept the Structure file from a previous run you get an additional performance boost of up to 80% on top of the mentioned processing speed above.
  • Easy template building, if you want to make a branding you only have to call 1 task and edit 3 files.
  • Command-line compatibility with phpDocumentor 1, phpDocumentor 2 is an application in its own right but the basic phpDocumentor 1 arguments, such as --directory, --file and --target, have been adopted.
  • Two-step process, phpDocumentor first generates a cache with your application structure before creating the output. If you'd like you can use that to power your own tools or formatters!

Requirements

phpDocumentor requires the following:
Note: If you do not want to install the Graphviz dependency you are encouraged to generate your own template and make sure that it does not contain anything related to Graph. An easier solution might be to edit data/templates/responsive/template.xml file and remove every line containing the word Graph but this will be undone with every upgrade of phpDocumentor.
Please see the documentation about creating your own templates for more information.

Installation

There are 3 ways to install phpDocumentor:
  1. Via PEAR (recommended)
  2. Via Composer
  3. Using the PHAR
Please note that it is required that the installation path of phpDocumentor does not contain spaces. This is a requirement imposed by an external library (libxml)

PEAR (recommended)

  1. phpDocumentor is hosted on its own PEAR channel which can be discovered using the following command:
    $ pear channel-discover pear.phpdoc.org
    
  2. After that it is a simple matter of invoking PEAR to install the application
    $ pear install phpdoc/phpDocumentor
    

Via Composer

  1. phpDocumentor is available on Packagist.
  2. It can be installed as a dependency of your project by running the following command.
    $ composer require --dev phpdocumentor/phpdocumentor
    
WINDOWS USERS you may encounter an error ZipArchive::extractTo(): Full extraction path exceed MAXPATHLEN (260) when trying to run the above command. If you do simply add --prefer-source at the end of the command.
Afterwards you are able to run phpDocumentor directly from your vendor directory:
$ php vendor/bin/phpdoc

Using the PHAR

  1. Download the phar file from http://phpdoc.org/phpDocumentor.phar, or from a release listed on github
  2. Move the file with sudo to your bin directory: sudo mv phpDocumentor.phar /usr/local/bin/phpdoc
  3. Ensure the file has execute rights: sudo chmod +x /usr/local/bin/phpdoc
  4. Confirm it runs (you may have to restart your SSH session if you're connecting remotely first) by running phpdoc --version from any directory.

How to use phpDocumentor?

The easiest way to run phpDocumentor is by running the following command:
$ phpdoc run -d <SOURCE_DIRECTORY> -t <TARGET_DIRECTORY>
This command will parse the source code provided using the -d argument and output it to the folder indicated by the -t argument.
phpDocumentor supports a whole range of options to configure the output of your documentation. You can execute the following command, or check our website, for a more detailed listing of available command line options.
$ phpdoc run -h

Configuration file(s)

phpDocumentor also supports the use of configuration files (named phpdoc.xml or phpdoc.dist.xml by default). Please consult the documentation to see the format and supported options.

Documentation

For more detailed information you can check our online documentation at http://phpdoc.org/docs/latest/index.html.

Known issues

  1. phpDocumentor must be installed in a path without spaces due to restrictions in libxml. The XSL transformation will throw all kinds of odd warnings if the path contains spaces.
from  https://github.com/phpDocumentor/phpDocumentor2

马来西亚公布金正男死因:VX神经毒剂

马来西亚警方周五宣布,用于杀死金正男的毒药是VX神经性毒剂,这是一种被列为化学武器的物质
马来西亚警方称,朝鲜领导人金正恩同父异母哥哥金正男是被神经毒气毒死的。警方说,在金正男脸上和眼睛上发现了维埃克斯毒气(VX GAS)。金正男2月15日在马来西亚的吉隆坡机场被两名女子在脸上抹上毒气身亡。维埃克斯毒气被联合国界定为大规模杀伤性武器。

VX (神经毒剂)
VX毒剂是一种比沙林毒性更大的神经性毒剂,是最致命的化学武器之一。它也是一种无色无味的油状液体 ,一旦接触到氧气,就会变成气体。工业品呈微黄、黄或棕色,贮存时会分解出少量的硫醇,因而带有臭 味,主要是以液体造成地面、物体染毒,可以通过空气或水源传播,几乎无法察觉。人体皮肤与之接触或 吸入就会导致中毒,头痛恶心是感染这种毒气的主要症状。VX毒气可造成中枢神经系统紊乱、呼吸停止, 最终导致死亡。
吸入后急性中毒症状:1-2分钟–瞳孔收缩;2-4分钟–多汗,流涎;5-10分钟–抽搐,麻痹,痉挛;10-15分钟–死亡。

Beautiful Docs

(文档生成工具,其实也是静态网站生成器)

I love documentation. If you work with/are writing code intended for usage and consumption by more than one person, you should love it, too. Documentation and other resources will make or break the success of your project. And the more open and collaborative you want development to be, the more crucial docs become.
With that in mind, here's a list of docs and other developer resources that myself and others find particularly useful, well-written, and otherwise "beautiful." May they serve to inspire you when writing and designing yours. Thanks to various contributors, we now also have sections dedicated to Writing about Documentation and Tools for Generating Docs.
This should be updated fairly regularly. As usual, pull requests are encouraged.
  • If you're contributing a link, be sure to include a few words on why you're adding it and some sort of self-attribution so that people can know from whom it came.
  • All docs are listed in the order they were added. Keep this order when submitting your PR.
Mark

And Now For The Docs

Writing about Docs

Generating Docs

  • docco - Pretty docs from source code comments with ports for many languages. (contributed by @kylewest)
  • DocumentUp - Instantly beautify your Github repositories' README.md. (contributed by @kylewest)
  • Sphinx - Comprehensive documentation tool using restructuredText with beautiful HTML and PDF output. (contributed by @nikhilcutshort)
  • MkDocs - Documentation with Markdown, written in Python. (contributed by ericbn)
  • Read the Docs - Hosted docs using Sphinx or MkDocs, supports translations and finding docs for specific software versions. Used by the Django Docs. (contributed by Stephen Paulger)
  • dr.js - Tiny JavaScript documentation generator from the author of RaphaëlJS. (contributed by @nikhilcutshort)
  • Markdoc - Lightweight documentation/wiki generator in Python, released in the public domain. (contributed by Neelfyn)
  • ApiGen - Creates clean API documentation from PHP source code (contributed by bryceadams)
  • docgenerator - Organize your documentation in Markdown files. (contributed by Florian Margaine)
  • dexy - Extensible documentation/report generator supporting multiple programming languages and serveral input and output formats. (contributed by troytop)
  • Slate - Static API documentation creation tool from the team at Tripit.
  • MireDot - REST API documentation generator for Java. Plugs into your build process and generates a searchable html page. (contributed by bertvh)
  • codo - CoffeeScript API documentation generator, similar to YARD. (contributed by Logan Koester)
  • Flatdoc - Create well designed open source documentation from Github repository README files or simple Markdown files. (contributed by @moore)
  • GitBook - Utility for generating documentation, books and exercises using GitHub/Git and Markdown. (contributed by Samy Pessé)
  • Daux - A documentation generator that uses a simple folder structure and Markdown files to create custom documentation on the fly. It helps you create great looking documentation in a developer friendly way. (contributed by veshinak)
  • comment.js - Simple API documentation generator. (contributed by @dciccale)
  • phpDocumentor - phpDocumentor enables you to generate documentation from your PHP source code. (contributed by shivamdixit)
  • Hologram - Hologram is a Ruby gem that parses comments in your CSS and helps you turn them into a beautiful style guide. (contributed by @jchild3rs)
  • Middleman - Static site generator using all the shortcuts and tools in modern web development. (contributed by Sota Yamashtia)
  • documentation.js - Generates documentation from JavaScript source code. (contributed by tmcw)
  • SassDoc - A Sass documentation generator that utilizes inline comments to make pretty and powerful docs. (contributed by Hugo Giraudel)
  • Pickles - Pickles is an open source living documentation generator that works on feature files written in the Gherkin language.
  • ApiDoc RESTful web API Documentation Generator that creates documentation from API descriptions in your source code. (contributed by Trenton Broughton)
  • Documentation theme for Jekyll - Documentation theme built on Jekyll. Includes detailed notes on how to tackle nearly every technical documentation scenario, from single sourcing to conditional filtering, PDF output, relative links, and more.
  • JSDoc - Generate JavaScript API documentation directly from source code comments. Also useful as a style guide for JS commenting, in general. Google uses a version of JSDoc tags for its Closure compiler.
  • Asciidoctor - Asciidoctor is a fast text processor and publishing toolchain for converting AsciiDoc content to HTML5, DocBook 5 (or 4.5) and other formats. (contributed by ThomasG77)
  • Bookdown - A open-source (GPL-3) R package to facilitate writing books and long-form articles/reports with R Markdown. Support for languages other than R, including C/C++, Python, and SQL, etc. (contributed by ThomasG77)
  • Pandoc If you need to convert files from one markup format into another, pandoc is your swiss-army knife. Can generate documentation from most common markup languages. (contributed by ThomasG77)
FROM  https://github.com/PharkMillups/beautiful-docs