Apache

  1. 1. Apache 概述
  2. 2. 安装 Apache
    1. 2.1. Linux (Ubuntu/Debian)
    2. 2.2. Linux (CentOS/RHEL)
    3. 2.3. macOS
  3. 3. 目录结构
    1. 3.1. Ubuntu/Debian
    2. 3.2. CentOS/RHEL
  4. 4. 基本配置
    1. 4.1. 主配置文件 (apache2.conf / httpd.conf)
    2. 4.2. 虚拟主机配置
    3. 4.3. SSL/HTTPS 配置
  5. 5. 常用模块
    1. 5.1. mod_rewrite (URL 重写)
    2. 5.2. mod_headers (HTTP 头控制)
    3. 5.3. mod_deflate (压缩)
    4. 5.4. mod_expires (缓存控制)
  6. 6. .htaccess 文件
    1. 6.1. 启用 .htaccess
    2. 6.2. 常用 .htaccess 配置
  7. 7. 性能优化
    1. 7.1. 启用 MPM (多处理模块)
    2. 7.2. 启用 HTTP/2
    3. 7.3. 连接保持
  8. 8. 日志管理
    1. 8.1. 日志格式
    2. 8.2. 日志轮转 (logrotate)
  9. 9. 安全加固
  10. 10. 常用命令
  11. 11. 总结核心知识要点
    1. 11.1. Apache 架构
    2. 11.2. 核心配置示例
      1. 11.2.1. 1. 完整虚拟主机配置
      2. 11.2.2. 2. HTTPS 虚拟主机 (Let’s Encrypt)
      3. 11.2.3. 3. 反向代理配置
      4. 11.2.4. 4. 负载均衡配置
      5. 11.2.5. 5. .htaccess 完整示例
    3. 11.3. 重要指令对比
    4. 11.4. MPM 模式选择
    5. 11.5. 性能优化清单
    6. 11.6. 常见问题排查
    7. 11.7. 最佳实践
    8. 11.8. 核心概念
  12. 12. References

Apache HTTP Server is a free and open-source cross-platform web server software, released under the terms of Apache License 2.0.

Apache 概述

Apache HTTP Server(简称 Apache)是世界上最流行的 Web 服务器软件之一,由 Apache 软件基金会维护。Apache 的特点包括:

  • 开源免费: 使用 Apache License 2.0
  • 跨平台: 支持 Unix/Linux、Windows、macOS 等
  • 模块化架构: 通过模块扩展功能
  • 高度可配置: 灵活的配置系统
  • 稳定可靠: 经过数十年的发展和验证

安装 Apache

Linux (Ubuntu/Debian)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 更新包索引
sudo apt update

# 安装 Apache
sudo apt install apache2

# 启动 Apache
sudo systemctl start apache2

# 设置开机自启
sudo systemctl enable apache2

# 检查状态
sudo systemctl status apache2

# 检查版本
apache2 -v

Linux (CentOS/RHEL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装 Apache
sudo yum install httpd

# 启动 Apache
sudo systemctl start httpd

# 设置开机自启
sudo systemctl enable httpd

# 检查状态
sudo systemctl status httpd

# 检查版本
httpd -v

macOS

1
2
3
4
5
6
7
8
# 使用 Homebrew 安装
brew install httpd

# 启动 Apache
brew services start httpd

# 检查版本
httpd -v

目录结构

Ubuntu/Debian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/etc/apache2/
├── apache2.conf # 主配置文件
├── ports.conf # 端口配置
├── sites-available/ # 可用的虚拟主机配置
│ └── 000-default.conf
├── sites-enabled/ # 已启用的虚拟主机(符号链接)
├── mods-available/ # 可用的模块
├── mods-enabled/ # 已启用的模块(符号链接)
├── conf-available/ # 可用的配置片段
└── conf-enabled/ # 已启用的配置片段

/var/www/html/ # 默认网站根目录
/var/log/apache2/ # 日志目录
├── access.log # 访问日志
└── error.log # 错误日志

CentOS/RHEL

1
2
3
4
5
6
7
8
9
10
11
/etc/httpd/
├── conf/
│ └── httpd.conf # 主配置文件
├── conf.d/ # 额外配置文件
├── conf.modules.d/ # 模块配置
└── logs -> /var/log/httpd/ # 日志目录(符号链接)

/var/www/html/ # 默认网站根目录
/var/log/httpd/ # 日志目录
├── access_log
└── error_log

基本配置

主配置文件 (apache2.conf / httpd.conf)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 服务器根目录
ServerRoot "/etc/apache2"

# 监听端口
Listen 80

# 加载模块
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule ssl_module modules/mod_ssl.so

# 服务器管理员邮箱
ServerAdmin admin@example.com

# 服务器名称
ServerName www.example.com:80

# 文档根目录
DocumentRoot "/var/www/html"

# 目录权限配置
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

# 日志配置
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# 默认字符集
AddDefaultCharset UTF-8

虚拟主机配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 基于域名的虚拟主机
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html

<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

# 基于 IP 的虚拟主机
<VirtualHost 192.168.1.100:80>
ServerName site1.example.com
DocumentRoot /var/www/site1
</VirtualHost>

# 基于端口的虚拟主机
<VirtualHost *:8080>
ServerName example.com
DocumentRoot /var/www/site2
</VirtualHost>

SSL/HTTPS 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 监听 443 端口
Listen 443

<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com/public_html

# 启用 SSL
SSLEngine on

# SSL 证书
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
SSLCertificateChainFile /etc/ssl/certs/ca-bundle.crt

# SSL 协议和加密套件
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5

<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

# HTTP 重定向到 HTTPS
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>

常用模块

mod_rewrite (URL 重写)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 启用模块
sudo a2enmod rewrite # Ubuntu/Debian
# 或在配置文件中
LoadModule rewrite_module modules/mod_rewrite.so

# .htaccess 示例
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# 强制 HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# 移除 www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

# 隐藏 .php 扩展名
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

# 前端路由(单页应用)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L]
</IfModule>

mod_headers (HTTP 头控制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 启用模块
sudo a2enmod headers

# 安全响应头
<IfModule mod_headers.c>
# HSTS (强制 HTTPS)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# XSS 保护
Header set X-XSS-Protection "1; mode=block"

# 防止 MIME 类型嗅探
Header set X-Content-Type-Options "nosniff"

# 点击劫持保护
Header set X-Frame-Options "SAMEORIGIN"

# CSP (内容安全策略)
Header set Content-Security-Policy "default-src 'self';"

# CORS (跨域资源共享)
Header set Access-Control-Allow-Origin "*"
</IfModule>

mod_deflate (压缩)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 启用模块
sudo a2enmod deflate

# 压缩配置
<IfModule mod_deflate.c>
# 压缩文本类型文件
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
AddOutputFilterByType DEFLATE application/json

# 排除旧浏览器
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>

mod_expires (缓存控制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 启用模块
sudo a2enmod expires

# 缓存配置
<IfModule mod_expires.c>
ExpiresActive On

# 默认过期时间
ExpiresDefault "access plus 1 month"

# 图片
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"

# CSS 和 JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"

# HTML
ExpiresByType text/html "access plus 0 seconds"
</IfModule>

.htaccess 文件

.htaccess 是 Apache 的分布式配置文件,允许在目录级别覆盖服务器配置。

启用 .htaccess

1
2
3
4
# 在虚拟主机或目录配置中
<Directory /var/www/html>
AllowOverride All
</Directory>

常用 .htaccess 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 自定义错误页面
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

# 目录索引
Options -Indexes

# 默认首页
DirectoryIndex index.html index.php home.html

# 密码保护目录
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user

# IP 访问控制
# 拒绝特定 IP
Require all granted
Require not ip 192.168.1.100

# 只允许特定 IP
Require ip 192.168.1.0/24

# 文件上传限制
php_value upload_max_filesize 20M
php_value post_max_size 20M

# 防盗链
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [F]

性能优化

启用 MPM (多处理模块)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看当前 MPM
apachectl -V | grep MPM

# 启用 event MPM (推荐用于高并发)
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

# event MPM 配置
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>

启用 HTTP/2

1
2
3
4
5
6
7
8
# 启用 HTTP/2 模块
sudo a2enmod http2

# 在虚拟主机中启用
<VirtualHost *:443>
Protocols h2 http/1.1
# ... 其他配置
</VirtualHost>

连接保持

1
2
3
4
# 启用持久连接
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

日志管理

日志格式

1
2
3
4
5
6
7
8
9
10
# 定义日志格式
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common

# 使用自定义格式
CustomLog ${APACHE_LOG_DIR}/access.log combined

# 条件日志
SetEnvIf Request_URI "^/health-check$" dontlog
CustomLog ${APACHE_LOG_DIR}/access.log combined env=!dontlog

日志轮转 (logrotate)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/logrotate.d/apache2
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}

安全加固

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 隐藏 Apache 版本信息
ServerTokens Prod
ServerSignature Off

# 禁止目录浏览
<Directory /var/www/html>
Options -Indexes
</Directory>

# 限制请求大小
LimitRequestBody 10485760

# 超时设置
Timeout 60

# 禁用不需要的 HTTP 方法
<Location />
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
</Location>

# 防止点文件访问
<FilesMatch "^\.">
Require all denied
</FilesMatch>

# 禁止访问敏感文件
<FilesMatch "(\.htaccess|\.htpasswd|\.git|\.env)">
Require all denied
</FilesMatch>

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 启动/停止/重启 Apache
sudo systemctl start apache2
sudo systemctl stop apache2
sudo systemctl restart apache2
sudo systemctl reload apache2 # 重载配置(不中断服务)

# 检查配置语法
sudo apachectl configtest
sudo apache2ctl -t

# 查看已加载的模块
apachectl -M
apache2ctl -M

# 启用/禁用模块 (Ubuntu/Debian)
sudo a2enmod rewrite
sudo a2dismod rewrite

# 启用/禁用站点 (Ubuntu/Debian)
sudo a2ensite example.com.conf
sudo a2dissite example.com.conf

# 查看虚拟主机配置
apachectl -S

# 实时查看日志
sudo tail -f /var/log/apache2/access.log
sudo tail -f /var/log/apache2/error.log

# 查看并发连接数
netstat -an | grep :80 | wc -l

总结核心知识要点

Apache 架构

  • MPM (多处理模块): prefork、worker、event 三种模式
  • 模块化设计: 核心功能 + 可选模块(mod_rewrite、mod_ssl 等)
  • 配置层级: 主配置 → 虚拟主机 → 目录 → .htaccess

核心配置示例

1. 完整虚拟主机配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin admin@example.com
DocumentRoot /var/www/example.com

<Directory /var/www/example.com>
Options -Indexes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>

# 自定义日志
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

# 环境变量
SetEnv APPLICATION_ENV production
</VirtualHost>

2. HTTPS 虚拟主机 (Let’s Encrypt)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

# 现代 SSL 配置
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
SSLSessionTickets off

# HSTS
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>

3. 反向代理配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 启用模块
# a2enmod proxy proxy_http

<VirtualHost *:80>
ServerName api.example.com

ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/

# WebSocket 支持
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
</VirtualHost>

4. 负载均衡配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 启用模块
# a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests

<Proxy "balancer://mycluster">
BalancerMember http://192.168.1.101:8080
BalancerMember http://192.168.1.102:8080
BalancerMember http://192.168.1.103:8080
ProxySet lbmethod=byrequests
</Proxy>

<VirtualHost *:80>
ServerName lb.example.com
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>

5. .htaccess 完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 启用重写引擎
RewriteEngine On

# 强制 HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# 移除 www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [L,R=301]

# PHP 路由
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]

# 安全设置
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
</IfModule>

# 缓存控制
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>

# 压缩
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript
</IfModule>

重要指令对比

指令 作用 示例
DocumentRoot 网站根目录 DocumentRoot /var/www/html
ServerName 主域名 ServerName example.com
ServerAlias 域名别名 ServerAlias www.example.com
DirectoryIndex 默认首页 DirectoryIndex index.html index.php
AllowOverride .htaccess 权限 AllowOverride All
Options 目录选项 Options -Indexes +FollowSymLinks
Require 访问控制 Require all granted

MPM 模式选择

MPM 特点 适用场景
prefork 多进程,每进程一个线程 PHP (非线程安全)
worker 多进程 + 多线程 中等并发
event 异步事件驱动 高并发、HTTP/2

性能优化清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 启用压缩
sudo a2enmod deflate

# 2. 启用缓存
sudo a2enmod expires
sudo a2enmod headers

# 3. 启用 HTTP/2
sudo a2enmod http2

# 4. 使用 event MPM
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

# 5. 启用持久连接
KeepAlive On

# 6. 禁用不必要的模块
sudo a2dismod status
sudo a2dismod autoindex

常见问题排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 检查配置语法
sudo apachectl configtest

# 2. 查看错误日志
sudo tail -f /var/log/apache2/error.log

# 3. 检查端口占用
sudo netstat -tulpn | grep :80

# 4. 检查进程
ps aux | grep apache2

# 5. 测试虚拟主机配置
apachectl -S

# 6. 检查文件权限
ls -la /var/www/html/

# 7. 测试 URL 重写
curl -I http://example.com

最佳实践

  • 分离配置文件: 每个站点独立配置文件
  • 使用 SSL/TLS: 启用 HTTPS 和 HSTS
  • 定期更新: 保持 Apache 和模块最新版本
  • 日志管理: 配置日志轮转,避免磁盘占满
  • 安全加固: 隐藏版本信息,禁用不必要的模块
  • 性能监控: 使用 mod_status 监控服务器状态
  • 备份配置: 修改前备份配置文件

核心概念

  • 虚拟主机: 一台服务器托管多个网站
  • 模块系统: 动态加载功能模块
  • URL 重写: mod_rewrite 实现 URL 友好化
  • 反向代理: 将请求转发到后端服务器
  • 负载均衡: 分发请求到多个后端服务器

References