delphij's Chaos
选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……
口令是许多系统中用于判断用户身份的重要手段。当然,使用口令作为身份验证方法是很不靠谱的(例如,许多用户会使用弱口令,或者在多个系统中使用同样的口令,以及它存在对称失密问题,等等),不过因为口令便于携带(相对于私钥)和实现,因此仍然被广泛使用。
验证用户口令有很多种不同的方法。最原始的方法,就是将用户输入的口令与我们保存的口令相比较,如果相同,就认为是验证通过。但是这样一来,我们就必须保存用户的口令,而保存用户的口令会导致很多问题,例如,假如系统用于保存口令的数据库被攻陷,直接泄露用户的明文口令肯定不是一件好事。
于是,我们可以对前面的方法进行改进,即,只保存用户口令的散列(hash)字符串,而不是口令的明文。散列算法是一种单向的计算,即散列函数 H 对明文信息 p 计算出的结果 h:
H(p) = h
Read more...说明:这篇文章希望能够以比较通俗的方式介绍一下相关的概念。
端到端加密,通常是指两个通信实体之间在会话通道基础上进行的、由两个实体之间协商的密文会话。端到端加密的好处是能够减少会话通道本身的泄密或其他问题导致两个通信实体之间的通讯遭到第三方破译,并避免通讯的对方对通讯内容抵赖(即,不承认通讯内容来自自己)。相对而言,端到端加密的实施成本要比单独架设一条物理的通讯线路要便宜许多,因此有时它也用于架设这类通讯线路。端到端加密本身不能阻止由于使用的会话通道本身的丢包导致的干扰。然而,由于端到端加密可以工作在较高的抽象层次上,它可以使用多个实际的会话通道而提高抗干扰能力。
通常我们会希望在一个安全系统中设置多个层次的安全设施,或者说类似"洋葱"的模型,例如,在系统中,将所有与安全有关的信息记录日志并放到不可擦除的介质上、对连接进行加密,和对发送的消息进行加密,这几种方法分别考虑的是不同级别的信息安全,而这些方法可以在同一个安全系统中作为其不同的保护层次来使用。在这一类模型中,我们不仅视阻止入侵为目标,同时也将检测入侵做为目标,或者换言之,每攻破系统中的一个层次,入侵者都需要付出额外的努力,并冒更大的被发现的风险才能达到这样的目标。
以邮件系统为例,传统的电子邮件系统是完全不使用任何加密或签名的手段的。拥有接入层控制权的网络管理员,可以轻易地通过在网络上监听数据包来获知用户与自己所使用的邮件服务器之间交换的邮件内容。随后,当邮件到达了邮件服务器时,邮件服务器管理员也可以很容易地知道邮件内容;在邮件服务器将邮件传送到互联网上的另一台邮件服务器时,问题就更多了,每一跳路由,以及它们所经过的所有网络都可以被监听,并将邮件内容泄漏出去;最后,在另一台服务器和收件人之间,也有和发件人这一边一样的风险。
在Internet上传输电子邮件的过程,由于其经过的环节众多,并且几乎完全不受收发邮件的双方控制,因此很容易导致一些敏感信息的泄露。针对这种问题,人们设计出了一种叫做Transport Layer Security(TLS,用于替代SSL)的密码学协议来实现服务器之间,以及客户端到服务器的端到端安全。简而言之,这套协议首先使用公钥加密算法在通讯双方之间协商一个会话密钥,并用这个密钥完成之后的通讯加密/解密。公钥加密算法是一种加密和解密时使用不同密钥的加密算法,以对方公开密钥加密的数据,只能以(不公开的)解密密钥解密,而从公开密钥或已知明文、密文推算出解密密钥的代价非常大,因此它能够确保数据只能被"正确的"那个接收方解密。
Read more...大扇区(超过旧式标准的512字节扇区)是改善硬件工艺或访问方式以后的一种直接提高存储密度的方法。对于磁介质来说,其盘片被分成若干的磁道(通常是同心圆)、每个磁道分成若干的扇区或称扇段,扇区是磁盘读写时的最小操作单元。对于基于闪存的存储设备而言,扇区则是一种模拟传统磁盘的概念。
对于磁盘来说,由于它是一种机械和电子一体化设备,由于各种原因的限制,其寻址和持续读写的可靠性方面都有一定的限制,例如,马达维持同样的转速,且磁头能够稳定在同一个位置,并将数据可靠地连续读写,可能只能持续8KiB或16KiB,为了提高可靠性,我们往往会需要在这之后重新校准设备。另一方面,对于随机写入的情形,较小的数据块有时会更为有利,同时,避免对磁介质的不必要的反复覆写,也有助于提高其使用寿命。因此,在磁道的基础上又引入了扇区的概念。
现代磁盘的设计中,扇区除了用户可见的部分之外,其前后还有一定的空隙用于定位和校验。这些空隙和其附近的介质一样可以用来保存数据,只是制造商和操作系统的撰写者通常不推荐使用这些空间。软盘上的这些空隙在DOS时代可以通过对控制器直接编程并改变扇区尺寸的方式强制覆写,并用类似的方法读出,从而起到一定的保密效果。
随着制造工艺的改善,现今的硬盘在十年前就早已不必受限于512字节的限制。由于在每个扇区前后都需要添加一些信息会浪费一部分空间并增加潜在的定位开销,因此硬盘制造商开始推出4KiB扇区的磁盘。这种磁盘在系统检测时会仍然汇报扇区尺寸是512字节,但物理扇区则是4KiB,并保持现有的512字节编址方式不便,从而与现有的BIOS保持兼容。
另一种已经存在一段时间的大扇区是Flash设备。这类设备采用的方法类似,不过其大扇区更多地是出于制造和避免不必要的擦写而不是提高存储密度考虑。
最后一种大扇区是RAID。许多RAID级别是一次性操作一整个stripe的,此时这种stripe也可以视为一种大扇区。
对于大扇区的支持主要是操作系统,特别是文件系统的责任,而应用程序只需确保自己操作的记录尽量是对齐的整块(例如,16K的记录,在文件中的偏移量都是从16K的整数倍开始)。文件系统需要保证应用程序对于磁盘的这种预期是能够满足的,换言之,文件系统的数据结构不应在磁盘上导致新的不对齐问题,这类不对齐可能是由于分区格式引起,也可能是文件系统本身的设计问题,如果存在这样的问题,操作系统中都需要予以纠正:例如,传统上从第63个512字节逻辑扇区开始的分区,可以牺牲掉一个512字节单元来换取对齐4KiB物理扇区的目的,由于对齐写入和读出操作需要的实际物理操作要少一半左右,因此这样做能够显著地改善性能并提高设备的使用寿命。
FreeBSD 9-CURRENT中目前已经支持通过GEOM子系统的stripe信息来描述磁盘或RAID的物理扇区尺寸以及GEOM相对于物理扇区的偏移量。新的ahci(4)驱动目前已经能够提供相关的GEOM信息给更上层的驱动程序了。
Read more...前一段时间帮一个朋友做了一个非常简单的网址缩短服务,已经上线运行了一段时间,这里把当时设计的一些想法分享出来,等有时间我会把代码也发布出来,程序很简单,用 web.py 做的。
网址缩短服务需要考虑两个问题,第一个问题是如何有效地查询,即,作为约束条件,在访问"短网址"的时候,它必须能够迅速的将结果返回;第二个问题是如何有效地将写操作复制出去。还有一点就是,缩短形成的短网址要真的越短越好。
接口
整个服务包括两个主要接口:一个是请求短网址,输入为网址(作为HTTP回应),输出为短网址;另一个是请求重定向,输入为短网址,输出为到短网址对应的真实网址的HTTP 302重定向回应。
设计
__请求短网址的流程__大致如下:
首先,检测输入的网址是否有效。
然后,计算输入的网址的 SHA256 散列值(计算时增加一个系统全局的salt值)的 URL-safe base64,并查找此散列串是否已经存在;如果已经存在,但对应的网址不同,目前版本将返回一异常(由于SHA256设计中的雪崩效应,这种情况基本可以忽略)。
如果不存在,则从前3位开始逐字向后取散列串,在查找表中查找到找到相同URL,或找不到结果为止;如果找不到结果,则将目前散列串的子串以及网址插入。
__请求重定向的流程__大致如下:
首先检测输入是否有效(不超长或超短)。
然后,直接从Berkeley DB中查找字符串对应的URL(实际实现中,将db文件以散列串首个字符命名,以利于未来将负载分散到不同的服务器)。
返回302回应。
未来的改进
目前的设计假定存在 2^0或2^1或2^2 .. 2^6 个节点能够提直接提供转向服务。转向回应信息可以在前端代理上永久缓存,因此可以通过增加前端代理服务器,而不是后端转向服务节点的方式来进行扩展。目前设计中故障转移等机制比较简单(根据SHA256计算出来的优先权值轮转),未来版本需要解决集群的原子提交问题。
目前的设计没有考虑自定义短网址,比如 foo.com/survey 这样的情况。这个问题可通过在长域名表(完整SHA256 base64与URL映射关系)基础上再增加一个查找表的方法来解决。
目前设计没有考虑删除以及禁止访问某些短网址的情况。
Read more...什么乱七八糟的东西都往数据库里面硬塞,该做的索引不做,不该做的索引一大堆,这再不慢等什么呢,天理难容嘛……
Read more...buffer和cache是两个经常被混为一谈的概念。从直观上说,两者都具备改善系统 I/O 吞吐量的能力,但是这两个概念是有区别的,其提高系统I/O吞吐量的原因也不尽相同。
cache改善系统性能的主要原因是数据访问的 局部性,即,通常应用程序在一段时间内操作的数据集的某个有限的部分,通常是很小的一部分。硬件实现的cache通常会只使用一小块(与主存相比)访问速度很快,但相对比较昂贵的存储部件,并放置于距离CPU较近的位置。
buffer改善系统性能的主要原因是减少不必要的状态切换和设备I/O。由于制造工艺等个方面的原因,系统中不同部件的速度往往是不一样的,一次进行批量的操作(例如,预先读取,或者将写数据凑成一个整数之后再写),往往要比到需要时等待这些操作完成要节省时间,并且有效地降低状态切换导致的开销。
还有一个比较显著的区别是,cache通常是硬件或OS提供,用户程序不需要(多数情况下也没有办法)为其分配存储的机制,通常它在使用者,如用户程序看来是透明的,它属于提供cache的一方而不是其使用者;而buffer往往是由用户程序知道并且与OS共享(换言之,用户程序需要分配一块内存,并告诉OS这块内存将要用于某种操作),或由OS分配,并在主机和外设之间共享(例如网卡的DMA buffer),在使用者看来它通常不是透明的,这些内存往往属于控制内存的程序,如用户程序,或OS,而不是向其传递数据的OS,或硬件。
不过,这个区别主要是传统意义上的cache。最近几年引入的一些新概念,特别是Internet cache并不能用这种方法来区分。我认为最关键的区别其实在于,buffer主要作用是在于减少实际的I/O操作次数,即,将多次操作尽量合并成一次的成批操作,通常其中的数据在操作完成之后,buffer不会被继续使用;而cache的主要作用在于更好地利用局部性原理,减少不必要的I/O,避免代价昂贵(例如,速度很慢)的I/O操作。
Read more...Jeff Roberson 下周左右将会正式发表对于 UFS 的一项改进,为 Soft Updates 加入 Journal-ling,从而简化其恢复逻辑,并消除对 fsck 的依赖。
目前常见的保持元数据一致性的方法有四种:最原始的、将元数据以同步方式写盘的方法,性能非常差;常见的文件系统中使用的元数据回写日志(如ext3),缺点是无法检验日志本身的正确性,而且元数据需要写入两次因此对性能有潜在影响;Soft Updates,缺点是需要运行fsck来释放资源泄漏,而这个操作很耗时,且实现本身比较复杂;Copy-on-Write,在WAFL和ZFS中采用的技术,随着硬盘的淘汰随机存取时间不再是性能瓶颈,应该是未来的发展趋势,目前的缺点是会导致产生较多碎片。SU+J结合了Soft Updates和Journalling的优点,即,使用Soft Updates来确保写到磁盘上的数据的一致性,而使用Journalling来确保资源泄漏能够迅速回收,从而消除了fsck的必要性。
非常期待看到明年BSDCan的presentation。虽然目前我拿到的代码还有少量毛边,但是总体来说这次改进:
如题。其实已经算是超期服役了,这次是硬件故障,相当严重的硬件故障,不过还是希望能多用一段时间。
Read more...FreeBSD 5.5和6.1开始内建了 portsnap,portsnap是一种新的 ports 套件同步机制。
与传统的 cvsup 更新方式相比, portsnap 有一些优越性:
早先,架设portsnap镜像的方法比较复杂。由于portsnap的设计,架设portsnap镜像所产生的流量,在通常情况下大约会是仅做portsnap操作的3000倍左右。
之前听lwhsu提到了台湾那边的镜像所采用的方法,值得借鉴:
由于portsnap使用的是HTTP协议,而数据集相对较小,因此,实际上可以把这些内容全部作为反向代理放进内存。
Read more...前几天看了一下 iGoogle,感觉就是,做门户首页的真可以洗洗睡了(我说的是首页,我很少去门户网站的首页,而是直奔新闻之类的子站)。
Read more...