httpd 命令
httpd 为 Apache HTTP 服务软件的命令
相关文件
| 文件 | 说明 |
|---|---|
/etc/httpd/conf/httpd.conf |
主配置文件 |
/etc/httpd/conf.d/ |
存放虚拟主机配置文件 |
/etc/httpd/conf.modules.d/ |
存放模块配置文件` |
/etc/httpd/modules/ |
存放模块文件 |
/var/log/httpd/ |
存放日志文件 |
/var/www/html/ |
存放默认的网页文件 |
主配置文件(/etc/httpd/conf/httpd.conf)

==理解==:主配置文件,配置权限的目的
Apache的权限配置 = 一套“门禁系统”,决定哪些文件夹能进、哪些不能进、进去后能干嘛。
1. 先看懂你的配置文件在说什么
你贴的配置里有三个<Directory>块,它们按从最严格到最宽松的顺序排列:
① 根目录(<Directory />)—— 全局“一刀切”禁止
apache
<Directory />
AllowOverride none
Require all denied
</Directory>
翻译成人话:
“整个Linux根目录(/)下的所有文件,默认统统不许访问!”
这是Apache的安全底线——万一有人想通过URL读取你的/etc/passwd或/root/,直接拦死。
② 你的网站根目录(<Directory "/data/www/html">)—— 白名单放行
apache
<Directory "/data/www/html">
AllowOverride none
Require all granted
</Directory>
翻译成人话: “虽然根目录全禁了,但这个特定的文件夹例外——所有人(all)都可以访问里面的文件(granted)。”
这就是你网站能正常打开的原因:Apache检查权限时,会选最匹配的那个<Directory>,而不是叠加所有规则。
③ /var/www 和 /var/www/html(中间两个)—— 兼容老路径
这两个块是为了兼容RHEL/CentOS系统的默认网站目录(老版本Apache默认用/var/www/html)。
你既然改成了/data/www/html,这两个块其实没用上,但留着也没坏处。
2. 为什么需要这套“门禁系统”?(背后的安全逻辑)
如果你不给/data/www/html加Require all granted,Apache会继承根目录的Require all denied,结果就是:
你浏览器访问
http://IP/index.html→ Apache查权限表 → 发现/被禁止 → 直接返回403 Forbidden
这就是初学者最常见的“配好路径却打不开网站”的根源——你配了根目录,但忘了给具体文件夹开门。
3. AllowOverride none 是啥意思?(很多人忽略的坑)
你配置里写了AllowOverride none,意思是:
禁止这个目录下的
.htaccess文件覆盖当前权限设置。
- 如果设为
All,Apache会去读取/data/www/html/.htaccess,并允许它临时修改权限(比如拒绝某个IP)。 - 设为
None,Apache直接忽略.htaccess,提升性能(不用每次请求都去磁盘找这个文件)。
实战建议:生产环境永远用None,把权限写在主配置文件里,既安全又快速。
4. 用“门禁卡”模型彻底吃透权限配置
想象你进入一栋大楼(Apache服务器):
| 配置项 | 比喻 |
|---|---|
<Directory /> |
大楼的总闸:晚上10点后全楼封锁 |
<Directory "/data/www/html"> |
你工位的门禁卡:只有这张卡能刷开特定办公室 |
Require all granted |
门禁卡权限设为“任何人都能进” |
Require all denied |
门禁卡权限设为“天王老子也别进” |
AllowOverride none |
禁止办公室员工自己改门锁密码(防乱改) |
虚拟主机
Httpd 支持在一台物理主机上实现多个网站,即多虚拟主机
- 网站的唯一标识,多虚拟主机有三种实现方案
- IP 相同 + Port 不同
- IP 不同 + Port 相同
- FQDN 不同

给网卡添加临时ip
给网卡添加IP地址 [root@server1 ~]# nmcli connection modify ens160 +ipv4.addresses “192.168.226.128 /24” [root@server1 ~]# nmcli connection modify ens160 +ipv4.addresses “192.168.226. …. /24” [root@server1 ~]# nmcli connection modify ens160 +ipv4.addresses “192.168.226. …. /24”


- 基于多IP加一个端口号


服务日志
httpd 有两种常见日志类型:==访问日志和错误日志==,==错误日志==使用标准 syslog 级别,==按严重性递增排序==。
日志配置文件
主配置文件日志配置相关定义块

不同工具访问
第一部分:日志格式解释(每列代表什么?)
这条日志使用的是标准的 Combined Log Format(组合日志格式)。按照从左到右的顺序,各个字段的含义如下:
192.168.226.1:客户端 IP 地址。这是发起请求的电脑(也就是您的本机)的IP。-:远程登录名(Identd)。因为大多数服务器不启用身份验证检查,所以通常是横杠“-”。-:认证用户名。如果您的网站需要HTTP基本认证(输入账号密码),这里会显示登录的用户名;否则也是横杠“-”。[05/Aug/2026:12:02:10 +0800]:时间戳。- 格式为
[日/月/年:时:分:秒 时区]。 - 也就是 2026年8月5日,12点02分10秒,东八区(北京时间)。
- 格式为
"GET / HTTP/1.1":请求行。GET:请求方法(获取网页)。/:请求的路径(即网站根目录)。HTTP/1.1:使用的HTTP协议版本。
200:HTTP 状态码。表示请求成功,服务器返回了内容(200是成功,404是找不到页面,408是请求超时等)。7829:响应体大小(字节)。服务器返回给客户端的网页数据量(不含响应头)。"Mozilla/5.0 ...":User-Agent(用户代理)。这是你问的第二个问题的关键。它告诉服务器客户端是什么浏览器或工具。
第二部分:为什么最后 curl 和浏览器显示的日志不一样?
在截图的最底部,您会看到前几行是 curl 发起的请求,最后一行突然变成浏览器请求了。它们的区别主要体现在以下两点:
1. 状态码和请求路径不同(404 vs 200)
- 最后一行(浏览器):
"GET /favicon.ico HTTP/1.1" 404 ...。这是浏览器在加载完网页后,自动去请求网站图标(favicon.ico)。因为您的服务器上可能没有这个图标文件,所以返回了 404 Not Found。 - 上面的
curl行:"GET / HTTP/1.1" 200 ...。您用curl默认请求的是根路径/,且服务器找到了页面,所以返回的是 200 OK。
2. User-Agent 不同(这一点最重要)
- 浏览器(末尾行):User-Agent 非常长,包含
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.0.0。这说明是 Windows 10 上的 Edge 浏览器 (Chromium内核) 发送的请求。 - 上面的
curl行:User-Agent 是curl/7.76.1。curl是命令行工具,它发出来的请求通常会有非常明显的标识,告诉服务器“我是个命令行工具,不是用户浏览器”。
为什么看起来不一样? 因为Web服务器记录日志时,就是如实记录客户端发来的 HTTP 请求头。
- 浏览器访问网页时,会发送详细的浏览器版本和操作系统信息。
- 命令行
curl默认只发送最简短的标识curl/版本号。
总结: 格式是完全标准的 Access Log。底部的变化只是因为发起请求的工具不同(curl 请求了 /,而浏览器随后又自动请求了 /favicon.ico),并且它们各自携带的“身份标识(User-Agent)”不同,服务器只是把收到的东西如实记录下来了。


三种网卡模式上网详解



==添加json格式的日志==

LogFormat "{n
"type": "apache_access",n
"timestamp": "%{%Y-%m-%dT%H:%M:%S%z}t",n
"client_ip": "%a",n
"method": "%m",n
"path": "%U",n
"query": "%q",n
"status": %>s,n
"response_size": %b,n
"referer": "%{Referer}i",n
"user_agent": "%{User-Agent}i",n
"response_time_ms": %D,n
"server_name": "%V"n
},n" json

URL匹配规则
Apache httpd的URL匹配规则主要包括以下几种指令:
- <Location> : 基于URL路径进行匹配。
- <LocationMatch> : 使用正则表达式进行URL路径匹配。
- <Directory> : 基于服务器文件系统的目录路径进行匹配。
- <DirectoryMatch> : 使用正则表达式进行目录路径匹配。
- <Files> : 基于文件名进行匹配。
- <FilesMatch> : 使用正则表达式进行文件名匹配。
具体用法见课件,不用记,本质就是匹配格式用到看一下
Options 指令和Override指令
相关介绍
用于控制特定目录下启用的服务器功能特性(如目录列表、符号链接等)
语法:Options [+|-]option [[+|-]option] ... 作用域:<Directory>, <Location>, <Files>, .htaccess 特性:
- +/- 前缀:动态添加或移除选项,支持配置继承与合并(无前缀时直接覆盖)
- 优先级:子目录配置优先于父目录,正则表达式匹配的配置最后生效
常用选项
| 选项 | 功能说明 | 适用场景 |
|---|---|---|
| Indexes | 当目录无默认文件(如 index.html)时,自动生成文件列表 | 开发环境调试,生产慎用 |
| FollowSymLinks | 允许通过符号链接访问目录外资源(在 <Location> 中无效) |
跨目录资源整合 |
| MultiViews | 内容协商:根据请求头(如语言)自动匹配文件(需 mod_negotiation) | 多语言站点适配 |
| ExecCGI | 允许执行 CGI 脚本(需 mod_cgi) | 动态脚本处理(如 Perl/Python) |
| Includes | 启用服务端包含(SSI)(需 mod_include) | 动态页面片段嵌入 |
| IncludesNOEXEC | 允许 SSI 但禁用 #exec 执行命令/CGI |
安全限制下的 SSI 功能 |
| SymLinksIfOwnerMatch | 仅当符号链接与目标文件所有者相同时允许访问(在 <Location> 中无效) |
高安全要求的共享环境 |
| All | 启用除 MultiViews 外的所有特性(默认值) |
快速启用常用功能 |
| None | 禁用所有额外特性 | 严格安全策略 |

实践
把 index.html 备份.bak文件,然后浏览器默认不返回响应报文,只返回服务端的原始样子


案例分析
使用 Index 和 FollowSymLinks,当访问无索引文件的目录时显示文件列表,允许符号链接跳转;依次去掉 FollowSymLinks 和 Index 观察现象。
# 准备实验环境
[root@localhost ~]# mkdir -pv /data/site04/public
[root@localhost ~]# touch /data/site04/public/{1,2,3}.html
[root@localhost ~]# ln -s /etc/passwd /data/site04/public/passwd.tx
[root@localhost ~]# cat << EOF > /etc/httpd/conf.d/site01.conf
Listen 8001
<Virtualhost 172.16.175.129:8001>
Documentroot /data/site04
<Directory /data/site04/public>
Options Indexes FollowSymLinks
Require all granted
</Directory>
</Virtualhost>
EOF
[root@localhost ~]# systemctl restart httpd
# 通过浏览器访问测试验证


AllowOverride 指令
相关介绍
用于控制是否允许在 .htaccess 文件中覆盖主配置文件的设定,通常用于目录级的动态配置,无需重启服务即可生效。作用域限制为:仅能在 <Directory> 块中生效,在 <Location>、<Files> 等配置段中无效。
常用参数
| 参数值 | 说明 |
|---|---|
| None | 完全忽略 .htaccess 文件,服务器不读取其内容(默认推荐,提升性能与安全性)。 |
| All | 允许 .htaccess 覆盖所有支持的指令(需谨慎启用,可能引发安全风险)。 |
| AuthConfig | 允许覆盖认证相关指令(如 AuthName, Require)。 |
| FileInfo | 允许覆盖文件处理指令(如 ErrorDocument, RewriteRule, Header)。 |
| Indexes | 允许覆盖目录索引控制指令(如 DirectoryIndex, IndexIgnore)。 |
| Limit | 允许覆盖访问控制指令(如 Allow, Deny, Order)。 |
| Options[=…] | 允许覆盖目录特性控制指令(如 Options FollowSymLinks,可指定具体允许的选项)。 |
案例分析
通过 AllowOverride 指令和 .htaccess 文件,动态为指定目录设定特性控制指令
# 准备实验环境
[root@localhost ~]# mkdir -pv /data/site05/public
[root@localhost ~]# touch /data/site05/public/{1,2,3}.html
[root@localhost ~]# cat << EOF > /etc/httpd/conf.d/site02.conf
Listen 8002
<Virtualhost 172.16.175.129:8002>
Documentroot /data/site05
<Directory /data/site05/public>
AllowOverride Options=Indexes
Require all granted
</Directory>
</Virtualhost>
EOF
[root@localhost ~]# systemctl restart httpd
# 通过浏览器访问:禁止访问
# 通过 .htaccess 文件覆盖设定
[root@localhost ~]# echo "Options Indexes" > /data/site05/public/.htaccess
# 通过浏览器访问测试验证
==理解==:
- 服务器启动时,主配置文件(
site02.conf)已经加载,AllowOverride Options=Indexes已经生效。 - 如果修改主配置文件,需要重启
httpd服务,这会影响业务连续性。 - 为了不重启服务,可以使用
.htaccess文件在运行中动态覆盖指定目录的配置。 AllowOverride后面跟的选项(如Options=Indexes)限定了哪些指令可以被覆盖,未列出的指令即使写在.htaccess里也无效。- 在
.htaccess中必须重新声明Options Indexes,不能只写Indexes,因为.htaccess里写的是完整的 Apache 配置指令语法。
AllowOverride 定义了 .htaccess 的“权限边界”,而 .htaccess 是 Apache 实现“不停机动态配置”的核心机制,两者配合可实现细粒度的目录级策略控制。
==实践==:



访问控制
针对各种资源,通常基于两种方式:客户端来源地址和用户账号来进行访问控制
基于IP地址
基于客户端IP地址的访问控制:
- Apache 2.4 默认 拒绝所有未显式授权 的访问,需明确配置
Require all granted开放全局访问 Require host可基于域名控制(如 Require host example.com),但需注意 DNS 解析延迟可能影响性能- 不带
not的多个Require是“或”关系(任一满足即可) - 带
not和不带not的语句混合时是“与”关系(需同时满足)
常见语法:
- 允许所有主机访问:
Require all granted - 拒绝所有主机访问:
Require all denied - 授权/拒绝指定来源的IP/host访问:
Require [not] <ip|host> <ipaddress|hostname>
组合策略配置:
<RequireAll>内部所有条件必须同时满足(逻辑与)<RequireAny>内部任一条件满足即可(逻辑或)
基于用户
基于用户的访问控制主要通过身份验证(Authentication)和授权(Authorization)机制实现:
认证类型:
- Basic 认证:用户名密码以 Base64 编码传输(明文,需配合 HTTPS 保证安全)
- Digest 认证:密码哈希传输(更安全,但配置复杂)
核心配置指令:
- AuthName:定义认证区域名称(浏览器弹窗提示文本)
- AuthUserFile:指定存储用户名密码的文本文件路径(如 .htpasswd)
- Require:授权规则(如 valid-user 允许所有认证用户,或指定用户/组)


==特殊文件==:. file以点(.)开头的文件是隐藏文件,要用 -a 参数才可看到
虚拟主机配置
apache
<VirtualHost 192.168.226.131:8007>
意思:定义一个虚拟主机,绑定到IP 192.168.226.131 的 8007 端口
→ 相当于在这台服务器上单独开了一个网站
启用密码认证
apache
AuthType Basic
AuthName "FBI warning"
AuthUserFile "/etc/httpd/.htpasswd"
| 配置项 | 意思 |
|---|---|
AuthType Basic |
使用基础密码认证(弹出登录框) |
AuthName "FBI warning" |
登录框显示的提示文字(”FBI警告”) |
AuthUserFile "/etc/httpd/.htpasswd" |
密码文件位置,里面存了用户名和加密密码 |



URL 处理机制
别名(Alias) 和 重定向(Redirect) 是两种不同的 URL 处理机制,核心区别在于是否改变客户端浏览器地址栏的 URL 以及是否触发新的 HTTP 请求
别名 Alias
用于将 URL 路径映射到文件系统的不同位置,实现灵活的资源管理和访问控制。
路径资源解耦:将 URL 路径(如 /images)映射到物理目录(如 /var/www/media),无需修改实际文件位置,示例如下:
Alias "/images" "/var/www/html/media"
访问 http://domain.com/images/photo.jpg 实际返回 /var/www/html/media/photo.jpg
简化URL结构:隐藏复杂路径,提升用户体验和 SEO 友好性 多域名/路径管理:同一服务器托管多个站点,示例如下:
<VirtualHost *:80>
ServerName blog.example.com
Alias "/" "/var/www/blog"
</VirtualHost>
<VirtualHost *:80>
ServerName notes.example.com
Alias "/" "/var/www/notes"
</VirtualHost>
...
案例分析
将 /usr/share/httpd/icons 独立资源通过 /icons 别名暴露简洁路径
1. Alias /icons /usr/share/httpd/icons
- 作用:这是路径别名。
- 说明:它把访问路径
/icons映射到服务器硬盘上的真实物理路径/usr/share/httpd/icons。 - 举例:如果用户在浏览器访问
http://192.168.226.128:8007/icons/abc.png,Apache 会去服务器的/usr/share/httpd/icons/abc.png目录下找这个图片。

[root@localhost ~]# vim /etc/httpd/conf.d/site01.conf # 配置子配置文件
Listen 8007
<Virtualhost 192.168.226.128:8007>
Alias /icons /usr/share/httpd/icons
<Directory /usr/share/httpd/icons>
Options Indexes FollowSymLinks
AllowOverride none
Require all granted
</Directory>
</Virtualhost>
# 通过浏览器访问 http://192.168.226.128:8007/icons/
# [root@localhost ~]# curl -I http://192.168.226.128:8007/icons/ 返回 200

重定向 Redirect
强制客户端跳转到另一个 URL,通常用于路径迁移或权限控制
相关介绍
网站改版迁移:旧路径 http://old.com 永久跳转到 http://new.com(301) 权限控制:未登录用户访问 /admin 时跳转到登录页(302) 临时维护:将流量临时导向通知页面(302)
案例分析1
网站改版迁移:旧域名访问新网站
[root@localhost ~]# mkdir -pv /data/site02/
[root@localhost ~]# echo "This is New NO.2 website!" > /data/site02/index.html
[root@localhost ~]# vim /etc/httpd/conf.d/site02.conf
# old site
<Virtualhost 192.168.226.128>
ServerName cloud.eagleslabtest.com
Redirect 301 / http://ncloud.eagleslabtest.com/
</Virtualhost>
# new site
<Virtualhost 192.168.226.128>
ServerName ncloud.eagleslabtest.com
Documentroot /data/site02
<Directory /data/site02>
Require all granted
</Directory>
</Virtualhost>
[root@localhost ~]# echo "192.168.226.128 ncloud.eagleslabtest.com" >> /etc/hosts
[root@localhost ~]# echo "192.168.226.128 cloud.eagleslabtest.com" >> /etc/hosts # 在linux操作系统配置dns域名解析服务
[root@localhost ~]# systemctl restart httpd
# 测试验证
[root@localhost ~]# curl -L http://cloud.eagleslabtest.com/index.html
This is New NO.8 website!
[root@localhost ~]# curl -I http://cloud.eagleslabtest.com/index.html
HTTP/1.1 301 Moved Permanently
Date: Mon, 07 Jul 2025 19:20:27 GMT
Server: Apache/2.4.62 (Rocky Linux)
Location: http://ncloud.eagleslabtest.com/index.html
Connection: close
Content-Type: text/html; charset=iso-8859-1



网页压缩技术
网页压缩技术主要通过 mod_deflate 模块实现,它能显著减少传输数据量,提升网站加载速度和用户体验
相关介绍
- 使用 mod_deflate 模块压缩页面优化传输速度
- 适用场景
- 节约带宽,额外消耗CPU;同时,可能有些较老浏览器不支持
- 压缩适于压缩的资源,例如文本文件
案例分析
# 准备实验环境
[root@localhost ~]# mkdir -pv /data/site03/ /data/site04/
[root@localhost ~]# tree /etc > /data/site03/blog.html
[root@localhost ~]# tree /etc > /data/site04/blog.html
# 配置对比vhost
[root@localhost ~]# vim /etc/httpd/conf.d/site03.conf
Listen 8009
Listen 8010
<Virtualhost *:8009>
Documentroot /data/site03/
<Directory /data/site03/> # 这个设置网页压缩技术
Require all granted
</Directory>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
SetOutputFilter DEFLATE
</Virtualhost>
<Virtualhost *:8010>
Documentroot /data/site04/
<Directory /data/site04/>
Require all granted
</Directory>
</Virtualhost>
[root@localhost ~]# systemctl restart httpd
# 默认curl没有压缩,需要加参数 --compressed,输出结果关注 Content-Encoding: gzip & Content-Length
[root@localhost ~]# curl -I --compressed 127.0.0.1:8009/blog.html
[root@localhost ~]# curl -I --compressed 127.0.0.1:8010/blog.html
本地调试和验证,不依赖网络
服务器在运行 Apache 服务后,首先要确认服务是否在本机正常运行。
- 使用
127.0.0.1不需要经过网卡、路由器或防火墙,数据直接在系统内核层面流转。 - 这可以排除很多网络层面的问题(比如防火墙阻挡了外部访问、路由配置错误等)。如果
curl 127.0.0.1能通,说明 Apache 本身是好的。
2. 适用于当前的上下文(同一台机器)
截图中的操作是在服务器本机的终端里进行的。
- 因为您已经在服务器里(
[root@localhost conf.d]#),您访问自己机器上的服务,最稳妥、最快的方式就是用127.0.0.1。 - 如果换成公网 IP(也就是
192.168.226.128),在某些云服务器或设置了强防火墙的环境下,可能需要额外开启端口权限才能访问。


HTTPS
Web网站的登录页面都是使用HTTPS加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议.
采用HTTPS协议的服务器必须要有一套证书,可以通过权威机构申请,也可以自己制作,目前国内很多网站都自己做的,当你访问一个网站的时候提示证书不可信任就表示证书是自己做的
案例分析
自建 HTTPS 服务器:自签名证书生成、Apache 配置、强制 HTTP 跳转 HTTPS及测试验证
[root@localhost ~]# mkdir -pv /data/site01/
[root@localhost ~]# echo "This is NO.1 website!" > /data/site01/index.html
# 安装 mod_ssl 模块和 openssl 工具
[root@localhost ~]# yum install mod_ssl openssl -y
# 确认 httpd 已经加载 ssl_module 模块
[root@localhost ~]# httpd -M | grep ssl
ssl_module (shared)
# 备份默认 ssl.conf 文件避免互相影响
[root@localhost ~]# mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak # 把文件备份,备份成.bak文件
[root@localhost ~]# grep -nr 'ssl' /etc/httpd/conf.modules.d/*
/etc/httpd/conf.modules.d/00-ssl.conf:1:LoadModule ssl_module modules/mod_ssl.so
# 创建 X509 自签名证书
[root@localhost ~]# openssl req -x509 -nodes -days 365 -newkey rsa:2048
-keyout /etc/httpd/ssl/server.key
-out /etc/httpd/ssl/server.crt
-subj "/C=XX/ST=Test/O=DevEnv/CN=ssl.eagleslabtest.com"
-addext "subjectAltName=DNS:ssl.eagleslabtest.com,IP:192.168.226.128"
# HTTPS 相关虚拟主机配置
[root@localhost ~]# vim /etc/httpd/conf.d/site01.conf
# 强制 HTTP 跳转 HTTPS
<VirtualHost 192.168.226.128:80>
ServerName ssl.eagleslabtest.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
Listen 443 https
<VirtualHost 192.168.226.128:443>
ServerName ssl.eagleslabtest.com
DocumentRoot /data/site01/
<Directory /data/site01/>
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key
# 安全增强配置(可选但推荐)
# 禁用旧协议
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
# 强加密套件
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
</VirtualHost>
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# echo "192.168.226.128 ssl.eagleslabtest.com" >> /etc/hosts
# 测试验证: -k 忽略证书警告测试
[root@localhost ~]# curl -k https://ssl.eagleslabtest.com/index.html
This is NO.10 website!
# 测试验证: 强制跳转
[root@localhost ~]# curl -k -L http://ssl.eagleslabtest.com/index.html
This is NO.1 website!
一、通过openssl工具来自己生成一个证书,然后颁发给自己
# 1. 安装mod_ssl和openssl
[root@localhost ~]# yum install mod_ssl openssl -y
# 2.生成2048位的加密私钥
[root@localhost ~]# openssl genrsa -out server.key 2048
# 3.生成证书签名请求(CSR)
[root@localhost ~]# openssl req -new -key server.key -out server.csr
# 一路回车到底,过程暂时不需要管
# 4.生成类型为X509的自签名证书。有效期设置3650天,即有效期为10年
[root@localhost ~]# openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
# 5.复制文件到相应的位置
[root@localhost ~]# cp server.crt /etc/pki/tls/certs/
[root@localhost ~]# cp server.key /etc/pki/tls/private/
[root@localhost ~]# cp server.csr /etc/pki/tls/private/
# 6.修改配置文件,指定我们自己的证书文件路径
[root@localhost ~]# vim /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/pki/tls/certs/server.crt
SSLCertificateKeyFile /etc/pki/tls/private/server.key
# 7.重启httpd
[root@node1 ~]# systemctl restart httpd
阶段一:基础环境与站点准备
bash
mkdir -pv /data/site10/
echo "This is NO.10 website!" > /data/site10/index.html
mkdir -pv:-p参数确保如果父目录(/data)不存在,则一并创建;-v参数让创建过程可视化。echo >: 创建了一个简单的测试页面,内容为This is NO.10 website!。这是后续验证Web服务是否正常工作的基础文件。
阶段二:安装与加载SSL模块
bash
yum install mod_ssl openssl -y
httpd -M | grep ssl
mod_ssl: 这是Apache的SSL/TLS模块。没有它,Apache就无法处理HTTPS协议。openssl: 这是一个强大的命令行工具包,我们后续会用它的req子命令来生成自签名证书。httpd -M: 这个命令会列出Apache当前加载的所有静态和共享模块。grep ssl用来确认ssl_module (shared)已成功加载。这步验证非常关键,避免了因模块未加载导致配置失败。
阶段三:准备证书文件与配置
1. 备份默认配置
bash
mv /etc/httpd/conf.d/ssl.conf{,.bak}
- 系统自带的
ssl.conf是默认的HTTPS配置示例。强烈建议备份或重命名它,因为如果不加修改直接使用,它可能会与你自己写的配置文件产生冲突(比如端口、证书路径等)。加.bak后缀是一个安全且常见的做法。
2. 验证模块加载路径
bash
grep -nr 'ssl' /etc/httpd/conf.modules.d/*
- 这步是双重确认。
conf.modules.d目录下的00-ssl.conf文件确保了mod_ssl.so会被加载。这保证了安装是成功的。
3. 生成X.509自签名证书
bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048
-keyout /etc/httpd/ssl/server.key
-out /etc/httpd/ssl/server.crt
-subj "/C=XX/ST=Test/O=DevEnv/CN=ssl.eagleslabtest.com"
-addtext "subjectAltName=DNS:ssl.eagleslabtest.com,IP:172.16.175.129"
这是核心命令,我们拆解一下每个参数的意义:
req: 用于处理证书请求和生成自签名证书的子命令。-x509: 告诉OpenSSL直接输出一个自签名的X.509格式证书,而不是生成一个待签名的证书请求(CSR)。-nodes: No DES。意思是“不加密私钥”。如果不加此参数,系统会要求你设置一个密码来保护私钥文件,但每次启动Apache时都需要手动输入密码。在自动化运维中这是不可接受的,因此我们使用此选项让私钥无密码保护。-days 365: 证书有效期,这里设置为365天。-newkey rsa:2048: 同时生成一个新的2048位RSA私钥和证书。-keyout与-out: 分别指定生成的 私钥文件 和 证书文件 的存储路径。请确保/etc/httpd/ssl/目录存在,否则命令会报错。-subj: Subject。这是证书的“主题”信息,用/分隔各个字段。你这里设置了国家(C)、省份(ST)、组织(O)、和通用名称(CN)。- 在传统的SSL中,
CN必须与用户访问的域名完全一致。
- 在传统的SSL中,
-addtext: 这是最关键的一点。从2015年起,主流浏览器要求证书必须包含 SAN(Subject Alternative Name,主题备用名称) 字段。所以你在这里明确指定了该证书同时适用于域名ssl.eagleslabtest.com和IP172.16.175.129。这使得你的测试环境在浏览器中能最大程度避免证书无效警告。





LAMP架构介绍及案例
MPM多路处理模块
httpd 支持三种 MPM 工作模式:prefork, worker, event
相关配置文件
[root@localhost ~]# cat /etc/httpd/conf.modules.d/00-mpm.conf |grep mpm
# LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule mpm_event_module modules/mod_mpm_event.so
prefork 模式
Prefork MPM,这种模式采用的是预派生子进程方式,用单独的子进程来处理请求,子进程间互相独立,互不影响,大大的提高了稳定性,但每个进程都会占用内存,所以消耗系统资源过高。

worker 模式
Worker MPM 是Apche 2.0 版本中全新的支持多进程多线程混合模型的 MPM,由于使用线程来处理 HTTP 请求,所以效率非常高,而对系统的开销也相对较低,Worker MPM 也是基于多进程的,但是每个进程会生成多个线程,由线程来处理请求,这样可以保证多线程可以获得进程的稳定性。

event 模式
这个是 Apache 中最新的模式,在现在版本里的已经是稳定可用的模式。它和 worker 模式很像,最大的区别在于,它解决了 keepalive 场景下 ,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,挂在那里等待,中间几乎没有请求过来,一直等到超时)。
event MPM 中,会有一个专门的线程来管理这些 keepalive 类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样,一个线程就能处理多个请求,实现了异步非阻塞。
event MPM 在遇到某些不兼容的模块时会失效,将会回退到 worker 模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。

==MPM多路处理模块配置文件==:


LAMP架构
LAMP就是由Linux+Apache+MySQL+PHP组合起来的架构
并且Apache默认情况下就内置了PHP解析模块,所以无需CGI即可解析PHP代码
请求示意图:

安装Apache
[root@localhost ~]# yum install -y httpd
# 启动httpd
[root@localhost ~]# systemctl enable --now httpd
# 关闭防火墙和SElinux
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
安装PHP环境
- 安装php8.0全家桶
[root@localhost ~]# yum install -y php*
# 启动php-fpm
[root@localhost ~]# systemctl enable --now php-fpm
[root@localhost ~]# systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
Active: active (running) since Sat 2025-01-18 21:54:09 CST; 7s ago
Main PID: 34564 (php-fpm)
Status: "Ready to handle connections"
Tasks: 6 (limit: 10888)
Memory: 22.6M
CPU: 119ms
CGroup: /system.slice/php-fpm.service
├─34564 "php-fpm: master process (/etc/php-fpm.conf)"
├─34565 "php-fpm: pool www"
├─34566 "php-fpm: pool www"
├─34567 "php-fpm: pool www"
├─34568 "php-fpm: pool www"
└─34569 "php-fpm: pool www"
Jan 18 21:54:09 localhost.localdomain systemd[1]: Starting The PHP FastCGI Process Manage>
Jan 18 21:54:09 localhost.localdomain systemd[1]: Started The PHP FastCGI Process Manager.
- 重启httpd服务以加载PHP相关模块
[root@localhost ~]# systemctl restart httpd
为什么安装php模块
1️⃣ Apache 和 PHP 的关系
text
用户访问 index.php
↓
Apache (httpd) 收到请求
↓
Apache 发现文件后缀是 .php
↓
需要 PHP 模块来处理 → 模块在哪里?→ 在 httpd 配置文件中加载
↓
PHP 模块执行 PHP 代码,返回 HTML 结果
↓
Apache 把 HTML 返回给用户浏览器
关键点:Apache 本身是”木头疙瘩”,只认识 HTML/静态文件。要让它处理 PHP,必须加载 mod_php(或通过 proxy_fcgi 转发给 php-fpm)。
2️⃣ 重启加载了什么?
当您执行 yum install -y php* 时,系统自动做了两件事:
| 动作 | 说明 |
|---|---|
| ① 安装了 PHP 和 Apache 的 PHP 模块 | 比如 /etc/httpd/modules/libphp.so |
| ② 在 Apache 配置中添加了加载指令 | 一般是 /etc/httpd/conf.d/php.conf 或 modules/ 目录下 |
php.conf 内容示例:
apache
# 加载 PHP 模块
LoadModule php_module modules/libphp.so
# 让 Apache 识别 .php 文件
AddHandler php-script .php
DirectoryIndex index.php
3️⃣ 为什么必须重启?
Apache 的模块是在启动时一次性加载到内存的,运行过程中不会自动重新读取配置文件。
text
安装 PHP 模块 → 配置文件变了(新增 LoadModule)
↓
不重启 → Apache 还在用旧的内存配置 → 不认识 PHP → 报错或下载 .php 文件
↓
重启 → Apache 重新读取所有配置文件 → 加载新模块 → 能处理 PHP 请求 ✅
安装MySQL数据库
# 安装mariadb数据库软件
[root@localhost ~]# yum install -y mariadb-server mariadb # mariadb-server 算是一种数据库的一种
# 启动数据库并且设置开机自启动
[root@localhost ~]# systemctl enable --now mariadb
# 设置mariadb的密码
[root@localhost ~]# mysqladmin password '123456'
# 验证数据库是否工作正常
[root@localhost ~]# mysql -uroot -p123456 -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+

⚠️ 一个小细节
mariadb(客户端)其实是 mariadb-server 的依赖包,会自动安装。所以写成 yum install -y mariadb-server 就够了,后面那个 mariadb 是多余的,但写上也没错。
mysqladmin 是什么?
- 这是 MariaDB/MySQL 自带的管理工具(由客户端包提供)
- 专门用来执行管理操作:改密码、创建/删除数据库、查看服务器状态、关闭服务等
这条命令具体做了什么?
text
mysqladmin → 连接到本地 MariaDB 服务(默认用 root 无密码)
↓
password '123456' → 将 root 用户的密码设置为 123456
⚠️ 安全警告(重要!)
bash
mysqladmin password '123456' # 这样写密码会暴露在命令历史中
更安全的做法:
bash
mysqladmin password # 不加密码,系统会交互式询问(输入时不可见)
Enter password: # 系统会提示输入新密码(更安全)
New password: ********
Confirm new password: ********
拆解这条命令:
| 参数 | 含义 |
|---|---|
mysql |
调用客户端工具 |
-uroot |
用 root 用户登录(-u 后面紧跟用户名,无空格) |
-p123456 |
密码是 123456(-p 后面紧跟密码,无空格) |
-e "show databases;" |
执行 SQL 语句并退出(不进入交互式界面) |
输出的三个数据库解释:
| 数据库名 | 作用 |
|---|---|
information_schema |
元数据仓库:存储所有数据库、表、列、权限等信息(只读,实际是内存虚拟表) |
mysql |
系统核心库:存储用户账号、权限、时区、日志等关键配置数据 |
performance_schema |
性能监控库:收集数据库运行时的性能指标(CPU、IO、锁等待等),用于调优 |
PHP探针测试
在==默认的网站根目录下==创建info.php
[root@localhost ~]# vim /var/www/html/info.php
<?php
phpinfo();
?>
写一个简单的PHP代码,可以使用==phpinfo函数查看PHP的信息,==从而检测是否成功解析PHP代码
编写好以后,我们访问:http://IP/info.php测试

默认httpd服务端根目录就是/var/www/html,客户端根据url自己匹配

数据库连接测试
编写PHP代码,用PHP来连接数据库测试
[root@localhost ~]# vim /var/www/html/mysql.php
<?php
$servername = "localhost";
$username = "root";
$password = "123456";
// 创建连接
$conn = mysqli_connect($servername, $username, $password);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "连接MySQL...成功!";
?>
完整执行流程图
text
用户访问 http://IP/mysql.php
↓
PHP 引擎执行代码
↓
尝试连接 MySQL(localhost, root, 123456)
↓
┌────┴────┐
↓ ↓
连接失败 连接成功
↓ ↓
die() 输出 echo 输出
错误信息 "连接成功"
↓ ↓
脚本终止 脚本结束
1️⃣ 一体机架构(您当前的学习环境)
text
┌─────────────────────────┐
│ 一台服务器 │
│ ┌──────┐ ┌──────────┐ │
│ │Apache│ │ MySQL │ │
│ │ PHP │ │MariaDB │ │
│ └──────┘ └──────────┘ │
└─────────────────────────┘
↑
用户访问(IP: 192.168.226.128)
- 特点:Web 和数据库在同一台机器
- 适用:学习、开发、小型个人网站
- 缺点:资源竞争、单点故障、无法独立扩展
2️⃣ 分离架构(生产环境标准)
text
┌──────────────┐ ┌──────────────┐
│ Web 服务器 │ │ 数据库服务器 │
│ ┌────────┐ │ 内网 │ ┌────────┐ │
│ │Apache │ │◄─────────►│ │ MySQL │ │
│ │ PHP │ │ 高速连接 │ │MariaDB │ │
│ └────────┘ │ │ └────────┘ │
└──────────────┘ └──────────────┘
↑ ↑
用户访问 数据存储
- 特点:各自独立,通过网络通信
- 适用:大多数企业级应用
- 优点:资源独立、可分别扩展、更安全
代码上的区别
一体机(您当前的写法)
php
$servername = "localhost"; // 或 "127.0.0.1"
因为数据库就在本机,直接用 localhost 连接。
分离架构(生产环境写法)
php
$servername = "192.168.1.100"; // 数据库服务器的实际 IP
// 或
$servername = "db.example.com"; // 数据库服务器的域名
==Web 服务器通过网络连接到另一台机器上的数据库。==
编写好以后,我们访问:http://IP/mysql.php测试:


安装phpmyadmin
由于我们还没有学习MySQL如何管理,我们可以部署phpmyadmin工具,该工具可以让我们可视化管理我们的数据库
# 移动到网站根目录
[root@localhost ~]# cd /var/www/html
# 下载phpmyadmin源码
[root@localhost ~]# wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip
# 解压软件包,并且重命名
[root@localhost ~]# unzip phpMyAdmin-5.1.1-all-languages.zip
[root@localhost ~]# mv phpMyAdmin-5.1.1-all-languages phpmyadmin
访问http://192.168.226.128/phpmyadmin测试:

个人博客
源码获取
下载typecho博客系统源码到/var/www/html/typecho
[root@localhost ~]# cd /var/www/html
# 创建typecho目录
[root@localhost ~]# mkdir typecho
[root@localhost ~]# cd typecho
[root@localhost ~]# wget https://github.com/typecho/typecho/releases/latest/download/typecho.zip
# 解压源码
[root@localhost ~]# unzip typecho.zip
创建数据库
点击创建数据库

安装博客系统
下面就可以开始进入网站安装的部分了,访问博客系统页面
http://IP/typecho

提示安装目录下面的/usr/uploads没有权限,那么我们手动赋予该目录w权限
[root@localhost typecho]# chmod a+w usr/uploads/

填写数据库信息,密码为部署mariadb时设置的123456




==LAMP==架构理解:
1. LAMP 架构组件关系(“一体性”的实质)
LAMP是一套提供完整 Web 服务处理闭环:
- Linux:提供操作系统内核、进程调度、文件系统和网络协议栈,作为底层运行环境。
- Apache HTTP Server:作为 Web 服务器进程,监听 HTTP 端口(默认 80),解析 HTTP 请求,并通过模块化架构加载扩展功能。在传统 LAMP 中,它加载
mod_php模块来执行 PHP 代码。 - PHP:作为服务器端脚本解释器,以 Apache 模块 (
mod_php) 或 FastCGI 进程管理器 (php-fpm) 形式运行,负责解析并执行后端业务逻辑。 - MySQL/MariaDB:作为关系型数据库管理系统(RDBMS),作为独立的守护进程运行,监听特定端口(默认 3306),提供数据的持久化存储、检索和事务处理。
PHP 脚本通过数据库扩展(如 mysqli 或 PDO)通过 TCP 协议与 MySQL 进程通信。
2. 软件包管理机制(“模块化”处理)
在 Linux 发行版(如 Rocky Linux)中,采用包管理器(如 yum 或 dnf)管理依赖:
- 主服务(如
httpd)是一个核心包。 - 扩展/模块由独立的软件包提供,例如
php(PHP 解释器)、php-mysqlnd(连接 MySQL 的驱动)、mod_php(Apache 模块)。 - 安装这些扩展包后,包管理器会自动在服务配置目录(如
/etc/httpd/conf.d/)中生成.conf配置文件。 - Web 服务器启动时,会读取这些配置文件,动态加载所需的共享对象(
.so文件)或启动对应的进程。
3. 前后端架构界定(“后端”的实质)
整个 Web 系统遵循 C/S(客户端/服务器)架构:
- 前端(客户端):主要是指用户的 Web 浏览器(如 Chrome),负责向服务器发送 HTTP 请求,并接收、解析、渲染服务器返回的 HTML、CSS、JavaScript 资源。
- 后端(服务端):指运行在物理或虚拟服务器上的全部服务和进程,包括:
- Web 服务器进程 (Apache):负责 HTTP 协议的请求响应。
- 逻辑处理进程 (PHP):负责动态生成响应内容。
- 数据库进程 (MySQL):负责数据的存储与读取。 这些后端进程运行在服务器端,不直接暴露给终端用户,而是通过网络协议彼此交互,最终向客户端返回处理后的结果。
4. 扩展机制:安装包即添加模块
无论是 yum 还是 apt 安装软件包,本质上是向特定的服务(Apache 或 Nginx)注入对应的功能模块或独立的处理进程。
- 数据库是独立的模块:MySQL 安装后是一个独立的守护进程(服务),拥有独立的进程空间、端口(3306)和文件系统。
- PHP 也是独立的模块:PHP 通常以
php-fpm(独立进程管理器)或mod_php(嵌入 Apache 的模块)形式运行,专门负责解析.php脚本。
5. 静态服务器 vs 动态服务器
- 静态服务器:Apache 和 Nginx 默认是“静态 Web 服务器”。负责接收 HTTP 请求,并将硬盘上预先写好的
.html或.jpg等静态文件原封不动地发送给浏览器。 - 动态扩展:为了返回根据用户情况变化的页面,管理员挂载了 PHP 处理能力。当请求对象是
.php文件时,Apache 或 Nginx 会将解析任务转交给 PHP。
6. PHP、数据库与“动态返回”的完整工作流
- 触发(请求到达):用户在浏览器访问
http://ip/mysql.php,Apache 收到请求,识别为.php文件。 - 执行(PHP 处理):Apache 将执行权交给 PHP。PHP 解释器运行代码。
- 查询(连接数据库):PHP 代码调用
mysqli_connect()等函数。PHP 进程通过 TCP 协议(例如 TCP 127.0.0.1:3306)向本机的 MySQL 守护进程发送 SQL 查询语句(如SELECT * FROM users)。 - 获取(数据库返回):MySQL 接收到 SQL 指令,在磁盘或内存中查找数据,将结果集以二进制流的形式返回给 PHP 进程。
- 生成(PHP 组装):PHP 接收到数据库返回的数据(数组或对象),利用它生成动态的 HTML 字符串(例如
echo "连接MySQL...成功!";)。 - 返回(响应客户端):PHP 将生成的 HTML 完整字符串交还给 Apache,Apache 将其封装成 HTTP 响应包,通过网络发回给用户的浏览器。
技术层面总结:Apache 负责 HTTP 协议通信,PHP 负责业务逻辑解析,MySQL 负责数据持久化存储与检索。三者作为独立的进程,通过 TCP 协议互相连接,实现了数据的动态存取和展示。