linux的Apache

作者:

在

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)

image-20260805190131257

==理解==:主配置文件,配置权限的目的

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 不同

image-20260805221722847

给网卡添加临时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”

image-20260805223616673

image-20260805224319406

  1. 基于多IP加一个端口号

image-20260806081535917

image-20260806081601513


服务日志

httpd 有两种常见日志类型:==访问日志和错误日志==,==错误日志==使用标准 syslog 级别,==按严重性递增排序==。

日志配置文件

主配置文件日志配置相关定义块

image-20260806084026946

不同工具访问

第一部分:日志格式解释(每列代表什么?)

这条日志使用的是标准的 Combined Log Format(组合日志格式)。按照从左到右的顺序,各个字段的含义如下:

  1. 192.168.226.1:客户端 IP 地址。这是发起请求的电脑(也就是您的本机)的IP。
  2. -:远程登录名(Identd)。因为大多数服务器不启用身份验证检查,所以通常是横杠“-”。
  3. -:认证用户名。如果您的网站需要HTTP基本认证(输入账号密码),这里会显示登录的用户名;否则也是横杠“-”。
  4. [05/Aug/2026:12:02:10 +0800]:时间戳。
    • 格式为 [日/月/年:时:分:秒 时区]。
    • 也就是 2026年8月5日,12点02分10秒,东八区(北京时间)。
  5. "GET / HTTP/1.1":请求行。
    • GET:请求方法(获取网页)。
    • /:请求的路径(即网站根目录)。
    • HTTP/1.1:使用的HTTP协议版本。
  6. 200:HTTP 状态码。表示请求成功,服务器返回了内容(200是成功,404是找不到页面,408是请求超时等)。
  7. 7829:响应体大小(字节)。服务器返回给客户端的网页数据量(不含响应头)。
  8. "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)”不同,服务器只是把收到的东西如实记录下来了。


image-20260806084240417

image-20260806085203107

三种网卡模式上网详解

image-20260806102513737

image-20260806102523015

image-20260806102538824

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

image-20260806103726069

    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

image-20260806104625605


URL匹配规则

Apache httpd的URL匹配规则主要包括以下几种指令:

  1. <Location> : 基于URL路径进行匹配。
  2. <LocationMatch> : 使用正则表达式进行URL路径匹配。
  3. <Directory> : 基于服务器文件系统的目录路径进行匹配。
  4. <DirectoryMatch> : 使用正则表达式进行目录路径匹配。
  5. <Files> : 基于文件名进行匹配。
  6. <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 禁用所有额外特性 严格安全策略

image-20260806141227056

实践

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

image-20260806142042538

image-20260806142057182

案例分析

使用 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
# 通过浏览器访问测试验证

image-20260806191826191

image-20260806191942499


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
# 通过浏览器访问测试验证

==理解==:

  1. 服务器启动时,主配置文件(site02.conf)已经加载,AllowOverride Options=Indexes 已经生效。
  2. 如果修改主配置文件,需要重启 httpd 服务,这会影响业务连续性。
  3. 为了不重启服务,可以使用 .htaccess 文件在运行中动态覆盖指定目录的配置。
  4. AllowOverride 后面跟的选项(如 Options=Indexes)限定了哪些指令可以被覆盖,未列出的指令即使写在 .htaccess 里也无效。
  5. 在 .htaccess 中必须重新声明 Options Indexes,不能只写 Indexes,因为 .htaccess 里写的是完整的 Apache 配置指令语法。

AllowOverride 定义了 .htaccess 的“权限边界”,而 .htaccess 是 Apache 实现“不停机动态配置”的核心机制,两者配合可实现细粒度的目录级策略控制。


==实践==:

image-20260806201734696

image-20260806201821394

image-20260806203112505


访问控制

针对各种资源,通常基于两种方式:客户端来源地址和用户账号来进行访问控制

基于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 允许所有认证用户,或指定用户/组)

image-20260806235310220

image-20260806235505859

==特殊文件==:. 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" 密码文件位置,里面存了用户名和加密密码

image-20260807002902856

image-20260807002940874

image-20260807003010188


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 目录下找这个图片。

image-20260807101330671

[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

image-20260807102403777


重定向 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

image-20260807145458842

image-20260807145513691

image-20260807145747296


网页压缩技术

网页压缩技术主要通过 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),在某些云服务器或设置了强防火墙的环境下,可能需要额外开启端口权限才能访问。

image-20260807154343341

image-20260807154537776


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 必须与用户访问的域名完全一致。
  • -addtext: 这是最关键的一点。从2015年起,主流浏览器要求证书必须包含 SAN(Subject Alternative Name,主题备用名称) 字段。所以你在这里明确指定了该证书同时适用于域名 ssl.eagleslabtest.com 和IP 172.16.175.129。这使得你的测试环境在浏览器中能最大程度避免证书无效警告。

image-20260807193532306

image-20260807193545515

image-20260807193552596

image-20260807194034990

image-20260807194254372

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,这种模式采用的是预派生子进程方式,用单独的子进程来处理请求,子进程间互相独立,互不影响,大大的提高了稳定性,但每个进程都会占用内存,所以消耗系统资源过高。

image-20260807200222373

worker 模式

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

image-20260807200333643

event 模式

这个是 Apache 中最新的模式,在现在版本里的已经是稳定可用的模式。它和 worker 模式很像,最大的区别在于,它解决了 keepalive 场景下 ,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,挂在那里等待,中间几乎没有请求过来,一直等到超时)。

event MPM 中,会有一个专门的线程来管理这些 keepalive 类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样,一个线程就能处理多个请求,实现了异步非阻塞。

event MPM 在遇到某些不兼容的模块时会失效,将会回退到 worker 模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。

image-20260807200502455

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

image-20260807201058105

image-20260807204925499


LAMP架构

LAMP就是由Linux+Apache+MySQL+PHP组合起来的架构

并且Apache默认情况下就内置了PHP解析模块,所以无需CGI即可解析PHP代码

请求示意图:

image-20260807200605179

安装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环境

  1. 安装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.
  1. 重启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 |
+--------------------+

image-20260807211955223

⚠️ 一个小细节

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测试

image-20260807212535325

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

image-20260818103841713

数据库连接测试

编写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测试:

image-20260818111706164

image-20260818111716248


安装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测试:

image-20260818113050966

个人博客

源码获取

下载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

创建数据库

点击创建数据库

image-20260818124939893

安装博客系统

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

http://IP/typecho

image-20260818125304894

提示安装目录下面的/usr/uploads没有权限,那么我们手动赋予该目录w权限

[root@localhost typecho]# chmod a+w usr/uploads/

image-20260818125816377

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

image-20260818125906376

image-20260818130341238

image-20260818130758265

image-20260818135300549

==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、数据库与“动态返回”的完整工作流

  1. 触发(请求到达):用户在浏览器访问 http://ip/mysql.php,Apache 收到请求,识别为 .php 文件。
  2. 执行(PHP 处理):Apache 将执行权交给 PHP。PHP 解释器运行代码。
  3. 查询(连接数据库):PHP 代码调用 mysqli_connect() 等函数。PHP 进程通过 TCP 协议(例如 TCP 127.0.0.1:3306)向本机的 MySQL 守护进程发送 SQL 查询语句(如 SELECT * FROM users)。
  4. 获取(数据库返回):MySQL 接收到 SQL 指令,在磁盘或内存中查找数据,将结果集以二进制流的形式返回给 PHP 进程。
  5. 生成(PHP 组装):PHP 接收到数据库返回的数据(数组或对象),利用它生成动态的 HTML 字符串(例如 echo "连接MySQL...成功!";)。
  6. 返回(响应客户端):PHP 将生成的 HTML 完整字符串交还给 Apache,Apache 将其封装成 HTTP 响应包,通过网络发回给用户的浏览器。

技术层面总结:Apache 负责 HTTP 协议通信,PHP 负责业务逻辑解析,MySQL 负责数据持久化存储与检索。三者作为独立的进程,通过 TCP 协议互相连接,实现了数据的动态存取和展示。