September 2009 Archives

主旋律影片飞屋环游记

| No Comments | No TrackBacks

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

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

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

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

设计与艺术的区别

| 1 Comment | No TrackBacks

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

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

先把想法记下来。

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

解决的问题:

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

另外一种DSR结构

| 2 Comments | No TrackBacks

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网口)。

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也支持。

概率趣题

| 7 Comments | No TrackBacks

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

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

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

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 | No TrackBacks

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

针对 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、推迟服务启动时间等)。

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 | No TrackBacks

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

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

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

模拟实模式x86 CPU

| No Comments | No TrackBacks

前一段时间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 | No TrackBacks

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

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

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 长时间停留。

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

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

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

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

-----

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

Monthly Archives

Pages

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