发布于2026-06-02 阅读(0)
扫一扫,手机访问
这几年跑Web服务器,大家基本都认准了Linux+Mysql+Apache+PHP这套开源方案。但从实际应用来看,选择什么系统,终究还是得看具体需求。比如你要跑Oracle这类大型应用——Oracle在Linux下的支持确实更好,那Linux自然是首选;要是换个系统,像FreeBSD上装Oracle简直是场噩梦。可如果是跑普通的网站应用,FreeBSD+Mysql+Apache+PHP的组合就很有吸引力了。对于一个网站而言,稳定和安全是底线,不然页面什么时候被人篡改了都浑然不觉,或者数据被删得干干净净,那可就真的糟了。毕竟现在什么红客、黑客的都虎视眈眈,不得不防。
当然,这不是说Linux不安全。问题在于Linux下集成了太多可能带来风险的组件,只要配置得当,Linux同样能固若金汤。看看中国网络应急响应中心几个月的数据:每个月被成功入侵的系统,Linux占到了六成多,Windows在三成多,而FreeBSD的入侵比例只有百分之几。差距还是相当明显的。
任何系统都可以很安全,也可以很不安全,关键看管理员怎么操盘。世界上没有绝对安全的系统,只有更安全的系统。下面的内容就是在FreeBSD上构建一个相对安全的Web服务器,希望能给网络安全爱好者带来一些启发,权当抛砖引玉。
从安全角度出发,系统选择最新的FreeBSD版本是明智的,不仅兼容性好,也能规避不少已知漏洞。这里选用的是FreeBSD 5.3,整个安装过程不算复杂,如果不熟悉的话可以参考FreeBSD中文手册。安装时必须带上基本包和内核源代码,后续编译内核会用到。如果习惯用ports管理软件,也一并装上,但那些用不上的程序尽量别装。系统文件拷贝完成后会要求配置IP、名字服务器等,记得关闭IPv6,别开DHCP,系统自带的FTP服务也禁用掉。配置 /etc/inetd.conf 时把SSH打开方便远程管理——要是不想用inetd这个超级服务,也可以在 /etc/rc.conf 中加上 inetd_enable="NO" 并设置 sshd_enable="YES",后面会详细聊SSH的配置。
系统装好后,在 /etc/inetd.conf 里把除了SSH之外的服务全部关掉,telnet、rlogin这些更要慎重,不然没几天系统就可能被攻破。紧接着建议用 make world 或 cvsup 升级系统和ports,这和Windows装完系统打补丁是同一个道理。
系统搞定后,就该安装应用软件了。原则很简单:选最新的版本,因为老版本往往存在溢出等漏洞。我们需要数据库来支撑Web服务,同时还得有个FTP服务来做远程文件管理。当然,为了图方便,也可以装个Webmin,万一没有SSH客户端的时候能顶上。
Web服务选Apache httpd 2.0.53,当时的最新版。网站用PHP开发,所以装PHP 4.3.11,也是最新版。如果网站需要PHP5,可以下php5.0.4。数据库用最快的Mysql 4.0.23,要是需要外键、事务、子查询、存储过程,可以考虑4.1或5.0。FTP服务选vsFTPd 2.0.2,这玩意儿既安全又快——我在局域网测试过,它的最高传输速率能达到10MB/S,而proFTPd才8MB/S。vsFTPd对小规模FTP服务器支持特别好,用户不多的话够用了。如果用户多、功能要求高,可以用proFTPd、pu re-FTPd或wu-FTPd,不过有些FTPd安全性存疑,选的时候得留个心眼。
服务器程序列表:
始终记住:最少的服务 + 最少的端口 + 安全的设置 = 最大的安全。用不上的服务(比如telnetd、rlogind)千万别装,装了反而危险。安装方式可以手工编译,也可以用FreeBSD的ports,看个人喜好。
用户越少越好。我们的FTP账户和系统账户绑定,所以添加用户时先建一个目录,然后把新建用户的主目录指向它。比如网站目录在 /usr/www,那就新建一个用户 www_user,主目录设成 /usr/www,同时把它的shell设置为 /usr/sbin/nologin,防止通过SSH登录系统。FTP密码要足够复杂,防止暴力破解。至于root用户的密码,最少也得10位,数字+字母+字符混搭,最好是18位。如果密码太简单,黑客暴力破解SSH上的root账户,没几天系统就可能失守。建议每月至少改一次root密码。普通用户原则上不给系统登录权限——把shell设成/usr/sbin/nologin。
如果要使用root权限,建议建一个属于wheel组的小用户,登录后用su命令提升为root。万一黑客拿到了普通用户的权限,至少不能直接操作root,这也算是一道防线。
有时候黑客拿到小权限用户后,可能会通过WebShell把 /etc/passwd 和 /etc/master.passwd 的内容读出来,然后尝试破解root密码。所以必须控制关键文件只能由root访问。比如uname、gcc这些工具,要是黑客拿到了小权限,就能查看系统版本,然后找对应版本的溢出程序,用gcc来编译。如果我们能限制黑客访问这些程序,就能在一定程度上拖慢入侵的节奏。
用chmod来改变文件的权限。比如要让 /etc/passwd 和 /etc/master.passwd 只允许root访问:
# chmod 700 /etc/passwd
# chmod 700 /etc/master.passwd
或者用字符标记的方式:
# chmod u+w+r+x,go-w-r-x /etc/passwd
# chmod u+w+r+x,go-w-r-x /etc/master.passwd
系统中还有很多重要文件需要控制访问权限,一定要把握好,否则威胁不小。
端口开得越多,黑客入侵的机会就越多;服务越多,风险越大,因为你不知道哪些服务暗藏漏洞。所以尽量少开服务。比如sendmail默认是打开的,建议关掉。在 /etc/rc.conf 中加上:
sendmail_enable = "NONE"
如果设为"NO",只能关闭pop3服务,smtp还在。只有设为"NONE"才能彻底关闭。
除了Apache、Mysql、vsFTPd、SSH,系统中最好不要开其他任何端口和服务。用 netstat -a 查看打开的端口,然后从端口对应去找相关服务。我们这边应该只开21、22、80、3306这几个端口。要是有其他端口,务必仔细检查——很可能是黑客的后门或者有威胁的服务。有些服务不需要对外暴露网络连接,比如Mysql,可以关闭Socket,这个在Mysql安全设置里会讲。另外,可以通过防火墙控制端口访问,比如让Mysql的3306端口只允许192.168.0.1访问,在ipfw里添加规则:
ipfw add 10001 allow tcp from 192.168.0.1 to 10.10.10.1 80 in
这样就能防止黑客直接攻击Mysql服务。防火墙的具体配置放在后面讲。
文件指纹包括文件权限、所属用户/组、最后修改日期、大小等信息。黑客入侵后通常会修改文件,文件指纹就会发生变化。文件的MD5校验值也属于文件指纹的一种。
为了防止黑客篡改关键文件(比如 /etc/passwd、/etc/shadow、/etc/inetd.conf等),可以把重要文件备份,同时保留一份当前的文件指纹。比如备份 /etc、/bin、/usr/bin 目录下的文件指纹:
# ls -l /etc > /var/back/etc.txt
# ls -l /bin > /var/back/bin.txt
# ls -l /bin > /var/back/usrbin.txt
当然,也可以给每个重要文件加上MD5校验值。感觉不对劲的时候就做一次匹配,确保文件安全。哪些目录需要备份,自己看着办。这主要是为了在被入侵后做系统检测和恢复——比如对比 /etc/inetd.conf 跟备份文件,看看有没有被安装服务型后门。
黑客入侵前,通常都会先扫描目标系统——包括开放的端口、使用的服务程序和操作系统信息。比如用手工检测Web服务的指纹:
# telnet target.com 80
这样很可能返回Apache和PHP的版本信息。同样,扫描工具也能获取Mysql、vsFTPd、SSH等服务的指纹。暴露的信息越多,风险越大。解决办法就是修改所有服务程序的Banner,迷惑黑客。下面简单说说几种服务的Banner修改方法。
* Apache
修改httpd.conf:
ServerSignature Off
ServerTokens Prod
上面适用于apache 1.x,apache 2.0默认也有,但仍有server=Apache字样。要彻底去掉,需要重新编译。修改httpd.h:
Include/httpd.h
Define SERVER_BASEVENDOR "Apache Group"
Define SERVER_PRODUCTVENDOR "Apache"
Define SERVER_BASEVERSION "1.3.27"
重新编译Apache后就能完全去掉了。
* PHP
在php.ini中设置:
expose_php = Off
这样HTTP头信息中就不会有PHP的版本信息。
* Mysql
(待补充)
* vsFTPd
vsFTPd默认的Banner信息是"Welcome to FTP Server!",高手一看就能猜出个大概。修改vsftpd.conf:
Ftpd_banner=xxxxx
把xxxxx换成你想要的。
* SSH
FreeBSD下默认安装的SSH在 telnet target.com 22 时,会显示SSH和FreeBSD的信息,这简直是把底牌都亮给黑客了。目前还没找到修改方法,知道的高手请不吝赐教。
FreeBSD有一个很实用的功能——定义系统内核的安全等级,主要用来防范内核后门。通过不同等级限制对内核的访问和对防火墙的修改。首先开启安全等级,然后在 /etc/rc.conf 中设置:
kern_securelevel_enable="YES"
kern_securelevel="-1"
第一句是开启安全等级,第二句是定义等级。一共五个等级:
如果已经装好防火墙、规则固定不变,建议用3级。如果还没装防火墙或准备改规则,别用3级。推荐使用2级,能防范大部分内核攻击。
系统优化主要是重新编译内核,去掉不用的驱动。这里重点对网络和内核参数进行优化和安全设置。编辑 /etc/sysctl.conf,加入以下内容:
| 参数 | 说明 |
|---|---|
| net.inet.tcp.sendspace=65536 | 最大的待发送TCP数据缓冲区空间 |
| net.inet.tcp.recvspace=65536 | 最大的接受TCP缓冲区空间 |
| net.inet.udp.sendspace=65535 | 最大的接受UDP缓冲区大小 |
| net.inet.udp.maxdgram=65535 | 最大的发送UDP数据缓冲区大小 |
| net.local.stream.sendspace=65535 | 本地套接字连接的数据发送空间 |
| net.inet.tcp.rfc1323=1 | 加快网络性能的协议 |
| net.inet.tcp.rfc1644=1 | |
| net.inet.tcp.rfc3042=1 | |
| net.inet.tcp.rfc3390=1 | |
| kern.ipc.maxsockbuf=2097152 | 最大的套接字缓冲区 |
| kern.maxfiles=65536 | 系统中允许的最多文件数量 |
| kern.maxfilesperproc=32768 | 每个进程能同时打开的最大文件数 |
| net.inet.tcp.delayed_ack=0 | 是否延迟ACK应答。高速网络/低负载时可略微提高性能;网络差时反而降低性能 |
| net.inet.icmp.drop_redirect=1 | 屏蔽ICMP重定向功能 |
| net.inet.icmp.log_redirect=1 | |
| net.inet.ip.redirect=0 | |
| net.inet6.ip6.redirect=0 | |
| net.inet.icmp.bmcastecho=0 | 防止ICMP广播风暴 |
| net.inet.icmp.maskrepl=0 | |
| net.inet.icmp.icmplim=100 | 限制系统发送ICMP速率 |
| net.inet.icmp.icmplim_output=0 | 安全参数,编译内核时需加options TCP_DROP_SYNFIN |
| net.inet.tcp.drop_synfin=1 | |
| net.inet.tcp.always_keepalive=1 | 清除没有正常断开的TCP连接。适合拨号用户 |
| net.inet.ip.intr_queue_maxlen=1000 | 若看到net.inet.ip.intr_queue_drops增加,则调大此值 |
| net.inet.tcp.msl=7500 | 防止DoS攻击,默认30000 |
| net.inet.tcp.blackhole=2 | 接收到已关闭端口发来的所有包直接drop;设为1则只针对TCP包 |
| net.inet.udp.blackhole=1 | 接收到已关闭端口发来的UDP包直接drop |
| net.inet.tcp.inflight.enable=1 | 为网络数据连接提供缓冲 |
| net.inet.ip.fastforwarding=0 | 打开后会记录路由表,但消耗内核内存 |
| kern.polling.enable (注释) | 编译内核时需打开options POLLING,高负载下使用,SMP不能和polling共存 |
| kern.ipc.somaxconn=32768 | 并发连接数,默认128,推荐1024-4096,越大越占内存 |
| security.bsd.see_other_uids=0 | 禁止用户查看其他用户的进程 |
| kern.securelevel=0 | 设置kernel安全级别 |
| net.inet.tcp.log_in_vain=1 | 记录任何TCP连接 |
| net.inet.udp.log_in_vain=1 | 记录任何UDP连接 |
| net.inet.udp.checksum=1 | 防止不正确的UDP包攻击 |
| net.inet.tcp.syncookies=1 | 防止DoS攻击 |
| kern.ipc.shm_use_phys=1 | 仅为线程提供物理内存支持,需256MB以上内存 |
| kern.ipc.shmmax=67108864 | 线程可使用的最大共享内存 |
| kern.ipc.shmall=32768 | 最大线程数量 |
| kern.coredump=0 | 程序崩溃时不记录 |
| net.local.stream.recvspace=65536 | lo本地数据流接收空间 |
| net.local.dgram.maxdgram=16384 | 本地数据报 |
| net.local.dgram.recvspace=65536 | |
| net.inet.tcp.mssdflt=1460 | 数据包数据段大小,ADSL为1452 |
| net.inet.tcp.inflight_enable=1 | 为网络数据连接提供缓冲 |
| net.inet.tcp.minmss=1460 | 数据包数据段最小值,ADSL为1452 |
| net.inet.raw.maxdgram=65536 | 本地数据最大数量 |
| net.inet.raw.recvspace=65536 | 本地数据流接收空间 |
| net.inet.ip.fw.dyn_max=65535 | ipfw防火墙动态规则数量,默认4096,增大可防病毒大量TCP连接 |
| net.inet.ipf.fr_tcpidletimeout=864000 | ipf防火墙TCP连接空闲保留时间,默认8640000(120小时) |
这节是重点,花点篇幅来聊。系统默认运行Apache、Mysql、vsFTPd、SSH等服务,下面一一讲解。
Apache的核心配置在 httpd.conf,安装目录是 /usr/local/apache2/,配置文件在 /usr/local/apache2/conf/httpd.conf。用ee或vi打开:
# ee /usr/local/apache2/conf/httpd.conf
下面重点讲安全相关的设置,基本服务、端口、主目录这些就不说了。
(1) 指定运行Apache的用户和组
这很重要——权限是继承的。如果运行Apache的用户权限太高,入侵者通过WebShell就能对系统造成严重威胁。一般用nobody用户和nobody组。在httpd.conf里找到User和Group选项:
User nobody
Group #-1
(2) Apache的日志文件
日志文件很重要,能反映Apache的运行状况和访问情况,对判断入侵很有帮助。默认配置如下:
ErrorLog logs/error_log # 错误日志存放目录
LogLevel warn # 日志级别(debug, info, notice, warn, error, crit)
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog logs/access_log common # 使用common格式
预定义的格式内容:
可以定制自己的日志格式,通过CustomLog调用。注意,日志文件由运行Apache的用户打开,要注意安全性,防止被改写或删除。
(3) Apache服务信息显示控制
配置文件中有个选项控制是否显示apache版本、主机名、端口、支持的CGI等信息:
ServerSignature On
默认为On,所有信息都会显示。比如故意访问一个不存在的文件:http://target.com/404.html,那么错误提示中会显示——
Apache/2.0.53 (Unix) PHP/4.3.11 Server at target.com Port 80
所有信息都暴露无遗。还有Off和EMail选项,Off不显示任何信息,EMail显示管理员邮箱。建议设为Off或EMail。
(4) 目录浏览
配置中可以设置Apache对没有索引文件的目录进行浏览:
Options Indexes FollowSymLinks
AllowOverride None
这很不安全。如果不需目录浏览,建议改成:
Options FollowSymLinks
AllowOverride None
(5) 用户主页
设置:
UserDir public_html
这样每个用户都能在自家目录下建public_html,然后通过 http://target.com/~用户名/ 访问。这对服务器来说没必要也不安全。直接关闭:
UserDir disabled
或者改名成黑客不容易猜到的文件名,比如:
UserDir webserver_public_htmlpath
也可以只允许部分用户:
UserDir enabled user1 user2 user3
(6) CGI执行目录
如果要执行perl等CGI程序,需要设置:
ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
但这也给了黑客机会——利用不安全的CGI程序搞破坏。如果不需要,建议注释掉:
#ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
(7) 控制PHP脚本只能访问指定目录
在httpd.conf中添加:
php_admin_value open_basedir /usr/www
后面路径是PHP脚本能访问的目录。如果PHP脚本想访问其他目录,会报错。