apache: 配置 - 基本配置



1. 配置结构

.
├── extra                                     # 扩展子配置目录
│   ├── httpd-autoindex.conf
│   ├── httpd-dav.conf
│   ├── httpd-default.conf
│   ├── httpd-info.conf
│   ├── httpd-languages.conf
│   ├── httpd-manual.conf
│   ├── httpd-mpm.conf
│   ├── httpd-multilang-errordoc.conf
│   ├── httpd-ssl.conf
│   ├── httpd-userdir.conf
│   ├── httpd-vhosts.conf
│   └── proxy-html.conf
├── httpd.conf                                # 主配置文件(配置入口)
├── magic                                     # 和mime相关的,详情见http://httpd.apache.org/docs/current/mod/mod_mime_magic.html#mimemagicfile
├── mime.types                                # mime文件,指定文件类型的
└── original                                  # 原始配置文件副本
    ├── extra
    │   ├── httpd-autoindex.conf
    │   ├── httpd-dav.conf
    │   ├── httpd-default.conf
    │   ├── httpd-info.conf
    │   ├── httpd-languages.conf
    │   ├── httpd-manual.conf
    │   ├── httpd-mpm.conf
    │   ├── httpd-multilang-errordoc.conf
    │   ├── httpd-ssl.conf
    │   ├── httpd-userdir.conf
    │   ├── httpd-vhosts.conf
    │   └── proxy-html.conf
    └── httpd.conf

3 directories, 29 files

重点:httpd.conf是主配文件,也是配置文件的入口,其他配置文件都通过这里Include

PS: 主配文件也可以修改,可以在启动时动态指定,但是一般都是用默认的

2. 配置说明

2.1 httpd.conf基本配置

# 这里是指定httpd的软件目录
ServerRoot "/usr/local/httpd-2.4.41"
# 注意结尾不要加"/"

# 监听的域名可以通过指定多个Listen来监听多个端口
# 443因为牵扯到要加载mod_ssl模块,所以是需要一定条件来监听
Listen 80

# 可以通过调整LoadModule配置,来增删加载的模块
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so

# php的模块
LoadModule php5_module        modules/libphp5.so


# 这种if的模块,只有在httpd启动或者重启的时候才会执行,一旦条件匹配
# 将会应用到全局
<IfModule unixd_module>
User  www
Group www
</IfModule>

ServerAdmin you@example.com

# 这里是安全配置,避免有人通过某些方式访问整个系统文件
<Directory />
    # 禁用.htaccess
    AllowOverride none
	# 全部禁止访问根目录
    Require all denied
</Directory>

# <Directory directory-path> ... </Directory>
# directory-path可以加双引号,也可以不加,但是中间有空格的时候,必须加
# directory-path可以用wildcard匹配,?代表任意字符,*代表任意多个字符
# 但是/任何情况下不会被匹配,所以/*/html不会匹配/var/www/html,但是会匹配/data/html
DocumentRoot "/usr/local/httpd-2.4.41/htdocs"
<Directory "/usr/local/httpd-2.4.41/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

# 安全配置,禁止所有人访问.htaccess等文件
<Files ".ht*">
    Require all denied
</Files>

ErrorLog "logs/error_log"
LogLevel warn

# 日志格式配置
<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" common
</IfModule>

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/usr/local/httpd-2.4.41/cgi-bin/"
</IfModule>
<IfModule cgid_module>
</IfModule>
<Directory "/usr/local/httpd-2.4.41/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>
<IfModule headers_module>
    RequestHeader unset Proxy early
</IfModule>
<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddType application/x-httpd-php .php
</IfModule>

# 引入外部配置
# 1. 引入mpm的配置
Include conf/extra/httpd-mpm.conf
# 2. 引入虚拟主机配置
Include conf/site-enabled/*.conf

<IfModule proxy_html_module>
Include conf/extra/proxy-html.conf
</IfModule>

# 在启用mod_ssl模块的情况下,再来监听443
# ssl_module和mod_ssl是一样效果的
# <IfModule mod_ssl.c>
# Listen 443
# </IfModule>
<IfModule ssl_module>
Listen 443
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

2.2 VirtualHost基本配置

<VirtualHost *:80>
    # ServerName指定一个唯一的值,来和其他的虚拟主机区分
    ServerName example.com
	# ServerAlias来扩展监听多个域名
    ServerAlias www.example.com *.example.com
	DocumentRoot "/data/html"
	DirectoryIndex index.html index.php
    ErrorLog  "logs/example-error_log"
    CustomLog "logs/example-access_log" common
</VirtualHost>

<VirtualHost *:443>
    ServerName example-ssl.com
    ServerAlias www.example-ssl.com *.example-ssl.com
    SSLEngine on
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"
	DocumentRoot "/data/html"
	DirectoryIndex index.html index.php
    ErrorLog  "logs/example-ssl-error_log"
    CustomLog "logs/example-ssl-access_log" common
</VirtualHost>

2.3 SetEnvIf

描述:基于请求的属性设置环境变量

语法:SetEnvIf attribute regex [!]env-variable[=value] [[!]env-variable[=value]] ...

模块:mod_setenvif

语法说明
attribute可以是如下内容:

  1. HTTP请求字段(详情见RFC2616),例如:Host, User-Agent, Referer, and Accept-language。可以用正则表达式来匹配字段。
  2. 以下请求信息:
    • Remote_Host, 发起请求的客户端的hostname(如果能得到的话)
    • Remote_Addr, 发起请求的客户端的IP
    • Server_Addr, 服务端的IP(2.0.43版本之后增加)
    • Request_Method, HTTP请求方法(GET, POST 等)
    • Request_Protocol,HTTP请求协议版本(”HTTP/0.9”, “HTTP/1.1” 等)
    • Request_URI, HTTP请求的URI,通常是scheme和host之后的,不包含查询字符串部分。
  3. 与请求关联的环境变量列表中的环境变量的名称。这允许SetEnvIf来测试前面的SetEnvIf匹配结果。所谓的“前面”意思是,更全局的设定(例如server-side),或相同scope但早于当前设定之前的SetEnvIf。只有当attribute未使用正则表达式并且请求特征之间不匹配时,才会将环境变量纳入考量。

regex就是正则表达式(regex)。如果正则匹配到了,后面的参数部分才会生效。

其他的部分就是变量的设定了,可选的设定模式有

扩展阅读:Apache HTTP 服务器中的环境变量

参考链接:

2.4 Alias

语法:Alias [URL-path] file-path|directory-path

将url映射到目录,提供了将文档储存在DocumentRoot之外的能力。

注意:其中本地目录的路径是区分大小写的,即使在系统不区分大小写的情况下。

Alias "/image" "/ftp/pub/image"

http://example.com/image/foo.gif的请求会返回/ftp/pub/image/foo.gif来响应。

只有完整的匹配到Alias的地址才生效,上例中的配置,http://example.com/imagefoo.gif这个请求不会被匹配。如果希望有更复杂的匹配规则,可以研究AliasMatch

需要注意的是,如果在匹配的url字符串末尾增加了/,那么服务器也需要增加/来扩展。

Alias "/icons/" "/usr/local/apache/icons/"

使用上面的配置,/icons就不会被匹配,因为它的末尾少了/。同样的,如果前面的url匹配字符串取消了/,后面的文件路径也需要去掉/

另外需要注意的是,如果Alias配置的目录是在DocumentRoot之外的,需要单独的设定Directory的权限。

Alias "/image" "/ftp/pub/image"
<Directory "/ftp/pub/image">
    Require all granted
</Directory>

如果在<Location><LocationMatch>中使用Alias,可以省略匹配字符串部分,而且目录路径遵循表达式语法。这种语法需要apache版本大于等于2.4.19。

<Location "/image">
    Alias "/ftp/pub/image"
</Location>
<LocationMatch "/error/(?<NUMBER>[0-9]+)">
    Alias "/usr/local/apache/errors/%{env:MATCH_NUMBER}.html"
</LocationMatch>

2.4 ScriptAlias

语法: ScriptAlias [URL-path] file-path|directory-path

Alias一样,其特殊之处在于,ScriptAlias的用途是其指向的目录是用于mod_cgi模块执行的CGI脚本的目录。

以下两种配置等效

ScriptAlias "/cgi-bin/" "/web/cgi-bin/"

Alias "/cgi-bin/" "/web/cgi-bin/"
<Location "/cgi-bin">
    SetHandler cgi-script
    Options +ExecCGI
</Location>

CGI脚本放在DocumentRoot之外会更安全,以免在配置发生更改时意外泄露其源代码。

Alias一样,如果在<Location><LocationMatch>中使用ScriptAlias,可以省略匹配字符串部分,而且目录路径遵循表达式语法。这种语法需要apache版本大于等于2.4.19。

<Location "/cgi-bin">
    ScriptAlias "/web/cgi-bin/"
</Location>
<LocationMatch "/cgi-bin/errors/(?<NUMBER>[0-9]+)">
    ScriptAlias "/web/cgi-bin/errors/%{env:MATCH_NUMBER}.cgi"
</LocationMatch>

3. 权限设定

3.1 目录权限

## 默认根目录,设置为拒绝
<Directory />
    AllowOverride none
    Require all denied
</Directory>

## 放开你希望用户可以访问的目录
<Directory "/usr/local/apache2/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

4. 如何同时监听80和443

apache是无法和nginx一样,同时监听80和443的,但是可以用下面的方式来达到节省配置项的效果 example.conf

<VirtualHost *:80>
    Include conf/site-enabled/example.include
</VirtualHost>

<VirtualHost *:443>
    SSLEngine on
    Include conf/site-enabled/example.include
</VirtualHost>

example.include

    ServerName example-ssl.com
    ServerAlias www.example-ssl.com *.example-ssl.com
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"
	DocumentRoot "/data/html"
	DirectoryIndex index.html index.php
    ErrorLog  "logs/example-ssl-error_log"
    CustomLog "logs/example-ssl-access_log" common

5. 关于apache使用的php.ini文件位置

如果想查看现在的php.ini位置,可以编写info.php文件,将其放置在DocumentRoot中,并在浏览器中访问查看。

<?php
  phpinfo();

如果想自定义修改php.ini的位置,可以在httpd.conf中做如下配置

PHPINIDir /usr/local/php/etc/apache2/

按照以上配置,apache会调用/usr/local/php/etc/apache2/php.ini