比尔盖子从去年开始进行全系统加固,无论是个人电脑还是服务器都部署了 Gentoo Hardened,并采取了不同程度的安全措施。Chromium、FireFox,以及基于 Webkit 的外壳浏览器是自由软件界的御三家,从特性上来说各有独自的优势 —— 如果要从这一点上进行谈论恐怕会触发圣战,这也并不是比尔盖子撰写本文的目的。本文企图从系统安全的角度来说明浏览器的选择。
比尔盖子从去年开始进行全系统加固,无论是个人电脑还是服务器都部署了 Gentoo Hardened,并采取了不同程度的安全措施。Chromium、FireFox,以及基于 Webkit 的外壳浏览器是自由软件界的御三家,从特性上来说各有独自的优势 —— 如果要从这一点上进行谈论恐怕会触发圣战,这也并不是比尔盖子撰写本文的目的。本文企图从系统安全的角度来说明浏览器的选择。
今天在微博上,@julyclyde 发现了一个看似简单但很有意思的问题,import os.path
的行为很奇怪。
今天下午,惊闻 MMD 宣布张峻锋(微博:@马鹿峻鋒連聊C)被认定参与了恶意软件的编写。按照我个人的了解,张峻锋在学业之外,积极参与自由软件开发,包括 AOSC 社区的一部分工作,不太可能从事利用蠕虫危害网络安全的事情。因此做了一些调查,事件始末如下。 Continue reading
由于众所周知的原因,服务器的 SSH 端口 22000
开始变得不太稳定,经常出现无法连接的情况。因此,现启用备用端口,如无法连接服务器,可尝试连接端口 12450
。
近日起,比尔盖子在 24 小时内收到了 20000 封来自公共邮件列表的订阅确认邮件,八成都来自自由和开源软件(FOSS)项目的邮件列表。而涵盖的项目也至少多达 20 个,不限于 OpenBSD、FreeBSD、GNU 计划、Ubuntu、CentOS、Qt、HostAp,甚至是以邮件著称的 Postfix。“订阅者”来自多个 IP。 Continue reading
前两年 GNOME 开始将 iBus 集成为其的一部分,为用户提供更为一致的输入体验,引发了众多非议,包括强迫用户使用如此之烂的 iBus “输入法”(显然是把 iBus 框架和 ibus-pinyin 引擎混为一谈的),阻止用户换用其它输入框架等等。 Continue reading
互联网安全随着以 NSA、GCHQ 为首的大规模政府监视已经变得岌岌可危了。Google 虽然还有一些信任度,但也不是像以前一样可以完全信任了。就说电子邮件吧,自建服务器才是目前最为可行的方案。然而,一旦服务器被入侵,上面的明文邮件也会全部泄露。
只有数学还是可信的。如果我们的邮件服务器在接收到邮件的同时,对邮件进行 PGP 加密再储存(已经加密就不需要再加密了),就是一个完美的安全方案了。如果这封邮件本身还是通过 TLS 加密的 SMTP 投递过来的,那么可以说牢不可破了。我们还可以把服务器配置成一个转发服务器,继续用自己原先的邮箱服务。
原本盖子打算写一个 Postfix 的 Filter 脚本来解决这个问题,然而,盖子发现几年前,就有人编写了 Exim 和 qpsmtpd 的插件支持,都是 Perl,在此分享:
注意,这会导致垃圾邮件也会被加密。一定要配合完善的反垃圾措施使用,qpsmtpd 的反垃圾就非常强大。
pub rsa4096/717E3FB8 2013-03-20 [已吊销:2015-01-01]
uid [ revoked] Tom Li (Biergaizi) (My Gmail) biergaizi2009@gmail.com
uid [ revoked] Tom Li (Biergaizi) admin@biergaizi.com吊销原因:密钥已泄漏
This key was considered as a unsafe key, because the private key was copied to multiple computers, including some semi-public computers. Although there is no any evidence shows anybody stole my private key, but I think I’d better to revoke the key and generate new keys. The new keys are E88E8D6D (crypt), 01EE20CD (sign), and 26DC385B (auth). Tom Li Thu Jan 1 16:31:50 CST 2015
更新 1:经过 tonghuix 与官方的交涉,现在我获得了全套管理工具,和 PKCS#11 的动态库,已经可以和 gpg 联合使用了。然而灵活性还是太差,因为私有中间件只能在 x86 上工作,打算进行反向工程。
如果你熟悉并使用以 RSA 为代表的非对称加密算法,来加密文件、签名电子邮件或者登录 SSH 服务器,那么你肯定会遇到密钥便携性的问题。如果你带着个装有私钥的 U 盘四处跑,私钥什么时候被拷贝走了估计你也不会知道。
为了解决这个问题,可以将私钥放到一个黑盒里,并由黑盒完成全部的加密和签名,同时没有办法从中获取私钥,还可以设置 PIN 码。这个黑盒就是智能卡。有两种规格的智能卡可以实现上述需求:其一是 OpenPGP card,由 FSFE 主导开发,开箱即用,但很难获得;第二是各类符合 PKCS#11 标准的智能卡。
ACOS5-64 就是一款 PKCS#11 的智能卡。它不但支持非对称加密,还支持对称加密,从特性上看,是一款十分强大的智能卡。然而千万不要购买它,这卡……没!有!驱!动!对,你没有看错!
既然支持 PKCS#11,那么应该直接使用通用工具就可以了吧?图样图森破!PKCS#11 允许厂商提供一个动态库来提供 PKCS#11,而这个动态库就相当于私有驱动。而 ACOS5-64 支持 PKCS#11,却没有提供驱动。事实上,ACS 公司确实开发了相关的驱动,但附在 SDK 里,需要另行购买,然而,这个驱动究竟是 Windows Only,还是也有 so 模块我们不得而知。而且,就算有 Linux 模块,但因为这是二进制驱动,因此无法在非 x86 下正常工作。
但不同于其它卡片的是,此卡的具体规格和 Datasheet 均可获得,不需要签署 NDA。曾有一 MIT 学生在 2010 年企图在 OpenSC 框架下实现此卡驱动,然而他仅仅完成了基本功能,以及 RSA 1024 的支持,最终因为众多坑放弃开发。
也就是说,这卡在任何系统平台与应用程序上,均完全无法使用!
更新 2:wget 1.16.1 版本已包括补丁,问题彻底解决。
更新 1:我的补丁已经被接受了,Bug 已修复。
wget
是 GNU 开发的实用下载工具,最近它刚刚发布了 v1.16。
先介绍一下背景,wget
向来就有两种进度条,“点形”和“条形”,其中,“条形”还有可选的跑马灯效果。
“刷屏点形”是指这样的效果
0K .......... .......... .......... .......... .......... 0% 107K 8m30s
50K .......... .......... .......... .......... .......... 0% 52.0K 13m0s
100K .......... .......... .......... .......... .......... 0% 31.3K 18m21s
150K .......... .......... .......... .......... .......... 0% 22.0K 24m4s
如果你的终端设备功能有限,不能做到即时更新屏幕内容,或者是重定向到了文件,“点形”进度条就很实用。
“条形”就是指这样的效果
filename 0%[ ] 134.05K 59.7KB/s
很适合可以即时更新的终端。
这两种类型可以使用
wget --progress=dot
wget --progress=bar
切换。
现在问题来了。如果文件名称很长,条形进度条左侧那一点点空间显示不下该怎么办呢?wget
的开发者想出了一个跑马灯效果,很像大街上的 LED 横幅,不停的让文字滚动,这样用户就可以“管窥”整个文件名了。
然而,盖子发现一个特别郁闷,而且能逼死强迫症患者的问题。wget
的滚动有 Bug,文件名的最后一个字符始终不显示!就象这样:
this_is_a_
his_is_a_f
is_is_a_fi
s_is_a_fil
_is_a_file
is_a_file_
s_a_file_n
_a_file_na
a_file_nam
<-- WTF!
this_is_a_
在 progress.c
中,不难发现这段代码
if (((orig_filename_cols > MAX_FILENAME_COLS) && !opt.noscroll) && !done)
offset_cols = ((int) bp->tick) % (orig_filename_cols - MAX_FILENAME_COLS);
else
offset_cols = 0;
offset_bytes = cols_to_bytes (bp->f_download, offset_cols, cols_ret);
bytes_in_filename = cols_to_bytes (bp->f_download + offset_bytes, MAX_FILENAME_COLS, cols_ret);
memcpy (p, bp->f_download + offset_bytes, bytes_in_filename);
p += bytes_in_filename;
由于有一些字符占用 1 字节,有些占用 2 字节,因此下面部分的代码全都在处理把字符转换成字节数的问题,其实这段代码做的事情很简单
if (orig_filename_cols > MAX_FILENAME_COLS
&& !opt.noscroll // 没有禁用跑马灯滚动效果
&& !done) // 下载仍未结束
offset_cols = bp->tick % (orig_filename_cols - MAX_FILENAME_COLS);
bp->tick
是 int
,每刷新一次进度条,它会就自增 1,可以把它理解成进度条刷新的次数,(orig_filename_cols - MAX_FILENAME_COLS)
就不用多说了,显然是计算文件名超出最大允许长度的字符数。
最后,从 offset_cols 开始截取 orig_filename_cols,一直截取 MAX_FILENAME_COLS 个字符。
用取余数运算来实现不断截取字符串的特性,看起来还是挺巧妙的。不过,正是这里的代码存在着问题。
写程序的时候,经常因为该 + 1
/- 1
而忘记了(len()
vs. 下标),不该加减 1 的时候乱加减,导致典型的越界往往和正确范围只差 1 位。
再比如这些令人困惑的表述
def range(begin, end)
/* 11 日到 21 日间断电 */
/* 变量取值范围 0 ~ 256 */
到底包不包括这个 end,或者包不包括 21 日,或者 256?P.S:幸好数学家们早就意识到了这个问题,发明了区间表示法,圆括号表示“排除”,方括号表示“包括”。
而 wget
的“最后一个字符始终不显示”的 Bug,具有典型的“范围差 1”的特征,那真正的问题到底出不出在这里呢?
为了看看 wget
的这个算法到底有没有 Bug,写个程序检验一下。
FILENAME = "this_is_a_file_name"
MAX = 10
def cut(string, _min, _max):
assert _max <= len(string) - 1
return string[_min:_max]
for i in range(0, 20):
offset = i % (len(FILENAME) - MAX)
print(offset, offset + MAX, cut(FILENAME, offset, offset + MAX))
这就是 Python 版本的简单算法实现了,运行之后:
0 10 this_is_a_
1 11 his_is_a_f
2 12 is_is_a_fi
3 13 s_is_a_fil
4 14 _is_a_file
5 15 is_a_file_
6 16 s_a_file_n
7 17 _a_file_na
8 18 a_file_nam
<-- WTF!
0 10 this_is_a_
果然出错?那么问题究竟出在哪里呢?拿这个例子分析一下,”this_is_a_file_name” 有 19 个字符,而最大的允许字符是 10 个。那么,那么,相差 9,看来编写者认为 9 就是需要的滚动次数。然而,滚动 9 次,就是有 10 种组合啊!
果然忘记 + 1
,而接下来就不用多说了。就等开发者接受补丁了。真是低级错误不可避啊……
Copyright © 2023 比尔盖子 博客
Theme by Anders Noren — Up ↑