标签 freebsd 下的文章

整整两个星期没有写东西了,这段时间发生了太多的事情。当然,也不排除我个人懒惰本性的原因。正如马云同志所说,有的时候懒惰也是一种优点

大约在一个月以前,公司有一个区域合作项目。对方出硬件,我们出技术,最后他们运营。当我在了解对方服务器部署的时候,老实说,我被雷到了。就说做 web 应用的服务器吧,一般的做法都是托管到双线机房完事。没想到对方搞了两台机器,分别放在电信和网通。

从理论上来说,用不同线路的两台机器去实现一个 web 应用,这样的冗余配置是可行的。域名解析方面也非常方便,无论是自己做 DNS 服务还是用第三方的智能解析(如 DNSPod)。但我想的是两台机器之间的数据同步问题:是自动同步,还是人工同步?两个机房之间的物理距离近吗?能否在它们之间接一条物理的线路?如果不能接,那它们之间的通信质量好吗?

根据当时的实际情况,最后我选择做自动同步。因为人工同步就意味着需要花费额外的、不必要的时间成本和人力成本去维护两台内容一样的机器。幸好,有一个很好的开源项目可以帮助解决这个问题,它就是 rsync

我们可以在其官方主页下载页面获得该软件的最新版本。我所使用的版本是 3.0.3

安装与配置方法可参见:
http://industry.ccidnet.com/art/1117/20030301/702597_1.html
http://hi.baidu.com/airpirate/blog/item/20d3f88f0e9e43ff503d922d.html

最后给 badbuildleftleg70 三位同学留言,爱车已到货并装好,近期发照。感谢三位提供的无私的帮助和强大的人文关怀。

前段时间公司内部的版本库服务器存储空间吃紧,必须增加外部存储设备或者更换服务器。于是我面临了痛苦的选择:那台联想万全 T200 服役了近 10 年。早在不经意之中,就摩擦出了爱情的火花。更换服务器,她就面临着退役,我不忍;增加外存,我担心她太累,又心疼。

于是另购了一块希捷的 250GB SCSI 硬盘,拆开机箱,连上数据线和电源线,可开机后提示找不到可以启动的系统。于是重启,回到 BIOS 选项,发现硬盘根本没有被认到。我首先想到的是跳线,但不肯定 SCSI 硬盘也有跳线这样的说法。

再一次拆开机箱,拆下硬盘,重新观察了一下,确实有跳线这个东西。具体接法见下图:

重新接好,设置从老硬盘启动,终于进入 FreeBSD。接着 sysinstall,为第二块硬盘划分 partition 和 label。整个过程比较简单,值得注意的是需要 w 将信息写入。分区完成后,我是直接修改 /etc/fstab 的,也可以手动挂载,具体办法见这里

现在的启动信息:

Waiting 5 seconds for SCSI devices to settle
da0 at ahc0 bus 0 target 0 lun 0
da0: <QUANTUM ATLAS10K3_18_WLS 020W> Fixed Direct Access SCSI-3 device 
da0: 160.000MB/s transfers (80.000MHz, offset 127, 16bit), Tagged Queueing Enabled
da0: 17537MB (35916548 512 byte sectors: 255H 63S/T 2235C)
da1 at ahc0 bus 0 target 1 lun 0
da1: <SEAGATE ST3146707LW D704> Fixed Direct Access SCSI-3 device 
da1: 160.000MB/s transfers (80.000MHz, offset 63, 16bit), Tagged Queueing Enabled
da1: 140014MB (286749480 512 byte sectors: 255H 63S/T 17849C)
da2 at ahc0 bus 0 target 2 lun 0
da2: <SEAGATE ST3146707LW D704> Fixed Direct Access SCSI-3 device 
da2: 160.000MB/s transfers (80.000MHz, offset 63, 16bit), Tagged Queueing Enabled
da2: 140014MB (286749480 512 byte sectors: 255H 63S/T 17849C)
延缓死亡的手续到此结束。

由于一直在生产环境中使用 FreeBSD 操作系统,平时经常会在虚拟机上装 N 多个系统用于测试。有些测试需要从干净的环境开始,所以经常建重复的虚拟机,让人无聊无比。如何快速搭建测试所需环境,成为了这种无聊事情中唯一有乐趣的事情。

一般来说,AMP 环境是众多测试项目环境的基础。譬如邮件系统、远程监控管理等众多应用都会用到 ApacheMySQL 等组件。因此,快速搭建 AMP 环境是那些有乐趣的事情中的重点。我们崇尚 BT 精神,追求搭建 AMP 环境的速度。公司里也有个文档,每次搭建一个就掐秒表,搭完了记录一下,看谁能保持最快纪录。

我初学 FreeBSD,对这样的竞赛不敢留有想法。要知道某些列车并不是我们这些泛泛之辈可以赶上的。为了让自己的动作也快一些,再快一些,我也做了这样一个笔记。

首先是一些时刻准备着的包:

www# ls
APC-3.0.13.tgz                                  jpeg-6b.diff.gz
Authen-SASL-2.10.tar.gz                         jpegsr6.zip
GD-2.35.tar.gz                                  jpegsrc.v6b.tar.gz
libgcrypt-1.2.4.tar.gz                          Storable-2.16.tar.gz
libiconv-1.11.tar.gz                            Unix-Syslog-0.100.tar.gz
libpng-1.2.12.tar.bz2                           ZendOptimizer-3.2.6-freebsd6.0-i386.tar.gz
libxml2-2.6.26.tar.bz2                          m4-1.4.9.tar.gz
autoconf-2.60.tar.bz2                           maildrop-2.0.4.tar.bz2
automake-1.9.6.tar.bz2                          make-3.81.tar.bz2
mhash-0.9.7.tar.bz2                             mm-1.4.2.tar.bz2
cyrus-sasl-2.1.22.tar.gz                        mysql-5.0.37.tar.gz
mysql_configure.sh                              pcre-6.7.tar.bz2
freetds-stable.tgz                              pcre-7.0.tar.bz2
freetype-2.1.9.tar.bz2                          perl-5.8.8.tar.bz2
freetype-2.3.2.tar.gz                           php-5.2.3.tar.bz2
freeze-2.5.tar.gz                               php_configure.sh
gd-2.0.34.tar.bz2                               gettext-0.16.tar.gz
pure-ftpd-1.0.21.tar.gz                         gmp-4.2.1.tar.bz2
wget-1.9.tar.gz                                 gzip-1.3.5.tar.bz2
zlib-1.2.3.tar.bz2                              httpd_configure.sh
其中 php_configure.sh 是 PHP 编译脚本,mysql_configure.sh 是 MySQL 编译脚本,httpd_configure.sh 是 Apache 编译脚本,其内容如下:

www# more php_configure.sh
#!/bin/sh
./configure --prefix=/usr/local/php --disable-cgi --sysconfdir=/etc --with-apxs2=/usr/local/apache/bin/apxs --enable-discard-path --
with-config-file-path=/etc/apache --enable-hash --with-openssl --with-mhash --enable-bcmath --with-bz2 --enable-calendar --enable-ct
ype --enable-dbase --enable-ftp --with-iconv --enable-exif --with-gd --enable-gd-native-ttf --with-zlib=/usr --with-ttf --with-freet
ype-dir=/usr --with-png --with-gmp --enable-mbstring --enable-mbregex --with-pcre-regex=/usr --with-mysql=/usr/local/mysql --with-my
sql-sock=/tmp/mysql.sock --enable-pdo --with-pdo-mysql=/usr/local/mysql --with-mssql=/usr/local/freetds --with-gettext=shared,/usr -
-with-expat-dir=/usr --with-xml --enable-wddx --with-mm=/usr --enable-sockets --disable-debug --disable-ipv6 --enable-memory-limit -
-enable-inline-optimization --enable-zend-multibyte --with-tsrm-pthreads --with-jpeg-dir=/usr --enable-zip

# LoadModule php5_module libexec/libphp5.so
# AddModule mod_php5.c               
# AddType application/x-httpd-php .php .phtml
www# more mysql_configure.sh
#!/bin/sh
# mysql configure
./configure --prefix=/usr/local/mysql --enable-assembler \
            --disable-largefile --with-charset=gbk \
            --with-pthread --with-zlib-dir=/usr \
            --without-debug --with-openssl=/usr --without-docs \
            --without-man
www# more httpd_configure.sh
./configure --prefix=/usr/local/apache --sysconfdir=/etc/apache --enable-modules=all --enable-mods-shared=all --enable-cache --enabl
e-mime-magic --enable-mem-cache --enable-ssl --enable-cgi --enable-rewrite --enable-isapi --enable-so
下面的过程已经比较精简了,就不再注释:

www# tar -xzvf wget-1.9.tar.gz
www# cd wget-1.9
www# ./configure
www# make
www# make install

www# file /usr/local/bin/wget
/usr/local/bin/wget: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), not stripped

www# /usr/local/bin/wget http://apache.mirror.phpchina.com/httpd/httpd-2.2.8.tar.gz
www# tar -xzvf httpd-2.2.8.tar.gz

www# /usr/local/bin/wget http://192.168.0.200/mysql-5.0.45.tar.gz
www# tar -xzvf mysql-5.0.45.tar.gz

www# /usr/local/bin/wget http://cn.php.net/get/php-5.2.5.tar.gz/from/this/mirror
www# tar xzvf php-5.2.5.tar.gz

www# cd ..
www# tar -xzvf zlib-1.2.3.tar.bz2
www# cd zlib-1.2.3
www# ./configure -s
www# make
www# make install

www# cd ../mysql-5.0.45
www# sh ../mysql_configure.sh
www# make
www# make install

www# cd ../httpd-2.2.8
www# sh ../httpd_configure.sh
www# make
www# make install

www# cd ..
www# tar -xzvf freetds-stable.tgz
www# cd freetds-0.64/
www# ./configure --prefix=/usr/local/freetds
www# make
www# make install

www# cd ..
www# tar -xzvf libiconv-1.11.tar.gz
www# cd libiconv-1.11
www# ./configure
www# make
www# make install

www# cd ..

www# file /usr/local/apache/bin/apxs
/usr/local/apache/bin/apxs: a /replace/with/path/to/perl/inte script text executable

www# tar -xzvf pcre-6.7.tar.bz2
www# cd pcre-6.7
www# ./configure
www# make
www# make install

www# cd ..
www# tar -xzvf perl-5.8.8.tar.bz2
www# cd perl-5.8.8
www# rm -f config.sh Policy.sh
www# sh Configure -de
www# make
www# make test
www# make install

www# file /usr/bin/perl
/usr/bin/perl: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), not stripped

www# vi /usr/local/apache/bin/apxs

#!/replace/with/path/to/perl/interpreter -w 换成

#!/usr/bin/perl -w www# cd ..
www# tar -xzvf libxml2-2.6.26.tar.bz2
www# cd libxml2-2.6.26
www# ./configure
www# make
www# make install

www# cd ..
www# tar -xzvf gzip-1.3.5.tar.bz2
www# cd gzip-1.3.5
www# ./configure
www# make
www# make install

www# cd ..
www# tar xzvf jpegsrc.v6b.tar.gz
www# gzip -d jpeg-6b.diff.gz
www# cd jpeg-6b
www# ./configure --prefix=/usr/local --enable-shared
www# make
www# make install

www# cd ..
www# tar -xzvf libpng-1.2.12.tar.bz2
www# cd libpng-1.2.12
www# ./configure
www# make
www# make check
www# make install

www# cd ..
www# tar -xzvf make-3.81.tar.bz2
www# cd make-3.81
www# ./configure
www# make
www# make check
www# make install

www# tar -xzvf freetype-2.1.9.tar.gz
www# cd freetype-2.1.9
www# /usr/local/bin/make
www# /usr/local/bin/make (没错,的确是两遍)
www# /usr/local/bin/make install

www# cd ..
www# tar -xzvf gettext-0.16.tar.gz
www# cd gettext-0.16
www# ./configure
www# make
www# make install

www# cd ..
www# tar -xzvf gmp-4.2.1.tar.bz2
www# cd gmp-4.2.1
www# ./configure
www# make
www# make check
www# make install

www# cd ..
www# tar -xzvf mhash-0.9.7.tar.bz2
www# cd mhash-0.9.7
www# ./configure
www# make
www# make install

www# cd ..
www# tar -xzvf mm-1.4.2.tar.bz2
www# cd mm-1.4.2
www# ./configure
www# make
www# make test
www# make install

www# cd ../php-5.2.5
www# sh ../php_configure.sh
www# make
www# make test
www# make install
未完待续。

又是一个不眠之夜,写点东西好了。

上个月托管在某电信机房的服务器遭受ARP 欺骗,虽然不是我的服务器中毒,但还是受到了一定程度的影响。事后我认识到双向绑定的重要性,于是和机房联系做了双绑。

对于双向绑定,我的理解是在下级客户端与上级网关上分别知道自己与对方的 IP 及其 MAC 地址,并且这是一个静态的关系。ARP 协议中,默认的关系是 dynamic,而且这与使用 DHCP 与否没有关系。我们来做个实验:

C:\>arp -a
Interface: 192.168.0.201 --- 0x10003
  Internet Address      Physical Address      Type
  192.168.0.1           00-14-78-99-3d-a9     dynamic
  192.168.0.50          00-0b-2f-10-12-ab     dynamic
C:\>arp -d
C:\>arp -s 192.168.0.1 00-14-78-99-3d-a9
C:\>arp -a
Interface: 192.168.0.201 --- 0x10003
  Internet Address      Physical Address      Type
  192.168.0.1           00-14-78-99-3d-a9     static
  192.168.0.50          00-0b-2f-10-12-ab     dynamic
这个例子已经说明了问题。绑定后的状态一直都是 static,直到系统下次重启。

如果服务器处于双线机房,或者由于其他原因,具有一个以上的 IP 地址,其操作方式雷同。我的服务器上有两个 IP 地址,arp -a 后的结果是这样的:

C:\>arp -a
Interface: 60.12.104.24 --- 0x10003
  Internet Address      Physical Address      Type
  60.12.104.1           00-11-bb-3e-62-3f     dynamic
  122.225.96.1          00-11-bb-3e-62-3f     dynamic
我设计了以下的脚本。将它放入计划任务,并设置为每次系统启动时启动该脚本,配合机房在网关设备上对该服务器 IP 与其 MAC 地址的绑定,就可以使 Windows 操作系统的服务器具备防止 ARP 欺骗的能力:

@echo off
arp -d
arp -s 122.225.96.1 00-11-bb-3e-62-3f
arp -s 60.12.104.1 00-11-bb-3e-62-3f
exit
对于类 Unix 操作系统的操作也基本相似。首先通过 arp -a 获取当前信息:

#arp -a
? (60.12.104.1) at 00:11:bb:3e:62:3f on em0 [ethernet]
? (60.12.104.31) at 00:0e:0c:3c:7d:ba on em0 permanent [ethernet]
? (122.225.96.1) at 00:11:bb:3e:62:3f on em0 [ethernet]
nstech (122.225.96.31) at 00:0e:0c:3c:7d:ba on em0 permanent [ethernet]
然后执行单向绑定,注意类 Unix 系统下对 MAC 地址的书写方式:

#arp -s 122.225.96.1 00:11:bb:3e:62:3f
#arp -s 60.12.104.1 00:11:bb:3e:62:3f
服务器上操作完成后,要求机房在网关设备上对该服务器 IP 与其 MAC 地址的绑定,就实现了传说中的双向绑定。

如果服务器当前正在遭受 ARP 欺骗攻击,在机房没有对中毒服务器实施断网处理前,我们只能每隔一段时间就执行一下上面的操作。为了方便起见,我们可以这样做:

#vi /etc/ipmac 将需要做绑定的网关 IP 与其 MAC 地址写入这个文件。每行一个,中间用空格隔开:

122.225.96.1 00:11:bb:3e:62:3f
60.12.104.1 00:11:bb:3e:62:3f
然后:

#crontab -e 添加一行:

*/1 * * * * /usr/sbin/arp -f /etc/ipmac 这里的“*/1”代表每隔 1 分钟执行一次,可以根据实际情况调整。和平时期,我一般设置为 10 分钟执行一次:

* */6 * * * /usr/sbin/arp -f /etc/ipmac 战争时期就设置为 5 秒执行一次:

*/12 * * * * /usr/sbin/arp -f /etc/ipmac 对于 Windows 操作系统,只要重新设置一下计划任务的属性,让它每隔一段时间执行一下脚本就可以了。

咳咳,综上所述,这个解决方案是一个临时性解决方案,比较适用于非战时的防御。如果真的遭遇 ARP 欺骗攻击,第一件事还是通过 arp -a 找到源头,然后将信息报告给机房,让机房尽快将中毒的机器断网才是上策。

听说 FreeBSD 系统下面有一个软件叫做“ipguard”,可以有效防御 ARP 欺骗。有空研究一下。

一直以来,我以为 ARP 欺骗仅仅只会发生在公司单位、网吧等局域网环境比较复杂的地方。也曾耳闻到某些 IDC 机房也出过这样的事情,但总觉得这事情应该离我很遥远。没想到昨天晚上,一个地级市的电信机房也发生了这样的事情。我有幸亲临了整个事件的始终,中途除了机房的技术人员,还有二位仁兄被迫中止睡眠,起身与我一共奋战。一位是 feelinglucky 同学,另一位是我公司的小刘同学,在此向你们二位表示深切的慰问与诚挚的感谢。

昨天晚上 12 点 30 分(也就是今天零点三十分)左右,我打算进入博客后台取点资料,在登录页面上发现了惊奇的一幕:

刷新了一次之后还是这样,突然有一种不详的预感。然后,事实证明这种预感是准确的。我查看页面源代码,发现了更惊奇的一幕:

很明显,页面被挂马了。但又觉得这代码有点不对劲,于是冒着风险用 IE 访问了一下:

现在,发生了什么事情已经非常确定了。从最后一张图上看,应该是 ARP 欺骗挂马的结果;但也有可能是我的博客程序或者是服务器被挂马了。我一边打机房电话,告诉值班人员发生的事情;一边用 FTP 把博客所在目录的文件拖了下来。经过对博客程序的模板、程序代码的检查,发现并没有隐藏框架的代码存在。

下一步,检查服务器日志。把服务器上的 Apache 日志看了又看,没发现异常。根据 lucky 的建议,kill 掉了一些进程,问题依旧。lucky 又建议我测试一下本机访问本机会怎么样,于是:

#vi /etc/apache/httpd.conf 增加:

Listen 127.0.0.1:80 然后:

#/etc/rc.httpd restart
#vi /etc/hosts
增加:

127.0.0.1    www.xuchao.org 然后:

#cd /root
#wget https://www.xuchao.org/xxx/
#cat index.htm
在这里,我并没有发现有隐藏框架的代码存在。于是我更加坚定了刚才的判断,马上再次致电机房,告诉对方我刚才的测试过程,并指出问题极有可能出在机房里。值班的技术人员迷迷糊糊的从美梦中醒来,然后答应帮我检查。由于已经是后半夜了,他说最迟到上午 8 点就可以搞定。

等待、等待……在漫长的等待过程中,我重新查阅了一些几年没看的有关 ARP 欺骗的资料。唉,早知道就做双向绑定了。失误啊、失误。又看了一下 dmesg 日志:

#cat /var/log/dmesg.today 呵呵,全都是这样的内容:

arp: 122.225.96.1 moved from 00:19:b9:f1:14:1c to 00:11:bb:3e:62:3f on em0
arp: 122.225.96.1 moved from 00:11:bb:3e:62:3f to 00:19:b9:f1:14:1c on em0
arp: 122.225.96.1 moved from 00:19:b9:f1:14:1c to 00:11:bb:3e:62:3f on em0
arp: 122.225.96.1 moved from 00:11:bb:3e:62:3f to 00:19:b9:f1:14:1c on em0
从我一直 ping 服务器的情况看,机房的人重启了 3 次交换机,然后那段该死的隐藏框架代码已经不存在了。几分钟后机房给我打来电话,说问题已经解决。我问他原因,他说我的服务器所在机柜有一台服务器中毒,广播 ARP 欺骗包数据,没有防御能力的机器都倒下了。

由于连续 3 次断网,我们的服务器上服务端已经与数据库失去连接了(又是没有走内网通讯的恶果)。重启服务器,开启游戏服务端。早上 6 点,一切恢复正常。

明天整理一下思路,给出一份防御 ARP 欺骗的方案(针对 FreeBSD 服务器与 Windows 服务器)。