1. httpd 简介
apache 特性:
- 高度模块化: core+modules
- DSO: 动态加载/卸载: 需要可以添加模块, 不需要就可以卸载, 节约内存空间
- MPM: Multi-processing Module, 多路处理模块, 通过修改MPM, 来影响apache接受请求的模式
apache 功能:
- 虚拟主机: IP, Port, FQDN
- CGI: Common Gateway Interface, 通用网管接口
- 反向代理
- 负载均衡
- 路径别名
- 丰富的用户认证机制: basic, digest
- 支持第三方模块
配置文件:
如:ServerRoot指令: 定义了服务器安装的基础目录, 也是后续所有文件的根路径.
配置文件中的相对路径, 相对的是 Server Root(服务器根路径) 的路径.
2. 编译安装
CentOS 7.8.2003 编译安装 httpd 最新版, httpd-2.4.46
说明: 由于httpd可以运行在不同的操作系统, 因此, 对于不同的操作系统需要开发不同版本的httpd, 这样会造成开发团队过多, 因此apache开发了APR, Apache Portable Run-time Library, Apache可移植运行库, ARP将不同的操作系统进行了抽象, 使得开发者可以面对APR开进行应用开发, 而无需直接面对操作系统.
但是, 应用程序和apr是存在依赖关系的. 因此, 如果系统自带的APR版本过低, 就要先编译APR, 在编译Apache.
编译httpd的两种方式:
分开编译: 太麻烦
- 先编译apr
- 再编译apr-util
- 再编译apache
一起编译:
将三者一起编译, 把apr和apr-util的源代码添加到httpd的目录里.
0. 安装源码编译依赖包
yum -y install gcc make pcre-devel openssl-devel expat-devel
1. 下载 httpd, apr, apr-util 源码包到统一的目录
[13:47:09 root@centos7-3 /data/prac]#ll
total 8292
-rw-r--r-- 1 root root 872238 Sep 2 13:41 apr-1.7.0.tar.bz2
-rw-r--r-- 1 root root 428595 Sep 2 13:41 apr-util-1.6.1.tar.bz2
-rw-r--r-- 1 root root 7187805 Sep 2 13:28 httpd-2.4.46.tar.bz2
2. 解压
[13:49:06 root@centos7-3 /data/prac]#tar xf httpd-2.4.46.tar.bz2
[13:49:21 root@centos7-3 /data/prac]#tar xf apr-util-1.6.1.tar.bz2
[13:49:28 root@centos7-3 /data/prac]#tar xf apr-1.7.0.tar.bz2
3. 将 apr, apr-util, 与 httpd 源码合并
当然, 也可以分开顺序编译, 先编译 apr, 再编译 apr-util, 最后编译httpd
[13:51:23 root@centos7-3 /data/prac]#mv apr-1.7.0 httpd-2.4.46/srclib/apr
[13:51:45 root@centos7-3 /data/prac]#mv apr-util-1.6.1 httpd-2.4.46/srclib/apr-util
[13:51:57 root@centos7-3 /data/prac]#ls httpd-2.4.46/srclib/
apr apr-util Makefile.in
4. 将三个源码包一起编译
[13:54:15 root@centos7-3 /data/prac]#cd httpd-2.4.46/
[14:00:00 root@centos7-3 /data/prac/httpd-2.4.46]#./configure \
--prefix=/app/httpd24 \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork \
--with-included-apr #指定编译包括apr和apr-util
如果需要修改apache默认工作模式, 可以在编译安装的时候指定, 也可以编译安装后, 再去修改配置文件, 然后重启服务.
--with-mpm=MPM Choose the process model for Apache to use by
default. MPM={event|worker|prefork|winnt} This will
be statically linked as the only available MPM
unless --enable-mpms-shared is also specified.
make && make install
5. 修改PATH变量
[14:59:29 root@centos7-3 /data/prac/httpd-2.4.46]#echo 'PATH="/app/httpd24/bin:$PATH"' > /etc/profile.d/httpd24.sh
[15:02:50 root@centos7-3 /data/prac/httpd-2.4.46]#. /etc/profile.d/httpd24.sh
6. 创建apache账户, 指定其为httpd运行用户和用户组
先利用apachectl启动httpd, 观察默认用户, 默认用户为daemon
[15:03:44 root@centos7-3 /data/prac/httpd-2.4.46]#apachectl
[15:06:06 root@centos7-3 /data/prac/httpd-2.4.46]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 [::]:80 [::]:*
[15:06:09 root@centos7-3 /data/prac/httpd-2.4.46]#ps aux | grep httpd
root 57952 0.0 0.1 99576 2392 ? Ss 15:06 0:00 /app/httpd24/bin/http
daemon 57953 0.0 0.0 99576 1608 ? S 15:06 0:00 /app/httpd24/bin/http
daemon 57954 0.0 0.0 99576 1608 ? S 15:06 0:00 /app/httpd24/bin/http
daemon 57955 0.0 0.0 99576 1608 ? S 15:06 0:00 /app/httpd24/bin/http
daemon 57956 0.0 0.0 99576 1608 ? S 15:06 0:00 /app/httpd24/bin/http
daemon 57957 0.0 0.0 99576 1608 ? S 15:06 0:00 /app/httpd24/bin/http
root 57960 0.0 0.0 112808 968 pts/1 R+ 15:06 0:00 grep --color=auto httpd
创建apache用户 --> 修改配置文件, 指定以apache来运行httpd --> 重启httpd
[15:08:17 root@centos7-3 /data/prac/httpd-2.4.46]#useradd -s /sbin/login -r apache
[15:10:17 root@centos7-3 /data/prac/httpd-2.4.46]#vim /app/httpd24/conf/httpd.conf
#
User apache
Group apache
[15:14:17 root@centos7-3 /data/prac/httpd-2.4.46]#apachectl restart
[15:14:23 root@centos7-3 /data/prac/httpd-2.4.46]#ps aux | grep httpd
root 57952 0.0 0.1 99576 2960 ? Ss 15:06 0:00 /app/httpd24/bin/httpd
apache 58028 0.0 0.0 99576 1824 ? S 15:14 0:00 /app/httpd24/bin/httpd
apache 58029 0.0 0.0 99576 1824 ? S 15:14 0:00 /app/httpd24/bin/httpd
apache 58030 0.0 0.0 99576 1824 ? S 15:14 0:00 /app/httpd24/bin/httpd
apache 58031 0.0 0.0 99576 1824 ? S 15:14 0:00 /app/httpd24/bin/httpd
apache 58032 0.0 0.0 99576 1824 ? S 15:14 0:00 /app/httpd24/bin/httpd
root 58034 0.0 0.0 112808 968 pts/1 R+ 15:14 0:00 grep --color=auto httpd
7. 配置man帮助
#添加到man_db.conf文件里
vim /etc/man_db.conf
MANDATORY_MANPATH /app/httpd24/man
8. 设置开机自动启动
- 将/app/httpd24/bin/apachetrl start添加到/etc/rc.d/rc.local --> CentOS 6版本
vim /etc/rc.,d/rc.local
/app/httpd24/bin/apachectl start
#修改权限
chmod +x /etc/rc.d/rc.local
- 创建service unit文件 --> CentOS 7以上版本
[15:14:25 root@centos7-3 /data/prac/httpd-2.4.46]#vim /lib/systemd/system/httpd.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
ExecStart=/app/httpd24/bin/apachectl start
ExecReload=/app/httpd24/bin/apachectl graceful
ExecStop=/app/httpd24/bin/apachectl stop
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
#关闭当前正在运行的httpd进程
apachectl stop
#重新加载daemon
systemctl daemon-reload
#设置httpd开启自启
systemctl enable --now httpd
#reboot, 验证httpd开启自启
9. 验证
[15:34:10 root@centos7-3 ~]#curl 10.0.0.73 | grep 'Testing'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4897 100 4897 0 0 642k 0 --:--:-- --:--:-- --:--:-- 683k
<h1>Testing 123..</h1>
10. 修改默认页面再测试
[16:05:51 root@centos7-3 ~]#vim /app/httpd24/htdocs/index.html
<html><body><h1>Welcome to HTTPD!</h1></body></html>
[16:06:11 root@centos7-3 ~]#curl 10.0.0.73
<html><body><h1>Welcome to HTTPD!</h1></body></html>
3. httpd 常见配置
准备工作:
- 为了方便后续用域名测试访问, 需要修改本机的hosts文件, 绑定域名和ip
IP: 10.0.0.187
域名: www.httpd.test
#Windows主机的hosts文件路径
C:\Windows\System32\drivers\etc\hosts
10.0.0.187 www.httpd.test
- 修改配置文件, 指定自定义配置文件存放路径
#创建conf.d目录
mkdir -pv /app/httpd24/conf.d
[22:28:52 root@apache /app/httpd24]#vim conf/httpd.conf
# 末尾添加
IncludeOptional conf.d/*.conf
[22:29:35 root@apache /app/httpd24]#systemctl restart httpd
- 注意, yum安装和自定义编译安装的httpd, 默认配置是不同的, 具体情况具体分析
1. 检查配置文件语法
httpd -t
2. 指定服务器名
如何启动服务时或者利用httpd -t
进行语法检查时, 遇到以下提示, 可以修改配置文件中的ServerName务即可
该ServerName只是一个描述性信息而已, 并不是服务器的真正URL
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, xxx. Set the 'ServerName' directive globally to suppress this message
添加后, 无需重启, 直接生效
ServerName www.httpd.test
3. include & IncludeOptional
包含其他配置文件, 可以将自己自定义的配置文件放在这里, 与系统的配置文件隔离. 便于管理和修改.
Include file-path|directory-path|wildcard
IncludeOptional file-path|directory-path|wildcard
说明:
- Include和IncludeOptional功能相同, 都可以包括其他配置文件
- 两个指令都是指定以ServerRoot为根目录的相对路径
- 但是当指定的目录内无匹配文件时, Include会报错,也就是说Include指定指定的目录内, 必须有可匹配的文件, IncludeOptional会忽略错误. 一般用IncludeOptional即可
- yum安装的httpd, 会默认启动这两个指令, 范例如下:
IncludeOptional conf.d/*.conf
[22:54:27 root@c8prac /etc/httpd]#ls conf.d
autoindex.conf README userdir.conf welcome.conf
Include conf.modules.d/*.conf #该目录下的配置文件可以用来定义httpd实际加载哪些模块
[22:53:35 root@c8prac /etc/httpd]#ls conf.modules.d/
00-base.conf 00-lua.conf 00-optional.conf 00-systemd.conf 10-h2.conf README
00-dav.conf 00-mpm.conf 00-proxy.conf 01-cgi.conf 10-proxy_h2.conf
- 编译安装的httpd, 一般没有这两个指令, 还需要手动修改
使用场景:
- 和主配置文件隔离, 便于管理
- 生产环境和测试环境配置文件隔离, 便于管理
4. 监听的ip和port
Listen [IP]:PORT
- 省略IP表示为本机所有IP
- Listen指令至少有一个, 可以监听在多个端口
范例:
[22:47:36 root@apache /app/httpd24/conf.d]#vim httpd_test.conf
Listen 10.0.0.187:8080 #将ip和端口号绑定. 这里只能绑定本机存在的ip地址, 否则重启服务会报错, 无法绑定的ip.
Listen 80 #主配置文件默认就是监听所有ip地址的80端口, 如果在主配置文件和子配置文件都配置了Listen指令, 那么都会生效, 不冲突
可以临时添加一个ip地址进行测试
ip a a 10.0.0.77/24 dev eht0 label eth0:1 # 增加
ip a del 10.0.0.77/24 dev eht0 label eth0:1 # 删除
5. 持久连接
Persistent Connection: 通过三次握手建立连接后, 每个资源获取完成后不会断开连接, 而是继续等待其他的请求完成, http/1.1默认开启持久而连接. 复用三次握手过程, 加快效率.
断开条件:
时间限制: 以秒为单位, 默认5s, httpd-2.4 支持毫秒级
请求数量: 请求数达到指定值, 也会断开
副作用: 对并发访问量大的服务器, 持久连接会使有些请求得不到回应
折中: 使用较短的持久连接时间
生产环境不建议持久连接时间太长, 会占用连接数,影响其他用户请求.
简单的Web页面, 不需要太久的持久连接
游戏服务可以长期连接
持久连接相关命令:
KeepAlive On|Off
KeepAliveTimeourt 15 #连接持续15s, 可以以毫秒为单位, 默认值为5秒
MaxKeepAliveRequests 500 #持久连接最大接受的请求数, 默认值为100
# 如果两个条件都开启, 那么只要有一个满足, 就会断开连接
测试方式:
# 如果关闭了持久连接, 那么telnet连接到服务器后, 执行一次命令, 就会立即退出, 断开连接
# 如果指定了超时时间, 那么到了超时时间, 连接会自动断开, 退出
telnet WEB_SERVER_IP PORT
GET /URL HTTP/1.1
Host: WEB_SERVER_IP
敲回车
敲回车
6. DSO 动态共享对象
加载动态模块配置, 修改配置文件, 重启httpd服务就立即生效
动态模块存放路径: /usr/lib64/httpd/modules, 这里存放的是可用的模块
在主配置 /app/httpd24/conf/httpd.conf 文件中定义的 Include conf.modules.d/*.conf 配置文件, 可以定义需要加载哪些模块, 也可以直接定义在主配置文件里
如果是yum安装的httpd, 那么默认在conf.modules.d下就会指定httpd加载哪些模块
如果是编译安装, 加载到程序中的模块会直接在主配置文件中定义, 也可以手动创建Include conf.modules.d/*.conf文件来定义.
ServerRoot "/app/httpd24"
Include conf.modules.d/*.conf
配置文件中指定实现模块加载格式:
LoadModule <mod_name> <mod_path>
模块文件路径可使用相对路径: 相对于ServerRoot
ServerRoot指令: 定义了服务器安装的基础目录, 也是后续所有文件的根路径. 在编译时通过--prefix指定
查看静态编译的模块:
静态加载的模块, 无法手动修改
[22:50:20 root@apache ~]#httpd -l
Compiled in modules:
core.c
mod_so.c
http_core.c
查看所有已经加载的模块:
[22:50:20 root@apache ~]#httpd -M
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
access_compat_module (shared) #(shared表示动态加载模块)
actions_module (shared)
alias_module (shared)
可手动修改, 添加或删除, 重启apache服务就会立即生效.
如果yum安装:
可以通过grep -R 递归搜索/etc/httpd/conf.modules.d/目录, 查看模块是存放在了哪个模块配置文件里
/etc/httpd/conf.modules.d/00-base.conf:LoadModule auth_basic_module modules/mod_auth_basic.so
查看模块加载的配置文件:
[07:03:38 root@c8prac /etc/httpd]#ls /etc/httpd/conf.modules.d/
00-base.conf 00-lua.conf 00-optional.conf 00-systemd.conf 10-h2.conf README
00-dav.conf 00-mpm.conf 00-proxy.conf 01-cgi.conf 10-proxy_h2.conf
[07:03:54 root@c8prac /etc/httpd]#cat /etc/httpd/conf.modules.d/00-base.conf
#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule actions_module modules/mod_actions.so
如果是编译安装, 已经加载到程序中的模块会保存在主配置文件, 直接查看配置文件即可
7. MPM, 多路处理模块
httpd 支持三种MPM工作模式: prefork, worker, event
查看当前系统httpd的工作模式
安装httpd后, 无需启动服务即可查看
httpd -M | grep mpm
httpd -V
命令会显示编译时的设置
切换使用的MPM:
yum安装: 修改 /etc/httpd/conf.module.d/00-mpm.conf文件, 需要重启服务
编译安装: 修改主配置文件, 或者 Include 中定义的配置文件
并发不大,追求稳定 - prefork - 以进程响应, 彼此隔离
高并发 - event - 多进程, 多线程响应
worker模型既不如prefork稳定, 也不如event性能好
[07:12:54 root@c8prac ~]#vim /etc/httpd/conf.modules.d/00-mpm.conf
LoadModule mpm_event_module modules/mod_mpm_event.so # CentOS-8上默认是event模型, 而7是prefork模型
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # 修改为prefork模型
#LoadModule mpm_worker_module modules/mod_mpm_worker.so # 修改为worker模型
注意: 不能同时启用多个MPM模块, 会出现报错
AH00534: httpd: Configuration error: More than one MPM loded.
CentOS 7上的prefork模型, 以进程显示, 而 8 的prefork模型,以线程显示
8. prefork模式相关配置
StartServers #服务启动时开启的进程数
MinSpareServers #最少需要的空闲进程数, 至少预留几个空闲进程等着用户请求
MaxSpareServers #最多存活的空闲进程数
ServerLimit #最多开启的进程数(包括主进程, 繁忙进程和空闲进程), 最大值, 20000, 默认256
MaxRequestWorkers #最大的并发连接数, 默认256, 在prefork模型中, 这个值和最多开启的进程数的值是等价的, 因为prefork是一个进程响应一个用户请求
MaxConnectionsPerChild #子进程最多能处理的请求数量. 在处理MaxConnectionsPerChild个请求之后, 子进程将会被父进程终止, 这时候子进程占用的内存就会被释放(为0时永远不释放)
MaxRequestsPerChild #从httpd-2.3.9开始MaxConnectionsPerChild被MaxRequestsPerChild代替
9. worker和event模式相关配置
ServerLimit 16 #最多worker进程数 Upper limit on configurable number of processes
StartServers 10 #Number of child server processes created at startup
MaxRequestWorkers 150 #Maximum number of connections that will be processed simultaneously, 这指的是最多的线程个数
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25 #Number of threads created by each child process
10. 定义主站点路径
修改默认页面存放路径
yum安装, 默认是存放在/var/www/html
DocumentRoot "/var/www/html"
Require all granted
编译安装会在/app/httpd24/htdocs, 具体根据DocumentRoot路径
DocumentRoot "/app/httpd24/htdocs"
修改默认设置:
DocumentRoot "/PATH"
<directory /PATH>
require all granted #每个目录都需要有授权才能被访问.
</directory>
说明:
- DocumentRoot指向的路径为URL路径的起始位置
- /PATH必须添加授权,才可以访问, 从httpd-2.4以后必须授权, httpd-2.3以前无需授权
- 如果在主配置文件,和IncludeOption指定的路径, 都配置了DocumentRoot, 那么在conf.d下的会生效, 如果把conf.d下的配置文件移走了或者conf.d下的目录没有默认页面, 那么就还是主配置文件中定义的目录.
范例:
mkdir /data/html
DocumentRoot "/data/html"
<directory /data/html>
Require all granted
</directory>
[07:46:34 root@c8prac ~]#echo '/data/html' > /data/html/index.html
[07:46:34 root@c8prac ~]#curl 10.0.0.84
/data/html
11. 定义主站点默认页面
默认情况下,访问Web服务器会默认显示index.html文件, 定义在配置文件中, 即使在目录里添加了其他的页面, 也不会显示, 除非指定文件路径
修改主配置文件即可
<IfModule dir_module>
DirectoryIndex index.html #可以指定多个文件, 访问主站点时会从左匹配, 匹配上了就不会继续匹配了
</IfModule>
12. 可实现访问控制的资源
可以针对文件系统和URL的资源进行访问控制, 还可以根据客户端ip设置白名单或者黑名单进行访问控制
基于文件系统路径做控制:
- 基于目录
<Directory "/path">
...
</Directory>
- 基于文件
<File "/path/file">
...
</File>
- 基于文件通配符
<File "/path/*file*">
...
</File>
- 基于扩展正则表达式
<FileMatch "regex">
...
</FileMatch>
范例:
基于扩展正则表达式
<FilesMatch ".+\.(gif|jpe?g|png)$">
...
</FilesMatch>
基于通配符
<Files ".ht*">
Require all denied
</Files>
基于URL路径做控制:
<Location "URL"> #URL就是域名后面跟的路径, 也就是根路径后的目录或文件
...
</Location>
<LocationMatch "regex">
...
</LocationMatch>
范例:
#1
<Location "/private1">
...
</Location>
/private1, /private1/, /private1/file.txt 匹配
/private1other 不匹配
#2
<Location "/private2/">
...
</Location>
/private2/, /private2/file.txt 匹配
/private2, /provate2other 不匹配
13. 针对文件系统路径和URL路径访问控制的具体实现
1. Options指令:
后跟一个或多个空白字符分隔的选项列表, 在选项前面的+,-表示增加或删除指定选项, 所有的选项, 要么不写+|-, 要么都写+|-. 一个写一个不写, 重启服务器会失败.
常见选项:
- Indexes:当主站点目录下没有index.html文件, 返回索引列表给用户(也就是显示文件列表), 如果该选项没有开启, 会显示403报错. yum和编译安装的httpd, 对于系统默认的主路径该选项默认是开启的.
httpd编译安装
[23:46:20 root@apache ~]#grep Indexes /app/httpd24/conf/httpd.conf
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
Options Indexes FollowSymLinks
httpd-yum安装
[00:35:45 root@CentOS-8-6 ~]#grep Indexes /etc/httpd/conf/httpd.conf
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
Options Indexes FollowSymLinks
注意: 如果yum安装的httpd, 主站点下如果没有定义的默认页面, 那么会显示apache默认站点页面, 该行为由welcome.conf设定, /etc/httpd/conf/welcome.conf, 所以如果想显示是索引列表, 还需要修改这个welcome.conf
-
FollowSymLinks: 允许访问符号链接文件所指向的源文件. 点击软链接文件, 会跳转到实际的文件, 并且显示其内容
-
None: 全部禁用
-
All: 全部允许
yum安装httpd, 如果没有在/var/www/html目录或自定义主站点目录下定义index.html文件, 那么访问主站点会显示apache默认页面. 该行为由welcome.conf文件控制 /etc/httpd/conf.d/welcome.conf
<LocationMatch "^/+$"> #访问主站点, curl 10.0.0.86, 10.0.0.86/, 10.0.0.86///没区别
Options -Indexes #禁用Indexes索引功能
ErrorDocument 403 /noindex/index.html #显示默认的错误页面
</LocationMatch>
将welcome文件重命名, 并且确保主站点目录允许, Indexes和FollowSymLinks, 既可实现以索引方式访问, 并且能从软连接文件获取实际文件的内容. 如果只挪走了welcome文件, 但是主站点没有启用Indexes功能, 那么访问的时候就是403
[08:21:02 root@c8prac /etc/httpd/conf.d]#mv welcome.conf welcome.conf.bak
DocumentRoot "/data/html"
<directory /data/html>
Require all granted
Options Indexes FollowSymLinks #这里如果把FollowSymLink取消, 那么软连接文件就不可见了
</directory>
systemctl restart httpd
编译安装的httpd一般没有这个限制
范例: 测试Indexes和FollowSymLinks选项
创建目录和文件
[root@c7node1 /data/html]#tree
.
├── dir
│ └── test.html
├── index.html.bak
├── linkfile -> /etc/centos-release
└── test.html
1 directory, 4 files
结合上一步, 允许/data/html下, Index.html 和 FollowSymLinks的功能, 即可实现以索引方式访问, 并且能通过软连接文件获取实际文件的内容
主站点总结:
-
如果DocumentRoot下, 没有指定的默认主页面文件, 那么访问时会显示默认页面, 该功能由welcome.conf文件控制. 403 noindex.html. 这是yum安装. 如果是编译安装, 一般没有这个welcome文件
-
如果移除了该welcome文件, 并且没有主页面文件, 那么就要看主站点配置文件有没有设置Indexes, 没有设置的话访问会显示403 permission denied报错.
-
如果希望DocumentRoot下的文件以索引目录形式显示, 需要在DocuementRoot目录下添加Indexes选项, 如果文件中包含软连接, 那么还要开启支持软连接, FollowSymLinks
-
Apache默认的DocuementRoot是开启了Indexes和FollowSymLinks的
2. AllowOverride指令
想要控制哪个目录的访问权限, 除了在配置文件中直接指定, 也可以在该目录下创建一个名为.htaccess文件(由AccessFileName指令指定, AccessFileName .htaccess为默认值, 文件中, 在这个文件中添加配置指令, 只对语句有效.
./extra/httpd-default.conf:AccessFileName .htaccess
常见用法:
- AllowOverride All: .htaccess中所有的指令都有效
- AllowOverride None: .htaccess 文件无效, 此为httpd-2.3.9以后版的默认值
- AllowOverride AuthConfig: .htaccess文件中, 除了AuthConfig其他指令都无法生效
.htaccess无法在前端打开, 因为系统做了默认的安全控制, 拒绝访问以.ht开头的文件. yum和编译安装都有该设置
image.png[08:42:09 root@c8prac /etc/httpd/conf.d]#grep -Ev '^#' /etc/httpd/conf/httpd.conf | grep -A 2 'ht\*'
<Files ".ht*">
Require all denied
</Files>
范例: AllowOverride All
DocumentRoot "/data/html"
<Directory "/data/html">
AllowOverride All #把对/data/html这个目录的控制命令,都放在其目录下的隐藏文件, .htaccess里
Require all granted
</Directory>
[12:55:06 root@c7node1 /data/html]#vim .htaccess
Options Indexes FollowSymLinks
重启服务后,测试访问不受影响即可
14. 基于客户端IP地址实现访问控制
企业内部用的较多, 白名单和黑名单
针对各种资源, 可以基于以下两种方式进行访问控制:
- 客户端来源ip地址
- 用户账号
基于客户端ip地址的访问控制:
- 无明确授权的目录, 默认拒绝
- 允许所有主机访问: Require all granted
- 拒绝所有主机访问: Require all denied
- 控制特定的访问ip
Require ip IP: 授权指定来源的ip访问
Require not ip IP: 拒绝特定的ip访问 - 控制特定的主机访问:
Require host HOSTNAME: 授权特定主机访问
Require not host HOSTNAME: 拒绝
HOSTNAME格式包含:
- FQDN: 特定主机名
- domain.tld: 指定域名下的所有主机
<RequireAll>: 不能有失败, 至少有一个成功匹配才成功, 即失败优先
<RequireAny>: 多个语句, 有一个成功,则成功, 即成功优先
黑名单:
如果是yum安装的httpd, 那么welcome.conf文件需要提前删除或者重命名, 否则黑名单的用户访问时会显示默认页面, 但实际也是被拒绝了, 可以在错误日志中看到记录
DocumentRoot "/data/html"
<directory /data/html>
<RequireAll>
Require all granted # 所有都允许
Require not ip 10.0.0.86 # 除了10.0.0.86
</RequireAll>
</directory>
systemctl reload httpd
# 从10.0.0.86访问10.0.0.187
[00:56:36 root@CentOS-8-6 ~]#curl 10.0.0.187
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>
# 从apache本地访问
[01:24:08 root@apache /data/html]#curl 10.0.0.187
page in /data/html
15. 日志设定
日志两种类型:
访问日志
错误日志
配置文件中有两个关于日志配置, 一个负责定义日志格式, 一个负责定义日志存放在哪个文件
如果想修改日志存放路径, 需要指明全路径. 否则就是相对的httpd安装路径., ServerRoot下
- 错误日志:
被拒绝访问也会放到错误日志里
yum安装默认存到 /etc/httpd/logs/error_log, 因为yum安装的ServerRoot是/etc/httpd
ErrorLOG "logs/error_log"
LogLevel warn #定义错误日志级别
由于配置文件格式错误, 导致服务器无法启动, 只会在错误日志记录服务关闭, 但是具体服务启动不起来的原因信息不会放在错误日志.
访问被拒绝的记录, 会记录在错误日志.
[Sun Oct 18 21:27:29.240909 2020] [authz_core:error] [pid 2848:tid 140529937389312] [client 10.0.0.71:46418] AH01630: client denied by server configuration: /data/html/
- 访问日志: 存放用户访问信息的日志
默认存到: /etc/httpd/logs/access_log
CustomLog "logs/access_log" combined
- 定义日志格式
LogFormat FORMAT NICKNAME #给定义的格式起别名, 在使用日志格式CustomLog中调用
- 使用日志格式:
CustomLog /PATH NICKNAME #调用LogFormat中定义的别名, /PATH指明日志存放的文件路径, 默认在logs/access.log
范例:修改日志格式, 便于日志统计
[01:34:21 root@apache /data/html]#vim /app/httpd24/conf/httpd.conf
LogFormat "%h \"%{%F %T}t\" %>s %{User-AGENT}i" newlog #\是为了转义
CustomLog "logs/newlog" newlog
#新的日志文件无需自己创建, 重新服务后系统会自动创建
修改后的日志结果
::1 "2021-03-10 01:40:24" 200 curl/7.29.0
10.0.0.86 "2021-03-10 01:40:31" 403 curl/7.61.1
10.0.0.86 "2021-03-10 01:40:55" 200 curl/7.61.1
10.0.0.1 "2021-03-10 01:41:47" 200 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45
10.0.0.1 "2021-03-10 01:41:47" 404 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45
10.0.0.1 "2021-03-10 01:41:54" 200 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
%h: 远程客户端ip地址
%l 和 %u : 远程登录用户信息, 用户名等
%t: 访问时间, 格式[18/Sep/2011:19:18:28 -0400]
%{format}t: 自定义时间格式, 通过strftime (3)`man 3 strftime`查看格式使用方法`
%>s: 响应码
\"%{Referer}i\": Referer指的是从哪个网站跳转过来的, i表示请求报文头部信息. 在nginx中防盗链技术会使用.
%b: 表示访问的文件大小, 字节为单位
\"%{User-Agent}i\": 用的哪个浏览器
16. 定义路径别名
默认的访问路径在DocumentRoot目录下
格式:
Alias /URL(别名) "/PATH"(真实路径), 真实路径可以是服务器文件系统上自定义的路径, 不一定必须是网站的家目录下的路径
范例:
dirr目录为别名, 真实路径指向/data/html/alias
[01:48:53 root@apache ~]#mkdir /data/html/alias
[01:49:01 root@apache ~]#echo 'alias /dirr/test.html' > /data/html/alias/test.html
alias /dirr /data/html/alias
<Directory /data/html/alias>
Require all granted
</Directory>
[01:53:18 root@CentOS-8-6 ~]#curl 10.0.0.187/dirr/test.html
alias /dirr/test.html
17. 基于用户的访问控制
比如: 服务管理后台登录验证
apache无需开发, 即可实现用户验证访问
认证质询: WWW-Authenticate, 响应码401, 拒绝客户端请求, 并说明要求客户端需要提供账号号密码
认证: Authorization, 客户端用户输入账户和密码后再次发送请求报文; 认证通过时, 则服务器发送相应的资源
认证方式两种:
- basic: 明文
- digest: 消息摘要认证, 兼容性差
安全域: 需要用户认证后方能访问的路径; 应该通过名称对其进行标识, 以便告知用户认证的愿意
用户的账号和密码政策:
虚拟账户: 仅用于访问某服务时用到的认证标识
存储: 文本文件, SQL数据库, ldap目录存储, nis等
basis认证配置实例:
1: 定义安全域
<Directory "/PATH">
AuthType Basic
AuthName "String"
AuthUserFile "/PATH/HTTPD_USER_PASSWD_FILE"
Require user username1 username2 ... #允许文件中, 指定的用户访问, 也可以用 Require valid-user, 允许账号文件中的所有用户登录访问
</Directory>
允许账号文件中的所用用户登录访问;
Require valid-user
- 提供账号和密码存储(文本文件)
使用专用命令完成此类文件的创建及用户管理
htpasswd [options] /PATH/HTTPD_PASSWD_FILE username
#需要确保apacahe用户对此文件要有读权限
setfacl -m u:apache:r /PATH/HTTPD_PASSWD_FILE
选项:
-c 自动创建文件, 仅在该文件不存在时使用, 如果文件存在则会覆盖
-p 明文密码
-d CRYPT格式加密, 默认
-m md5格式加密, 默认
-s sha格式加密
-D 删除指定用户
案例: 只允许认证的用户访问主站点admin目录下的文件
- 创建admin目录,制作默认页面
[02:17:18 root@apache /data/html]#mkdir admin
[02:17:24 root@apache /data/html]#echo /data/html/admin/index.html > /data/html/admin/index.html
- 利用htpasswd命令. 创建账户密码文件
[02:18:42 root@apache /app/httpd24/conf.d]#htpasswd -c /app/httpd24/conf.d/.adminuser linux
New password:
Re-type new password:
Adding password for user linux
[02:18:56 root@apache /app/httpd24/conf.d]#cat /app/httpd24/conf.d/.adminuser
linux:$apr1$zJ0LLzBh$2Rb7Q0Ytc3GR08hqiTDMp.
[02:19:35 root@apache /app/httpd24/conf.d]#setfacl -m u:apache:r /app/httpd24/conf.d/.adminuser
[02:20:37 root@apache /app/httpd24/conf.d]#htpasswd -s /app/httpd24/conf.d/.adminuser nginx
New password:
Re-type new password:
Adding password for user nginx
[02:20:52 root@apache /app/httpd24/conf.d]#cat /app/httpd24/conf.d/.adminuser
linux:$apr1$zJ0LLzBh$2Rb7Q0Ytc3GR08hqiTDMp.
nginx:{SHA}yYSu0BSux2I6VPBZHaB6hf1Ldi0=
- 修改配置文件, 允许文件中所有的人访问
<Directory "/data/html/admin">
AuthType Basic
AuthName "Only valid user can login"
AuthUserFile "/app/httpd24/conf.d/.adminuser"
Require valid-user
</Directory>
systemctl restart httpd
- 重启服务测试 此处需要使用Firefox浏览器, 否则"Only valid user can login"的提示信息由于兼容性无法显示. 不影响使用.
利用curl浏览器测试方式
[02:22:04 root@apache /app/httpd24/conf.d]#curl http://linux:000000@10.0.0.187/admin
<!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://10.0.0.187/admin/">here</a>.</p>
</body></html>
[02:24:59 root@apache /app/httpd24/conf.d]#curl http://linux:000000@10.0.0.187/admin/ #需要补全/
/data/html/admin/index.html
基于组账户进行认证
组里的账户, 也要属于htpasswd账号文件里的人
- 定义安全域
<Directory "/path">
AuthType Basic
AuthName "String"
AuthUserFile "/PATH/HTTPD_USER_PASSWD_FILE" #基于组认证, 也需要利用htpasswd先把用户账号密码文件创建出来
AuthGroupFile "/PATHHTTPD_GROUPFILE" #组文件是按照特定格式手写的
Require group grpname1 grpname 2...
<Directory>
- 创建用户账号和组账号文件
组文件: 每一行定义一个组
GRP_NAME: username1 username2 ...
范例:
<Directory data/html/ITdocs">
AuthType Basic
AuthName "IT only"
AuthUserFle "/app/httpd24/conf.d/.htpassd"
AuthGroupFile "/app/httpd24/conf.d/.htgroup"
Reuire group IT
</Directory>
vim /app/httpd24/conf.d/.htgroup
IT : username1 username2
也可以基于.htaccess来做用户或者组认证
在配置文件中指明利用.htaccess文件, 然后在要控制的目录下创建.htaccess文件写入控制指令
vim /app/httpd24/conf.d/test.conf
<Directory "/data/html/admin">
allowoverride authconfig #指名和验证相关的配置放在了.htaccess文件
</Directory>
vim /data/html/admin/.htaccess
AuthName "Only valid user can login"
AuthUserFile "/app/httpd24/conf.d/.adminuser" # 利用htpass创建的用户和密码文件进行认证
Require valid-user
18. 远程客户端和用户验证的控制
Satisfy ALL|Any
- ALL 客户机IP和用户验证必须都通过才可以, 此为默认值
- Any 客户机IP和用户验证, 有一个满足即可
19 隐藏服务器版本信息
服务器版本信息会存放在响应报文头部中, 如果不隐藏, 会暴露服务器信息给公网, 包括使用的软件名(apache|nginx)和版本号
ServerTokens Major|Minor|MIn[imal]|Prod[uctOnly]|os|Full #Full是默认
建议使用 ServerTokens Prod ; 或者修改apache源码, 改成自定义的版本, 然后源码编译
curl -I
命令可以只查看头部信息
修改前
[02:25:23 root@apache /app/httpd24/conf.d]#curl -I 10.0.0.187
HTTP/1.1 200 OK
Date: Tue, 09 Mar 2021 18:41:46 GMT
Server: Apache/2.4.46 (Unix)
Last-Modified: Tue, 09 Mar 2021 15:45:20 GMT
ETag: "13-5bd1c70192f05"
Accept-Ranges: bytes
Content-Length: 19
Content-Type: text/html
修改配置文件
[02:42:26 root@apache /app/httpd24/conf.d]#vim /app/httpd24/conf.d/httpd_test.conf
ServerTokens prod
systemctl restart httpd
修改后
[02:42:54 root@apache /app/httpd24/conf.d]#curl -I 10.0.0.187
HTTP/1.1 200 OK
Date: Tue, 09 Mar 2021 18:42:56 GMT
Server: Apache # 如果不修改源码, 那么最多只能隐藏版本信息, 具体用的哪个服务器软件还是会暴露
Last-Modified: Tue, 09 Mar 2021 15:45:20 GMT
ETag: "13-5bd1c70192f05"
Accept-Ranges: bytes
Content-Length: 19
Content-Type: text/html
20. status状态页
httpd提供了状态页, 可以用来观察httpd的运行情况. 此功能需要加载mod_status.so模块来实现
需要对状态页控制权限, 由于基于用户名和密码的AuthType
指令只适用于<directory>和.htaccess, 而status页面是需要写到<Location>里的是一个URL路径, 所以需要用基于IP控制, 利用白名单, 只有运维人员的电脑才可以访问.
配置:
LoadModule status_module modules/mod_status.so # 使用状态页需要加载对应模块
<Location "/status"> #/status文件名可以自己指定, 这里的status是DocumentRoot下的一个文件而不是目录
SetHandler server-status
</Location>
ExtendedStatus on #显示扩展信息, httpd 2.3.6 以后默认为on
范例: 启动状态页, 并规定特定ip可以访问
#确认status_mode已经加载
[02:42:56 root@apache /app/httpd24/conf.d]#httpd -M | grep status
status_module (shared)
#修改配置文件
[02:47:07 root@apache /app/httpd24/conf.d]#vim /app/httpd24/conf.d/httpd_test.conf
<Location "/apache_status">
SetHandler server-status
<Requireany>
Require all denied
Require ip 10.0.0.1 #只允许10.0.0.1 ip访问, 我的windows主机
</Requireany>
</Location>
测试
image.png这时, 即使在本地访问状态页也会被拒绝
[23:37:22 root@c8prac ~]#curl 10.0.0.84/apache_status
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /apache_status
on this server.<br />
</p>
</body></html>
网友评论