January 2011 Archives

今天 Colin 在blog上介绍说 他刚刚修正了一个 TarSnap 重大安全漏洞。简单地说,用来加密密钥文件的AES-CTR实现时,计数器没有增加(正确的实现中计数器应该每次递增),导致在已知明文时能够通过加密块推算出一块数据使用的密钥,并用它来解密余下的数据。

这个漏洞会导致通过某种渠道获得使用受影响的版本(从1.0.22到1.0.27,包含首尾)上传的加密数据的人,在知道其对应明文的情况下能够解密这些数据。

这是tarsnap目前首次发现安全方面的问题,它也再次说明了对于加密代码的安全审计是非常必要的。

PS 漏洞发现者得到了Colin之前承诺的奖金。欢迎大家继续捉虫。

作弊条

在一个git库中跟踪不同的svn branch

首次创建git库:git svn clone [svn代码库到HEAD分支的URL] [git代码库名]

例如,对于 FreeBSD,对应的URL为 http://svn.freebsd.org/base/head/

一般来说,从远程svn库复制需要的时间会比较长,也可以考虑首先在本地建立一份镜像,然后直接用 file:/// 去指定。

接下来编辑 .git 中的 config 文件,找到类似:

[svn-remote "svn"]
        url = file:///downloads/mirrors/freebsd/base/head
        fetch = :refs/remotes/git-svn

对于不同的分支,可以继续添加新的svn-remote小节,例如:

[svn-remote "svn-releng-8.2"]
        url = file:///downloads/mirrors/freebsd/base/releng/8.2
        fetch = :refs/remotes/git-svn-releng-8.2

添加完之后,用git svn fetch svn-releng-8.2这样的命令来同步对应的分支。

本地开发分支

本地开发分支比较简单,只需git checkout -b [你的分支名字] [源分支]即可。

远程开发分支

如果需要在另一个系统上做开发,则需要一些特别的步骤。

首先是git clone远程系统上的代码库。然后编辑.git/config,其中应该有类似这样的部分:

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = server:/repo/freebsd.git

为svn的branch建立对应的remote:

[remote "svn"]
        fetch = +refs/remotes/*:refs/remotes/svn/*
        url = server:/repo/freebsd.git

然后git pull,在git branch -r时就能看到远程系统上的git-svn branch了。这个主要是在git merge的时候比较有用。

我一直是非常反对重装系统的。从技术上说,今天的折腾并不算是重装系统,不过因为把机器上所有的数据(是的,文件系统全部都拆掉重建了)都重写了一遍,所以还是算做了一次吧。

缘起

在采购 家里的路由器 的时候,选择了 WDAV-25【1】 系列硬盘。我选的那款硬盘使用的是新式的 AF (4kiB扇区)格式。

FreeBSD 使用的主流文件系统 UFS 和 ZFS,以及 ahci(4) 驱动都 直接支持 4kiB 扇区。但是,目前市面上的AF硬盘,为了与先前的 BIOS 和操作系统(主要是 Windows XP)兼容,对于 ATA IDENTIFY 的回应,原先返回扇区尺寸的位置变成了逻辑扇区尺寸,这种做法俗称512e,即硬盘通过固件或其他方式模拟山区尺寸为512字节,并处理相关的回写操作。

以512字节为单位进行读写时,在AF格式的硬盘上是低效的。FreeBSD的 ahci(4) 驱动和对应的 ada(4) 驱动会设置 stripesize 以反映驱动器采用的实际物理扇区尺寸,但文件系统并不直接识别这个尺寸。

对于 ZFS 而言,其扇区尺寸是在创建时以 ashift 值写死的,目前在命令行没有办法指定这个值,也不能在创建 ZFS 之后修改。如果修改内核令其使用 GEOM 的 stripesize 来产生 ashift,对 AF 硬盘则会出现内核得到的 ashift 比先前已经存在的 ashift 大,从而导致 ZFS 无法识别的问题(如果创建 ZFS 时已经使用了更大的 ashift 则没有关系)。因此,必须想办法让 ZFS 在创建时就知道扇区尺寸是 4KiB。

FreeBSD 5.3-RELEASE 时新增了一个调试用的 GEOM class ---- gnop。可以用它来封装其他 GEOM 对象,并改变扇区尺寸,方法是 gnop create -S 4096 /dev/gpt/store (此处 /dev/gpt/store 是一个按 4k 对齐的 GPT 分区的 label)。gnop会产生一个新的设备节点,/dev/gpt/store.nop,其向系统汇报的扇区尺寸是我们指定的 4096 字节,而不是驱动器汇报的逻辑扇区尺寸 512 字节。

使用这个设备节点创建的 ZFS 就会采用正确的 ashift 值了。

使用 zdb -C pool名字可以检查 ashift 值:对于扇区尺寸为 512 字节的 zpool,其 ashift 是 9,而我们希望的 ashift 值是12。

gnop节点在系统重启以后会消失,但 ZFS 会记住 ashift,因此并不会导致问题。此处也可以 zpool export,gnop destroy /dev/gpt/store.nop 然后再 zpool import 来验证。

经测试,ZFS在知道正确的扇区尺寸以后,持续写操作的性能可以提高至少一倍。

在服务器上用gpg-agent

| 1 Comment | No TrackBacks

上回书说到通道服务器的问题。在 /etc/csh.cshrc 中添加下列内容,可令系统同时启动gpg-agent和ssh-agent:


 
setenv SSH_AUTH_SOCK    /dev/null/nonexistent
if ("${TERM}" != "su") then
        [ -e ~/.gpg-agent.csh ] && source ~/.gpg-agent.csh >& /dev/null
        echo UPDATESTARTUPTTY | /usr/local/bin/gpg-connect-agent >& /dev/null || /usr/local/bin/gpg-agent --daemon --ignore-cache-for-signing >& ~/.gpg-agent.csh && source ~/.gpg-agent.csh >& /dev/null
        [ -e ~/.ssh-agent.csh ] && source ~/.ssh-agent.csh >& /dev/null
        [ -e ${SSH_AUTH_SOCK} ] || ssh-agent -c -t 20m >& ~/.ssh-agent.csh && source ~/.ssh-agent.csh >& /dev/null
endif

启动gpg-agent的作用是在一段时间内不用重新输入gpg的密码。

和之前的那篇类似,这里也给出一些安全方面的注意事项:

  1. gpg-agent的安全性依赖于本地文件系统安全性。只应在可以信赖的系统,例如作为"通道"的服务器上使用。
  2. gpg-agent作为ssh-agent使用时,其安全性还依赖于远程系统的本地安全性。如果远程系统不可信赖,在 ssh 登录时应禁用 Forward Agent。远程系统并不能获得私钥,但可以让本地系统进行签名,从而导致问题。
  3. 默认的过期时间是gpg密钥600秒(10分钟)。可以通过--default-cache-ttl来调整。

更新:发现 gpg-agent 由于某种原因没有对 ssh 生效(不是没有指定 --enable-ssh-support),所以暂时先用两个daemon来跑。

Monthly Archives

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.2.3