2009年9月13日星期日

软件自由英雄谱

    谨以此缅怀那些为了今日软件事业的自由做出贡献的先辈们。(注1: 多数人没牺牲,谢谢)(注2: 排名不分先后)(注3: 科普作品,大家别怕)
    我在撰写这篇文章的时候,避免使用自由软件这个词,而改为更普遍意义上的软件自由。因为自由软件是RMS提出的一个专有词语,指软件的开源,复制,协作等 特质。而我试图通过软件自由这个词,表达人们在使用软件上的自由,以及使用软件来为我们获取自由。我们拥有知道软件一切内幕的自由,我们拥有修改软件的自 由,我们拥有思考的自由,我们拥有挑战老系统的自由,我们拥有拒绝通过软件收费的自由,我们拥有通过软件获得信息的自由,我们拥有不受任何人,包括政府监 控的自由。为了这种自由而付出的,不仅是自由程序的拥护者,也有商业程序的拥护者。
1.Richard Matthew Stallman
    大名鼎鼎的RMS,GNU的核心人物,自由软件的布道者。要是在这个列表上没有他的名字,那我不知道还有谁能留在这张表上。具体可以看这里(http://zh.wikipedia.org/zh-cn/%E7%90%86%E6%9F%A5%E5%BE%B7%C2%B7%E6%96%AF%E6%89%98%E6%9B%BC)。简单来说这家伙最大的几个成就:创立了GNU和FSF,为自由软件的传播奠定了基础。制作了emacs,当今黑客世界两大编辑器之一(另一个是VIM)。制作了GCC,世界上使用最广泛的编译器。
    RMS的核心想法是,因为软件而收费是罪恶的,这种人是撒旦(当然,Bill Gates是其中最大的那个)。他认为软件应当自由分享,程序员从中收取的应当是服务费。今天,RedHat正是继承了这一模式。通过免费的软件和收费的服务来进行持续的开发。
2.Linus Benedict Torvalds
    常常和RMS并提的一个家伙,具体在这里(http://zh.wikipedia.org/zh-cn/%E6%9E%97%E7%BA%B3%E6%96%AF%C2%B7%E6%89%98%E7%93%A6%E5%85%B9)。 一个低调又火爆的家伙,没有什么太多言论,但经常语出惊人,最有名的是以“一群自慰的猴子”(OpenBSD crowd is a bunch of masturbating monkeys)来形容OpenBSD的团队。最大的成就就是写了个操作系统——没错,就是叫Linux的那个。
3.Donald Ervin Knuth
    哈,这个人就不像上两个那么广为人知了。他(可不能叫这家伙,得敬老)有个中文名字,叫高德纳,页面在这里(http://zh.wikipedia.org/zh-cn/%E9%AB%98%E5%BE%B7%E7%BA%B3)。 最大的成就是写了本书,叫做《计算机程序设计艺术》。有意思的是,写到一半的时候,觉得现在(那是上世纪80年代的事情)的排版软件不爽——于是自己下 手,写了一个叫做Tex的排版系统——然后再回来继续写书。这本书算起来已经写了30多年了,估计成书时间和《浮士德》有的一拼。而Tex是当今高端排版 中最流行的系统(多数都不是直接拿来用,而是用了LaTex之类的包装),如果有向国际期刊投稿过的应该有印象。Tex也是被誉为最接近完美的程序,它的 介绍在这里(http://zh.wikipedia.org/zh-cn/TeX)。他的版本号是以圆周率为基准的,头一个版本叫3,后一个叫3.1, 以此类推。目前的版本号是3.1415926,刚好是祖冲之的密率。高伯伯曾表示,等他死之后,版本号就改为π,剩下的bug就作为程序的功能放在那里。
    有一个未经证实的故事。据说上世纪Internet还没出现的时候,美国军方找人设计了TCP/IP协议,他们希望有人为他们实现基于Unix的TCP /IP协议栈。于是他们花了四千万美金,找人写了一个协议栈,并且拿到高伯伯的学校去用。对此高伯伯非常不满意——别误会,我指的是实现的效果。于是就自 己花了点时间写了一个,结果比原版的协议栈更快速而稳定。美国军方觉得非常困惑,问他是怎么做的。高伯伯说,读你们的协议,然后编码。
4.Andrew Stuart Tanenbaum
    这个知道的人也不会太多,当然,职业玩家例外。当初AT&T禁止UNIX7的代码公布,因此大学里面都没什么实际产品可以用来教操作系统这门课。 于是,有个叫AST的老师就怒了,你不让我干,我自己干。于是写了一个叫做Minix的系统,并且还写了本书,叫做《操作系统:设计和实现》。后来有个学 生,觉得这个系统改改能干别的,于是给AST去信。AST说,改什么改,我写这东西是拿来教书的。于是这个学生就自己写了一个系统——对了,这个学生就是 上面的Linus,而那个系统,就是大名鼎鼎的Linux。
    时至今日,Minux已经发展到了第三版(他的版本号是跟着书走的,第一版,第二版,第三版...),是大多数大学里面教授操作系统基础原理的标准教材。 同时,也在嵌入式系统等领域有非常大的应用。但是,由于AST还是坚持他的教学和精简原则,因此在桌面和服务器领域就别指望了。关于AST,大家可以看这 里(http://en.wikipedia.org/wiki/Andrew_S._Tanenbaum)。
5.Ian Murdock
    这个人很多人都听过,不过看着名字还是认不出来。他是Debian系统的作者,具体可以看这里(http://en.wikipedia.org/wiki/Ian_Murdock)。
    Debian有什么特殊呢?其实就本身来说,Debian并不算特别成功。但是Debian有庞大的衍生系统群,更有Ubuntu这样充满活力的发行。 Linux世界有所谓三大发行,四大包管理系统之说。其中三大发行指三个在世界上最广泛用于服务器的发行版本,即RedHat Enterprise Linux,SuSe, Debian,其中只有Debian是无服务商支持的。而四大包管理系统就是指RH的RPM系统,Debian的APT系统,arch的PCMAN系统, 和Gentoo的emerge系统。
6.Ken Thompson
    有没有听说过?至少看着眼熟吧。这家伙是贝尔实验室的,最大成就就一个:Unix作者。详细内容请看这里(http://en.wikipedia.org/wiki/Ken_Thompson)。
7.Dennis Ritchie
    没听说过?也很眼熟?这家伙和上面那位是朋友,最大成就也就一个:给上面那位提供了基础语言,C语言。详细内容请看这里(http://en.wikipedia.org/wiki/Dennis_Ritchie)。
8.Bjarne Stroustrup
    又是一个怎么看怎么眼熟的家伙?那当然。他和上面两位不怎么熟,不过他们都是一路的。他是C++的作者,详细内容请看这里(http://en.wikipedia.org/wiki/Bjarne_Stroustrup)。
9.Phil Katz
    这个就很少有人知道了吧,不过大家肯定天天和他打交道。大家用记事本打开任意一个ZIP文件,开始的两个字肯定是PK,这就是Phil Katz,具体请看这里(http://en.wikipedia.org/wiki/Phil_Katz)。
    这是一个有点悲剧的人物。在上个世纪的时候,大家还在BBS上混。由于速度有限,因此下载站的资源都是压缩提供的(当然,直到今天肯定还是如此)。最初的 压缩格式大多是ACE的,这是一家商业公司,直到今天还活着。由于PK不满意这家公司的压缩软件,压缩率低,速度慢,而且还不断提出高昂的收费。因此他决 定自己写一个压缩软件,就是最初的PKZIP。由于软件免费提供使用,压缩率高,解压速度快,因此很多站长自发的将数据格式转换为ZIP。后来PK就干脆 开了PKWARE软件公司,免费发行压缩程序代码,同时提供方便使用的图形界面版本。但是非常可悲的,由于格式开放,因此这个软件有个非常大的竞争 者,winzip。我想有些Win95时代的老用户还记得这个软件。PK在软件开发上很有天分,但是在市场策略上却不很成功。WinZip对ZIP格式的 熟悉其实比不上PK(那当然,人家是原作者),然而WinZip却拥有很多用户友好的特性,右键菜单解压,虚拟解压(将压缩包的内容临时虚拟成一个目录, 用户可以无缝的使用,XP中集成了这个功能,但是WinZip的虚拟解压很容易撤销)。所以最终PK的软件公司破产了。他本人在2000年4月14日因饮 酒过度,在一家小旅馆内死去。
    至于WinZip呢?碰到了一个更强大的对手,WinRar。功能类似,但更简洁,最主要是支持大多数流行的压缩格式。因此目前压缩软件领域还是WinRar占据着主流,市场就是这么残酷。
10.Phil Zimmermann
    这个人基本没人知道,但是却是这张表里面最典型和突出的一个人。他是PGP的作者,具体可以看这里(http://en.wikipedia.org/wiki/Philip_Zimmermann)。他的成就很难用一句话说明,要阐明他的成就,就必须从美国的国家安全出口管制说起。
    在上个世纪,美国政府有一种观点,他们需要能随时随地的窃听任何一个人和其他人的通讯。同时,作为延伸,他们制定了国家安全出口法案,将密码产品作为军用 管制品,限制出口。这其实是很荒谬和不合逻辑的,任何公开的算法都可以被多个人独立的实现。只要算法是公开的,即使产品不允许出口,国外也可以没有任何阻 碍的实现出来。而如果算法是不公开的,则会出现两个弊端。一个是阻碍密码学的交流和进步,更麻烦的是,根据密码学的内在逻辑,这样的系统,由于验证不完 全,因此比公开的系统更加不安全。
    在1991年前后,PZ制作了PGP软件,用于保障当时备受争议的电子邮件的安全(小常识: 电子邮件默认是明文的,安全程度和你写在明信片背面寄给你父母的句子差不多)。这个软件使用了1980年以来提出的现代密码系统几大密码系统,实现了签名 安全和秘密安全。这里我们小小的讲解一下电子邮件的两大安全系统,对此无爱的人自行跳到下一段。签名安全就是指,你收到一个邮件的时候,能够确信,这个信 的内容是原始发件人的真实意思表示,而不是被篡改过的。秘密安全就是指,当你收到一个信的时候,你能够确信,除了你没有别人能够偷看到内容。对此,一般采 用公钥系统来实现两者的安全。所谓公钥系统是这样一种系统,用公钥加密必须用私钥解密,用私钥加密必须用公钥解密,私钥很容易计算出公钥,公钥非常难计算 出私钥。当你要签名安全的时候,将邮件内容用自己的私钥加密再发送一次(实际是将内容hash了再加密的),接收者解密后对比。由于篡改者只有公钥,因此 虽然可以拦截和修改内容,但是无法伪造出一对匹配的内容,用公钥解密后刚好一致。而秘密安全则是用对方的公钥加密。对于更高层级的要求,你的公钥不仅要求 公布,而且必须在国家认可的部门公布,这样就由国家认定了你的公钥和你的身份的一致性。当你对一个内容签署的时候,只要能用公钥验证签名,就可以认定内容 是你的真实意思表述,并被法律所承认。
    当时的PGP当然还没有这么复杂,但是对于当时缺乏任何安全性特征(当时连TLS都没有)的电子邮件来说,是非常必要的补充。可是我们上文说了,美国禁止 出口这些产品。于是,PZ免费的将软件的最初版本散发给同事和其他人使用,而这些人又可以免费的分发出去——这和自由模式非常的吻合,除了我找不到具体信 息标明当时PZ是否从授权上同意他们做这个事情。法律上说,PZ并没有“出口”密码产品,但是实际上,是他实现并且向全世界推广了高强度的电子邮件安全系 统。从某种意义上说,PZ可以说是叛国者。非法散布军用管制品,危害美国的国家安全(这还不像中国那种含糊不清的指控,这里的军用管制品定义是明确的,并 且是由国会制定的)。于是,PZ受到了三年的官司和五年的调查,直到96年的时候,克林顿签署了新的法案,放松了密码产品的出口限制。其实也没松多少,从 40位到56位——大概就是从5个字符到7个字符的区别。反之,我们改变观点,从世界的角度说,由于他的勇气和决心,我们每个人从中受益匪浅。
    必须得说,其实这一改变很大程度上并不是PZ个人努力或者公民运动的结果,其中有巨大的商业力量。IBM,微软和Lotus之类的跨国软件巨头在出口产品 的时候,由于受到出口限制,因此在海外产品上的安全性一直很成问题。很多时候他们因为这个问题受到了巨大的挑战。在这一问题上,他们有足够的理由去游说白 宫,改变出口限制的要求。关于这个案件的其他资料,可以参考这里(http://cyberlaw.stanford.edu/~prz/ZH/faq/index.html)和这里(http://www.techcn.com.cn/index.php?doc-view-130949)。
    在今日,PGP仍旧是一个非常强大的加密系统,并且是开源的——理所当然,如果不开源,我们会担心其中是否有漏洞和后门继续危害我们的安全。并且,从密码 学内在的逻辑来说,不公开的系统是不安全的。不过他仍旧受限于美国国家安全出口管制条例,原因是因为由于今日强大的计算能力,因此密钥通常的长度是 1024,2048,4096位长的——远远超过美国国家限制数十倍。因此这一软件的强密钥版本只有英文版,因为不用考虑出口。对于海外人士来说,我们更 推荐OpenPGP,同样是开源的,而且基于开源模式开发的GNU自由软件。能够充分保证你的信息安全。
11.Lawrence Edward Larry Page
    哈,在所有人中,这个是最出名的。不过在这个列表中列出此人,并非因为Google的成功,而是因为其公司“不作恶”的信条。直到今日为止,Google还良好的保持着不作恶的信条。
结尾
    我们遍数评论一个个的软件自由英雄的时候,才会发现,无论在哪里,通向真正自由的路都坎坷而血腥。RMS直到快50还一直单身,到处流浪。他没有自己的汽 车、电视和房产。PZ面临了政府的指控,三年的官司,五年的调查,以及叛国者的骂名。PK更是直接挂了。当然,其中也不乏成功者,Donald Knuth和Andrew.S.Tanenbaum的书都卖的不错。Linus Torvalds和Ian Murdock也算是软件白领,收入不菲。Larry Page更是名列世界级的富豪榜。然而我们必须知道两件事情,没有他们的存在,我们就没有安全的通讯,没有廉价而优质的软件。因此,照RMS的最大对手所说的,即使没有这些人,人类也应当把它们造出来。

2009年9月8日星期二

计算机中的海森堡效应和罗素悖论

    有点标题党,海森堡测不准原理大家都知道吧,你观测一个东西以获得他精确的描述,然而你测量行为本身就会干扰这个东西的存在,从而永远无法准确测量。
    近日贝壳碰到一个计算机中的海森堡效应,因为工作需要,贝壳需要获得/proc/loadavg中的load参数。这个参数在uptime时会显示,大致意义是这一秒内平均的活跃进程数。(对电脑无爱者请自行跳过以下内容到下一段)准确的计算方法是在一秒内的所有tick上,累加当前的待运行线程列表长度,而后除以一秒内的所有tick。当tick趋于无穷小时,相当于对活跃进程的定积分除以横轴长度,即平均值。
    同个文件内有另外一个值,活跃进程数,是当前的待运行队列长度。从理论上说,如果贝壳要计算一个小时(或者其他大尺度时间)的loadavg,可以高速取样该值,在一小时内求平均,即复现load参数的意义?
    想法很好,不过实际上差很多。开发服务器上的loadavg大约是0.01-0.05,但是贝壳按照后者算出来的load总大于1。问题在哪里?
    记住一点,当你去获得loadavg的时候,你当前的线程永远是在运行的。因此你获取的行为会增长活跃进程的值,哪怕其他时间什么都不做,这样会将取值的瞬间的load提高至少1。而内核的计算的时候,是不会把自己的行为计算为活跃进程的。
    那么将值减去1对不对?也未必。在知道上述问题的同时,我们可以想象。在高压力下,你的线程什么时候会获得运行的机会?只有在最高优先级的任务空闲的时候。因此,你取得的值会严格的小于真实的压力。
    因此,不要相信当前活跃进程数,那个值永远大于1,并且不总正确。如果那个值是0,那逻辑上讲,你就碰到了罗素悖论。
    咳咳,又来一个问题,什么是罗素悖论?
    很简单。如果说真话的人永远说真话,说假话的人永远说假话。有人对你说:“我在说谎”。你就听到了罗素悖论。同理,如果理发师只给不给理发师理发的人理发,而所有理发师的头发都有人理,那你也碰到了罗素悖论。同样,如果有程序告诉你,我读取了当前的活跃进程数,但是这个数表明我不活跃。
    同样,你也碰到了罗素悖论。

2009年9月3日星期四

搭建家用的OpenVPN服务器

    啥都不说了,贝壳最近搞了一个家用的OpenVPN服务器,任何机器,随时随地可以穿到家里来,很方便。用VPN干啥?这就多了。我可以用vpn操作 Windows上的vnc,使用Windows的共享文件服务,直接向Linux Server放文件(这样别人可以用http下载),查看摄像头(被网络公布了)。将来如果有其他网络设备(例如冰箱和空调),也可以一并管理。不过最直 观的——可以很方便的打游戏,我们根本就在一个网络里面。要点是,这些服务要分别开映射端口非常麻烦。而且有的服务从安全起见,根本不能开端口(例如臭名 昭著的Windows文件共享服务)。
    具体原理上,贝壳有一台Windows,上面用Vmware搭建了一台Debian Linux,两者使用桥接模式。从概念上看,就是一台通向公网的路由器,里面放了一台Windows和一台Linux。现在,贝壳想通过某种方法,将外部 的一台机器接入内部的局域网中,就如同随身携带着一根通向家里路由器的网线一样。
    下面直接上具体配置:
-----------filename: /etc/network/interface-------------------
auto lo
iface lo inet loopback
iface eth0 inet static
        address 0.0.0.0
iface tap0 inet static
        address 0.0.0.0
auto br0
iface br0 inet static
        bridge_ports eth0 tap0
        address 192.168.1.IP
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        dns-nameservers 192.168.1.1
        dns-search home
-------------------------------------------------------------
    使用上述配置的原因是,vpn只能联通你机器上的逻辑网卡和服务器上的逻辑网卡。单就vpn自身而言,是无法让你连到服务器上的内网网卡的。因此,我们需要通过网桥的配置,将eth0和tap0配置成网桥。这样,你的服务器就如同一台交换机一般,联通了两个网段。
    而后,我们设定服务器配置。
-----------filename: /etc/openvpn/server.conf----------------
local 192.168.1.51
port 1194
proto udp
dev tap0

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem

server-bridge 192.168.1.IP 255.255.255.0 192.168.1.100 192.168.1.149
push "route 192.168.1.0 255.255.255.0"
keepalive 10 120

user nobody
group nogroup

persist-key
persist-tun

cipher DES-EDE3-CBC # Triple-DES
comp-lzo

verb 3
status /var/log/openvpn-status.log
;log openvpn.log
log-append openvpn.log
-------------------------------------------------------------
    其中的server-bridge是因为我们采用网桥的关系,100-149是向外部拨入分配的IP池。贝壳的2-100是内部固定IP保留,150-199是内部DHCP池,200-254保留。这个大家可以按照自己的情况配置。
    需要特别注意的是,由于上文我们已经建立了tap0这个设备,因此才dev中必须指定tap0设备。如果你仅写tap,那有可能是新建一个设备出来。到时候就好玩大了...
    上文中,我们使用了ca cert key dh四个密钥文件选项。下面我们说说如何产生这些密钥文件。
    首先,你需要复制usr/share/doc/openvpn/examples/easy-rsa/2.0/到你的个人目录,并修改其中的vars文 件。将其中的一些东西修改为你需要的参数(很简单,我假定大多数人都会用,这个是基于SSL的),而后source vars,执行下述命令。
./clean-all
./build-ca
./build-key-server server
./build-dh
#需要�入密�的
./build-key-pass username
#不需要�入密�的
./build-key username
    最后两个可以随便签署,想发多少密钥就给多少人签署。不过请注意,easy-rsa的默认脚本中,是没有ns-cert-type server的设定的,因此*千万不要*在配置中加上这个设定。否则会导致TLS handshark failed。
    最后,启动vpn,并且修改你的防火墙和路由器映射,贝壳这里使用的是udp1194端口(默认)。再给客户分发配置和key,具体如下:
------------------filename: home.ovpn-----------------------
remote shell909090.3322.org 1194
client
proto udp
dev tap

ca home.crt
cert shell.crt
key shell.key

resolv-retry infinite
persist-key
persist-tun

cipher DES-EDE3-CBC
comp-lzo

verb 3
-------------------------------------------------------------
    其中home.crt是服务器上的server.crt,shell.crt和shell.key是刚刚签署的用户密钥。如果有密码,需要设定密码,或在连接时提供。

--
与其相濡以沫,不如相忘于江湖