二月, 2010


24
二 10

使用expires模块降低apache负载

使用expires模块声明静态文件过期时间-减少客户端不必要的请求

<Location />
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/* “access plus 1 month”
ExpiresByType text/css “access plus 1 month”
ExpiresByType text/javascript   “access plus 1 month”
ExpiresByType application/x-javascript “access plus 1 month”
</IfModule>
</Location>
另一种方式:
<FilesMatch “\.(css|js|jpg|gif|png)$”>
<IfModule mod_expires.c>
ExpiresActive  On
ExpiresDefault A2592000
</IfModule>
</FilesMatch>

22
二 10

最小化权限的ssh账号-只能使用TCP转发

建立只能使用ssh“转发”功能的系统账户

为了满足“翻墙”的需要,在国外的Linux主机上(比如 DreamHost )上建个可 ssh登录的用户,使用 ssh 的 Tunnel 来作代理是十分常见的方法。

但是主人往往又想最小化用户权限,以避免对系统造成影响。最简单的办法就是,禁止用户登录。

其实 ssh 可以连接到 sshd 但是不执行远程命令(默认是启动用户设定的 shell ),使用 -N 参数即可。

在服务器上建一个 username :
添加用户:useradd -s /bin/false  username,将用户的shell设置成/bin/false。这样用户就无法与系统进行交互。
设置密码:passwd username

小技巧:
也可以使用 /usr/bin/passwd 作为用户的 shell ,这样用户就可以通过登录而来自主修改密码。需要注意的是,需要将 /usr/bin/passwd 这一行写进 /etc/shells文件。
sshd 认证通后之后,会检查设定的 shell 是否登记在 /etc/shells 文件中,若已经登记,则fork自己,然后fork出来的子进程再exec 设定的 shell 。而 ssh 的 -N 参数,则是告诉 sshd 不需要执行 shell。

建立Tunnel:

ssh -D 1080 -qfnN    username@hostname

输入密码即可使用(也可以用key认证)。

Windows的话,可以使用plink.exe或者MyEnTunnel(MyEnTunnel 本质上也是使用plink.exe来建立Tunnel)。

此时账号username 可以通过sshd的认证使用 TcpForwarding ,但是不能运行 shell,不能与系统交互。刚好可以用来为朋友提供国外的代理翻墙。

参数详解:
-D 1080 建立动态Tunnel,监听在本地1080端口。
-q  安静模式。
-f   ssh在后台运行,即认证之后,ssh退居后台。
-n  将 stdio 重定向到 /dev/null,与-f配合使用。
-N  不运行远程程序。即通知 sshd 不运行设定的 shell。


20
二 10

Linux系统上的Watchdog实现

为了满足“高可用性”的需求,人们设计了”watchdog”,俗称“看门狗”。

“Watchdog” 在实现上可以是硬件电路也可以是软件定时器,能够在系统出现故障时自动重新启动系统。

硬件
搜索 “watchdog card”和“看门狗卡”,可以找相关的信息,常见的是PCI接口和USB接口,体积很小。

软件
有很多相关的软件用来做“看门狗”。

Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog 程序。

内核 watchdog 模块通过 /dev/watchdog 这个字符设备与用户空间通信。用户空间程序一旦打开 /dev/watchdog 设备,就会导致在内核中启动一个 1分钟的定时器,此后,用户空间程序需要保证在 1分钟之内向这个设备写入数据,每次写操作会导致重新设定定时器。如果用户空间程序在 1分钟之内没有写操作,定时器到期会导致一次系统 reboot 操作。

用户空间程序可通过关闭 /dev/watchdog 来停止内核中的定时器。

用户空间的 watchdog 守护进程:
在用户空间,还有一个叫做 watchdog 的守护进程,它可以定期对系统进行检测,包括:

* Is the process table full?
* Is there enough free memory?
* Are some files accessible?
* Have some files changed within a given interval?
* Is the average work load too high?
* Has a file table overflow occurred?
* Is a process still running? The process is specified by a pid file.
* Do some IP addresses answer to ping?
* Do network interfaces receive traffic?
* Is the temperature too high? (Temperature data not always available.)
* Execute a user defined command to do arbitrary tests.

如果某项检测失败,则可能导致一次 soft reboot (模拟一次 shutdown 命令的执行),它还可以通过 /dev/watchdog 来触发内核 watchdog 的运行。

内核级”watchdog”与用户空间的”watchdog”的主要区别是,内核态的”watchdog”抗干扰能力强,运行稳定。

参考:
http://baike.baidu.com/view/280158.htm
http://www.ibm.com/developerworks/cn/linux/l-cn-watchdog/index.html
http://www.oschina.net/p/watchdog
http://www.linuxidc.com/Linux/2008-05/12747.htm
http://blog.chinaunix.net/u1/40912/showart_354070.html


20
二 10

使用deflate模块压缩输出

启用web服务器的压缩功能主要有两个好处:
1. 提高用户打开页面的速度。
2. 节省服务器的带宽资源。

一定会有人认为启用压缩会消耗服务器的CPU及内存资源。就目前的计算机处理能力来讲,这点消耗并不是影响系统负载的“主要矛盾”。相反地,因为启缩,会提高传输效率,从而提高计算机处理请求的速度,从而降低系统负载。

Apache 自带的 mod_deflate 模块,提供了DEFLATE输出过滤器,允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。

通常,我们只压缩文本内容,图片文件因为本身已经是压缩格式的,再次压缩的意义不大。

我常用的压缩配置如下:

<Location />
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript
</IfModule>
</Location>

需要注意的是:压缩会于代理服务器造成一定的困扰。比如当我使用Nginx的反向代理+缓存(storage)的时候,存储在Nginx本地的文件是压缩过的(比如 a.css 本来应该是文本文件,存在Nginx本地的是被压缩生成的二进制文件),当用户再次请求时,Ngnix反回给用户的是压缩内容,于是用户这边显示乱码。

另外一个需要注意的问题是:Very 头对缓存命中的影响 http://www.chedong.com/blog/archives/001429.html

参考:
《高性能网站建设指南》
http://www.bsdmap.com/manuals/Apache/mod/mod_deflate.html


10
二 10

系统调用exec和fork

Exec 与 fork 是 UNIX 中的两个系统调用,UNIX 程序利用它们来创建新的进程。

由一个进程产生 (spawn) 另一个进程 ,可能是进程产生后用新进程取代它,即exec;或者如何需要保留这个进程,那就复制一个进程,即 fork 。

举个例子:Getty 进程监测一个串行端口 (tty),提供了一个 “login:” 提示符,当用户输入登录名回车之后,getty的任务就完成了;它执行 (exec) 了 login 命令,当 login 检测密码输入正确之后,它执行 (exec) 登录 shell 。一旦用户启动另一个程序,shell 程序就会派生 (fork) 自己,并且这个复本将执行 (exec) 用户所要运行的任何程序。


10
二 10

使用header标识服务器

当你在维护集群时,你会发现很难定位服务器。比如我们的 LVS 结构下的后端 RS 出现意外的问题的时候,怎么去定位它?

最终我们使用的方法是在 RS 上配置、增加一个额外的 header ( 我们的 RS 上运行的是 Web 服务 ),比如:

我在我的每台 web 上都做了如下配置
<IfModule mod_headers.c>
# Device ID, A(apache) N (Nginx) L(Lighttpd) S(Squid) V(Varnish), CPU x sum, RAM(G), DISK(G), bandwidth, CNC/TEL/EDU, City
Header Append Node “H01-A1-3.4Gx4-4G-100G-100M-CNC1-CQ1″
</IfModule>

这样,通过 Firebug ,我就可以很容易地定位服务器,从而快速的定位故障之所在。


7
二 10

大小写转换

将文件file.txt的小写字母转换成大写

1. 使用tr
cat file.txt | tr a-z A-Z
2. 使用sed
sed ‘y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/’ file.txt

sed的 y/source/dest/   Transliterate  the  characters  in  the  pattern space which appear in source to the corresponding character in dest.


6
二 10

使用apxs为Apache编译模块

apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用LoadModule指令在运行时加载到Apache服务器中。

1. 进入apache源代码的modules目录

2. 运行如下命令自动编译、安装和修改httpd.conf文件,激活mod_proxy模块:

apache path/bin/apxs -c -i -a mod_proxy.c proxy_util.c

选项说明:

-c 执行编译操作
-i 安装操作,安装一个或多个动态共享对象到服务器的modules目录
-a 自动增加一个LoadModule行到httpd.conf文件,以激活此模块,若此行存在则启用之
-A 与-a类似,但是它增加的LoadModule行前有井号前缀(#)
-e 需要执行编辑操作,可与-a和-A选项配合使用,与-i操作类似,修改httpd.conf文件,但并不安装此模块
3. 如果还需要其他proxy模块如mod_proxy_http、mod_proxy_ftp,则单独

apxs -c -i proxy_http.c
apxs -c -i proxy_ftp.c

参考:
http://www.bsdmap.com/manuals/Apache/programs/apxs.html


6
二 10

使用RCS管理配置文件

时下是SVNGit大行其道的时候,RCS出现的频率很小。

RCS,全称 Revision Control System ,一种版本控制系统,用于保存配置文件、Shell脚本和其他任何操作过的文本文件的多个修订版本。与SVN、Git、以及CVS不同的是,RCS不支持C/S结构,RCS的所有内容都保存在本地文件系统中。因此,RCS,不适合多人协作(于是出了SVN、Git这样的版本控制系统),相反的却非常适合管理员(甚至是多位管理员)来管理配置文件。假如你有很多机器要管理,那么另当别论!

RCS将所有修订版本都保存在文件当前目录下名为RCS/的目录中,假如该目录不存在,则保存在与文件相同的目录里。为了不使当前目录看上去很凌乱,建议使用RCS目录。

以Apache配置为例:

1. 创建仓库
mkdir /etc/httpd/conf/RCS
2. 将配置文件httpd.conf初始化到仓库中
ci -i /etc/httpd/conf/httpd.conf
/etc/httpd/conf/RCS/httpd.conf,v <– /etc/httpd/conf/httpd.conf
enter description, terminated with single ‘.’or end of file:
NOTE: This is NOT the log message!

>> Apache Configuration Files
>> .
initial revision: 1.1
done
ci -i 进行“登入和初始化”,为RCS提供文件的第一份完好的副本。RCS提示输入初始化说明,然后从当前目录中删除该文件。
3. 登出文件
co /etc/httpd/conf/httpd.conf
/etc/httpd/conf/RCS/httpd.conf,v –> /etc/httpd/conf/httpd.conf
revision 1.1
done

在RCS初始化文件文件后,登出该文件。
4. 操作配置文件
锁定文件,以防操作时其他用户对访文件进行更新。实际上,RCS是使用文件权限来控制“锁”的,比如co httpd.conf的时候,httpd.conf的文件权限被设置成444,于是不能编辑,当co -l httpd.conf时,权限被设置成 644,于是可以编辑,当ci -u httpd.conf,文件权限又被设置成444。
co -l /etc/httpd/conf/httpd.conf
/etc/httpd/conf/RCS/httpd.conf,v –> /etc/httpd/conf/httpd.conf
revision 1.1 (locked)
done

现在可以随意修改了。
5. 提交文件
完成编辑工作后,重新登入并用ci -u 解锁
ci -u /etc/httpd/conf/httpd.conf
/etc/httpd/conf/RCS/httpd.conf,v <– /etc/httpd/conf/httpd.conf
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single ‘.’or end of file:
>> unload negotiation_module and negotiation_module
>> .
done
请务必使用有意义的日志!
6. 查看文件修改了哪些内容
比如我加载了mod_logio模块:
rcsdiff /etc/httpd/conf/httpd.conf
==================================
RCS file: RCS/httpd.conf,v
retrieving revision 1.2
diff -r1.2 httpd.conf
167c167
< #LoadModule logio_module modules/mod_logio.so

> LoadModule logio_module modules/mod_logio.so

也可以查看两个不同版本之间的差别
rcsdiff -r1.1 -r1.2 httpd.conf
7. 查看修订log
rlog /etc/httpd/conf/httpd.conf
8. 登出某个版本
co -l -r1.1 /etc/httpd/conf/httpd.conf
9. 常见问题( Troubleshooting)
常见的是在登入或者登出的时候出现问题,那可能是在某些节点忘记了 -l (在co中)或 -u(在ci中)选项。通常可以先制作备份,然后再次登出该文件并复回原来的位置:
cd /etc/httpd/conf
cp httpd.conf httpd.conf.bk
co -l httpd.conf
cp httpd.conf.bk httpd.conf
ci -u httpd.conf

6.参考:
《Linux Server Hacks》
http://www.juyimeng.com/httpd-conf-version-control.html


3
二 10

编译安装Apache

温习编译Apahce的相关知识

预备知识

Makefile的惯例

  1. make clean 清除当前目录下在 make 过程中产生的文件。它不能删除软件包的配置文件,也不能删除 build 时创建的那些文件。
  2. make distclean 类似于”clean”,但增加删除当前目录下的的配置文件、build 过程产生的文件。
  3. make install-strip 和”make install”类似,但是会对复制到安装目录下的可执行文件进行 strip 操作。

make的常用选项

  1. -jN , –jobs[=N],指定并行执行的命令数目。
  2. -n –just-print,–dry-run,–recon,只打印出所要执的命令,但并不实际执行命令。
  3. -s –silent,–quit,不显示所执行的命令。

编译Apache的要求

  1. 磁盘空间
  2. ANSI-C编译器及编译环境
  3. 确保准确的时间
  4. Perl 5 [可选]
  5. apr/apr-util >= 1.2

apr和apr-util包含在Apache httpd的发行源代码中,并且在绝大多数情况下使用都不会出现问题。当然,如果apr或apr-util的1.0或1.1版本已经安装在你的系统中了,则必须将你的apr/apr-util升级到1.2版本,或者将httpd单独分开编译。要使用发行源代码中自带的apr/apr-util源代码进行安装,你必须手动完成:
# 编译和安装 apr 1.2
cd srclib/apr
./configure –prefix=/usr/local/apr-httpd/
make
make install

# 编译和安装 apr-util 1.2
cd ../apr-util
./configure –prefix=/usr/local/apr-util-httpd/ –with-apr=/usr/local/apr-httpd/
make
make install

# 配置 httpd
cd ../../
./configure –with-apr=/usr/local/apr-httpd/ –with-apr-util=/usr/local/apr-util-httpd/

Apache的模块状态

通常我们认为Apache的模块分五类:多路处理模块(MPM),基本模块(Base),扩展模块(Extension),实验性模块(Experimental),第三方模块(External)。
关于各模块的状态详情可以查看手册。第三方模块不包含在发行版中,手册中只标识了四种状态:

M 多路处理模块 必须有且仅有一个MPM被静态编译到服务器中。
B 基本模块 默认包含,必须明确禁用。
E 扩展模块 默认不包含,必须明确启用。
X 试验模块 默认不包含,必须明确启用。

Apache的基本模块

Apache 2.2.14 默认被静态编译进httpd的模块:

核心模块

不可或缺
core.c
http_core.c
mod_so.c
prefork.c(Linux上默认是prefork.c)

认证相关模块

mod_authn_file.c
mod_authn_default.c
mod_authz_host.c
mod_authz_groupfile.c
mod_authz_user.c
mod_authz_default.c
mod_auth_basic.c

其它模块

mod_include.c
mod_filter.c
mod_log_config.c
mod_env.c
mod_setenvif.c
mod_version.c
mod_mime.c
mod_status.c
mod_autoindex.c
mod_asis.c
mod_cgi.c
mod_negotiation.c
mod_dir.c
mod_actions.c
mod_userdir.c
mod_alias.c

我的Apache的常用模块

最简单的认证模块组合

[B]mod_auth_basic.c 或
[E]mod_auth_digest.c 加 (2.2.14版时,已经由实验模块转为扩展模块)
[B]mod_authn_file.c 加
[B]mod_authz_user.c
注意!basic加密方式密码是明文传送的,不安全,建议使用digest方式的认证。

保护认证而加载的模块

[B]mod_authn_default.c
[B]mod_authz_default.c
出于安全考虑,强烈建议加载!

最常用的访问控制模块

[B]mod_authz_host.c
提供基与主机名、IP地址以及请求特征的访问控制。

其它常用模块

[B]mod_log_config.c
[B]mod_alias.c
[B]mod_dir.c
[B]mod_mime.c
[B]mod_setenvif.c
[E]mod_rewrite.c
[E]mod_deflate.c
[E]mod_expires.c
[E]mod_headers.c

我常用的编译指令


1. ./configure --prefix=/opt/httpd-2.2.14 --with-mpm=prefork --enable-mods-shared=all LDFLAGS='-s'
2. ./configure --prefix=/opt/httpd-2.2.14 --with-mpm=prefork --enable-mods-shared=all --enable-cache --enable-mem-cache --enable-ssl --enable-file-cache --enable-disk-cache --enable-proxy --enable-proxy-http LDFLAGS='-s'
3. ./configure --prefix=/opt/httpd-2.2.14 --with-mpm=prefork --enable-mods-shared=all --enable-dir=static --enable-authz-host=static --enable-auth-basic=static --enable-authn_file=static --enable-authz_user=static --enable-authn-default=static --enable-authz-default=static --enable-setenvif=static --enable-alias=static --enable-log-config=static --enable-deflate=static --enable-rewrite=static --enable-mime=static --enable-expires=static --enable-cache=static --enable-mem-cache=static --enable-headers=shared --enable-disk-cache=shared --enable-file-cache=shared LDFLAGS='-s'

注意:因为Apache的./configure生成的Makefile不支持make install-strip,所以使用 LDFLAGES=’-s’来编译被strip的代码。

参考:
深入理解软件包的配置、编译与安装
Apache 2.2 手册-编译与安装
Apache 2.2 手册-动态共享对象支持
Apache 2.2 手册-各模块的简介描述
Apache 2.2 手册-描述模块的术语
Apache 2.2 手册-指令速查


3
二 10

mod_authn_default 和 mod_authz_default

mod_authn_default
该模块是一个失败补救(fallback)模块,它在未正确配置认证模块(比如mod_auth_basic缺失mod_authz_user模块的,语法检查检查不出来)的情况下简单拒绝一切认证信息。起到保护数据的作用。

mod_authz_default
在未正确配置授权支持模块的情况下简单拒绝一切授权请求。同样起到保护数据的作用。

假如没有加载default模块,那么,错误的认证配置,会使服务端产生一个500状态码,默认情况下,会生成一个“The server encountered an internal error or misconfiguration and was unable to complete your request.”的提示,有助于管理员调试

假如加载了default模块,那么错误的认证配置,会使客户端始终不能通过认证,最终返回一个401状态码。

出于安全考虑,这两个模块在启用认证的情况下,一定要加载!


2
二 10

使用parted为超大磁盘建立GPT格式的分区表

安装CentOS 5.3 时,遇到的问题:
硬件环境:Dell R710,6块SATA 1T容量、7.2k转的磁盘,6i RAID卡。

问题:将前5块盘做的RAID5,共4T左右的存储容量。将第六块盘做的全局热备。

安装CentOS5.3时提示:

Your boot partition is on a disk using the GPT partitioning Scheme but this machines cannot boot using GPT.

解决方法:
1. 通过RAID卡为系统/boot分区建立单独的小容量设备sda,将/dev/sda使用MBR格式的分区表建立分区;将其他空间分配到设备sdb上,使用parted建立GPT格式分区(fdisk不支持GPT格式)。

2. 根据下表,对Linux系统启动过程的分析,判断应该是CentOS 5.3的grub版本过低,从而不支持从GPT分区引导系统,为grub打上 gpt patch 应该同样能解决问题。

MBR格式的分区表,有一定的局限性,比如:最大分区不超过2T,一个MBR只能记录四个主分区(扩展分区+逻辑分区,为扩展解决方案)。
当分区大于2T时,需要使用GPT格式的分区表。

使用parted:
1. 建立分区表
mklabel / mktable  LABEL-TYPE   create a new disklabel (partition table)
注意该操作会破坏分区表,谨慎操作!
LABEL-TYPE 支持以下几种类型(man parted):
bsd”, “dvh”, “gpt”, “loop”, “mac”, “msdos”, “pc98″ or “sun”.
2. 建立分区
mkpart PART-TYPE [FS-TYPE] START END     make a partition
mkpartfs PART-TYPE FS-TYPE START END     make a partition with a file system
3. 建立文件系统
mkfs NUMBER FS-TYPE     make a FS-TYPE file system on partititon NUMBER
支持以下几种类型(man parted) fat16″, “fat32″, “ext2″, “linux-swap”  or  “reiserfs”。不支持的文件系统,可以在退出parted之后,使用mkfs来建立。
4. 命名分区
name NUMBER NAME         name partition NUMBER as NAME
例:name 1 /boot
5. 设置分区标志(比如Boot Flag)
toggle [NUMBER [FLAG]]    toggle the state of FLAG on partition NUMBER
toggle 1 boot
toggle 使用类似开关一样的方式设置FLAG,执行一次,修改一次状态。比如当前状态为空时,toggle 1 boot 是将第1个分区设置成boot,再执行一次toggle 1 boot时,boot FLAG被去掉。
也可以使用set 1 boot on/off 来设置。
6.其他命令
help 输出帮助信息
print 输出当前分区信息

参考:
http://baike.baidu.com/view/10817.html
http://www.ixdba.net/article/c0/1999.html
http://en.wikipedia.org/wiki/GUID_Partition_Table
http://zh.wikipedia.org/zh-cn/%E5%85%A8%E5%B1%80%E5%94%AF%E4%B8%80%E6%A8%99%E8%AD%98%E5%88%86%E5%8D%80%E8%A1%A8

parted的用法
http://oss.org.cn/ossdocs/gnu_linux/redhat/rhl-cg-zh_CN-9/ch-disk-storage.html


2
二 10

查找后门程序

每个进程都会有一个PID,而每一个PID都会在/proc目录下有一个相应的目录,这是Linux(当前内核2.6)系统的实现。

一般后门程序,在ps等进程查看工具里找不到,因为这些常用工具甚至系统库在系统被入侵之后基本上已经被动过手脚(网上流传着大量的rootkit。假如是内核级的木马,那么该方法就无效了)。

因为修改系统内核相对复杂(假如内核被修改过,或者是内核级的木马,就更难发现了),所以在/proc下,基本上还都可以找到木马的痕迹。

思路:
在/proc中存在的进程ID,在 ps 中查看不到(被隐藏),必有问题。

str_pids=`ps -A | awk ‘{print $1}’`
for i in /proc/[0-9]* ; do
        if  echo $str_pids | grep -q `basename $i` ; then
                :
            else
                echo “Rootkit’s PID: `basename $i`”
        fi
done
unset str_pids i

讨论:

检查系统(Linux)是不是被黑,其复杂程度主要取决于入侵者“扫尾工作”是否做得充足。对于一次做足功课的入侵来说,要想剔除干净,将是一件分精密、痛苦的事情,通常这种情况,需要用专业的第三方的工具(有开源的,比如tripwire,比如aide)来做这件事情。

而专业的工具,部署、使用相对比较麻烦,也并非所有的管理员都能熟练使用。

实际上Linux系统本身已经提供了一套“校验”机制,在检查系统上的程序没有被修改。比如rpm包管理系统提供的 -V 功能:

rpm -Va

即可校验系统上所有的包,输出与安装时被修改过的文件及相关信息。但是rpm系统也可能被破坏了,比如被修改过。


1
二 10

修改Apache的Max open files限制

相信绝大多数人,都是直接对 /etc/security/limits.conf  文件进行的修改,添加类似下面的两行:

*     soft         nofile           10240
*     hard       nofile           10240

这样也能达到效果。但是经验告诉我,能在局部修改,就不要动全局——因为我们不好评估全局会对哪些应用造成影响(就修改nofile参数一事来说,目前还没有发现修改全局对系统的明显影响,但是理论上可以肯定,将全局的限制放宽,意味着使系统容易受到“资源耗尽”类的攻击,然而在我的工作经历中,还没有遇到一例类似事故发生过),所以我建议将这些局部性的修改放到各自的启动脚本里。

在apachectl脚本里,有这样的语句:

#
# Set this variable to a command that increases the maximum
# number of file descriptors allowed per child process. This is
# critical for configurations that use many file descriptors,
# such as mass vhosting, or a multithreaded server.
ULIMIT_MAX_FILES=”ulimit -S -n `ulimit -H -n`”
# ——————–                              ——————–
# ||||||||||||||||||||   END CONFIGURATION SECTION  ||||||||||||||||||||

# Set the maximum number of file descriptors allowed per child process.
if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then
    $ULIMIT_MAX_FILES
fi

所以,我推荐直接修改apachectl,在ULIMIT_MAX_FILES=”ulimit -S -n `ulimit -H -n`” 之前,设定nofile的“硬限制”,如下:

# number of file descriptors allowed per child process. This is
# critical for configurations that use many file descriptors,
# such as mass vhosting, or a multithreaded server.
ulimit -H -n 5000
ULIMIT_MAX_FILES=”ulimit -S -n `ulimit -H -n`”
# ——————–                              ——————–
# ||||||||||||||||||||   END CONFIGURATION SECTION  ||||||||||||||||||||

# Set the maximum number of file descriptors allowed per child process.
if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then
    $ULIMIT_MAX_FILES
fi

这样修改的好处在于,只有Apache的“nofile”受到影响,不影响其它。
原公司的所有应用的管理脚本中(apachectl、nginxctl),都进行了修改,并且使用”isystem”(自己写的一套脚本、小程序的集合)进行统一管理,以至于到后来,我几乎已经忘掉了这些事情,但是系统仍然运行良好,没有再出过 “too many open files” 的问题。

注意:修改过nofile的hard限制以后,需要先stop,再start,httpd进程的限制才能使用新改的参数。

查看当前运行中的进程的limit信息,可以利用/proc(当前Linux内存为2.6),比如apache的一个进程号是10232:

cat /proc/10232/limits


1
二 10

Apache的认证

Apache的认证模型

Apache的认证模块分成三个部分:认证类型模块,认证支持模块,认证授权模块。

认证类型模块(auth):
mod_auth_basic
mod_auth_digest

认证支持模块(authn):
mod_authn_alias
mod_authn_anon
mod_authn_file
mod_authn_dbd
mod_authn_dbm
mod_authn_default
mod_authnz_ldap

认证授权模块(authz):
mod_authnz_ldap
mod_authz_dbm
mod_authz_default
mod_authz_user
mod_authz_groupfile
mod_authz_owner

注意:
mod_authnz_ldap模块即包含认证功能也提供授权功能。mod_authn_alias本身并实现认证功能,但是允许其它认证支持模块以更灵活的方式进行配置。
mod_authz_host 模块提供基于主机名、IP地址、请求特征的访问控制,但并不属于认证支持系统。

一般常用的AuthType 是”Basic/Digest”,这个认证需要用到认证模块mod_auth_basic/mod_auth_digest,和认证支持模块mod_authn_file和认证授权模块mod_authz_user。

就是说,最常用的认证组合方式是:
mod_auth_basic/mod_auth_digest
    +
mod_authn_file
    +
mod_authz_user

即是说,一个使用认证以及访问控制(支持Order Allow,Deny ,Allow from all这样的指令)Apache系统,至少要用到下面四或者五个模块:
mod_auth_basic/mod_auth_digest
    +
mod_authn_file
    +
mod_authz_user
    +
mod_authz_host

不太熟悉Apache认证的管理员,为了优化Apache占用的内存,往往会注释掉一些用不到的模块,而又因为不明白认证模块之间的关系,而导致认证总是不能成功,而apache(目前我使用的版本:2.2.3)的语法检查检查不出来mod_authz_user模块的缺失,故常常使管理员困惑。

重要提醒
Basic认证类型不加密来自用户浏览器的密码,因此不应该用于保护敏感数据。对于敏感的数据,应使用Digest方式来进行认证(比较老的浏览器不支持,不过时至今日,应该已经不是问题了)。

参考:http://www.bsdmap.com/UNIX_html/ApacheMenu_zh_CN/howto/auth.html


1
二 10

快速了解Apache环境

当前使用的Apache的版本为2.2.3,支持以下使用方式:
apachectl -v
apachectl -V
apachectl -l
apachectl -L
apachectl -S
apachectl -M

apachectl -V

1. 查看Server version。
2. 查看编译时间。
3. APR 及 APR-Util 的版本。
4. 硬件架构/平台(64-bit/32-bit)
5. 查看 Server MPM(Prefort/Worker)
6. 是否支持线程(threaded)
7. 定位 HTTPD_ROOT
8. 定位配置文件
9. ……

apachectl -l

静态编译进httpd程序的模块。比如:
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
这个命令也可以用来查看 Server MPM,一般情况下,要么是prefork.c,要么是worker.c。

apachectl -L

查看目前Apache支持的指令,其中不包括加载模块后模块支持的指令。
apachectl -L | grep ^[A-Z]

apachectl -S / apachectl -t -D DUMP_VHOSTS

查看Apache下配置的虚拟主机情况。注间这里的“default server”是有特殊作用的。有时候我们需要专门统过调整Vhost配置段的位置或者vhosts配置文件被加载的顺序来调整、设立“default server”。

apachectl -M / apachectl -t -D DUMP_MODULES

查看apache目前配置里加载的模块。