一. Apache 虚拟主机
1. 虚拟主机是什么
虚拟主机是指在单一机器上运行多个网站, 虚拟主机可以基于IP, 基于主机名, 或者是端口号, 这些站点运行在同一个物理服务器上 用户在访问是不会感到异常的.
2. Apache 支持的虚拟主机
2.1 基于名称和 基于IP 的虚拟主机选择
- apache 支持基于ip的虚拟主机配置, 如果需要配置多个主机, 则需要为主机分配多个IP地址
- 使用基于名称的虚拟主机 通常更加简单, 只需要配置DNS 服务器将每个主机名映射到正确的IP 地址上, 然后配置Apache HTTP Server 识别主机名, 基于名称的主机可以减少对IP地址的需求.
2.2 基于域名的虚拟主机
- 服务如何识别基于名称的虚拟主机解析, 服务器会首先选择匹配的 IP 的后, 才选择合适的基于名称的虚拟主机, 在所有 VirtualHost 指令中使用通配符(*) 作为IP 地址使得基于IP 的映射.
- 当强求达到, 服务器会根据 <VirtualHost> 根据请求使用IP地址 和端口找到最佳匹配参数, 如果多个虚拟主机包含最佳匹配地址和端口. Apache 会进一步匹配 ServerName 和 ServerAlias 指令, 请求中存在服务器名称进行比较.
2.2.1 配置示例
<VirtualHost *:80>
ServerName www.hostname1.com
ServerAlias hostname.com
DocumentRoot '/data/wwwroot/host1'
</VirtualHost>
<VirtualHost *:80>
ServerName www.hostname2.com
DocumentRoot '/data/wwwroot/host2'
</VirtualHost>
2.2.2 配置
- 编辑配置文件
conf/extra/httpd-vhosts.conf
- 在本地host文件修改
- 添加本地测试文件
- 重启 Apache
[root@node10009 apache24]# ./bin/apachectl -k restart
[root@node10009 apache24]# ss -tan | grep 80
LISTEN 0 128 :::80 :::*
[root@node10009 apache24]#
- 测试
2.3 基于IP的虚拟主机
- 基于IP 虚拟主机是一种根据接受请求的IP地址和端口应用你不同指令的方法, 最常见的是不同端口或接口上为不同的站点提供服务.
- 多数情况下基于 主机名的虚拟主机 更加方便,允许多个虚拟主机共享单个地址/端口
2.3.1 系统需求
- 基于IP 时, 系统必须为每个基于IP的虚拟主机提供 IP地址/端口组合.
- 这里可以通过一个网卡配置多个IP地址, 或者多个网卡上的多个IP地址.
2.3.2 设置Apache
- apache 需要为对虚拟主机的IP和端口进行监听,
2.3.3 配置示例
<VirtualHost 192.168.10.9:80>
ServerAdmin user@host.com
DocumentRoot "/data/wwwroot/host1"
ServerName www.host1.com
</VirtualHost>
2.3.4 配置
- 添加ip地址
[root@node10009 apache24]# ip addr add 192.168.10.109/24 dev ens33
[root@node10009 apache24]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:8f:4e:4a brd ff:ff:ff:ff:ff:ff
inet 192.168.10.9/24 brd 192.168.10.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.10.109/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe8f:4e4a/64 scope link
valid_lft forever preferred_lft forever
- 现在ens33 上有两个ip地址(192.168.10.9, 192.168.10.109)
- 修改httpd配置文件
- vim conf/extra/httpd-vhosts.conf
<VirtualHost 192.168.10.9:80>
ServerAdmin fangfc@localhost.com
DocumentRoot "/opt/case/wwwroot/host1"
ServerName localhost
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
<VirtualHost 192.168.10.109:80>
DocumentRoot "/opt/case/wwwroot/host2"
ServerName localhost
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
- 重启 httpd
[root@node10009 apache24]# ./bin/apachectl -k restart
[root@node10009 apache24]# ss -tln | grep 80
LISTEN 0 128 :::80 :::*
- 测试
2.3 基于 端口的虚拟主机
基于端口的虚拟主机 和基于ip的虚拟主机一样, 只是修改了配置文件上的端口号, 并且需要在主配置文件上添加需要监听的端口号
- 修改主配置文件
- 添加需要监听的端口
vim conf/httpd.conf
#Listen 12.34.56.78:80
Listen 80
Listen 8080
Listen 8081
- 修改vhost 配置文件
vim conf/extra/httpd-vhosts.conf
<VirtualHost *:8080>
ServerAdmin fangfc@localhost.com
DocumentRoot "/opt/case/wwwroot/host1"
ServerName localhost
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
<VirtualHost *:8081>
DocumentRoot "/opt/case/wwwroot/host2"
ServerName localhsot
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
- 重启服务
[root@node10009 apache24]# ./bin/apachectl -k restart
[root@node10009 apache24]# ss -tln | grep 80
LISTEN 0 128 :::8080 :::*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::8081 :::*
- 测试
二. Apache 身份认证
1. 概述
- 身份认证是验证用户是否具有权限进入指定目录获取信息 的过程控制.
- 前提条件:
- 该配置需要在主服务配置文件中(通常是在 <Directory> 部分) 或者每个目录的单独配置文件(.htaccess文件)中.
- 添加
AllowOverride AuthCofnig
配置项,
2. 配置
- 创建用户密码文件
[root@node10009 apache24]# ./bin/htpasswd -cm /opt/app/apache24/passwd/.passwd fangfc
New password:
Re-type new password:
Adding password for user fangfc
[root@node10009 apache24]# cat passwd/.passwd
fangfc:$apr1$1zq3VvB5$sihTm0kAoGghVYVSa.HFJ/
[root@node10009 apache24]#
- 设置配置文件
vim conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
DocumentRoot "/opt/case/wwwroot/host1"
ServerName www.host1.cc
<Directory "/opt/case/wwwroot/host1">
AllowOverride AuthConfig
AuthName "host1 auth"
AuthType Basic
AuthUserFile "/opt/app/apache/passwd/.passwd"
Require valid-user
</Directory>
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
- 配置项
AllowOverride AuthConfig
# 允许使用 .htaccess 配置文件覆盖, 可以设置允许覆盖的指令
AuthConfig: 允许使用授权指令
FileInfo: 允许使用控制文档类型
Indexes: 允许使用指令控制目录索引
Limit: 允许使用指令 控制主机访问(allow, Deny, Order)
Options: 允许使用指定的 配置性
AuthName "host1 auth"
# 设置验证域 的名称, 这个域被提供给客户端, 便于管理用户和密码.
AuthType Basic
# 设置验证用户身份的类型, 可用的身份类型是:
None, Basic(mod_uath_basic 提供), Digest(mod_auth_digest 提供), Form(mod_auth_form 提供)
AuthUserFile "/opt/app/apache/passwd/.passwd"
# 用于设置 包含用户身份和密码的 列表文件的地址
Require valid user
# 根据特定授权和指令, 来限制允许的用户
all granted: 无条件允许访问
all denied 无条件拒绝
env env-var 设置一个给定的环境变量时才允许访问
method http-method [..] 允许给定的 HTTP 方法访问
user UserID 指定用户才可以访问资源
group GroupID 指定用户组可以访问资源
valid-user 有效的用户 允许访问
ip x.x.x.x 指定ip/范围 的用户可以访问
-
重启服务
-
测试
三. Apache 重定向
1. rewrite 模块介绍
- mod_rewrite 模块提供了基于正则的动态修改传入URL 请求的方法, 允许将任意URL 映射到 另一个URL.
- 支持无限数量的规则 和规每个规则的附加条件, 提供灵活强大的 URL 操作机制, URL操作依赖于各种测试: 服务器变量, 环境变量, HTTP 标头, 时间戳, 外部数据库查找 以及各种其他程序处理.
2. 域名跳转设置
- 修改配置文件中 老的站点 跳转到新的站点
<VirtualHost *:80>
DocumentRoot "/opt/case/wwwroot/host1"
ServerName www.host1.cc
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule "^/(.*)$" http://www.host2.cc/$1 [R=301,L]
</IfModule>
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/opt/case/wwwroot/host2"
ServerName www.host2.cc
ServerAlias host2.cc
</VirtualHost>
- 配置解析
<IfModule mod_rewrite.c>
# IfModule 是用于判断是否存在模块,
RewriteEngine on
# 是否启用rewrite引擎
RewriteRule "^/(.*)$" http://www.host2.cc/$1 [R=301,L]
# 定义Rewrite 规则, 可以定义多个,
语法是: RewriteRule Pattern Substitution [Flags]
Pattern: 是正则表达式, 用于定位位置
Substitution 替换上面匹配到的 URL 的, 可以是 文件路径, URL, 网址, -
Flags: 特殊操作标志位,
</IfModule>
- 测试
[root@node10009 apache24]# curl host1.cc
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.host2.cc/">here</a>.</p>
</body></html>
[root@node10009 apache24]#
三. Apache 日志配置
1. 概述
- apache 提供全面且灵活的的日志记录功能.
- apache 提供不同机制, 记录方式, 记录服务器上发生的事情, 从初始的请求到URL 映射过程, 到连接最后总解决方案, 包括流程中可能发生的错误, 除此, 第三方模块也可以提供日志记录功能, 或者写入日志, CGI 程序也可以向服务器记录错误日志.
2. 错误日志
- 服务器错误日志(其名称和位置是由 ErrorLog 指令设置), 是最重要的日志文件, 记录了Apache httpd 诊断信息, 和错误信息.
- 日志记录格式由
ErrorLogFormat
指令设置.可以自定义格式.
2.1 记录格式 - ErrorLogFormat
-
设置错误日志记录条目的格式
-
示例:
ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [clietn %a] %M"
-
可选参数:
%% 百分号
%a 客户端IP地址和 端口
%{c}a 底层对等IP地址和端口 (负载均衡会修改客户端地址)
%A 本地IP地址和端口
%{name}e 环境变量名称
%E APR/OS 错误的状态码和字符串
%F 源文件和日志调用 行号
%{name}i 请求头名称
%k 连接的保持活动的 请求数
$l Loglevel 日志等级
%L 请求日志ID
%{c}L 连接日志ID
%m 记录消息的模块
%M 实际的日志消息
%{name}n 请求备注名称
%P 当前进程ID
%T 当前线程ID
%t 当前时间
%v 服务器规范(ServerName)
$V 设置请求提供者的服务器名称
\ 非字符分隔符
% 字符分割福(无输出)
2.2 记录等级 -- LogLevel
-
用户控制ErrorLog 记录日志的等级,和详细程度
-
可选参数
emerg 紧急情况- 系统无法使用, 如: 子线程无法打开锁定文件
alert 需要立即抢救 如: getwuid, 无法从uid 获得用户名
crit 关键报错 如: 无法获得套接字, 退出子线程
error 错误信息
warn 警告信息
notice 正常 但是重要的信息
info 普通消息
debug 调试信息
3. 访问日志
- 服务器访问日志记录服务处理的所有请求, 记录内容根据
CustomLog
和LogFormat
指令控制. - 通用日志记录格式:
LogFormat "%h %l %u %t \"%r\" %>s %b"
示例:
日志:
192.168.10.1 - fangfc [04/Dec/2018:14:26:46 +0800] "GET / HTTP/1.1" 200 54
含义:
192.168.10.1 (%h)
向服务器发送请求的客户端的iP地址,
- (%l)
如果显示是 - 表示字段米诶有信息,
fangfc (%u)
http 身份验证确定的用户标识符,
[04/Dec/2018:14:26:46 +0800] (%t)
系统当前时间
"GET / HTTP/1.1" ($r)
客户端的请求头, 以及http 协议信息
200 ($>s)
服务器响应的状态码,
54 (%b)
返回内容的大小, 如果没有内容则是 -
3.1 设置访问日志 -- CustomLog
-
设置日志的文件名和格式, 指定了日志格式, 并且可以选择使用环境变量是请求特这称为条件.
-
格式:
CustomLog file|pipe format|nickname [env=[!]environment-variable|expr=expression]
-
选项说明:
参1:
file:
文件名
pipe:
管道符, 可以跟上程序路径. 使用程序对日志控制
参2:
format|nickname
有 LogFormat 指令设置的内容也是日志格式部分中显示的格式字符串
参3: 可选
控制是否记录特定请求.
3.2 日志记录格式 LogFormat
-
用于控制日志记录格式,
-
格式:
LogFormat format|nickname [nickname]
- 参1: 记录格式
- 参2: 记录格式的名称, 以便后面使用
-
记录格式可选项:
%a 客户端IP
%A 本地IP
%B 响应大小(不包含http头)
%b 相应大小(不包含HTTP 头), 以 CLF格式, 即没有发送字节时, 显示 - , 不显示0
%D 服务请求需要的时间, 微秒单位
%{VARNAME}e 环境变量VARNAME内容
%f 文件名
%h 远程主机名
%H 协议
%k 该链接的 keepalive 请求数,
%l 远程日志名称(有 identd 提供)
%L 来自错误日志的请求日志ID, 查找匹配的错误日志行, 查看那些请求导致错误
%m 请求方法
%{VARNAME}n 来自一个模块 note VARNAME内容
$p 为请求提供服务的 子进程 ID
%q 查询字符串
%r 第一行请求
%R 生成响应的处理程序
%s 状态, 对于内部重定向的请求, 原始请求的状态, 使用 %>s 是最终状态
%t 收到请求的时间
%T 服务请求需要的时间,
%u 远程用户, (需要验证)
%U 请求的 URL 不抱哈任何查询字符串
%v 服务器名
$X 响应完成时连接状态
X 表示完成前终止, + 发送响应后可以保持连接, - 发送响应后关闭连接
%I 收到字节数, 包括请求和标题, 不可为0
%O 发送字节数, 包含标题, 极少数情况下可以为0
%S 传输的字节, 不可为0
4. 设置请求属性 -- SetEnvIf
-
有时, 需要根据客户请特征从访问日志中排除某些条目, 需要通过环境变量 设置, 必须设置环境变量只是请求满特定的请求条件, 通过
SetEnvIf
社会中 env .然后在从 CustomLog 中指定的日志记录方式进行排除. -
SetEnvIf
指令根据请求属性定义环境变量, 第一个参数中指定属性, 是以下4中之一:-
- HTTP请求头字段, 如:Host, Uset-Agent, Referer, Accept-Language, 正则表达式可用于指定一组请求标头
-
- 请求以下方面
- Remote_Host 发出请求的客户端的主机名
- Remote_Addr 发出请求的客户端IP 地址
- Server_Addr 收到请求的服务的IP 地址
- Request_method 收到请求的方法(GET,POST, ..)
- Request_Protocol 用于请求的协议的名称和版本(如 "HTTP/0.9", "HTTP/1.1")
- Request_URI HTTP 请求行上请求的资源,
-
- 与请求现骨干的列表的环境变量的名称, 允许SetEnvIf 针对先前匹配结果测试,
-
-
参2(正则表达式) 如果正则匹配成功则计算其余参数.
4.1 示例
SetEnvIf Request_URI "\.gif$" img # 设置img 格式图片访问的变量为 img
SetEnvIf Request_URI "\.jpg$" img
SetEnvIf Referer "www\.hostname\.com" host1 # 访问 www.hostname.com 时, 设置变量为 host1
4.2 配置实例
- 未添加图片日志过滤
- 添加配置
<VirtualHost *:80>
DocumentRoot "/opt/case/wwwroot/host2"
ServerName www.host2.cc
ServerAlias host2.cc
<IfModule mod_setenvif.c>
SetEnvIf Request_URI "\.gif$" img
SetEnvIf Request_URI "\.png$" img
SetEnvIf Request_URI "\.ico$" img
SetEnvIf Request_URI "\.jpg$" img
</IfModule>
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "/opt/case/wwwroot/host2/logs/access.log" common env=!img
</VirtualHost>
- 重启测试
[root@node10009 apache24]# ./bin/apachectl -t
Syntax OK
[root@node10009 apache24]# ./bin/apachectl -k restart
四. Apache 日志切割
apache 服务提供了日志切割工具,rotatelogs
, 支持基于日志时间 间隔或大小切割
1. rotatelogs 日志工具
1.1 语法:
rotatelogs [-l] logfile [rotationtime [offset]] | [filesizeM]
1.2 选项解释
-l:
使用本地时间切割, 而不是使用 GMT 作为基准
logfile:
记录日志的文件路径, 可以使用 strftime 的格式创建文件名, strftime是 %Y%m%d 记录年月日, 用于保留历史日志, 可以使用crontab做定期删除过期日志.
rotationtime:
日志切割的 间隔时间, 单位是秒, 所以需要按天切割, 则是 86400 秒(60*60*24)
filesize(B|K|M|G)
按照日志文件大小切割,
offset:
和 UTC 时间的偏移分钟数, 例如中国是 +8小时地区, 则该参数应当为 +480
END