Apache2基本配置

Published on 2014-12-31

Apache2基本配置(Apache2.4及以上)

Apache2的配置一般位于/etc/apache2/apache2.conf中。你也可以新建多个配置文件,如新建一个mysite.conf文件,然后将其include到这个主配置文件中,语法为

Include mysite.conf

其中mysite.conf文件中为你需要的配置内容。配置语法将随后详细介绍。

可以使用如下两条命令之一来检查配置文件是否有语法错误

apache2 -t
apachectl configtest

变量定义

在Apache的配置文件中可以使用Define指令定义变量,然后使用${}调用变量,如

Define servername example
DocumentRoot /var/www/${servername}

另外,借助已经定义的变量,就可以方便地使用<IfDefine>指令进行条件配置,如

Define localstatic
<IfDefine localstatic>
    Alias /static/ /var/www/example/static/
</IfDefine>
<IfDefine !localstatic>
    Alias /static/ http://cdn.some.com/xxxx/static/
</IfDefine>

从上边的例子可以看出,<IfDefine>指令的测试条件有两种,第一种是<IfDefine parameter-name>,在parameter-name已经有定义的情况下使用;第二种是<IfDefine !parameter-name>,在parameter-name没有被定义的情况下使用。

全局配置

ServerRoot "/etc/apache2"
指定apache服务器的配置文件存放的根目录。

Timeout 300
超时时间,单位秒,如果超过这段时间仍未收到或者送出数据,则断开连接。

KeepAlive On|Off
启用表示允许保持连接,让每次连接可以提出多个请求。建议关闭,因为保持连接会使会话常驻内存,如果连接数目较多则内存耗尽。

MaxKeepAliveRequests 100
每次连接可提出请求的数量,0表示数量不限。

KeepAliveTimeout 15
连续两个请求之间的时间如果超过15秒还未到达,则连接中断。

LoadModule <name> <path>
加载模块。

ServerName some.com
设置主机名称,以取代主机的真实名称,发送到远程连接程序。

ServerAdmin someone@some.com
管理员邮件地址,发送出错报告。

DocumentRoot "/var/www/html"
Apache服务器存放网页的文档根目录。(在我安装的apache2中的配置文件中暂未找到这一项,故机理还不明确)

访问控制

配置方法

直接在配置文件中进行的配置选项会在整个服务器中生效,如果需要让某些配置仅对服务器的一部分生效,如某个目录或文件等,就需要将配置项放在特定的作用域中,也就是使用<Directory>, <DirectoryMatch>, <Files>, <FilesMatch>(这四种是面向文件系统的),<Location>, <LocationMatch>(这两种是面向网络URL的)配置节。其中带Match后缀的配置节可以使用正则表达式作为参数。(其实不带这个后缀也可以使用正则表达式,请参考官方文档

另外,还有一种不同含义的限定作用域的方式,就是需要让配置项仅针对某个虚拟主机(Virtual Host)效,此时使用<VirtualHost>配置节。这方面的内容在下一节介绍。

<Directory>中的配置指令,将递归地应用于其指定的目录下的所有文件和目录(在使用.htaccess文件的时候也是如此,详见本节第三小节)。则如下边的配置使得路径对文件系统中的目录/var/www/mysite/static中的内容无条件允许访问,但是不允许访问目录索引(即禁止访问目录树形结构)。

<Directory /var/www/mysite/static>
    Options -Indexes
    Require all granted
</Directory>

而在<Files>中的指令则将仅仅对指定的文件生效,不对目录生效。如下面的配置将禁止任何位置上的private.html的访问请求。

<Files private.html>
    Require all denied
</Files>

为了更精细地对文件访问进行控制,指令<Directory><Files>可以组合使用。例如,下边的例子将禁止访问目录/var/www/site/及其子目录下的任何private.html文件。

<Directory /var/www/site>
    <Files private.html>
        Require all denied
    </Files>
</Directory>

配置节<Location><LocationMatch>的用法也类似,只不过是面向网络位置即URL的。

在Apache2.4以前的版本中,访问控制指令是由AllowOverride, Order, Allow, Deny实现的,从2.4开始使用新的指令Require,但是为了保持兼容,旧指令依然可以正常使用,只是不建议。

访问控制指令详解

Apache中的访问控制指令有OptionsRequire两类,分别针对不同的方面进行控制。

Options指令

配置在特定的目录中,可以使用哪些特性,配置语法为Options [+|-]option [[+|-]option] ...,默认为Options FollowSymLinks。其中参数option可选列表如下

  • All:除MultiViews之外的所有的选项
  • ExecCGI:允许使用mod_cgi执行CGI脚本
  • FollowSymLinks:服务器在当前目录中跟踪符号链接(follow symbolic links),也就是说,访问控制对符号链接同样生效。只对<Directory>和.htaccess文件有效。不能将禁用该选项视为安全策略
  • Includes:允许mod_include提供服务器端的includes
  • IncludesNOEXEC:允许服务器端的includes,但是#exec cmd#exec cgi被禁用。不过仍然可以从ScriptAlias目录中#include virtual CGI脚本
  • Indexes:如果一个指向目录的URL出现,而相应的目录中没有index.html文件,则服务器会使用mod_autoindex返回这个目录中的文件列表。
  • MultiViews:允许使用mod_negotiation提供内容协商(Content Negotiation) "MultiViews"
  • SymLinksIfOwnerMatch:只有连接指向的目标文件或目录与连接属于同样的用户时,服务器才跟踪符号链接。只对<Directory>和.htaccess文件有效。不能视为安全策略

如果多个Options同时作用于一个目录,则这些Options指令中最直接起作用的一个会被使用,而其他的会被忽略,也就是说,Options不会被合并。但是如果某个Options中的参数带有+/-符号,那么这个Options指令会被合并使用。举两个例子:

<Directory /web/docs>
    Options Indexes FollowSymLinks
</Directory>
<Directory /web/docs/spec>
    Options Includes
</Directory>

在上边的例子中,/web/docs/spec仅仅会被配置为Includes,也就是说,其父目录的配置被忽略。

<Directory /web/docs>
    Options Indexes FollowSymLinks
</Directory>
<Directory /web/docs/spec>
    Options +Includes -Indexes
</Directory>

在上边的例子中,/web/docs/spec会被配置为FollowSymLinksIndexes,也就是说,因为子目录的Options是带+/-符号的,所以Options指令被合并(叠加)到其父目录的指令上,作为它自己的指令。

需要注意的是,同一条Options指令的参数中,要么都带+/-符号,要么都不带,混合使用会引发语法错误。

Require指令

Require指令用来测试一个认证的用户是否被授权进行访问。配置语法为Require [not] entity-name [entity-name] ...

mod_authz_core提供的授权指令有

  • Require all granted:无条件允许访问
  • Require all denied:无条件拒绝访问
  • Require env env-var [env-var] ...:仅当其中一个环境变量env-var存在时允许访问
  • Require method http-method [http-method] ...:仅仅允许使用给定的HTTP方法进行访问
  • Require expr expression:当表达式为真时允许访问

mod_authz_user, mod_authz_host, mod_authz_groupfile提供的授权指令有

  • Require user userid [userid] ...:仅允许指定用户访问
  • Require group group-name [group-name] ...:仅允许指定组中的用户访问
  • Require valid-user:仅允许合法用户访问
  • Require ip 10 172.20 192.168.2:仅允许指定地址范围中的客户端访问

如果在Require指令中使用了not参数,则需要配合其他Require指令进行使用,如

<Directory /www/docs>
    <RequireAll>
        Require group alpha beta
        Require not group reject
    </RequireAll>
</Directory>

上边的例子中,允许在alpha和beta两个组中的用户访问,但如果用户同时属于组reject,则拒绝其访问。<RequireAll>用来组合多个Require指令。另外请参考<RequireNone>指令。

使用.htaccess files

.htaccess文件是另一种进行访问控制的方法,将访问控制指令写到一个.htaccess文件中并置于网站的某个目录下,则其中的访问控制指令就会对该目录及其子目录生效。但是一般应该避免使用这种方式进行访问控制,因为这种方法会拖慢服务器的速度,最好的方式依然是对Apache进行配置。

.htaccess文件相关的指令有:AccessFileName, AllowOverride等。

虚拟主机

在Apache中配置虚拟主机有两种方法,一种是基于IP的,另一种是基于域名的。每个虚拟主机的配置文件建议单独放置在sites-available目录中,需要使用的时候添加软连接

sudo ln -s /etc/apache2/sites-available/site.conf /etc/apache2/sites-enabled/site.conf

这里先介绍基于域名的虚拟主机配置方法,而且一般情况下也建议使用这种配置方法。

基于域名配置虚拟主机

适用于在一个二级域名下使用多个三级域名。在这里需要使用配置节<VirtualHost>,并且至少在其中配置ServerNameDocumentRoot,当然还可以配置更多的内容,与虚拟机直接相关的内容具体配置如下

<VirtualHost *:80>
    ServerAdmin someone@site.com
    DocumentRoot /var/www/site
    ServerName www.site.com
    ErrorLog /var/log/apache2/site-error_log
    TransferLog /var/log/apache2/site-access_log
</VirtualHost>

在本机测试的时候需要先指定DNS映射,不然会找不到地址的。比如你可以在/etc/hosts文件中添加如下映射,使得访问域名site.com的时候指向你自己的机器。

127.0.0.1 site.com
127.0.0.1 abc.site.com

然后进行如下的虚拟主机配置。

<VirtualHost *:80>
    DocumentRoot /var/www/site
    ServerName site.com
</VirtualHost>
<VirtualHost *:80>
    DocumentRoot /var/www/abc
    ServerName abc.site.com
</VirtualHost>

这样在访问site.com时就会进入/var/www/site指定的网站中,访问abc.site.com时就会进入/var/www/abc指定的网站中。

基于IP配置虚拟主机

基于IP配置虚拟主机跟上边的方法基本相同,只是需要设定特别的IP。下边举一个具体的例子。

首先使用ifconfig命令查看本机可用IP,一般都会有一个本地环回地址127.0.0.1,以及正在联网的网卡的IP地址,比如我的是10.0.2.11。现在进行如下配置

<VirtualHost 10.0.2.11:80>
    DocumentRoot /var/www/abc
    ServerName abc.site.com
</VirtualHost>
<VirtualHost *:80>
    DocumentRoot /var/www/site
    ServerName site.com
</VirtualHost>

这样,在使用IP地址10.0.2.11进行访问的时候,会访问到网站/var/www/abc,而使用其他地址访问,则会访问到站点/var/www/site