####################################
### Apache2.2的一些新特性 ###
####################################
首先了解一些Apache2.2的新特性
Apache2.2编译过程与2.0版本非常相似,你曾经使用过的configure命令行在某些情况下仍然可以使用.(在安装目录下的build/config.nice文件中)
主要是模块的名称变化了,特别是认证和授权模块。
如果你选择使用新的2.2版默认配置文件,你将会发现它已经删除了绝大多数不属于基本配置的指令,比以前大大简化了。
在安装目录下的conf/extra/子目录中,有一组包含许多高级特性的示例配置。默认的配置文件被安装在conf/original子目录中。
1、mod_auth 被拆分为 mod_auth_basic、mod_authn_file、mod_authz_user、mod_authz_groupfile
mod_access 被更名为 mod_authz_host
2、将内置的PCRE升级到5.0版本
3、命令行新增了graceful-stop(优雅停止)参数,配置文件新增了 GracefulShutdownTimeout 指令
4、支持big file(在Apache2之前的版本不支持超过2G文件)
一些需要注意的运行时配置更改:
apachectl 选项startssl被取消了。要启用SSL支持,你必须编辑httpd.conf文件,在其中包含与mod_ssl相关的指令,然后使用 apachectl start 命令启动服务器。Apache安装包中提供了一个示范如何启用mod_ssl的配置文件:conf/extra/httpd-ssl.conf 。
####################################
###### 基础概念 ######
####################################
Apache配置文件包含三类:"段";"指令";"注释"
1、"段",用类HTML标签指定,给特定的指令集划定范围
2、"指令",由指令名指定,后跟某个值,配置服务器上所有的单个设置
Apache配置文件是靠指令工作的。一个指令是一个被赋予一个或多个值的关键字,用来指示服务器某一行为的某一方面
3、"注释",以#开头,被服务器忽略,只用于配置文件的注释
####################################
###### 检查apache安装 ######
####################################
1、apache2.0
#列出apache所有的静态模块
/install-path/bin/httpd -l
#检查加载的动态模块
ls /install-path/modules/; #同时检查httpd.conf中的LoadModule指令
2、apache2.2
添加了一个新的命令行选项 -M 用来列出基于当前配置加载的所有模块。
不同于 -l 选项的是,它还列出了通过mod_so加载的DSO(动态共享对象)。
####################################
###### httpd.conf ######
####################################
1、ServerRoot
#Apache安装目录
2、Listen
#侦听端口
3、TimeOut:服务器在断定请求失败前等待的秒数
用于设置Apache等待以下三种事件的时间长度:
- 接受一个GET请求耗费的总时间。
- POST或PUT请求时,接受两个TCP包之间的时间。
- 应答时TCP包传输中两个ACK包之间的时间。
4、ServerAdmin
#返回给client的管理员邮件地址
5、ServerName
#服务器主机名和端口号
6、DocumentRoot
#文档根目录
7、PidFile
#记录父进程(监控进程)PID的文件
8、AccessFileName
#说明分布式配置文件的名字
9、TypesConfig conf/mime.types
#指定mime.types文件的位置
例:application/octet-stream bin dms lha lzh exe class so dll dmg flv
10、DefaultType text/plain
#在服务器无法由其他方法确定内容类型时,发送的默认MIME内容类型
例:DefaultType application/x-httpd-php #表示不带后缀名的文件都解释为php程序
11、LogLevel warn
#控制错误日志的详细程度
12、ServerTokens
#这个指令控制了服务器回应给客户端的"Server:"应答头是否包含关于服务器操作系统类型和编译进的模块描述信息。
13、UseCanonicalName Off
#配置服务器如何确定它自己的域名和端口
14、SetEnvIf
#根据客户端的请求属性设置环境变量
15、SetOutputFilte
#设置了用于在服务器应答发送到客户端之前使用的过滤器。
16、BrowserMatch
#只是SetEnvIf的一种特殊情况,基于User-Agent头有条件地设置环境变量。
17、SetEnvIfNoCase
#等同于SetEnvIf ,仅仅是进行不区分大小写的匹配
18、Header
#配置HTTP应答头
append方法: 向同名应答头添加新内容而不修改原来已经存在的旧内容。当向一个已经存在的头添加新值时,将用逗号与原来已经存在的旧值分开。这是向HTTP头赋以多个值的标准方法。
####################################
###### prefork设置参数 ######
####################################
设置apache的MaxClients (设置可连接的最大连接数)
ServerLimit 1024
StartServers 30
MinSpareServers 30
MaxSpareServers 80
MaxClients 1024
MaxRequestsPerChild 3000
1、对于prefork MPM,只有在你需要将MaxClients设置成高于默认值256的时候才需要使用ServerLimit指令。要将此指令的值保持和MaxClients一样。
Apache在编译时内部有一个硬限制“ServerLimit 20000”(对于preforkMPM为“ServerLimit 200000”)。你不能超越这个限制。
2、也可以编译前修改apache源代码去掉这个限制:server/mpm/prefork/prefork.c
3、根据上面的配置,只要 Web 服务器启动,就会立即以root是否启动一个httpd进程,同时这个进程启动 30 个子进程,并尽力保持 30 到 80 个空闲服务器运行。进程数的硬性限制由 MaxClients 指定。
4、尽管一个进程能够处理许多相继的请求,Apache 还是会取消连接数超过 3,000 以后的进程,这降低了内存泄漏的风险,如果MaxRequestsPerChild为"0",子进程将永远不会结束。
5、最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。
将MaxRequestsPerChild设置成非零值有两个好处:
1、可以防止(偶然的)内存泄漏无限进行,从而耗尽内存
2、给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量
####################################
###### 关于日志 ######
####################################
1、如果是Apache1.3以前的版本,检查所有apache日志包括access_log,error_log日志是否有定时自动截取功能。
cp /dev/null access_log
PS:为什么要使用cp?如果使用mv access_log access_log.bak,因为Apache正在运行,mv只是给日志文件改名,文件的inode节点没有改变,Apache打开的fd仍然指向 access_log.bak,日志会继续写到改名后的文件中,这样你就可能会丢失一部分日志。
2、确定cgi脚本的日志,要求所有程序日志都必须放在“项目目录/log”目录下,不可放在DocumentRoot和cgi-bin下。
####################################
###### 其他配置 ######
####################################
1、检查在/etc/rc.local里是否加入开机自启动apache。检查apache是否自启动,路径是否正确。
2、检查程序目录是否有除了应用程序以外的其他文件,比如tar.gz压缩包,一些无用日志、txt文件、以bak或者日期为后缀的备份文件、脚本等。可以通过 find ./htdocs/ -name *.*.*来查看是否有一些特殊文件,如果没用文件请尽快转移或者删除
3、可通过 crontab -l | grep -E "cgi-bin|htdocs" 命令查看crontab 中的是否是存放在htdocs或者cgi-bin目录下的程序。转移到非web程序目录。
####################################
###### 安全 ######
####################################
1、保持不断更新和升级
2、ServerRoot目录的权限,必须保证ServerRoot下的文件是受保护的,不允许非root用户对它修改。
3、CGI程序
4、系统设置的保护
Options FollowSymLinks
AllowOverride None#禁止用户使用可能导致安全特性被覆盖的.htaccess文件
Order deny,allow
Deny from all
5、观察日志
如果客户端可以访问.htpasswd文件,而且在访问日志中发现类似如下的记录:
foo.bar.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1"
这可能表示服务器配置文件中的下列指令已经被注解了:
Order allow,deny
Deny from all
6、保证所有的服务都通过虚拟主机。
7、检查所有VirtualHost是否都做了apache的 404/500跳转,把这两个文件放在所有VirtualHost的DocumentRoot下
ErrorDocument 500 /error500.html
ErrorDocument 404 /error404.html
8、检查是否有favicon.ico图标文件,将favicon.ico放在所有虚拟主机的DocumentRoot下
9、在每个虚拟主机下设置php的可执行目录,保证php程序只能在指定目录上执行,没有安装php可以不作这一步
例如: php_admin_value open_basedir "/data1/project/program/:/usr/local/lib/php:/tmp/"
10、设置部分目录和文件不可访问
Options None
AllowOverride None
Order allow,deny
Deny from All
Satisfy All
Deny from all
Deny from all
Deny from all
11、apache的htdocs目录和cgi-bin目录不能让www用户有写权限
12、去掉某个目录的php程序的执行功能
php_flag engine off #如果是php3换成php3_engine off
####################################
###### 虚拟主机 ######
####################################
1、基于主机名的虚拟主机(一个IP地址,多个网站)
core模块,相关指令:
DocumentRoot
NameVirtualHost
ServerAlias
ServerName
ServerPath
例子:
NameVirtualHost 192.168.0.1
ServerName www.drupaluser.org #(必须)
DocumentRoot /data1/apache2/htdocs #必须)
ScriptAlias /cgi-bin/ "/data2/iAsk2/cgi-bin/"
ErrorLog /data2/iAsk2/logs/error_log
CustomLog /data2/iAsk2/logs/access_log combined env=!dontlog
# 你可以在这里添加其他指令
ServerAlias指令中可以为一个web站点配置多个域名:
ServerAlias www.drupaluser.org www.iask.cn *.iask.com(通配符"*"和"?")
如果你打算使用多端口(如运行SSL)你必须在参数中指定一个端口号,比如"*:80",在NameVirtualHost指令中指定IP地址并不会使服务器自动侦听那个IP地址。
下一步就是为每个虚拟主机建立段。的参数与NameVirtualHost 的参数必须是一样的(比如说,一个IP地址或"*"代表的所有地址)。在每个段中,至少要有一个 ServerName指令来指定伺服哪个主机和一个DocumentRoot指令来说明这个主机的内容位于文件系统的什么地方。
这样,所有对域iask.com的访问请求都将由虚拟主机www.drupaluser.org处理。通配符标记"*"和"?"可以用于域名的匹配。
当一个请求到达的时候,服务器会首先检查它是否使用了一个能和NameVirtualHost相匹配的IP地址。如果能够匹配,它就会查找每个与这个IP地址相对应的段,并尝试找出一个与请求的主机名相同的ServerName或ServerAlias配置项。如果找到了,它就会使用这个服务器。否则,将使用符合这个IP地址的第一个被列出的虚拟主机。
ServerPath:一些古董级的客户端与基于域名的虚拟主机不兼容。为了与基于域名的虚拟主机兼容,客户端必须发送"Host"头。HTTP/1.1规范中对此做了要求。
综上所述,第一个列出的虚拟主机充当了默认虚拟主机的角色。当一个IP地址与NameVirtualHost指令中的配置相符的时候,主服务器中的DocumentRoot将永远不会被用到。所以,如果你想创建一段特殊的配置用于处理不对应任何一个虚拟主机的请求的话,你只要简单的把这段配置放到段中,并把它放到配置文件的最前面就可以了。
IP查找对一个特定的TCP/IP进程只执行一次。但在持久连接(KeepAlive)中,每个请求都会进行一次这样的查找过程。换句话说,一个客户端在一个持久连接中可以向位于不同的基于域名的虚拟主机的页面提出请求。
2、基于IP地址的虚拟主机(每个站点拥有一个的独立IP地址)
Listen 192.168.0.1:80
Listen 192.168.0.2:80
NameVirtualHost 192.168.0.1:80
NameVirtualHost 192.168.0.2:80
...
...
3、基于侦听端口的虚拟主机(每个站点拥有一个的独立IP地址)
Listen 80
Listen 8080
NameVirtualHost *:80
NameVirtualHost 192.168.0.1:80
NameVirtualHost 192.168.0.1:8080
...
...
3、使用"_default_"虚拟主机,这样配置可以捕获所有指向没指定的IP地址和端口的请求。比如:一个没被任何虚拟主机使用的地址/端口对。
4、文件描述符限制(在日志文件过多的情况下会产生的限制)
当使用了大量虚拟主机,而且每个主机又使用了不同的日志文件时,Apache可能会遭遇斨创建子进程过程中服务器对请求的响应停顿,但是它对服务器性能的影响太大了,必须予以改变。在 Apache1.3中,这个"一秒钟一个"的规定变得宽松了,创建一个进程,等待一秒钟,继续创建第二个,再等待一秒钟,继而创建四个,如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。
设n为创建足够的进程所需要的数据(秒),StartServers=5,apache启动后要达到100个并发请求需要多少秒
从启动开始,每秒创建的进程数: 5+1+2+4+8+16+32+32
很容易算出需要8秒