指南
Apache 一般代指的 Apache HTTP Server (官方文档)。Apache HTTP Server 是介于应用程序和用户之间的一个中间件系统。

Apache 在网站工作过程中,起着非常重要的作用。下面列出一些常见的设置场景,供用户参考
场景
域名绑定
当服务器上只有一个网站时,不做域名绑定也可以访问网站。但从安全和维护考量,域名绑定不可省却。
假设用户已经上传网站到服务器,那么域名绑定操作步骤如下:
- 确保域名解析已经生效
- 使用 WinSCP 等工具登录云服务器
- 修改 Apache虚拟机主机配置文件,将其中的 ServerName 项的值修改为你的域名
<VirtualHost *:80>
 ServerName www.mydomain.com # 此处修改为你的域名
 DocumentRoot "/data/wwwroot/mysite2"
 ...
- 保存配置文件,重启 Apache 服务
设置伪静态
使用和设置 Apache 伪静态有三个步骤:
- 打开 Apache模块配置文件,检查 Rewrite 模块是否启用(LAMP 环境默认已经开启 Rewirte)
- 保证 Apache 虚拟主机配置文件中 VirtualHost 配置段中增加 AllowOverride All
- 给需要使用伪静态的网站的根目录中增加.htaccess文件,并在其中配置伪静态规则
范例:重定向
- 开启Apache的rewrite模块
- 在网站根目录中增加.htaccess文件
<IfModule mod_rewrite.c>
RewriteEngine On
Redirect 301 "/empirecmsall-image-guide" "/xdocs/empirecms-image-guide"
Redirect 301 "/wordpress-image-guide" "/xdocs/wordpressold-image-guide"
</IfModule>
范例:隐藏后缀名
<IfModule mod_rewrite.c>
RewriteRule ^test$ test.php
ErrorDocument 404 /404.txt
</IfModule>
配置 Apache 使用不同端口访问网站
当服务有多个网站,但不想通过域名访问,可以配置 Apache 使用不同的端口访问不同的网站,步骤如下:
- 
确保在安全组中已放通相应端口 
- 
使用 WinSCP 等工具登录云服务器 
- 
修改 Apache虚拟机主机配置文件,修改虚拟主机 ** VirtualHost ** 端口号 <VirtualHost *:81>
 ServerName wordpress.example.com
 #ServerAlias example.com
 DocumentRoot "/data/wwwroot/web1"
 ErrorLog "logs/wordpress-error_log"
 CustomLog "logs/wordpress-access_log" common
 <Directory "/data/wwwroot/web1">
 Options Indexes FollowSymlinks
 AllowOverride All
 Require all granted
 </Directory>
 </VirtualHost>
 <VirtualHost *:82>
 ServerName wordpress.example.com
 #ServerAlias example.com
 DocumentRoot "/data/wwwroot/web2"
 ErrorLog "logs/wordpress-error_log"
 CustomLog "logs/wordpress-access_log" common
 <Directory "/data/wwwroot/web2">
 Options Indexes FollowSymlinks
 AllowOverride All
 Require all granted
 </Directory>
 </VirtualHost>
- 
保存配置文件,在 Apache 主配置文件 httpd.conf 中监听对应端口 #Listen 12.34.56.78:80
 Listen 80
 Listen 81
 Listen 82
- 
重启 Apache 服务 
Require 指令控制外部访问
Require 指令用于控制外部访问,下面是常见的场景:
<Directory xxx/www/yoursite>
 
    <RequireAll>
        # 允许所有
        Require all granted
        # 允许所有
        Require all granted
        # 仅允许本地
        Require local
        # 拒绝所有
        Require all denied
        # 只允许特需域名访问
        Require host google.com
        # 只允许特定 IP 段
        Require ip 192.120 192.168.100 192.168.1.1
    </RequireAll>
 
</Directory>
拒绝通过 IP 访问应用
编辑网站的 Apache 虚拟主机配置段为如下格式,其中 xxx.xxx.xxx.xxx 表示服务器 IP 地址
NameVirtualHost  xxx.xxx.xxx.xxx
<virtualhost  xxx.xxx.xxx.xxx:80>
ServerName   xxx.xxx.xxx.xxx
<Directory />
Order Allow,Deny
Deny from all
</Directory>
</virtualhost>
设置 Apache 并发连接数
有大量访问的时候速度很慢,或403错误后反复刷新才能访问等问题,可能是性能造成的。
一方面,需要提高服务器配置,另外一方面需要通过修改 Apache 并发参数以提升性能:
- 登录服务器后运行命令httpd -V,查询当前Apache的NPM工作模式httpd -V
 AH00558: httpd: Could not reliably determine the server's fully qualified domain name
 Server version: Apache/2.4.6 (CentOS)
 Server built: Aug 8 2019 11:41:18
 Server's Module Magic Number: 20120211:24
 Server loaded: APR 1.4.8, APR-UTIL 1.5.2
 Compiled using: APR 1.4.8, APR-UTIL 1.5.2
 Architecture: 64-bit
 Server MPM: prefork
 threaded: no
 forked: yes (variable process count)
- 修改 /etc/httpd/conf/httpd.conf,根据服务器配置的承载能力修改并发相关参数。比如:MaxClients 设置为2000,就可以处理2000个并发请求
<IfModule prefork.c>
 StartServers 5
 MinSpareServers 5
 MaxSpareServers 10
 MaxClients 256
 MaxRequestsPerChild 3000
 </IfModule>
HTTP 跳转 HTTPS
方案一:修改.htaccess文件
.htaccess文件提供了一种目录级别的修改配置的方式。
#任何情况下均强制跳转
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#指定域名下的自动跳转
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^yourdomain\.com [NC]
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]
#指定文件夹的自动跳转
RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteCond %{REQUEST_URI} folder 
RewriteRule ^(.*)$ https://www.yourdomain.com/folder/$1 [R,L]
方案二:修改vhost文件
要想开启自动跳转功能,请确保 Apache 的 Rewirte 模块加载,然后按照以下方案进行设置:
- 整站跳转
如果需要整站跳转,则在网站的配置文件(/etc/http/vhost/vhost.conf)的 <Directory> 标签内添加:
RewriteEngine on
 RewriteCond %{SERVER_PORT} !^443$
 RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [L,R=301]
- 只对某个目录的页面进行自动跳转,请将 yourfolder 改成自己的目录名
RewriteEngine on
 RewriteBase /yourfolder
 RewriteCond %{SERVER_PORT} !^443$
 #RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [L,R]
 RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
- 只将带 www 的 URL 跳转至 HTTPS,请将 www.yourdomain.com 改成自己想要设置跳转的域名
RewriteEngine On
 RewriteRule ^/(.*)$ www.yourdomain.com/$1 [R=301]
- 对除了某一个页面的其他所有页面进行 HTTPS 跳转
这段配置的作用是指除了 /tz.php 页面用 http 访问,其他页面均为 https 访问,/tz.php 可改为自己实际要 http 访问的后缀。RewriteEngine on
 RewriteCond %{SERVER_PORT} !^443$
 RewriteCond %{REQUEST_URI} !^/tz.php
 RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]
设置网站默认首页
默认访问网站目录时,系统会自动根据顺序寻找列出的页面,并显示其中一个。
<VirtualHost *:80>
ServerName win.websoft9.com
<IfModule dir_module>
  DirectoryIndex index.hmtl defalut.html README.html readme.html about.html
</IfModule>
DocumentRoot "/data/wwwroot/default/site"
...
设置缓存,提升性能
Apache HTTP 服务器提供了一系列缓存功能,这些缓存功能旨在以各种方式提高服务器的性能。
详情参考官方文档:缓存指南
安全防护
大多数情况下,Web服务器受到威胁,并不是因为HTTP Server代码中的问题。而是来自附加代码,CGI脚本或基础操作系统的问题。因此,您必须始终注意系统上所有软件的问题和更新。
DoS攻击防护
最有效的反DoS工具通常是防火墙或其他操作系统配置。例如,大多数防火墙可以配置为限制来自任何单个IP地址或网络的同时连接数,从而防止一系列简单的攻击。当然,这对分布式拒绝服务攻击(DDoS)没有帮助。
但Apache HTTP Server配置设置可以帮助缓解问题:
- RequestReadTimeout
- TimeOut
- KeepAliveTimeout
- MaxRequestWorkers
关闭 Apache Test Page
使用 # 号将: /etc/httpd/conf.d/welcome.conf 中的所 有内容全部注释掉,然后重启 Apache 服务
关闭缺省情况目录列表可查看
Apache httpd 服务器在缺省的情况下,开启了基于目录列表的访问,这是一个存在安全隐患的问题,因此可以关闭这个功能。
连接程序语言环境
Apache可以作为常见的开发语言的 Web 服务器,集成数据库、应用容器,最后形成一个完整的应用运行环境,例如:Apache+PHP,Apache+Tomcat+Java等
下面我们以常见的开发语言为例,分别介绍它们是如何与Apache一起工作的。
PHP
Apache被广泛用于PHP环境,Apache有两种PHP处理机制:
- php-fpm:PHP内核中用来处理PHP文件的解释器和进程管理器
- mod_php:Apache的PHP处理模块
mod_php 作为Apache的模块,没有独立的进程,无需额外设置和处理,使用起来非常简单。
PHP-FPM(PHP FastCGI Process Manager)意:PHP FastCGI 进程管理器,用于管理PHP 进程池的软件,用于接受Apache HTTP Server等Web服务器的请求。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置。
下面是Apache+PHP-FPM共同工作的系统架构图,其中mod_proxy_fcgi用于Apache连接php-fpm

接下来我们将以 php-fpm 转换成 mod_php 为范例,介绍如何作出相应的配置:
- 使用 SFTP 工具修改 /etc/httpd/conf.d/php.conf (如果该目录下有php.conf的备份文件,直接复制内容到php.conf)
#
# The following lines prevent .user.ini files from being viewed by Web clients.
#
<Files ".user.ini">
    <IfModule mod_authz_core.c>
        Require all denied
    </IfModule>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Deny from all
        Satisfy All
    </IfModule>
</Files>
#
# Allow php to handle Multiviews
#
AddType text/html .php
#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php
# mod_php options
<IfModule  mod_php7.c>
    #
    # Cause the PHP interpreter to handle files with a .php extension.
    #
    <FilesMatch \.(php|phar)$>
        SetHandler application/x-httpd-php
    </FilesMatch>
    #
    # Uncomment the following lines to allow PHP to pretty-print .phps
    # files as PHP source code:
    #
    #<FilesMatch \.phps$>
    #    SetHandler application/x-httpd-php-source
    #</FilesMatch>
    #
    # Apache specific PHP configuration options
    # those can be override in each configured vhost
    #
    php_value session.save_handler "files"
    php_value session.save_path    "/var/lib/php/session"
    php_value soap.wsdl_cache_dir  "/var/lib/php/wsdlcache"
    #php_value opcache.file_cache   "/var/lib/php/opcache"
</IfModule>
- 
停止 PHP-FPM 服务 
- 
保存并重启 Apache 服务 
Java
Apache HTTP Server 无法直接运行Java程序,而是与Tomcat一起组合去部署Java程序。
这种组合下,Apache处理静态资源,JSP等动态程序需转发给Tomcat处理,然后返回给用户。
Apache HTTP Server 与 Tomcat 最 常见的连接方式是http_proxy,即利用 Apache 自带的 mod_proxy 模块使用代理技术来连接 Tomcat。
http_proxy 模式是基于 HTTP 协议的代理,因此它要求 Tomcat 必须提供 HTTP 服务,也就是说必须启用 Tomcat 的 HTTP Connector。一个最简单的配置如下:
ProxyPass /images !
ProxyPass /css !
ProxyPass /js !
ProxyPass / http://localhost:8080/
更多请参考:《Apache HTTP Server 与 Tomcat 的三种连接方式介绍》
Python
Apache HTTP Server 也可以用于Python环境,通过扩展模块mod_proxy_uwsgi,连接Python的uWSGI服务器或Gunicorn服务器,便可以解析Python程序。
这种组合的的基本配置方法如下:
- 配置为uwsgi.ini
[uwsgi]
 chdir = /home/vagrant/myweb/
 virtualenv = /home/vagrant/env/
 socket = 127.0.0.1:8080
 env = DJANGO_SETTINGS_MODULE=myweb.settings
 module =myweb.wsgi:application
 master = true
 processes = 4
 vacuum = True
 max-requests = 5000
 daemonize = /var/log/uwsgi.log
 pidfile = /var/log/uwsgi.pid
- apache的配置文件加载mod_proxy_uwsgi.so
- apache的配置文件反向代理到uwsgi
ProxyPass / uwsgi://127.0.0.1:8080
Node.js
Apache HTTP Server 也可以用于Node.js环境,Apache HTTP Server 与 Node.js 最常见的连接方式是http_proxy,即利用 Apache 自带的 mod_proxy 模块使用代理技术来连接 Node.js。
下面是典型的配置文件范例:
server {
        listen 80 default_server;
        server_name _;
        location / {
         proxy_pass http://127.0.0.1:2368;
         proxy_set_header Host $host;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}
故障排除
Apache 报错:You don't have permission to access/on this server
解决办法:
- 检查网站目录的权限
- 配置虚拟主机配置文件是否有 "AllowOverride All Require all granted" 相关内容
Apache 频繁 403 错误?
403错误是一种在网站访问过程中的错误提示,表示禁止访问或拒绝服务。出现403错误,情况有两种:
- 服务器被动的受到人为饱和的DoS或DDoS恶意攻击,导致服务器无法提供正常的服务
- 服务器的主动防御措施(Apache 的 mod_evasive 模块),当某个 IP 短时间连续向服务器发送请求,服务器启动DoS防御策略,利用预设的规则主动拒绝向某个IP提服务
重启 Apache 服务显示 No spaces...
出现此信息的时候,重启服务是成功的。
解决方案:
echo "fs.inotify.max_user_watches=262144" >> /etc/sysctl.conf 
sysctl -p
命令 httpd -t 报错 [so:warn] [pid 14645] AH01574: module ssl_module is already loaded
问题原因:mod_ssl 重复加载
解决方案:检查下面两个文件,找到 mod_ssl 字段,注释其中一个
- /etc/httpd/conf.modules.d/00-base.conf
- /etc/httpd/conf.modules.d/00-ssl.conf
参数
路径
不同的Linux发行版,对应的安装路径有一定的差异:
CentOS/RedHat
Apache 安装目录:/etc/httpd
Apache 虚拟主机配置文件:/etc/httpd/conf.d/vhost.conf
Apache 主配置文件: /etc/httpd/conf/httpd.conf
Apache 日志文件: /var/log/httpd
Apache 模块配置文件: /etc/httpd/conf.modules.d/00-base.conf
Ubuntu/Debian
Apache 安装目录:/etc/apache2
Apache 虚拟主机配置文件:/etc/apache2/sites-available/000-default.conf
Apache 主配置文件: /etc/apache2/apache2.conf
Apache 日志文件: /var/log/apache2
Apache 模块目录: /etc/apache2/mods-available
命令行
Apache HTTP 服务器包含的所有命令行(可执行程序)如下:
| 命 令 | 说明 | 
|---|---|
| httpd | Apache 服务器 | 
| apachectl | Apache HTTP 服务器控制工具。 | 
| ab | Apache HTTP 服务器性能基准工具。 | 
| apxs | Apache 扩展工具。 | 
| configure | 配置源代码。 | 
| dbmmanage | 为基本认证创建和更新 DBM 格式的用户认证文件。 | 
| fcgistarter | 启动 FastCGI 程序。 | 
| htcacheclean | 清理磁盘缓存。 | 
| htdigest | 为摘要认证创建和更新用户认证文件。 | 
| htdbm | 操作 DBM 密码数据库。 | 
| htpasswd | 为基本认证创建和更新用户认证文件。 | 
| httxt2dbm | 为 RewriteMap 创建 dbm 文件。 | 
| logresolve | 将 Apache 日志文件中的 IP 地址解析到主机名称。 | 
| log_server_status | 周期性的记录服务器状态。 | 
| rotatelogs | 不关闭 Apache 而切换日志文件。 | 
| split-logfile | 将多个虚拟主机的日志文件按照主机拆分。 | 
| suexec | 执行外部程序前切换用户。 | 
服务启停
以 httpd 服务为例,在不同的操作系统启用如下:
#CentOS/Redhat/Fedora
sudo systemctl start httpd
sudo systemctl stop httpd
sudo systemctl restart httpd
sudo systemctl status httpd
# Ubutnu/Debian
sudo systemctl start apache2
sudo systemctl stop apache2
sudo systemctl restart apache2
sudo systemctl status apache2
# Docker
sudo docker start apache
sudo docker stop apache
sudo docker restart apache
sudo docker stats apache
VirtualHost 模板
Apache中的虚拟主机是通过 VirtualHost 进行配置的,下表是 VirtualHost 核心参数:
| VirtualHost 项 | 作用说明 | 必要性 | 
|---|---|---|
| ServerName | 主域名 | 必须填写 | 
| ServerAlias | 辅域名 | 可以不填或删除 | 
| DocumentRoot | 网站存放目录,同下 | 务必准确无误 | 
| Directory | 网站存放目录,同上 | 务必准确无误 | 
| ErrorLog | 错误日志路径,系统会根据定义的路径产生相关日志文件 | 可以不填或删除 | 
| CustomLog | 访问日志路径,系统会根据定义的路径产生相关日志文件 | 可以不填或删除 | 
下面是常见的 VirtualHost 模板,适用于各种 Apache 应用场景:
HTTP VirtualHost 标准模板
<VirtualHost *:80>
ServerName www.mydomain.com
ServerAlias other.mydomain.com
DocumentRoot "/data/wwwroot/zdoo"
ErrorLog "/var/log/httpd/www.mydomain.com_error_apache.log"
CustomLog "/var/log/httpd/www.mydomain.com_apache.log" common
<Directory "/data/wwwroot/zdoo">
Options Indexes FollowSymlinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
HTTP Alias 模板
Alias /path /data/wwwroot/zdoo
<Directory "/data/wwwroot/zdoo">
Options Indexes FollowSymlinks
AllowOverride All
Require all granted
</Directory>
HTTP Proxy 模板
下面是一个包含了 Proxy 的虚拟主机配置文件,其中应用程序运行在8069端口,通过转发配置域名访问。
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.localhost
ServerName youdomain.com
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://172.21.172.27:8069/
ProxyPassReverse / http://172.21.172.27:8069/
</VirtualHost>
HTTPS VirtualHost 模板
<VirtualHost *:443>
ServerName  www.mydomain.com
DocumentRoot "/data/wwwroot/zdoo"
#ErrorLog "logs/www.mydomain.com-error_log"
#CustomLog "logs/www.mydomain.com-access_log" common
<Directory "/data/wwwroot/zdoo">
Options Indexes FollowSymlinks
AllowOverride All
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile  /data/cert/www.mydomain.com.crt
SSLCertificateKeyFile  /data/cert/www.mydomain.com.key
SSLCertificateChainFile  /data/cert/root_bundle.crt
</VirtualHost>