嗯,最近VPS频频遭到蛋疼的人的DDOS攻击,于是我不得不把VPS的安全防护设置提上日程。通过向google老师请教,知道iptables有一个模块,叫做connlimit,用来限制每个IP的连接数,当某个IP的最大连接数达到某个设定的最大值时,就自动把这个IP的所有连接给Drop掉,从而达到减轻DDOS攻击影响的效果。这个模块正是我需要的,于是我打算马上开工……
不过,这东东看起来貌似很简单,不过做起来,我却遇到了各式各样的问题,于是也有了这篇手记。
iptables的connlimit模块,在内核版本2.6.23开始,就已经默认编译到系统内核中了,不过悲剧的是,我的系统是CentOS 5.5,内核版本为2.6.18。网上也有文章介绍技巧,如何不编译内核,只将connlimit编译成系统模块,然后手动加载到内核的(参考这里)。不过我在Linode的VPS上试了,还是不行,编译出来的模块,不能通过系统的安全校验,因而无法加载。通过发Ticket和Linode的客服交流,得知Linode默认给用户提供的内核,都打开了安全校验这个开关的,客服建议我自己编译内核,在编译时,关掉CONFIG_IP_NF_SECURITY和CONFIG_IP6_NF_SECURITY这两个安全验证开关,并加载到VPS。
Oh,看来还是得自己动手编译整个内核。不过Linode的系统确实挺强大,在Linode的后台,Linode已经为我们提供了多个不同版本的内核,供我们选择,你可以后台通过菜单选择需要的内核版本,然后重启VPS,就可以生效了。如下图:
如果你对Linode提供的各个内核不满意,可以自己动手编译自己想要的内核版本,并让Linode的VPS来加载并运行。关于手动编译内核,客服还给我提供了官方的文档,上面会介绍如何在Linode VPS上编译自己的内核,并让VPS加载。官方的教程,可以参考这里。
下面介绍一下我的整个升级过程,和官方的有点不一样的地方。
- 下载内核
可以去kernel.org,或者更为保险,直接去下载Linode的官方Kernel源码。不过,Linode提供的源码,没有Kernel.org的新。我直接去Linode官方内核源码页面,下载了一个2.6.32.16版本的内核,其实只要可以用上connlimit模块,我就足矣。
- 解压内核
把Linode官方的kernel源码解压
tar jxvf 2.6.32.16-linode28.tar.bz2
- 配置内核编译选项
这里要注意一下,Linode需要一些特定选项的支持,也就是说,你最好保证你的.config文件中,如下几行选项,设置为打开:
- CONFIG_PARAVIRT_GUEST=y
- CONFIG_XEN=y
- CONFIG_PARAVIRT=y
- CONFIG_PARAVIRT_CLOCK=y
- CONFIG_XEN_BLKDEV_FRONTEND=y
- CONFIG_XEN_NETDEV_FRONTEND=y
- CONFIG_HVC_XEN=y
- CONFIG_XEN_SCRUB_PAGES=y
.congif文件,就是用来保存你的编译内核的具体选项的。建议你这样做会比较保险:
将VPS中现有的内核配置选项给拷贝过来,这样,可以保证上面的几个开关都是打开的
zcat /proc/config.gz > .config
接下来,检查.config中是否包含我们需要的配置项:
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_IP_NF_SECURITY=n
CONFIG_IP6_NF_SECURITY=n
第一个,就是我们需要的connlimit模块,设置为y,这样,编译时就能将其编译到内核中。下面两个是为关闭内核模块安全验证的。
如果你还想打开内核的其他模块,可以通过内核配置菜单来配置模块:
make menuconfig
这样,你可以在一个图形化的菜单中勾选需要的模块。 配置完后退出图形菜单,更改会自动保存到.config。
接下来,一切准备妥当,可以开始编译并安装我们的内核了,请看第4步。
- 编译、安装内核
首先,需要清理一下/boot目录,删除/boot/下面的所有内容,因为等一会我们编译好的内核,会安装到这里。
#清理/boot
rm -rf /boot/*
#开始编译
make modules
make
#安装内核
make install
make modules_install
最后一步,配置启动菜单。Linode通过PV-GRUB的方式来加载我们的自编译内核,需要我们再配置一个启动菜单项。来到/boot目录,你会看到刚才已经编译好的内核,创建一个目录,叫做grub,然后创建启动菜单:menu.lst
mkdir /boot/grub
cd /boot/grub
touch menu.lst
#用编辑器编辑menu.lst,然后输入以下内容
vim menu.lst
#输入下面内容
timeout 5
title Custom Compiled, kernel 2.6.32.16-linode28
root (hd0)
kernel /boot/vmlinuz-2.6.32.16-linode28 root=/dev/xvda ro quiet
这里一定要注意:kernel那个配置项,一定要指向你的/boot目录下的已经编译好的内核文件,文件名要完全相同。
这样,就算大功告成了,新的内核我们已经配置好了。你会说,这么快?呵呵,不急,还有最后一步,还记得刚才我介绍那个Linode后台的内核版本配置菜单么,其实还有最后一步,去到你的Linode后台管理面板的Configuration Profile,打开那个Boot Settings下拉列表,把内核从Linode提供的默认内核版本,改成pv-grub-x86_32或者pv-grub-x86_64即可,32还是64,是根据你的VPS当前系统是32位,还是64位决定的。改好后,如下图所示,保存配置。
最后,去管理面板,点击Reboot,让你的VPS重启即可,这样我的Linode VPS内核就升级成功了,接下来,就可以折腾我的iptables的connlimit模块了。VPS启动好后,用uname -a验证你的内核版本,如下图:
后记
升级好内核后,其实我发现我的connlimit还是不能正常使用,正在郁闷之际,想到了是否是iptables版本太旧的问题,于是我将iptables版本从1.3.5升级到了1.4.9,这样,connlimit就正常使用了,关于iptables手动升级版本,可以参考我之前的一篇博文《VPS上手动升级iptables》
另外,你可能会遇到因为使用自己编译的内核,因为配置问题,或者其他原因,导致VPS无法正常启动加载内核的问题。不要紧,Linode不是为我们提供了很多预设的内核么,随便选一个,切换回去,这样VPS又可以正常启动了,待启动好后,再仔细查看自己的内核是否有配置疏忽的地方。
好久都没写这么长的博文了,此篇博文,纯属流水账。打完收工~~