CentOS 7搭建Apache(httpd) web 服务器-静态

一、Apache 概述

Apache 核心特性

  • 跨平台:支持 Linux、Windows、BSD 等,CentOS 7 中默认以 httpd 服务运行;
  • 虚拟主机:支持基于域名、IP、端口的多站点部署,一台服务器可托管多个网站;
  • 模块扩展:通过动态模块(如 mod_rewrite 重写、mod_ssl 加密)扩展功能;
  • 安全稳定:运行于低权限 apache 用户,支持 SELinux 权限控制,减少系统风险。

二、安装 Apache(httpd)

CentOS 7 的官方软件仓库已包含 httpd,通过 yum 可一键安装,自动处理依赖关系。

1. 安装 httpd 包

1
2
3
4
5
# 1. 更新本地软件包索引(可选,确保安装最新版本)
sudo yum update -y httpd

# 2. 安装 httpd 及依赖(包含 Apache 核心服务)
sudo yum install -y httpd

2. 验证安装结果

1
2
3
4
5
6
7
# 查看 httpd 版本
httpd -v
# 输出示例:Server version: Apache/2.4.6 (CentOS)

# 查看 Apache 运行用户与组(安装后自动创建 `apache` 用户/组)
grep apache /etc/passwd # 输出:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
grep apache /etc/group # 输出:apache:x:48:
  • apache 用户的 shell 为 /sbin/nologin,仅用于运行服务,无法登录系统,提升安全性。

三、Apache 服务管理

通过 systemctl 命令管理 httpd 服务,核心操作包括启动、停止、重启、设置开机自启等,需区分“重启”与“重载”的差异(重载不中断现有连接)。

1. 基础服务命令

功能描述 命令 说明
启动服务 sudo systemctl start httpd 首次启动或服务停止后启动
停止服务 sudo systemctl stop httpd 停止服务,中断所有连接
重启服务 sudo systemctl restart httpd 停止后重新启动,会中断现有连接(配置文件重大修改时使用)
重载配置 sudo systemctl reload httpd 不中断连接,仅加载新配置(如虚拟主机、日志路径修改,推荐优先使用)
开机自启 sudo systemctl enable httpd --now --now 表示立即启动并设置开机自启
禁止开机自启 sudo systemctl disable httpd 取消开机自启,需手动启动服务
查看服务状态 sudo systemctl status httpd 查看是否运行(active (running) 为正常)、PID、启动日志

2. 测试配置语法(关键!)

修改任何配置文件后,必须先测试语法,避免错误导致服务启动失败:

1
2
3
# 测试 Apache 配置语法
sudo apachectl configtest
# 输出 `Syntax OK` 表示配置无错;若报错,按提示修改对应文件(如行号、指令错误)

四、Apache 核心配置文件详解

Apache 的配置文件采用“主配置+分文件”结构,核心目录与文件如下:

路径 作用描述
/etc/httpd/conf/httpd.conf 主配置文件,定义全局参数(如监听端口、运行用户、默认根目录)
/etc/httpd/conf.d/ 额外配置目录,存放虚拟主机、模块加载等 .conf 文件(自动加载所有 .conf
/etc/httpd/conf.modules.d/ 模块配置目录,定义加载的 Apache 模块(如 mod_phpmod_ssl
/var/www/html/ 默认网站根目录(DocumentRoot),存放静态页面(如 index.html
/var/log/httpd/ 日志目录,包含 access_log(访问日志)和 error_log(错误日志)

1. 主配置文件 httpd.conf 核心指令

先备份默认配置文件,避免修改错误后无法恢复:

1
sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak

编辑主配置文件 sudo vi /etc/httpd/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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# -------------------------- 1. 全局基础配置 --------------------------
# Apache 安装根目录(所有配置文件的相对路径基于此)
ServerRoot "/etc/httpd"

# 监听端口(默认 80,HTTP 协议;HTTPS 需后续配置 443 端口)
Listen 80

# Apache 运行的用户与组(低权限用户,避免系统风险)
User apache
Group apache

# 管理员邮箱(错误页面会显示此邮箱,便于用户反馈)
ServerAdmin webmaster@example.com

# 服务器名称(消除启动时的“无法确定域名”警告,填写域名或服务器 IP)
ServerName www.example.com:80 # 若无域名,可填服务器 IP:80(如 192.168.1.100:80


# -------------------------- 2. 目录权限控制(<Directory> 块) --------------------------
# 根目录(/)权限:拒绝所有访问,防止 Apache 泄露系统文件
<Directory />
AllowOverride None # 不允许 .htaccess 文件覆盖配置(安全)
Require all denied # 拒绝所有用户访问
</Directory>

# 默认网站根目录(/var/www)权限:允许所有访问
<Directory "/var/www">
AllowOverride None # 不启用 .htaccess
Require all granted # 允许所有用户访问
</Directory>

# 具体网站根目录(/var/www/html)权限:支持目录索引和符号链接
<Directory "/var/www/html">
# Options:目录行为控制
# Indexes:若目录无 index.html,显示文件列表;
# FollowSymLinks:允许 Apache 跟随目录内的符号链接
Options Indexes FollowSymLinks

AllowOverride None # 后续若需 .htaccess,可改为 All(需配合 mod_rewrite)
Require all granted # 允许所有访问
</Directory>


# -------------------------- 3. 网站根目录与默认页面 --------------------------
# 网站根目录(默认存放静态页面的路径)
DocumentRoot "/var/www/html"

# 默认首页(访问目录时优先加载的文件,顺序从左到右)
<IfModule dir_module>
DirectoryIndex index.html index.php # 先找 index.html,再找 index.php(动态页面后续添加)
</IfModule>


# -------------------------- 4. 日志配置 --------------------------
# 错误日志路径(记录服务错误,如启动失败、访问不存在的页面)
ErrorLog "logs/error_log" # 相对路径,实际为 /var/log/httpd/error_log

# 日志级别(warn:警告及以上错误;debug:调试信息,生产环境不推荐)
LogLevel warn

# 访问日志配置(记录所有客户端访问,格式为 "combined")
# combined 格式包含:客户端 IP、访问时间、请求方法、状态码、Referer、User-Agent 等
CustomLog "logs/access_log" combined # 实际路径 /var/log/httpd/access_log


# -------------------------- 5. 加载额外配置文件 --------------------------
# 加载模块配置(如 PHP 模块、SSL 模块)
Include conf.modules.d/*.conf

# 加载额外配置(如虚拟主机配置,存于 /etc/httpd/conf.d/ 目录)
IncludeOptional conf.d/*.conf # IncludeOptional:文件不存在时不报错

2. 验证默认站点

启动 httpd 服务后,访问默认网站根目录 /var/www/html,验证基础功能:

1
2
3
4
5
6
7
8
# 1. 启动 httpd 服务
sudo systemctl start httpd

# 2. 在默认目录创建测试页面
echo "<h1>Apache Default Page (CentOS 7)</h1>" | sudo tee /var/www/html/index.html

# 3. 本地测试(服务器上执行,或客户端浏览器访问服务器 IP)
curl http://localhost # 输出:<h1>Apache Default Page (CentOS 7)</h1>

客户端浏览器输入 http://服务器IP(如 http://192.168.1.100),应显示测试页面,说明 Apache 基础功能正常。

五、防火墙与 SELinux 配置(关键!避免访问被拦截)

CentOS 7 默认启用 firewalld 防火墙和 SELinux 安全机制,若不配置,客户端将无法访问 Apache 服务。

1. 防火墙配置(开放 HTTP/HTTPS 端口)

HTTP 协议默认使用 80 端口,HTTPS 用 443 端口,通过 firewalld 永久开放:

1
2
3
4
5
6
7
8
9
# 1. 永久开放 HTTP(80)和 HTTPS(443)服务
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https

# 2. 重新加载防火墙规则,使配置生效
sudo firewall-cmd --reload

# 3. 验证开放的服务(输出应包含 http 和 https)
sudo firewall-cmd --list-services

2. SELinux 配置(允许 Apache 访问目录和日志)

SELinux 是 CentOS 7 的强制访问控制机制,默认会拦截 Apache 对自定义目录(如虚拟主机目录)的访问,需通过 semanagerestorecon 配置安全上下文。

(1)SELinux 状态查看与临时调整

1
2
3
4
5
# 查看 SELinux 状态(Enforcing:启用;Permissive:宽容模式;Disabled:关闭)
getenforce # 默认输出 Enforcing

# 临时切换为宽容模式(测试用,重启后失效)
sudo setenforce 0 # 输出 Permissive

不推荐永久关闭 SELinux(会降低系统安全性),建议通过上下文配置解决权限问题。

(2)目录安全上下文配置(以虚拟主机目录为例)

若后续创建虚拟主机目录 /var/www/example.com/html 和日志目录 /var/www/example.com/log,需设置 SELinux 上下文:

  • httpd_sys_content_t:Apache 可读取的静态文件目录上下文;
  • httpd_log_t:Apache 可写入的日志目录上下文。

配置命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 为网站根目录设置 httpd_sys_content_t 上下文(允许读取)
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com/html(/.*)?"

# 2. 为日志目录设置 httpd_log_t 上下文(允许写入)
sudo semanage fcontext -a -t httpd_log_t "/var/www/example.com/log(/.*)?"

# 3. 应用上下文配置(-R:递归处理子目录;-v:显示修改过程)
sudo restorecon -Rv /var/www/example.com/html
sudo restorecon -Rv /var/www/example.com/log

# 4. 验证上下文(输出应包含 httpd_sys_content_t 或 httpd_log_t)
ls -dZ /var/www/example.com/html
ls -dZ /var/www/example.com/log

(3)全局 SELinux 布尔值(可选,简化配置)

若需快速允许 Apache 访问所有目录(适合测试环境,生产环境不推荐),可设置 httpd_unified 布尔值:

1
2
# 永久允许 Apache 统一权限(-P:重启后生效)
sudo setsebool -P httpd_unified 1

六、虚拟主机配置(多站点部署核心)

虚拟主机(Virtual Host)允许一台服务器托管多个网站,通过 ServerName(域名)区分不同站点。CentOS 7 推荐两种配置方式:conf.d 目录直接创建配置文件(简单),或 sites-available/sites-enabled 软链接(规范,便于管理)。

1. 方案 1:conf.d 目录直接配置

以部署两个站点为例:

  • 站点 1:www.example.com(默认站点,公网访问);
  • 站点 2:slackware.local(本地测试站点,仅局域网访问)。

(1)创建站点目录与测试页面

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 站点 1:www.example.com(公网)
sudo mkdir -p /var/www/example.com/{html,log} # html:页面目录;log:日志目录
sudo echo "<h1>Welcome to www.example.com (Public Site)</h1>" | sudo tee /var/www/example.com/html/index.html

# 2. 站点 2:slackware.local(本地)
sudo mkdir -p /var/www/slackware.local/{html,log}
sudo echo "<h1>Welcome to slackware.local (Local Site)</h1>" | sudo tee /var/www/slackware.local/html/index.html

# 3. 设置目录权限(非 root 用户可管理页面,Apache 有读写权限)
sudo chown -R your_username:your_username /var/www/example.com /var/www/slackware.local
sudo chmod -R 755 /var/www/ # 目录权限 755(用户读写执行,其他只读执行)
sudo chmod -R 644 /var/www/*/html/* # 文件权限 644(用户读写,其他只读)

替换 your_username 为你的 sudo 用户名(如 centos)。

(2)创建虚拟主机配置文件

配置站点 1:www.example.com(公网)
1
sudo vi /etc/httpd/conf.d/example.com.conf

添加以下内容(带详细解释):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 虚拟主机监听所有 IP 的 80 端口(*:80 表示不限制 IP)
<VirtualHost *:80>
# 主域名(必须与 DNS 解析一致,如 www.example.com)
ServerName www.example.com
# 域名别名(如 example.com,用户访问 example.com 也会指向此站点)
ServerAlias example.com
# 网站根目录(页面存放路径)
DocumentRoot "/var/www/example.com/html"
# 管理员邮箱(错误页面显示)
ServerAdmin webmaster@example.com

# 错误日志路径(记录此站点的错误,如 404 页面不存在)
ErrorLog "/var/www/example.com/log/error.log"
# 访问日志路径(记录此站点的所有访问,格式为 combined)
CustomLog "/var/www/example.com/log/access.log" combined

# 目录权限控制(针对 DocumentRoot)
<Directory "/var/www/example.com/html">
Options Indexes FollowSymLinks # 允许目录索引、跟随符号链接
AllowOverride None # 不启用 .htaccess(如需 URL 重写,后续改为 All
Require all granted # 允许所有用户访问(公网站点需开放)
</Directory>
</VirtualHost>
配置站点 2:slackware.local(本地)
1
sudo vi /etc/httpd/conf.d/slackware.local.conf

添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<VirtualHost *:80>
ServerName slackware.local # 本地域名(无需公网解析)
ServerAlias slackware # 别名(简化访问)
DocumentRoot "/var/www/slackware.local/html"
ServerAdmin webmaster@local

ErrorLog "/var/www/slackware.local/log/error.log"
CustomLog "/var/www/slackware.local/log/access.log" common # common 格式:仅基础访问信息

<Directory "/var/www/slackware.local/html">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted # 允许局域网用户访问
</Directory>
</VirtualHost>

(3)本地测试站点的域名解析(关键!)

本地站点 slackware.local 无公网 DNS 解析,需在客户端电脑hosts 文件中添加映射(服务器 IP + 本地域名):

  • Windows:编辑 C:\Windows\System32\drivers\etc\hosts,添加:
    1
    192.168.1.100  slackware.local  # 替换为你的服务器内网 IP
  • Linux/macOS:编辑 /etc/hosts,添加同上内容。

(4)生效配置并测试

1
2
3
4
5
6
7
8
9
# 1. 测试配置语法
sudo apachectl configtest # 输出 Syntax OK

# 2. 重载 Apache 服务(不中断连接)
sudo systemctl reload httpd

# 3. 测试访问(服务器本地或客户端)
curl http://www.example.com # 输出公网站点页面
curl http://slackware.local # 输出本地站点页面

2. 方案 2:sites-available/sites-enabled 软链接(规范方案)

此方案将“待启用”和“已启用”的虚拟主机分离,便于管理(如临时禁用站点只需删除软链接),步骤如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 创建 sites-available 和 sites-enabled 目录
sudo mkdir -p /etc/httpd/{sites-available,sites-enabled}

# 2. 在主配置文件中添加加载 sites-enabled 目录的指令
sudo echo "IncludeOptional sites-enabled/*.conf" >> /etc/httpd/conf/httpd.conf

# 3. 将虚拟主机配置文件放入 sites-available(以 example.com 为例)
sudo mv /etc/httpd/conf.d/example.com.conf /etc/httpd/sites-available/

# 4. 创建软链接,启用站点(sites-enabled 中的文件为软链接)
sudo ln -s /etc/httpd/sites-available/example.com.conf /etc/httpd/sites-enabled/

# 5. 重载服务生效
sudo systemctl reload httpd

# 禁用站点:删除软链接即可(不删除原配置文件)
# sudo rm /etc/httpd/sites-enabled/example.com.conf

3. 基于IP的虚拟主机配置

当服务器有多个IP地址时,可以为每个IP地址分配不同的网站。

(1)查看服务器IP地址

1
2
3
4
# 查看所有网络接口和IP
ip addr show
# 或使用
ifconfig

假设服务器有两个IP:

  • 192.168.1.100 - 主IP
  • 192.168.1.101 - 附加IP

(2)创建站点目录和测试页面

1
2
3
# 为 IP 192.168.1.101 创建站点
sudo mkdir -p /var/www/ip-site/{html,log}
sudo echo "<h1>Welcome to IP-based Site (192.168.1.101)</h1>" | sudo tee /var/www/ip-site/html/index.html

(3)基于IP的虚拟主机配置

1
sudo vi /etc/httpd/conf.d/ip-based.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 基于IP的虚拟主机配置
<VirtualHost 192.168.1.101:80>
# 服务器名称(可省略或使用任意名称)
ServerName ip-based-site
# 网站根目录
DocumentRoot "/var/www/ip-site/html"
# 管理员邮箱
ServerAdmin admin@ip-site.com

# 错误日志和访问日志
ErrorLog "/var/www/ip-site/log/error.log"
CustomLog "/var/www/ip-site/log/access.log" combined

# 目录权限控制
<Directory "/var/www/ip-site/html">
Options -Indexes +FollowSymLinks # 禁用目录索引,启用符号链接
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

(4)SELinux上下文设置

1
2
3
4
# 设置目录安全上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/ip-site/html(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/var/www/ip-site/log(/.*)?"
sudo restorecon -Rv /var/www/ip-site/

(5)测试访问

1
2
3
4
5
6
7
8
# 测试配置语法
sudo apachectl configtest

# 重载服务
sudo systemctl reload httpd

# 测试访问(从其他机器)
curl http://192.168.1.101

4. 基于端口的虚拟主机配置

在同一IP上使用不同端口提供不同网站服务,适合测试环境或内部服务。

(1)创建不同端口的站点目录

1
2
3
4
5
6
7
# 创建端口8080的站点
sudo mkdir -p /var/www/port-8080/{html,log}
sudo echo "<h1>Welcome to Port 8080 Site</h1>" | sudo tee /var/www/port-8080/html/index.html

# 创建端口8081的站点
sudo mkdir -p /var/www/port-8081/{html,log}
sudo echo "<h1>Welcome to Port 8081 Site</h1>" | sudo tee /var/www/port-8081/html/index.html

(2)修改主配置文件监听额外端口

1
sudo vi /etc/httpd/conf/httpd.conf

找到 Listen 指令部分,添加:

1
2
3
4
5
6
# 默认HTTP端口
Listen 80

# 添加额外监听端口
Listen 8080
Listen 8081

(3)创建基于端口的虚拟主机配置

1
sudo vi /etc/httpd/conf.d/port-based.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
# 端口8080的虚拟主机
<VirtualHost *:8080>
ServerName server.local:8080
DocumentRoot "/var/www/port-8080/html"
ServerAdmin admin@port8080.com

ErrorLog "/var/www/port-8080/log/error.log"
CustomLog "/var/www/port-8080/log/access.log" combined

<Directory "/var/www/port-8080/html">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

# 端口8081的虚拟主机
<VirtualHost *:8081>
ServerName server.local:8081
DocumentRoot "/var/www/port-8081/html"
ServerAdmin admin@port8081.com

ErrorLog "/var/www/port-8081/log/error.log"
CustomLog "/var/www/port-8081/log/access.log" combined

<Directory "/var/www/port-8081/html">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

(4)防火墙开放额外端口

1
2
3
4
5
6
7
# 永久开放8080和8081端口
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8081/tcp
sudo firewall-cmd --reload

# 验证端口开放
sudo firewall-cmd --list-ports

(5)SELinux上下文设置

1
2
3
4
5
6
# 设置端口站点目录的安全上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/port-8080/html(/.*)?"
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/port-8081/html(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/var/www/port-8080/log(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/var/www/port-8081/log(/.*)?"
sudo restorecon -Rv /var/www/port-8080/ /var/www/port-8081/

(6)测试访问

1
2
3
4
5
6
7
8
9
10
11
12
# 测试配置语法
sudo apachectl configtest

# 重载服务
sudo systemctl reload httpd

# 测试不同端口的访问
curl http://localhost:8080
curl http://localhost:8081
# 或从客户端访问
curl http://服务器IP:8080
curl http://服务器IP:8081

5. 混合配置示例(IP+端口+域名)

实际环境中经常需要混合使用多种虚拟主机类型:

场景描述:

混合配置示例:

1
sudo vi /etc/httpd/conf.d/mixed-hosts.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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 主网站 - 基于域名(默认端口80)
<VirtualHost 192.168.1.100:80>
ServerName www.example.com
ServerAlias example.com
DocumentRoot "/var/www/example.com/html"

ErrorLog "/var/www/example.com/log/error.log"
CustomLog "/var/www/example.com/log/access.log" combined

<Directory "/var/www/example.com/html">
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

# 测试环境 - 基于端口和域名
<VirtualHost 192.168.1.100:8080>
ServerName test.example.com
DocumentRoot "/var/www/test-env/html"

ErrorLog "/var/www/test-env/log/error.log"
CustomLog "/var/www/test-env/log/access.log" combined

<Directory "/var/www/test-env/html">
Options -Indexes +FollowSymLinks
AllowOverride All # 允许.htaccess用于测试
Require all granted
</Directory>
</VirtualHost>

# 内部管理 - 基于IP和域名
<VirtualHost 192.168.1.101:80>
ServerName admin.internal.com
DocumentRoot "/var/www/admin/html"

ErrorLog "/var/www/admin/log/error.log"
CustomLog "/var/www/admin/log/access.log" combined

# 限制访问来源(仅允许内网IP段)
<Directory "/var/www/admin/html">
Options -Indexes +FollowSymLinks
AllowOverride None
Require ip 192.168.1.0/24 # 仅允许192.168.1.x网段访问
</Directory>
</VirtualHost>

防火墙配置:

1
2
3
4
5
# 开放必要的端口和服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

6. 虚拟主机匹配优先级

当多个虚拟主机配置可能匹配同一个请求时,Apache按以下顺序匹配:

  1. 精确IP+端口+ServerName匹配
  2. IP+端口+第一个定义的虚拟主机(作为默认或回退)
  3. 第一个定义的虚拟主机(当没有匹配时)

设置默认虚拟主机:

1
2
3
4
5
# 第一个定义的VirtualHost会成为默认主机
<VirtualHost _default_:80>
DocumentRoot "/var/www/default"
# 捕获所有未匹配的请求
</VirtualHost>

或者明确指定:

1
2
3
4
5
<VirtualHost *:80>
ServerName default
DocumentRoot "/var/www/default"
# 这个会处理所有未匹配到其他虚拟主机的请求
</VirtualHost>

七、Apache认证配置

Apache支持多种认证方式,包括基本认证(Basic Authentication)和摘要认证(Digest Authentication),用于保护特定目录或文件的访问。

1. 基本认证(Basic Authentication)配置

基本认证是最常用的认证方式,浏览器会弹出用户名/密码输入框。

(1)创建密码文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建认证目录(建议放在/etc/httpd/目录下)
sudo mkdir -p /etc/httpd/auth

# 创建密码文件并添加第一个用户(-c 选项创建新文件)
sudo htpasswd -c /etc/httpd/auth/.htpasswd user1
# 按提示输入密码

# 添加第二个用户(不使用 -c 选项,避免覆盖)
sudo htpasswd /etc/httpd/auth/.htpasswd user2

# 查看密码文件内容
sudo cat /etc/httpd/auth/.htpasswd
# 输出示例:user1:$apr1$xxxxxxxx$yyyyyyyyyyyyyyyyyyyyyy
# user2:$apr1$zzzzzzzz$wwwwwwwwwwwwwwwwwwwwww

(2)为目录配置基本认证

假设我们要保护 /var/www/example.com/html/secure 目录:

1
2
3
# 创建安全目录
sudo mkdir -p /var/www/example.com/html/secure
sudo echo "<h1>Secure Area - Authentication Required</h1>" | sudo tee /var/www/example.com/html/secure/index.html

在虚拟主机配置中添加认证设置:

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
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot "/var/www/example.com/html"

# ... 其他配置 ...

# 保护特定目录
<Directory "/var/www/example.com/html/secure">
# 认证类型
AuthType Basic
# 认证领域名称(显示在登录框中)
AuthName "Restricted Area - Please Login"
# 密码文件路径
AuthUserFile /etc/httpd/auth/.htpasswd
# 允许认证用户访问
Require valid-user

# 可选:允许特定用户访问
# Require user user1 user2

# 目录权限设置
Options -Indexes +FollowSymLinks
AllowOverride None
</Directory>
</VirtualHost>

(3)测试认证配置

1
2
3
4
5
6
7
8
9
# 测试配置语法
sudo apachectl configtest

# 重载服务
sudo systemctl reload httpd

# 测试访问(会返回401状态码)
curl -I http://www.example.com/secure/
# 输出:HTTP/1.1 401 Unauthorized

在浏览器中访问 http://www.example.com/secure/,会弹出登录框要求输入用户名和密码。

2. 基于用户组的认证

对于更复杂的权限管理,可以使用用户组。

(1)创建组文件

1
2
# 创建组文件
sudo vi /etc/httpd/auth/.htgroups

添加组和用户关系:

1
2
3
4
# 格式:组名: 用户1 用户2 用户3
admins: user1 user2
users: user3 user4
readonly: user5

(2)配置组认证

1
2
3
4
5
6
7
8
9
10
11
12
<Directory "/var/www/example.com/html/admin">
AuthType Basic
AuthName "Admin Area"
AuthUserFile /etc/httpd/auth/.htpasswd
AuthGroupFile /etc/httpd/auth/.htgroups

# 仅允许admins组访问
Require group admins

Options -Indexes +FollowSymLinks
AllowOverride None
</Directory>

3. 摘要认证(Digest Authentication)

摘要认证比基本认证更安全,密码不会以明文形式传输。

(1)创建摘要认证密码文件

1
2
3
4
5
6
# 创建摘要认证密码文件
sudo htdigest -c /etc/httpd/auth/.htdigest "Restricted Area" user1
# 按提示输入密码

# 添加第二个用户
sudo htdigest /etc/httpd/auth/.htdigest "Restricted Area" user2

(2)配置摘要认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Directory "/var/www/example.com/html/secure-digest">
# 使用摘要认证
AuthType Digest
AuthName "Restricted Area"
AuthDigestDomain /secure-digest/

# 摘要认证密码文件
AuthDigestProvider file
AuthUserFile /etc/httpd/auth/.htdigest

# 允许认证用户访问
Require valid-user

Options -Indexes +FollowSymLinks
AllowOverride None
</Directory>

4. IP地址限制与认证结合

可以结合IP限制和认证,提供更灵活的安全策略。

(1)IP白名单 + 认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Directory "/var/www/example.com/html/secure-ip">
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/httpd/auth/.htpasswd

# 访问控制配置
Order deny,allow
Deny from all

# 允许本地网络无需认证
Allow from 192.168.1.0/24
# 其他IP需要认证
Require valid-user
Satisfy any
</Directory>

(2)分时段访问控制

1
2
3
4
5
6
7
8
9
10
11
12
<Directory "/var/www/example.com/html/office-hours">
AuthType Basic
AuthName "Office Hours Only"
AuthUserFile /etc/httpd/auth/.htpasswd

# 定义办公时间(9:00-18:00)
<RequireAll>
Require valid-user
# 仅允许在工作时间访问
Require expr %{TIME_HOUR} >= 9 && %{TIME_HOUR} < 18
</RequireAll>
</Directory>

5. .htaccess 文件认证配置

如果主配置中允许 .htaccess 覆盖,可以在目录中创建 .htaccess 文件进行认证配置。

(1)启用 .htaccess 覆盖

在主配置或虚拟主机配置中:

1
2
3
4
5
<Directory "/var/www/example.com/html">
AllowOverride AuthConfig # 允许认证配置覆盖
# 或者允许所有覆盖
# AllowOverride All
</Directory>

(2)创建 .htaccess 文件

1
sudo vi /var/www/example.com/html/secure/.htaccess

内容:

1
2
3
4
5
6
7
AuthType Basic
AuthName "Protected Directory"
AuthUserFile /etc/httpd/auth/.htpasswd
Require valid-user

# 其他.htaccess指令
Options -Indexes

6. 认证与SSL/TLS结合

对于生产环境,认证应该与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
# 强制使用HTTPS进行认证
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot "/var/www/example.com/html"

# SSL配置
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key

# 安全目录配置
<Directory "/var/www/example.com/html/secure">
AuthType Basic
AuthName "Secure Login"
AuthUserFile /etc/httpd/auth/.htpasswd
Require valid-user
</Directory>
</VirtualHost>

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

7. 认证配置最佳实践

(1)安全建议

1
2
3
4
5
6
# 设置密码文件权限
sudo chown root:apache /etc/httpd/auth/.htpasswd
sudo chmod 640 /etc/httpd/auth/.htpasswd

# 定期更改密码
sudo htpasswd /etc/httpd/auth/.htpasswd user1

(2)性能优化

对于大量用户的场景,考虑使用数据库认证:

1
2
3
4
5
6
# 使用数据库认证(需要mod_authn_dbd)
AuthType Basic
AuthName "Members Area"
AuthBasicProvider dbd
AuthDBDUserPWQuery "SELECT password FROM users WHERE username = %s"
Require valid-user

(3)错误页面定制

1
2
3
# 自定义认证错误页面
ErrorDocument 401 /error/401.html
ErrorDocument 403 /error/403.html

8. 测试认证功能

(1)命令行测试

1
2
3
4
5
6
7
8
9
# 测试认证(会返回401)
curl -I http://www.example.com/secure/

# 带认证测试
curl -u user1:password http://www.example.com/secure/

# 或分步操作
curl -u user1 http://www.example.com/secure/
# 会提示输入密码

(2)浏览器测试

  • 访问受保护URL
  • 确认弹出登录框
  • 输入正确用户名密码后能正常访问
  • 测试错误密码时的拒绝访问

9. 常见问题解决

(1)认证失败

  • 检查密码文件路径:确保 AuthUserFile 路径正确
  • 检查文件权限:Apache用户需要能读取密码文件
  • 验证密码:使用 htpasswd -v 验证密码

(2)性能问题

  • 对于高流量站点,考虑使用数据库或缓存认证
  • 启用 mod_authn_socache 模块缓存认证结果

(3)SELinux问题

如果认证目录在非标准位置,可能需要设置SELinux上下文:

1
2
sudo semanage fcontext -a -t httpd_sys_content_t "/custom/auth/path(/.*)?"
sudo restorecon -Rv /custom/auth/path

八、常见问题与解决方案

1. Apache 启动失败:Job for httpd.service failed

  • 原因 1:配置文件语法错误;
    解决:执行 sudo apachectl configtest 查看错误位置(如行号、指令拼写错误),修改后重试。
  • 原因 2:80 端口被占用(如 Nginx 服务);
    解决:查找占用进程 sudo ss -tulpn | grep :80,停止占用服务(如 sudo systemctl stop nginx)。
  • 原因 3:SELinux 拦截目录访问;
    解决:按步骤五设置目录的 SELinux 上下文(如 httpd_log_t 用于日志目录)。

2. 访问页面显示 403 Forbidden(禁止访问)

  • 原因 1:目录权限不足(Apache 无读取权限);
    解决:设置目录权限 sudo chmod -R 755 /var/www/your_site,文件权限 sudo chmod -R 644 /var/www/your_site/html/*
  • 原因 2Require all denied 配置错误;
    解决:检查 <Directory> 块中的 Require 指令,确保为 Require all granted

3. PHP 页面显示源码而非解析

  • 原因:未安装 mod_php 模块或未重启 Apache;
    解决:安装 sudo yum install -y php,重启 Apache sudo systemctl restart httpd

CentOS 7搭建Apache(httpd) web 服务器-静态
https://netguy6.github.io/2026/02/05/CentOS 7搭建Apache(httpd) web 服务器-静态/
作者
net06
发布于
2026年2月5日
许可协议