Apache + SSL Howto译文(Slackware 10 默认安装环境)
提要:如果你有过在线付费的经历并且发现所有的URL是https://开头,并且在浏览器上有一个小锁头的图标,那就是SSL.
为了能让Apache加入SSL支持我们需要编辑
/etc/apache/httpd.conf 文件并且滚动到文件的最下部。
在这里去掉如下的注释。
把如下行:
#Include /etc/apache/mod_ssl.conf
更改为:
Include /etc/apache/mod_ssl.conf
注意:
如上的处理方法是建立在你的发行版已经安装有mod_ssl和httpd的基础之上的。如果你是从源代码编译安装而来或你的发行版不包括这两个软件包,这篇文章就不适合你啦。
一旦完成上一步之后你需要见到的编辑一下文件
/etc/rc.d/rc.httpd
让apache服务器知道你想开启有SSL支持的服务。
把如下行:
'start')
/usr/sbin/apachectl start ;;
更改为:
'start')
/usr/sbin/apachectl startssl ;;
现在所有剩余的工作就设置SSL证书了,如果你不在意非要使用正式的证书的话,slackware自带了一些预设好的证书,我就用这个,但是如果你运行一个真正的生产环境中的web服务器的话,有很可能想付费并且获得一个真正的证书。你也可以选择制作自己的自签名的证书,如果你对这个感兴趣的话,在这篇 Howto文章的最底部有相应的说明。我们仍然运行如下的命令使用预设的证书,当问及是否覆盖时,选择是。
cp /etc/apache/ssl.crt/snakeoil-rsa.crt /etc/apache/ssl.crt/server.crt
cp /etc/apache/ssl.key/snakeoil-rsa.key /etc/apache/ssl.key/server.key
现在所要做的事情就是重新启动apache 服务器了:
/etc/rc.d/rc.httpd restart
如果你想确认SSL现在已经正确的运行了,可以执行如下命令。
netstat -tpan | grep 443
如果一切运行正常,你会得到像下面的输出:
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 27426/httpd
如果你没有获得任何的输出,那么无论如何是出错了然后你需要看看
/var/log/apache/error_log
文件啦。
现在SSL就完全建立起来了,下面你将要告诉apache当有人用https://访问的时候应该提供什么内容,这需要通过VirtualHost指令来实现,并且与SSL连接相关的的配置可以在文件
/etc/apache/mod_ssl.conf中找到。默认情况下它是如下样子的,而且你应当需要该其中的一些配置的。
# General setup for the virtual host
DocumentRoot "/var/www/htdocs"
ServerName new.host.name
ServerAdmin you@your.address
ErrorLog /var/log/apache/error_log
TransferLog /var/log/apache/access_log
最后,如果你想制作你自己的自签名的证书,不使用slackware预先提供的,其实也是很容易的。我从http://www.apache-ssl.org/#FAQ 找到如下命令:
第一步,创建key和request:
openssl req -new > new.cert.csr
第二步,从key中删除passphrase(可选):
openssl rsa -in privkey.pem -out new.cert.key
第三步,把request转换成signed sert:
openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 1825
第四步,把cert和key文件拷贝到适当的位置。
cp new.cert.cert /etc/apache/ssl.crt/server.crt
cp new.cert.key /etc/apache/ssl.key/server.key
一些注释:
当在第一步被问及Common Name的时候,请输入你的web服务器的完全限定域名(FQDN)例如: www.mywebserver.com
当在第一步被问及A challenge password的时候,直接按回车继续。
如果你没有在第二步从key中把passphrase删除,那么每次你运行
/etc/rc.d/rc.httpd start
启动服务器的时候你都要输入密码。这也就意味着如果你的服务器因为某些原因重新启动了,除非你在服务器旁手动敲入了密码,否则你的web服务器就不会启动。
2007年6月3日星期日
Apache + SSL Howto译文
Apache最新官方配置文件中文版。帮忙web服务器管理员更方便的对Apache进行配置
文章简介:Apache最新官方配置文件中文版。帮忙web服务器管理员更方便的对Apache进行配置。
#
# Based upon the NCSA server configuration files originally by Rob McCool.
#参照NCSA服务器的配置文件,原版由Rob McCool发布
#
# This is the main Apache server configuration file. It contains the
# configuration directives that give the server its instructions.
# See for detailed information about
# the directives.
#这是Apache server的主配置文件. 它包含配置指令,来指示服务器
#请参考 http://httpd.apache.org/docs-2.0 了解关于指令的详细信息
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#不要仅仅是阅读本指令,而应该理解指令做了什么。在这里仅起提示的作用。
#如果你不清楚请参阅在线文档。特别提示
# The configuration directives are grouped into three basic sections:
#配置文件批令分为三个基本组
# 1. Directives that control the operation of the Apache server process as a
# whole (the 'global environment').
# 1. 控制Apache server的全局操作的指令(全局环境变量).
# 2. Directives that define the parameters of the 'main' or 'default' server,
# which responds to requests that aren't handled by a virtual host.
# These directives also provide default values for the settings
# of all virtual hosts.
# 2.配置主服务或者默认服务的指令,它针对那些被虚拟主机以外的请求作出响应.
# 它也包含虚拟主机的一些默认参数
# 3. Settings for virtual hosts, which allow Web requests to be sent to
# different IP addresses or hostnames and have them handled by the
# same Apache server process.
# 3. 虚拟主机设置,这使得发往不同的ip或者主机名的请求可以被子同一个Apache服务# 器处理
# Configuration and logfile names: If the filenames you specify for many
# of the server's control files begin with "/" (or "drive:/" for Win32), the
# server will use that explicit path. If the filenames do *not* begin
# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
# with ServerRoot set to "C:/Program Files/Apache Group/Apache2" will be interpreted by the
# server as "C:/Program Files/Apache Group/Apache2/logs/foo.log".
#配置和日志文件名:如果你所指定的文件名以”/”(在Win32中以盘符:/)开头,服务器将以绝对路径来处理。如果不以”/”开头,则以相对于ServerRoot不解释,所以对于logs/foo.log来讲,当ServerRoot为"C:/Program Files/Apache Group/Apache2”时,则指的是
C:/Program Files/Apache Group/Apache2/logs/foo.log文件
# NOTE: Where filenames are specified, you must use forward slashes
# instead of backslashes (e.g., "c:/apache" instead of "c:\apache").
注意,在文件名的定义中,必须用正斜杠,而不是反斜杠,如c:/apache而不是c:\apache
# If a drive letter is omitted, the drive on which Apache.exe is located
# will be used by default. It is recommended that you always supply
# an explicit drive letter in absolute paths, however, to avoid
# confusion.
#如果省略了盘符,则以Apache.exe所在的盘符为默认值
建议在绝对路径中永远使用显式的盘符,这样有助于消除误解
### Section 1: Global Environment
#第一部分全局环境
#
# The directives in this section affect the overall operation of Apache,
# such as the number of concurrent requests it can handle or where it
# can find its configuration files.
#本部分的指令将影响整个Apache服务器,例如它所能处理的并发请求数或者它在哪里能够找到其配置文件
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
# ServerRoot: 服务器的配置,错误和日志文件的根目录
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the LockFile documentation (available
# at );
# you will save yourself a lot of trouble.
#注意:如果将其保存到NFS上或者网络上mounted的文件系统上,然后应该阅读LockFile文档,http://httpd.apache.org/docs-2.0/mod/mpm_common.html#lockfile,将能解决你的很多麻烦.
# Do NOT add a slash at the end of the directory path.
#不要在目录的末尾加上斜杠
ServerRoot "C:/Program Files/Apache Group/Apache2"
ServerRoot:根目录
#
# ScoreBoardFile: File used to store internal server process information.
# If unspecified (the default), the scoreboard will be stored in an
# anonymous shared memory segment, and will be unavailable to third-party
# applications.
ScoreBoardFile: 保存服务器内部的处理信息
如果未定议(默认状态),scoreboard将被保存在匿名的共享内存段中,并且对于第三方来讲,是不可获得的
# If specified, ensure that no two invocations of Apache share the same
# scoreboard file. The scoreboard file MUST BE STORED ON A LOCAL DISK.
#如果已定义,应确保Apache的两个调用不能共享同一个scoreboard. Scoreboard文件必须存放在可分配的磁盘上
#ScoreBoardFile logs/apache_runtime_status
#
# PidFile: The file in which the server should record its process
# identification number when it starts.
#PidFile:当服务器起努时,服务器需要将其进程ID号存放在此文件中
PidFile logs/httpd.pid
#
# Timeout: The number of seconds before receives and sends time out.
#Timeout:接收和发送数据的超时设置,秒数
Timeout 300
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#KeepAlive: 是否支持持久联接(而不是每个请求建一个连接),设off关闭此功能
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#MaxKeepAliveRequests:在持久连接期间,所允许的最大请求数量。设为0表示不作限制
建议设为较高的数,以提高性能
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#KeepAliveTimeout:在同一个客户连接中,等待下一个请求的等待时间。
KeepAliveTimeout 15
##
## Server-Pool Size Regulation (MPM specific)
## 常规Server-Pool服务器池的大小(每分钟M数)
# WinNT MPM WinNT 的MPM
# ThreadsPerChild: constant number of worker threads in the server process
ThreadPerChild:服务器进程中工作的线程数量
# MaxRequestsPerChild: maximum number of requests a server process serves
每个服务进程的最大请求数
ThreadsPerChild 250
MaxRequestsPerChild 0
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the
# directive.
#Listen:允许你将Apache绑定到指定的IP地址或端口,而不是默认端口,请同时参考指令
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#像下面那样指定侦听的IP地址,防止Apache抢占所有绑定的IP地址
#Listen 12.34.56.78:80
Listen 80
#
# Dynamic Shared Object (DSO) Support
#动态共享对象支持DSO
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#为了能够使用模块功能,模块通常以DSO的方式构建,你应该在下面使用LoadModule行,使得能够在使用前获得指令的功能。静态编译模块(在httpd-1中所列举的)不需要在此装载
# Example:
# LoadModule foo_module modules/mod_foo.so
#
LoadModule access_module modules/mod_access.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule asis_module modules/mod_asis.so
LoadModule auth_module modules/mod_auth.so
#LoadModule auth_anon_module modules/mod_auth_anon.so
#LoadModule auth_dbm_module modules/mod_auth_dbm.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule cern_meta_module modules/mod_cern_meta.so
LoadModule cgi_module modules/mod_cgi.so
#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
#LoadModule expires_module modules/mod_expires.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule headers_module modules/mod_headers.so
LoadModule imap_module modules/mod_imap.so
LoadModule include_module modules/mod_include.so
#LoadModule info_module modules/mod_info.so
LoadModule isapi_module modules/mod_isapi.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule negotiation_module modules/mod_negotiation.so
#LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule status_module modules/mod_status.so
#LoadModule unique_id_module modules/mod_unique_id.so
LoadModule userdir_module modules/mod_userdir.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule ssl_module modules/mod_ssl.so
#
# ExtendedStatus controls whether Apache will generate "full" status
# information (ExtendedStatus On) or just basic information (ExtendedStatus
# Off) when the "server-status" handler is called. The default is Off.
#扩展状态控制Apache是否产生完整的状态信息(设为on产生全部),如果设为Off则产生基本的信息,当与server-status头有关,默认值为Off
#ExtendedStatus On
### Section 2: 'Main' server configuration
#第二部分:主服务配置
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
# definition. These values also provide defaults for
# any containers you may define later in the file.
#本节中指令的设置值,将被主服务所使用,主服务响应那些没有被所处理的请求,这些值也为容器提供了默认值,你可以在后面的文件中定义
# All of these directives may appear inside containers,
# in which case these default settings will be overridden for the
# virtual host being defined.
所有这些指令将出现在容器中,这些设定值将在定义virtual host时被覆写。
#
#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin@your-domain.com
# ServerAdmin:你的地址,当系统故障时,可以给你发email。此地址出现在那些由服务器生成的页面上,如出错文档。例如:admin@your-domain.com
ServerAdmin webmaster@moers.com
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#ServerNaem定义了server名称和端口号,用以标明自己的身份。通常可以自动定义,建议显式地定义,避免起动时出错
# If this is not set to valid DNS name for your host, server-generated
# redirections will not work. See also the UseCanonicalName directive.
#如果没有正确定义主机的DNS,服务器产生的重定向将不会工作,同时参考UseCanonicalName指令。
# If your host doesn't have a registered DNS name, enter its IP address here.
# You will have to access it by its address anyway, and this will make
# redirections work in a sensible way.
#如果你没有注册DNS名字,请在这里输入IP地址。
你可以在任何情况下使用ip地址,这也使用得重定向变得敏感
ServerName www.moers.com:80
#
# UseCanonicalName: Determines how Apache constructs self-referencing
# URLs and the SERVER_NAME and SERVER_PORT variables.
# When set "Off", Apache will use the Hostname and Port supplied
# by the client. When set "On", Apache will use the value of the
# ServerName directive.
#UseCanonicalName:决定Apaceh如何构建自定参考URL,和SERVER_NAME及SERVER_PORT变量
当设为Off时,Apache将使用客户端给出的域名和端口。当设为On时,Apache将使用ServerName指令
UseCanonicalName Off
#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#DocumentRoot:服务器文档放置目录。在默认情形下,所有的请求都从这里开始,除了记号和别名将改指它处以外。
DocumentRoot "C:/Program Files/Apache Group/Apache2/htdocs"
#
# Each directory to which Apache has access can be configured with respect
# to which services and features are allowed and/or disabled in that
# directory (and its subdirectories).
#每个可供Apache访问的目录,可以配置成允许或禁止哪些服务和特征(包括其子目录)
# First, we configure the "default" to be a very restrictive set of
# features.
#首先,我们定义一个默认的非常严格的配置
Options FollowSymLinks
AllowOverride None
#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#注意,从这一点往前,你必须许可某些特殊的功能,所以如果某些功能未能如你所愿,要确保你在在下述中启用了该功能。
#
# This should be changed to whatever you set DocumentRoot to.
# 这将改变你对DocumentRoot的设置
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
可能的值为None,All或者任意组合
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
# 索引包括FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#注意MultiViews被显式地Options All,
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs-2.0/mod/core.html#options
# for more information.
#选项指令既复杂又重要,请参阅http://httpd.apache.org/docs-2.0/mod/core.html#options了解详情
Options Indexes FollowSymLinks
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#AllowOverride 控制什么指令能够加入到.htaccess中,可以是All,None,或者组合关键字
AllowOverride None
#
# Controls who can get stuff from this server.
#控制谁可以可以访问此服务
Order allow,deny
Allow from all
#
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received. Be especially careful to use
# proper, forward slashes here. On Windows NT, "Personal/My Website"
# is a more appropriate choice.
# UserDir: 用户的home的名称,当接到到~user的请求时。
请小心正确使用”/”. 在WinNT上,”Personal/My Website”是更合适的选择
UserDir "My Documents/My Website"
#
# Control access to UserDir directories. The following is an example
# for a site where these directories are restricted to read-only.
#控制UserDir目录,以下是一个例子,这个目录是只读的
# You must correct the path for the root to match your system's configured
# user directory location, e.g. "C:/WinNT/profiles/*/My Documents/My Website"
# or whichever, as appropriate.
#你必须更正root目录,与系统设置相配,如用户目录是C:/WinNT/profiles/*/My Documents/My Website或者其它合适的
#
# AllowOverride FileInfo AuthConfig Limit
# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
#
# Order allow,deny
# Allow from all
#
#
# Order deny,allow
# Deny from all
#
#
#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#DirectoryIndex: Apache服务器将要以一个目录的形式响应服务
# The index.html.var file (a type-map) is used to deliver content-
# negotiated documents. The MultiViews Option can be used for the
# same purpose, but it is much slower.
#index.html变量文件(一种映射)将直接传送内容。MultiViews选项可以用于同样的目的,但是要慢得多
DirectoryIndex index.html index.html.var
#
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#AccessFileName: 用来查找各个目录下额外的配置指令的配置文件名,同时参考AllowOverride(允许重载)指令
#Acce
AccessFileName .htaccess
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#下面两行,阻址Web客户端访问 .htaccess和htpasswd(访问设定和密码)的文件
#
Order allow,deny
Deny from all
#
# TypesConfig describes where the mime.types file (or equivalent) is
# to be found.
# TypesConfig,描述在何处找到mime型别
TypesConfig conf/mime.types
#
# DefaultType is the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
如果服务器不能确定文档的型别,将使用默认的MIME型别,例如根据扩展名
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value. If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#如果你的服务器主要包括text/html文档,”text/plain”就是一个好的取值。如果你的大多数内容是binary(二进制)的,如应用程序或图片,你可能希望使用application/octet-stream,使得浏览器试图显示二进制数据,尽管它们是文本
DefaultType text/plain
#
# The mod_mime_magic module allows the server to use various hints from the
# contents of the file itself to determine its type. The MIMEMagicFile
# directive tells the module where the hint definitions are located.
# mod_mime_magic模块,允许服务器根据内容提示来识别文件型别。MIMEMagicFile指令告知模块“内容提示”应到何处找。
MIMEMagicFile conf/magic
#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
HostNameLookups: 客户日志或者仅其IP地址,如www.apache.org(on) 或者204.62.129.132
(off).默认为值设为off比较好,如果希望将此置为on将意味着第一次客户请求都至少要查询一次nameserver.
#
HostnameLookups Off
#
# EnableMMAP: Control whether memory-mapping is used to deliver
# files (assuming that the underlying OS supports it).
# The default is on; turn this off if you serve from NFS-mounted
# filesystems. On some systems, turning it off (regardless of
# filesystem) can improve performance; for details, please see
# http://httpd.apache.org/docs-2.0/mod/core.html#enablemmap
# EnableMMAP: 控制是否通过内存映射的方式传送文件(须得操作系统支持)
默认值为on; 如果你使用NSF加载的文件系统(通常在linux下),应置为off. 在某些系统上,置off,不管使用什么文件系统,能够提高效率,详细情况,请参阅文档
#EnableMMAP off
#
# EnableSendfile: Control whether the sendfile kernel support is
# used to deliver files (assuming that the OS supports it).
# The default is on; turn this off if you serve from NFS-mounted
# filesystems. Please see
# http://httpd.apache.org/docs-2.0/mod/core.html#enablesendfile
# EnableSendfile: 控制内核传送文件是否支持(需要OS支持)。默认为on,如果使用NFS,则使用off
#EnableSendfile off
#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a
# container, that host's errors will be logged there and not here.
#ErrorLog: 出错日志文件
如果你想为虚拟主机定义Errorlog指令,则该虚拟主机的错误信息将被记录到这里
ErrorLog logs/error.log
#
# LogLevel: Control the number of messages logged to the error.log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
# LogLever: 日志等级,(与log4j相似,译者注),决定哪些级别的出错信息将被记录,如debug,info,notice,warn,error, crit,alert,emerg等,在设定级别以上的信息就会被记录(译者注).
LogLevel warn
#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
# 日志格式(与log4j相似)
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
# You need to enable mod_logio.c to use %I and %O
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
未完待续……
FIN_WAIT_2状态下的连接与Apache
FIN_WAIT_2状态下的连接与Apache
警告:
此文档没有考虑到Apache HTTP服务器 2.0 版本中的变化并为之作完全更新。 其中某些信息可能仍然有效,但使用时请小心。
从Apache 1.2 beta测试版开始,人们就一直在报告说是处于 FIN_WAIT_2状态的连接(就是netstat所报告的)比使用旧版本的要多得多。 当服务器关闭一个TCP连接时,它发送一个设置了FIN位标记的包给客户端, 客户端以返回一个设置了ACK位标记的包来响应。 然后由客户端发送一个设置了FIN位标记的包给服务器, 服务器响应以一个设置了ACK位标记的包,这样连接就关闭了。 连接处于服务器接收到客户的ACK和FIN信号之间的阶段这时候的状态就叫做FIN_WAIT_2。 参看TCP RFC了解状态过渡的技术细节。
FIN_WAIT_2状态有点不寻常,在关于它的标准上没有超时的定义。 这意味着在许多操作系统上,一个处在FIN_WAIT_2状态的连接会保留直到系统重起。 如果系统没有超时限制并且建立了太多的FIN_WAIT_2连接的话,这些连接会填满分配来存储信息的空间并使内核崩溃。 FIN_WAIT_2连接不与一个httpd进程相关。
为什么会发生?
对此有许多原因,其中一些至今也不很清楚。已知的原因如下:
有缺陷的客户端与持久连接
有一些客户端在处理持久连接(aka keepalives)时存在问题。当连接空闲下来服务器关闭连接时(基于KeepAliveTimeout指令), 客户端的程序编制使它不发送FIN和ACK回服务器。这样就意味着这个连接 将停留在FIN_WAIT_2状态直到以下之一发生:
• 客户端为同一个或者不同的站点打开新的连接,这样会使它在该个套接字上完全关闭以前的连接。
• 用户退出客户端程序,这样在一些(也许是大多数?)客户端上会使操作系统完全关闭连接。
• FIN_WAIT_2超时,在那些具有FIN_WAIT_2状态超时设置的服务器上。
如果你够幸运,这样意味着那些有缺陷的客户端会完全关闭连接并释放你服务器的资源。 然而,有一些情况下套接字永远不会完全关闭,比如一个拨号客户端在关闭客户端程序之前从ISP断开。 此外,有的客户端有可能空置好几天不创建新连接,并且这样在好几天里保持着套接字的有效即使已经不再使用。 这是浏览器或者操作系统的TCP实现的Bug。
已经被证实存在这个问题的客户端有:
• Mozilla/3.01 (X11; I; FreeBSD 2.1.5-RELEASE i386)
• Mozilla/2.02 (X11; I; FreeBSD 2.1.5-RELEASE i386)
• Mozilla/3.01Gold (X11; I; SunOS 5.5 sun4m)
• MSIE 3.01 on the Macintosh
• MSIE 3.01 on Windows 95
没有出现问题的有:
• Mozilla/3.01 (Win95; I)
预计许多别的客户端也有同样的问题。客户端应该做的工作 是周期性地检查自己打开的套接字看是否已经被服务器所关闭,并关闭那些已在服务器端被关闭的套接字。 这个检查只需要每几秒一次,在某些系统上甚至可以被操作系统信号检测到。 (例如,Win95和NT客户端有这种能力,但是它们似乎忽视了这一点)。
Apache 不能 避免这些FIN_WAIT_2状态出现,除非对那些客户端禁止持久连接, 就像因为其他问题我们对Navigator 2.x 客户端坐的建议那样。然而,非持久连接增加了每个客户端 需要的连接的数量并使得访问具有大量图片的页面速度降低。由于非持久连接具有自己的资源消耗与 短暂的每次关闭后的等待时期,为了更好地提供服务,一个繁忙的服务器会需要持续性。
就我们所知,客户端导致的FIN_WAIT_2问题对所有支持持久连接的服务器都存在, 包括 Apache 1.1.x 和 1.2.
在 1.2 版中引入的一点必需的代码
尽管上述bug是个问题,但还不是全部的问题。一些用户在Apache 1.1.x 上没有观察到FIN_WAIT_2问题, 但在 1.2b 上建立了足够多的FIN_WAIT_2状态连接就会崩溃内核。 这些附加FIN_WAIT_2状态最有可能的源头是一个叫做lingering_close()的函数调用, 它在 1.1 和 1.2版本之间被加入。这个函数对于正确处理持久连接和任何含有内容的请求(例如 ,PUTs和POSTs)是必需的。它的工作是在服务器关闭连接后的特定时刻读取任何客户端发送的数据。 这样做的确切理由有点复杂,但是涉及到在客户端于服务器发送响应并关闭连接的同一时刻提出请求的情况。 没有延迟的情况下,客户端在有机会读取服务器响应之前可能被强制重置其TCP输入缓冲区, 如此就可以理解连接关闭的原因了。参看附获得更详细的了解。
lingering_close()的代码看起来似乎是引起一系列问题,包括它引起的 traffic patterns(译注:字典说是“起落航线”,我感觉像流量模式之类的东西,请分析过源码的朋友解释一下)的改变. 这些代码已被彻底地复查过了,我们没有在其中发现任何bug。 除了缺乏FIN_WAIT_2状态的超时机制,有可能在BSD TCP栈中有点问题,被引起我们观察的这些问题的 lingering_close代码暴露出来了。
我能对它做什么?
对于这个问题有几种可能的变通办法,其中一些工作得更好。
为 FIN_WAIT_2 增加 超时机制
明显的变通办法是简单地为FIN_WAIT_2状态加上超时机制。 这不是由RFC明确规定的,还有可能与RFC有所冲突,但是这个办法被广泛公认是必需的。 以下系统已知具有超时机制:
• FreeBSD 从 2.0 或者更早版本开始。
• NetBSD 版本 1.2(?)
• OpenBSD 所有版本(?)
• BSD/OS 2.1, 安装了 the K210-027 补丁。
• Solaris 从大约 2.2 版本开始。 可以用ndd调节超时来改变tcp_fin_wait_2_flush_interval, 但是缺省值应该适合大多数的服务器,并且不正确的调节会产生反面作用。
• Linux 2.0.x 与更早版本(?)
• HP-UX 10.x 缺省值是在超过普通持活超时限制以后 终止the FIN_WAIT_2状态的连接。这不涉及到持久连接或HTTP保持活动的超时,但是跟套结字选项 SO_LINGER有关——Apache把它激活了。这个参数可以用nettune来调校修改 像tcp_keepstart和tcp_keepstop这样的参数。 在较晚的修订版中,有一个用于FIN_WAIT_2态连接的可以被修改的显式时钟; 接洽HP支持可以获得细节。
• SGI IRIX可以打补丁来支持超时。 对于IRIX 5.3、6.2、和 6.3,分别使用补丁1654、1703 和 1778。如果寻找补丁遇到困难, 请向你的SGI支持渠道寻求帮助。
• NCR's MP RAS Unix 2.xx 和 3.xx 版都有FIN_WAIT_2超时支持。在 2.xx 版中是600秒不可调, 而在 3.xx 版中缺省为 600 秒,由可调节的"max keep alive probes" (缺省为8)乘以 "keep alive interval"(缺省为75秒)得来。
• Sequent's ptx/TCP/IP for DYNIX/ptx 自从1994年中的4.1发行半以来都有FIN_WAIT_2超时支持。
以下系统是已知没有超时支持的:
• SunOS 4.x 没有而且几乎可以肯定以后也不会有这个功能, 因为对于Sun公司它已经处于其开发生命周期的最后时刻了。如果你有内核的源码它补丁应该很容易。
有一个 可用的补丁,能够给它加入FIN_WAIT_2状态的超时支持。最早是为BSD/OS开发的, 但是应该能够适合使用BSD网络代码的大多数系统。你需要内核源码才能使用它。
不使用lingering_close()的编译
编译不使用lingering_close()函数的Apache 1.2 是可能的。 这会使得那一部分的代码更接近 1.1 版的相应部分。如果你这样做, 要意识到这样会引起PUTs、POSTs 和持久连接方面的问题,特别是在客户端使用管道的情况下。 那是说,情况不会比1.1版更坏,而且我们明白保持你的服务器的运行是相当重要的。
要不带lingering_close()函数进行编译, ,在你的Configuration文件的EXTRA_CFLAGS 行的最后加上-DNO_LINGCLOSE,重新运行 Configure并重新编译服务器。
使用SO_LINGER作为lingering_close()之外另一个选择
在许多系统上,有一个可以由setsockopt(2)设置的叫做 SO_LINGER的选项。它完成与lingering_close()相似的工作, 除了这一点:它在许多系统上会终止以致引起比lingering_close多得多的问题。 在某些系统上它也会工作的很好,如果你没有别的选择也值得一试。
要试试它,在你的Configuration文件的EXTRA_CFLAGS 行的最后加上-DUSE_SO_LINGER -DNO_LINGCLOSE,重新运行 Configure并重新编译服务器。
注意
试图同时使用SO_LINGER和lingering_close() 非常可能会出现很糟的结果,所以不要这样做。
增加存储连接状态的内存数量
基于BSD的网络代码:
BSD 把网络数据存储在一个叫做mbuf的区域中,比如连接状态数据。 当你有太多的连接以至于内核没有足够的mbuf来容纳它们全部的时候, 你的内核就很可能崩溃。你可以通过增加可用的mbuf数量来减少这个问题的影响; 这样不能防止问题出现,只是让服务器在崩溃之前运行得久一点。
正确的增加方法与你的操作系统有关;找一找关于"mbufs"或者"mbuf clusters"数量的参考资料。 在许多系统上,可以这样做:在你的内核配置文件中添加一行NMBCLUSTERS="n", n是你想要的mbuf簇的数量,再重新编译内核。
禁止KeepAlive
如果你无法做上述任何一项修改,那么作为最后的手段,你应该禁止KeepAlive。 编辑你的httpd.conf并把"KeepAlive On"改为"KeepAlive Off"。
附录
下面是来自Roy Fielding的文章,他是HTTP/1.1的作者之一:
为什么延迟关闭功能对HTTP是必需的
服务器延续一个已关闭连接的需要在HTTP规范中被提到好几次但没有解释。 这里的解释是基于我以前在W3C的时候我、Henrik Frystyk、Robert S.Thau、Dave Raggett和 John C. Mallery之间在MIT的走廊上的讨论。
如果服务器在客户端发送数据时关闭连接的输入端(或者准备发送数据),那么 服务器的TCP栈会给客户端发一个RST信号(重置)。当接收到RST,客户端会刷新他自己的TCP输入缓冲区, 使之回到亦由RST包的参数所指定的未确认的包的状态。如果恰好在连接关闭之前, 服务器发送了一条消息给客户——通常是一个错误信息,客户端在其应用程序代码从TCP输入缓冲区读取 此错误消息之前接收了RST包并且服务器也已在接受缓冲收到客户端的ACK信号,那么, 这个RST信号将会在客户应用程序有机会读取这个错误信息之前把它刷新掉。 其结果就是客户端被留在那里考虑网络连接无缘无故的失败。
在两种情况下很可能会引发这样的情况:
1. 在没有正确授权的情况下POST或者PUT数据
2. 在接收到响应之前发送多个请求(管线)并且其中一个请求导致了错误或者其它引起连接中断的结果。
其解决办法都是:发送响应,只关闭连接中写操作的那一半(本来是停止运转), 并继续从套接字读取直到客户关闭连接(表示读取响应已经完成)或者出现超时。 这就是如果SO_LINGER被设置的话内核应该做的事。不幸,SO_LINGER在某些系统上不起作用; 在一些其它的系统上,它又没有自己的超时以致TCP内存段只好一直堆积连接直到下一次重起(计划中的及之外的)。
请注意简单地移走延迟代码并不能解决问题 -- 这样只是把问题转移到另一个检测起来困难的多的地方。.