September 2009 Archives

主旋律影片飞屋环游记

| No Comments

不知道为什么我总是觉得PIXAR的电影都是主旋律电影,或者说很大程度上都在宣传美国的价值观。

电影开头的部分其实是一段悲剧----老人和妻子从幼年相识直到暮年,希望通过存钱来完成他们周游南美洲的梦想,但因为一次次意外而不得不放弃,到最后老太太快要去世的时候,老爷子用他们童年时候一样的蓝色气球----老人后来成了一个钉子户,因为房子是他和妻子一生的回忆。

一个胖胖的小男孩出现了,老人不想受到打扰而编了一个谎言把小孩骗走,此时建筑工人出现,在争执中老人将对方打伤,法院判决让老人住进老人院,离开房子。老人又找到了年轻时候的那本探险日志,一夜未眠,第二天老人院工作人员来接老人时,他终于放起了一大片的气球,将房子拔地而起,开始了旅行。

影片余下的部分主要是探险的经历,这里就不剧透了。影片的配乐非常不错。

设计与艺术的区别

| 1 Comment

蛇头GG发来的一篇文章,值得一读:The Difference Between Art and Design。摘录一下标题:

  • 艺术源于灵感,而设计源于动机。
  • 艺术为人诠释,而设计为人理解。
  • 艺术是一种品味,而设计则是一种主张。
  • 艺术来自天赋,而设计来自技艺。
  • 艺术为不同的人带来不同的信息,而设计为不同的人带来相同的信息。

一部分应用层协议放进kernel?

| No Comments

先把想法记下来。

  • 提供一种描述语言,将应用层协议描述成DFA;
  • 一个generator将DFA转换为代码;
  • 用户态程序通过某种接口来向kernel请求已经协商好的该种协议的socket并由kernel直接填写一部分数据结构;
  • 应用程序对socket的第一个回应有时间限制----如果一段时间之内不回应,则系统将该socket交给下一个监听进程。

解决的问题:

  • 减少上下文切换。内核直接完成协议初始的协商会话(包括TLS/SSL?)
  • 减少用户能看到的出错情形,i.e. 服务进程不在的时候(例如,在重启过程中)内核可以将服务交给其他服务进程而不是简单地回应RST。

另外一种DSR结构

| 2 Comments

dawnh在之前的人肉traceback中提到了 另一种DSR结构。即:

  • 服务器端将虚拟IP绑在lo0上(子网掩码为/32);----确保服务器收包、不广播ARP;
  • 负载平衡设备接Internet的网口接路由器进来的VLAN;("VLAN-Internet")----从Internet进入的包发到负载均衡设备上;
  • 负载平衡设备的内网网口能够到达服务器;("VLAN-Incoming")----负载均衡设备将请求根据负载均衡的条件路由到VLAN-Incoming上的服务器;
  • 路由器提供一个绑定某一内网网址,且能联通服务器的接口;("VLAN-Outgoing")----服务器回应包发到VLAN-Outgoing上的Internet路由器;
  • 服务器默认网关设为路由器的内网地址。

(此VLAN划分是出于性能方面的考虑,不划分VLAN并不会导致整个系统不能用)。

这种做法保持了在外网网卡上直接绑一个未用公网IP之后,不需要绑定路由器MAC地址的优点,而在这种配置中,服务器直接连接网络的网卡上都不需要绑定公网IP地址。缺点是需要有一个能够在VLAN-Outgoing到Internet之间进行路由的路由设备,或能够直接控制到Internet那一跳的路由器(当然,这种情况,路由器本身甚至也可以不占用同网段IP,即,VLAN-Internet与VLAN-Outgoing合并、负载平衡设备公网网口绑VLAN-Outgoing上的内网IP,在路由器上配置指定的Internet地址段路由到VLAN-Outgoing网口)。

改一行代码带来的性能改进

| No Comments

FreeBSD先前的vesa framebuffer驱动有个问题,就是滚屏的时候会比较慢。jkim大长辈于是改了一行代码

好吧,我承认我之前一直以为是console驱动想要锁&Giant的问题。其实真正的原因是默认的pmap_mapdev并不做写合并,所以应该呼叫更低阶的pmap_mapdev_attr并传入PAT_WRITE_COMBINING参数。

现在VESA console的滚屏几乎和文本模式一样了。活到老学到老吧......

因为有人在我前一篇blog《使用DSR模式实现单IP服务冗余》里提了个问题,这里解释一下。

DSR比较常见的两种配置,一种是我之前文章中提到的禁止外网网卡ARP的方法,另一种是把虚拟IP绑定到lo0上。这两种方法各自有一些优缺点。一般来说,我喜欢用前一种方法。

实现DSR结构的关键是,通往Internet路由器的那个网络上,只有负载平衡设备在网络上宣示虚拟出来的那个IP的MAC地址,这样,当请求进来的时候,数据会发到负载平衡设备,而不是某一台服务器上。

禁止某块网卡上的ARP的时候,由于这块网卡完全忽略ARP(不仅是禁止发出ARP请求,同一广播域上的ARP广播也会忽略)。禁止网卡上的ARP,但将虚拟IP绑在网卡上的语义是这样:

  • 当收到目的地址为虚拟IP的包时,将这个包看作是发给自己的包;
  • 这块网卡不接受任何ARP协议的请求,也不广播ARP。

而另一种方法,也就是网卡上绑与虚拟IP同网段的另一个IP(服务器之间不冲突),但将虚拟IP绑在lo0上的做法的语义则是这样:

  • 当收到目的地址为虚拟IP的包时,将这个包看作是发给自己的包;
  • 禁止响应虚拟IP的ARP请求,也不主动宣示虚拟IP的MAC地址;

第一种做法的优点是无需在与虚拟IP同网段的网络上再占用一个IP(第二种方法需要:这个IP必须和虚拟IP是同一个网段上的,以便让系统知道通往路由器的网卡是这一块)。很明显,DSR的时候你不会希望使用 RFC 1918 规定的的私有IP,除非这个服务是针对内部网络的。

第二种做法的优点是无需在服务器上维护路由器IP与MAC地址的对应表。这个特性可以减少维护的压力。例如,如果网络上只有一个路由器,而没有做VRRP或CARP的时候,在做路由器割接时,由于路由器的MAC地址变动,第一种做法会需要一次性修改全部服务器上的MAC绑定。当然,如果网络上的路由器是冗余的,这个优势可能就不那么明显了;另一方面,IPv4地址已经快用完了,所以,为了世界和平,还是建议大家用第一种做法。lo上绑定的IP地址掩码最好是/32(仅此IP)。

当然,两种做法,*nix系统都是支持的。FreeBSD支持,Linux也支持。

概率趣题

| 6 Comments

今天在 Matrix67 的 blog 上看到这么一道题:

一个人有两个小孩儿,其中有一个生于星期二的男孩儿。问另一个是男孩儿的概率是多少?

答案当然不是1/2或者1/4,因为我们已经知道了有一个是生于星期二的男孩,因此这是一个条件概率问题。

ZFS实现快速部署(作弊条)

| No Comments

FreeBSD从8.0开始支持从ZFS引导系统,因此,可以使用ZFS的快照功能来实现快速部署。

新机器使用LiveFS启动,Fix it,CDROM。

kldload /dist/boot/kernel/nullfs.ko

mount_nullfs /dist/boot /boot

kldload tmpfs

kldload zfs

如果需要,此时用dd抹除硬盘内容,例如 dd if=/dev/zero of=/dev/da0 bs=1m count=1

gpart create -s gpt da0(重复此步直到所有硬盘皆包含GPT分区表)

gpart add -b 34 -s 128 -t freebsd-boot da0(实际上只有启动盘需要,不过64K空间对现代硬盘来说基本上可以忽略不计)

gpart add -b 162 -s 8388608 -t freebsd-swap da0(根据需要酌情配置)

gpart add -b 8388770 -t freebsd-zfs da0

cd /boot

gpart bootcode -b pmbr da0(建议所有盘有freebsd-boot分区的盘都做)

gpart bootcode -p gptzfsboot -i 1 da0(所有有freebsd-boot分区的盘都做)

glabel label swap0 /dev/da0p2(swap1,2,3,4,...类推)

glabel label vdsk0 /dev/da0p3(vdsk1...类推)

zpool create -m legacy 集群名 raidz2 /dev/label/vdsk0 /dev/label/vdsk1 .. spare /dev/label/vdskn

ifconfig em0 inet x.x.x.x/m

nc -l 80 | zfs receive -vF 集群名

在样本机上执行:zfs send 集群名@快照名 | nc 客户机IP 80

之后,在安装的机器上mount -t zfs 集群名 /mnt,然后把/boot/zfs内容复制到/mnt/boot/zfs,修改etc/rc.conf等,即可。如果配置时使用的是DHCP,则此过程可进一步简化。

SYNCookie反制

| No Comments

最近看到一个很有意思的攻击。记一笔。

针对 SYN Flood 攻击(特点是攻击者发出大量 SYN 请求,但并不完成 TCP 握手),目前操作系统会采用 SYNcookie 予以反制。FreeBSD上的实现是在系统资源充足的时候采用标准的握手机制,而当发现存在可能的攻击(即可用的 TCP 状态资源不足时)应用 SYNcookie;SYNcookie是将TCP状态建立推迟到三次握手 之后,具体做法是将服务器本地的一个秘密数据与来源/目的IP、端口编码来形成序号来发出SYN+ACK,并在收到对方回应ACK时验证这个序号的真实性。

这种方法实际上是用计算来换内存资源,即增加了两步计算操作来避免在握手完成之前消耗 TCP 状态资源。

SYN Flood提供了两个优势:

  1. 攻击者可以伪造来源IP
  2. 攻击者可以不维护TCP状态(四两拨千斤)

新的攻击方法在攻击者一方也使用了类似SYN cookie的方法,即,它能够实际完成TCP握手,从而击败 SYN cookie(当然,由于完成了三次握手,伪造源IP就不太容易了),方法是将本机和服务器的端口/IP编码进序号。

这次公开的攻击方法还有很多非常聪明的做法,在改TCP实现之前,防守一方能够采取的缓解方法不太多(限制IP、推迟服务启动时间等)。

使用DSR模式实现单IP服务冗余

| 3 Comments

FreeBSD支持以DSR(Direct Server Return,即服务器直接将流量通过路由器返回,而不经过负载平衡设备;俗称"单臂模式")模式提供服务。为了改善服务的可用性,可以使用这种方法来配置服务器。这种方法非常适合于大并发、大流量的环境。

网络及服务器的规划

首先,需要对服务可能产生的负载、流量进行估计,并据此设计网络的结构。DSR结构极大地降低了负载平衡设备成为瓶颈的可能,但仍对它们有一些要求,因此,设计者需要考虑下面一些问题:

  • 如何在服务器之间分摊负载。简单地说,就是应平均地分配流量,还是根据一些特征,例如会话等等去分配流量?原则上,网络设备对于协议本身所做的计算越少,它们所需要消耗的性能就越少,合理的设计应尽可能减少对网络设备在这方面的依赖,以改善整个系统的可扩充性。靠近应用层的规则往往会比靠近物理层的规则消耗更多的计算资源,因此应用的设计者应当尽可能将这部分开销考虑在内。
  • 网络设备的背板带宽。接入层交换机的容量是有限的,在考虑成本的前提下,有时出于性能考虑,很可能会希望使用不同的网络设备,而不是仅仅采用VLAN来划分不同的网络。
  • 了解可能出现瓶颈的点,并予以因应。

服务器配置

DSR结构对服务器有这样一些要求:

  • 接入Internet的网络端口不应发出或响应ARP请求。具备三层能力的交换机在看到ARP请求时,会将二层地址(MAC地址)和三层地址(IP地址)予以绑定。因此,在这些交换机看来,拥有公网IP地址的端口应该是负载平衡设备,而不是最终提供服务的服务器。
  • 服务器上应绑定提供服务的公网IP地址。操作系统通常只处理发到本机的IP包。
  • 服务器上应绑定公网路由器的MAC地址。操作系统的TCP/IP协议栈会发二层包到公网路由器。
  • (可选)服务器应配置两组,而不是一组默认路由。严格地说这并不是必需的,因为提供服务的服务器并不一定需要直接主动发起访问 Internet 的请求,例如,它们可以使用有内网IP地址的代理服务器。
  • 每一台实际提供服务的服务器应拥有一个唯一的内网IP地址。

在FreeBSD上,这可以通过在 rc.conf 中的网卡配置中增加"-arp"参数,并配置 static_arp (9.0和更高版本,我会在稍后将其MFC)来实现。

负载平衡设备配置

在负载平衡设备上,在实现DSR结构时,这些设备扮演的角色是 路由器,而不是 NAT 网关。也就是说,它们的作用是将来自客户端的访问 IP 包直接 路由 到服务器的内网地址(说明:此时,这些内网 IP 地址会被当作"下一跳";负载平衡设备查找本地 ARP 表并将数据包在2层上直接传递给对应的服务器;而服务器看到的数据包的目的地址仍是提供服务的那个公网IP)。

FreeBSD pf规则举例:pass in on em0 route-to { em1 内网IP1, em1 内网IP2, em1 内网IP3 } round-robin proto tcp from any to 公网IP port http keep state (sloppy)

其中,(sloppy)需要比较新版本的pf。目前的 FreeBSD 版本并不支持这一用法。可以使用 这个 补丁。这个选项表示pf应使用较为宽松的状态机;如果不需要状态(DNS协议通常不需要保持完整的会话,因为通常不会有很大的请求包)则不需要keep state和(sloppy)配置。

DNS和MX的冗余

| 1 Comment

一般来说DNS和MX都需要做冗余。前者的冗余和容灾要求要高于后者。

DNS的冗余通常需要做到跨ISP,甚至跨大洲。由于安全和性能方面的理由,提供权威DNS解析的服务器都不应同时作为缓存DNS服务器;此外,实践上权威DNS服务器应该是受保护的管理服务器的slave,而不应直接在权威DNS服务器上操作(读、写分开),这样可以有效减少由于修改操作所导致的downtime。

MX的冗余可以是跨网段,也可以是跨ISP甚至跨大洲的。如果条件不具备,甚至可以在同一网段,但这会增加网络设备或机房故障所导致的downtime风险。不同的MX在会话阶段的过滤策略应该是一致的。

模拟实模式x86 CPU

| No Comments

前一段时间commit了来自XFree86 -> NetBSD -> OpenBSD的x86emu,这是一个大约9千行C代码的x86实模式CPU模拟器。

由于 amd64/EM64T "long mode" 不支持先前 x86 保护模式中的 "vm86" 扩展(虚拟实模式环境),因此,这个模拟器使得 FreeBSD 能够在 amd64(EM64T) 平台上支持 vesa、dpms 等功能了。

这些改动同样适用于 RELENG_6、RELENG_7、RELENG_8(前两个可能需要略微做一点点改动)。具体的changeset包括:

r197009 - 导入原版(OpenBSD 4.6)x86emu

r197019 - 对x86emu进行一些修改使其适用于 FreeBSD 编译环境,连接到build上。(需要说明的是,x86emu是跨平台的)。


r197021 - MFC时需要:建立目录。

r197022 - 把vesa和dpms代码复制到新位置。(注:svn无法有效地在一次commit中表达把文件挪到新的位置,并进行修改这样的操作。为了便于在 diff -c 时能够看到改动,将这个mv操作拆成了cp和rm)

r197025 - 对vesa、dpms代码进行修改,不再使用vm86而改为使用x86emu。删除原先位置的 vesa 和 dpms。

r197042 - bz@ 补齐了我在 197025 中忘记删除的一个文件。

r197081 - 告诉 make delete-old 需要删除的文件。

r197085 和 r197109 - 启动时可通过 hint 配置直接进入高分辨率模式。

还有一些小问题需要修正,不过大体上是做完了。其中,x86emu的代码经过OpenBSD和NetBSD两拨人的修整已经很清晰易读(主要是译码和执行单元两部分)。

西雅图-波特兰

| 3 Comments

借着美国劳工节长假去了一趟美国西部的重要城市----华盛顿州的西雅图,以及俄勒冈州的波特兰。整理了一些照片在 这里

西雅图是美国西岸的重要城市,因西雅图酋长而得名。

Chief Seattle, 39,885 octets

西雅图的地形与旧金山有些想象,但不比旧金山险峻。这个城市的咖啡消费量极大,第一家星巴克咖啡即发源于此,在Pike Market的星巴克门口拍到了一位常年在此演唱的吉他手。

Guitar Player at Starbuck at Pike Market, 49,801 octets

由于地理位置的原因,西雅图的气候比较多云雨。有朋友说,在此间住的太久会有得抑郁症的危险。不过,在西雅图的那几天天气都相当晴朗。西雅图的著名地标是 Space Needle,这是一座为1962年世博会设计的建筑,其瞭望台高达520英尺。

Space Needle, 34,886 octets

由于去西雅图的时候是搭的早上的飞机,在飞机降落的时候,云层中隐隐约约露出了这些高层建筑。在这些在云层之上每天工作的人们是否已经习以为常?

西雅图周边地区有两家对此间经济非常重要,也是大家非常熟悉的企业----波音微软。为了让更多的人了解航空科技,波音特别提供了针对公众的 Future of Flight 来展示波音的民用飞机装配过程,不过,比较遗憾的是装配车间不允许携带相机、手机等摄像器材。

停机坪上是经过改装的波音 747 "Dreamlifter",用于运载准备在其他地方组装波音 787 "Dreamliner" 飞机部件。

747 Dreamlifter, 40,642 octets

另一家公司是 Microsoft,总部位于Redmond市。

Microsoft, 43,631 octets

而全球销售额最大的会员制批发超市 Costco 总部也在附近的 Kirkland 市。因为时间关系,没有在 Kirkland 长时间停留。

不按牌理出牌的无线网络

| 2 Comments

今天到了Seattle,在一家很便宜的酒店住下。酒店发给我一张密码卡,用来上那里的无线网。摆弄了几下发现:

加密模式是open,所以需要自己加密数据了。

密码的实现方式是劫持DNS,然后指到1.1.1.1。

最搞笑的是,实际上不登录,IP访问也是通的......

-----

话说,其实我觉得在网关上做点规则比DNS劫持要简单的多?有谁知道他们为啥会这样实现吗?

About this Archive

This page is an archive of entries from September 2009 listed from newest to oldest.

August 2009 is the previous archive.

October 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

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