一、httpd的运行模式
httpd具有以下特性:
- 高度模块化;
- DSO:dynamic shared object,模块动态装卸;
- MPM:Multipath processing Modules ,多路处理模块,与接受请求相对应。
其中并行处理模式MPM(多路处理模块)包含了三种运行模式。分别为prefork、worker和event。
1、prefork模式
profork是一个两级进程模型,父进程管理子进程,每个进程响应一个请求。由一个主进程负责生成多个子进程以及回收子进程、创建套接字、接收请求,并将请求派发给某个子进程进行处理。每个子进程只负责处理一个请求。其工作模型:预先生成几个空闲进程,等待用于响应用户请求,设定最大空闲和最小空闲;所有已建立的套接字由客户端进程和服务期端子进程进行通信,一旦出现空闲,会回收子进程。
特点:进城之间完全独立,无需担心线程安全问题。但进程占用的系统资源较多,在处理高并发请求时无法快速处理。
其在httpd2.2为的配置:
<IfModule prefork.c>
StartServers 8 #进程启动时创建多个子进程
MinSpareServers 5 #最少空闲进程数
MaxSpareServers 20 #最大空闲进程数
ServerLimit 256 #服务器支持的最大进程数
MaxClients 256 #允许的最大并发请求数量,对于prefork即为最大并发的子进程数量
MaxRequestsPerChild 4000 #设置的是每个子进程可处理的请求数。每个子进程在处理了指定个请求后将自动销毁。0意味着无限,即子进程永不销毁。
</IfModule>
2、worker模式
worker是一个三级结构、多进程多线程的模式,其在启动时也预先fork了几个子进程,每个子进程能够生产若干个服务线程和若干个监听线程,每个服务线程处理一个请求,监听线程负责接入请求并将其传递给服务线程处理和应答。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此内存的占用会减少些,在高并发的场景下表现比prefork模式更好。其工作模型:
一个主进程:负责生成多个子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理; > 多个子进程:每个子进程负责生成多个线程;
每个线程:负责响应用户请求;
并发响应数量:m*n
m:子进程数量
n:每个子进程所能创建的最大线程数量;
worker模式的特点:线程比起进程会更轻量级,因此占用用内存少,处理高并发请求时性能更好。但是当一个线程出现问题的时候会导致同一进程下的线程也会出现问题。在keep-alive长连接的方式下,某个线程会被一直占用,即使中间没有请求,也需要等待到超时才会被释放。
在httpd2.2中的配置
<IfModule worker.c>
StartServers 4 #服务器启动时建立的子进程数量
MaxClients 300 #限制同一时间并发请求的数量
MinSpareThreads 25 #设置空闲线程的最小数量
MaxSpareThreads 75 #设置空闲线程的最大数量
ThreadsPerChild 25 #设置每个子进程产生的最大线程数量
MaxRequestsPerChild 0 #设置的是每个子进程可处理的请求数。每个子进程在处理了指定个请求后将自动销毁。0意味着无限,即子进程永不销毁。
</IfModule>
3、event模式
event是一个事件驱动模型,是一个两级结构的多进程模型,父进程管理子进程,子进程通过event-driven机制直接响应多个请求。event模式解决了在keep-alive模式下,线程被长期占用直到超时,从而导致资源浪费的问题。
在event模块中,有一个专门的线程来管理这些keep-alive类型的线程,当接收到真实的请求时,会将请求传递给服务线程,执行完毕后,会将对应的服务线程释放,这样就能实现线程的异步非阻塞。
在httpd2.2中的配置:
<IfModule mpm_event_module>
StartServers 3 #服务启动时建立的子进程的数量
MinSpareThreads 75 #空闲线程的最少数量
MaxSpareThreads 250 #空闲线程的最大数量
ThreadsPerChild 25 #每个子进程产生的线程数量
Maxclients 400 #最大的并发的线程数
MaxRequestsPerChild 0 #每个子进程处理的最大连接数,0表示不限制。
</IfModule>
示例:
Centos6系统下实现httpd-2.2的安装,并分别实现prefork、worker、event等几种工作方式.
1、centos6上安装装httpd-2.2
yum install -y httpd
prefork模式
实现prefork模式。httpd的默认运行模式为prefork,查看其运行模式为:
[root@localhost httpd]# httpd -M | grep mpm
httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
mpm_prefork_module (static)
Syntax OK
在/etc/httpd/conf/httpd.conf文件中查看prefork的设置
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
启动httpd服务并查看相关进程状态:
[root@localhost httpd]# service httpd start
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost httpd]# service httpd status
httpd (pid 2848) is running...
[root@localhost httpd]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 2848 0.0 0.0 184328 3860 ? Ss 12:56 0:00 /usr/sbin/httpd
apache 2851 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2852 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2853 0.0 0.0 184460 2512 ? S 12:56 0:00 /usr/sbin/httpd
apache 2854 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2855 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2856 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2857 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
apache 2858 0.0 0.0 184460 2484 ? S 12:56 0:00 /usr/sbin/httpd
root 2881 0.0 0.0 103252 832 pts/0 S+ 12:56 0:00 grep httpd
修改/etc/httpd/conf/httpd.conf中的prefork配置
<IfModule prefork.c>
StartServers 5 #修改启动时创建的进程数为5
MinSpareServers 5
MaxSpareServers 10 #设置空闲进程为10
ServerLimit 25
MaxClients 25 #修改最大并发请求的数量为25
MaxRequestsPerChild 4000
</IfModule>
重启httpd服务并常看进程状态:
[root@localhost httpd]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost httpd]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 3056 0.0 0.0 184264 3800 ? Ss 13:02 0:00 /usr/sbin/httpd
apache 3059 0.0 0.0 184264 2472 ? S 13:02 0:00 /usr/sbin/httpd
apache 3060 0.0 0.0 184264 2472 ? S 13:02 0:00 /usr/sbin/httpd
apache 3061 0.0 0.0 184264 2500 ? S 13:02 0:00 /usr/sbin/httpd
apache 3062 0.0 0.0 184264 2472 ? S 13:02 0:00 /usr/sbin/httpd
apache 3063 0.0 0.0 184264 2472 ? S 13:02 0:00 /usr/sbin/httpd
root 3065 0.0 0.0 103252 828 pts/0 S+ 13:02 0:00 grep httpd
#说明配置生效
worker模式
修改配置文件/etc/sysconfig/httpd配置文件,将文件中HTTPD=/usr/sbin/httpd.worker这一句取消注释。然后重启服务查看进程状态。
[root@localhost httpd]# vim /etc/sysconfig/httpd
# Configuration file for the httpd service.
#
# The default processing model (MPM) is the process-based
# 'prefork' model. A thread-based model, 'worker', is also
# available, but does not work with some modules (such as PHP).
# The service must be stopped before changing this variable.
#
HTTPD=/usr/sbin/httpd.worker
#
# To pass additional options (for instance, -D definitions) to the
# httpd binary at startup, set OPTIONS here.
#
#OPTIONS=
[root@localhost httpd]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.worker: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost httpd]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 3540 0.0 0.1 184536 4052 ? Ss 13:30 0:00 /usr/sbin/httpd.worker
apache 3655 0.0 0.1 528796 5372 ? Sl 13:30 0:00 /usr/sbin/httpd.worker
root 3696 0.0 0.0 103252 832 pts/0 S+ 13:30 0:00 grep httpd
然后修改/etc/httpd/conf/httpd.conf文件中的worker配置
<IfModule worker.c>
StartServers 2
MaxClients 100 #更改最大并发请求的数量为100
MinSpareThreads 25
MaxSpareThreads 100 #修改最大空闲线程的数量为100
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
event模式
修改配置文件/etc/sysconfig/httpd配置文件,将文件中HTTPD=/usr/sbin/httpd.worker这一句修改为HTTPD=/usr/sbin/httpd.event。然后重启服务查看进程状态。
[root@localhost httpd]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.event: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost httpd]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 6124 0.0 0.1 184540 4040 ? Ss 13:42 0:00 /usr/sbin/httpd.event
apache 6127 0.0 0.1 528800 5340 ? Sl 13:42 0:00 /usr/sbin/httpd.event
apache 6128 0.0 0.1 528800 5344 ? Sl 13:42 0:00 /usr/sbin/httpd.event
apache 6129 0.0 0.1 528800 5356 ? Sl 13:42 0:00 /usr/sbin/httpd.event
root 6218 0.0 0.0 103252 832 pts/0 S+ 13:42 0:00 grep httpd
修改配置文件/etc/httpd/conf/httpd.conf,添加evnet配置
#event MPM
<IfModule event_module>
StartServers 4
MaxClients 200
MinSpareThreads 20
MaxSpareThreads 200
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
查看进程状态
[root@localhost httpd]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 6309 0.0 0.1 184540 4048 ? Ss 13:46 0:00 /usr/sbin/httpd.event
apache 6312 0.0 0.1 528800 5344 ? Sl 13:46 0:00 /usr/sbin/httpd.event
apache 6313 0.0 0.1 528800 5360 ? Sl 13:46 0:00 /usr/sbin/httpd.event
apache 6314 0.0 0.1 528800 5352 ? Sl 13:46 0:00 /usr/sbin/httpd.event
root 6409 0.0 0.0 103252 828 pts/0 S+ 13:47 0:00 grep httpd
二、http的request报文请求方法和状态响应码
一次完整的http请求处理过程:
- 建立或处理链接:接受请求或拒绝请求
- 接收请求:接收来自网络上的主机请求报文中对特定资源的一次请求过程
- 处理请求:对请求报文进行解析,获取客户端请求的资源及请求方法等相关信息
- 访问资源:获取请求报文中请求的资源
- 构建响应报文:
- 发送响应报文:
- 记录日志:
在一次完整的http请求过程中,会出现两种报文,分别是http的请求报文request和http的响应报文response。
1、报文格式
request请求报文的格式为:
<method> <URL> <VERSION>
<headers>
<blank-line>
<request body>
response响应报文的格式为:
<version> <status> <reason-phrase>
<headers>
<blank-line>
<entity-body>
以上各字段的含义:
- method:请求方法,标明客户端希望服务器对资源执行的动作,如GET、POST、HEAD等;
- version:http服务的版本,格式通常为:
HTTP/<major>.<minor>
;- status:状态响应码,其格式通常为三位数字,如200,301,302,404等,每一个状态响应码标记请求处理过程中发生的情况;
- reason-phrase:状态响应码所标记的状态的简要描述;
- headers:由每个请求或响应报文包含的任意首部组成的,其首部格式类似于:Connection: Keep-Alive;
- blank-line:在编写完最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
- entity-body:请求报文中附加的数据或响应时附加的数据;
2、报文的请求方法
http协议的请求方法共有以下7中
- GET:向服务器请求访问获取特定的资源;
- HEAD:只从服务器获取文档的响应首部;
- POST:向指定资源提交数据进行处理请求,如提交表单或上传文件等;数据包含在请求体中,POST请求可能会导致新的资源的创建或已有资源的修改;
- PUT:向指定资源位置上传数据;
- DELETE:请求服务器删除Request-URI所标识的资源内容;
- TRACE:回显服务器收到的请求,主要用于测试或诊断;
- OPTIONS:请求服务器返回对指定资源支持使用的请求方法;
3、状态响应码status
状态响应码是http请求处理返回的结果状态标识,属于响应报文中的内容,熟知常见的状态响应码能帮助我们快速定位故障及进行相应的排错,状态码的类型大体可分为下面几类:
- 1xx:100-101, (额外)信息提示类的状态码;
- 2xx:200-206, 成功类的状态码;
- 3xx:300-305, 重定向类的状态码;没有把请求的页面响应给客户端,而是重定向到其它地方,或是无需获取此资源;
- 4xx:400-415, 错误类信息,客户端的错误类的状态码;例如请求不存在的资源;
- 5xx:500-505, 错误类信息,服务器端错误类的状态码;例如服务器内部的问题,因为资源有语法错误运行部成功,无法响应,不是资源不存在;
常用的状态码:
200: 成功,请求的所有数据通过响应报文的entity-body部分发送;原因短语为OK
301: 请求的URL指向的资源已经被删除(移动到其它位置)是永久重定向,资源被永久删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;原因短语为Moved Permanently
302: 与301相似,但在响应报文中通过Location指明资源现在所处临时新位置,资源不是永久删除,是临时重定向; 原因短语为Found
304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端,客户端可继续使用本地网页缓存;原因短语为Not Modified
401: 需要输入账号和密码认证方能访问资源,只有服务器要求时才输入账号密码,基于basic认证时就是401;原因短语为Unauthorized
403: 请求被禁止,资源禁止客户端访问;原因短语为Forbidden
404: 服务器无法找到客户端请求的资源;原因短语为Not Found
500: 服务器内部错误;原因短语为Internal Server Error
502: 代理服务器从后端服务器收到了一条伪响应;原因短语为Bad Gateway
503:Service Unavailable,由于临时的服务器维护或者过载,服务器当前无法处理请求;
504:Gateway Time-out,504错误是(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
三、httpd服务的配置
httpd服务的主配置文件/etc/httpd/conf/httpd.conf。此文件内容通常以下三大部分组成:
Section 1: Global Environment
Section 2: 'Main' server configuration
Section 3: Virtual Hosts
除主配置稳健以外,其余的相关配置文件包括:
/etc/httpd/conf.d/.conf
/etc/httpd/conf.modules.d/.conf模块配置文件
这些配置文件在httpd2.4中通常在主配置文件中通过IncludeOptional conf.d/*.conf
、Include conf.modules.d/*.conf
进行调用响应目录下的配置文件。路径为相对路径,其根目录由主配置文件中的Serverroot进行设定。
1、修改监听IP和端口
在主配置文件中,修改httpd服务监听IP和接口的格式为:
Listen [IP-address]port[protocol]
注意:
- IP-address可省略,省略表示可匹配全部IP,相当于表示为0.0.0.0
- Listen指令可重复出现多次,用于监听多个端口
- 修改监听的socket后,要重启服务才能生效
- 若限制其必须通过ssl通信时,protocol必须定义为https
示例:
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
Listen 80
Listen 192.168.0.109:8080
[root@localhost httpd]# ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.2.102:8188 *:*
LISTEN 0 128 *:111 *:*
LISTEN 0 5 192.168.122.1:53 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 128 :::111 :::*
LISTEN 0 128 :::8080 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
2、持久链接
持久链接是指tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行。对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常响应;此时,设置较短的持久连接时长,以及较少的请求数量来缓解。具体设置如下:
KeepAlive On|Off #是否启用持久链接
KeepAliveTimeout 15 #单位是秒钟;
MaxKeepAliveRequests 100 #链接请求最大数量;
示例:
[root@localhost httpd]# vim /etc/httpd/conf.d/keepalive.conf
KeepAlive on
KeepAliveTimeout 15
MaxKeepAliveRequests 100
[D:\~]$ telnet 192.168.2.102 8188
Connecting to 192.168.2.102:8188...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
GET /index.html HTTP/1.1
Host:192.168.2.102
HTTP/1.1 200 OK
Date: Wed, 31 Oct 2018 14:09:03 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 31 Oct 2018 10:03:23 GMT
ETag: "67-5798369a7b9b8"
Accept-Ranges: bytes
Content-Length: 103
Content-Type: text/html; charset=UTF-8
<html>
<head>
<title>testhtml</title>
</head>
<body>
<h1>testhtml,hello</h1>
</body>
</html>
GET /index1.html HTTP/1.1
Host:192.168.2.102
HTTP/1.1 200 OK
Date: Wed, 31 Oct 2018 14:09:30 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 31 Oct 2018 14:05:51 GMT
ETag: "d-57986ccc1c9f2"
Accept-Ranges: bytes
Content-Length: 13
Content-Type: text/html; charset=UTF-8
hello world
Connection closing...Socket close.
Connection closed by foreign host.
Disconnected from remote host(192.168.2.102:8188) at 22:10:24.
Type `help' to learn how to use Xshell prompt.
3、定义web文件路径
在httpd服务的主配置文件中,“'Main' server”部分,定义web文档路径映射。
- 使用
DocumentRoot "/PATH/TO/FILE"
语句定义URL路径的起始位置,用于基于文件系统路径或URL路径的访问控制。- 使用
DirectoryIndex index.html
定义站点默认首页。- 使用
AddDefaultCharset UTF-8
定义默认字符集,常用中文字符集有:GBK、Gb2312、GB18030等。
站点访问控制机制:
常用的站点访问控制即只有两种:一种是基于文件系统路径的访问控制机制;另一种是基于URL的站点访问控制机制。两者可同时设置
基于文件系统路径:
1、基于源地址实现访问控制,在此设置的目录下所有文件都遵循此处的指令设置。格式为:
httpd-2.2:
<Directory "/PATH/TO/FILE">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
httpd-2.4:
<Directory "/PATH/TO/FILE">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
2、针对单个文件实现访问控制。其格式为:
<File "/PATH/TO/FILE">
....
<File>
3、DSO动态共享对象机制
在/etc/httpd/conf/httpd.conf主配置文件中使用配置指令实现模块加载:
LoadModule <mod_name> <mod_path>
模块文件路径可使用相对路径:相对于ServerRoot(默认为/etc/httpd)
例如:
ServerRoot "/etc/httpd"
# LoadModule foo_module modules/mod_foo.so
#
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
4、根据模式匹配到的文件实现访问控制。正则表达式要启用引擎,因此建议不使用;其格式为:
<FileMatch "PATTERN">
...
</FileMatch>
基于URL路径:
定义URL的目录,表示在此设置的目录下所有文件都遵循此处的指令设置;
<Location "/PATH/TO/FILE">
...
</Location>
<LocationMatch "/PATH/TO/FILE">
...
</LocationMatch>
"Directory"中各选项的参数
- Options的参数:
- Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户;作为下载站点时才使用;否则,不使用此选项;
- FollowSymLinks:允许跟踪符号链接文件所指向的源文件;
- None:都禁止;
- All:都允许;
- Includes:允许启用服务器包含功能;
- SymLinksifOwnerMatch:比FollowSymLinks在限制上更为严格的机制;表示只有原文件的属主和链接文件的属主相同时,才允许跟踪;
- ExecCGI:允许执行cgi脚本;
- MultiViews:允许执行内容协商;非常消耗资源且不太安全;
- AllowOverride
AllowOverride用于定义与访问控制相关的哪些指令可以放在.htaccess文件中,会使网站资源解析时性能影响非常大,因此通常设置为None。- All: 所有指令都可放在这个隐藏文件中;
- None:这个隐藏文件中什么指令都不放;
- Order allow,deny:基于源地址做访问控制的机制
- Order:定义生效次序;写在后面的表示默认法则;
- Order allow,deny 表示白名单;
- Order deny,allow 表示黑名单;
- Order:定义生效次序;写在后面的表示默认法则;
- Allow/Deny from(在httpd2.2中使用)
Allow和Deny语句可以针对客户机的域名或IP地址进行设置,以决定哪些客户机能够访问服务器。- Allow from IP:表示允许某些地址访问。
- Deny from IP:显式定义拒绝那些地址访问。
- Require all granted:允许所有人访问
在httpd2.4中使用Require限制源地址访问控制,Require all granted是允许所有人访问,Require all granted禁止所有人访问,还可以禁止某个IP或域名的访问:- 基于IP的控制
- Require ip IP地址或者网络地址 :允许访问
- Require not ip IP地址或者网络地址:拒绝访问
- 基于主机名控制:
- Require host 主机名或域名:允许访问
- Require not host 主机名或域名:拒绝访问
- 注意:这些访问控制要放置于
<Requireall>...</Requireall>
配置块或<RequireAny>...</RequireAny>
配置块中
- 基于IP的控制
示例
新建/web/html目录,编辑修改httpd服务,使其能够web访问/web/html目录下的index.html目录文件:
[root@localhost /]# mkdir -pv /web/html
mkdir: created directory `/web'
mkdir: created directory `/web/html'
[root@localhost /]# vim /web/html/index.html
hello!
this is a test page
[root@localhost /]# chcon -R --reference /var/www/html/ /web/html/
[root@localhost /]# vim /etc/httpd/conf/httpd.conf
DocumentRoot "/web/html"
<Directory "/web/html">
Options none
AllowOverride None
Order allow,deny
Allow from all
</Directory>
[root@localhost /]# service httpd start
5、httpd的虚拟主机
httpd的虚拟主机是利用httpd自带的VirtualHost功能来实现的。一个httpd服务器上配置多个虚拟主机,实现一个服务器提供多站点服务,其实就是访问同一个服务器上的不同目录。虚拟主机的配置方式为:
在/etc/httpd/conf/httpd.conf主配置文件中修改,或者在//etc/httpd/conf.d/*.conf目录下新建配置文件。
<VirtualHost IP:PORT>
ServerName FQDN
DocumentRoot "/PATH/TO/FILE" #设置此虚拟主机的web根目录
</VirtualHost>
httpd虚拟主机有三种实现方式:
1、基于IP方式的实现:需要给每个虚拟主机设置至少一个IP地址。
示例:
利用virtualhost基于IP的方式实现/var/www/html目录和/web/html目录下的网页文件的同时访问
[root@localhost ~]# mkdir -pv /web/html
mkdir: 已创建目录 "/web"
mkdir: 已创建目录 "/web/html"
[root@localhost ~]# chcon -R --reference /var/www/html/ /web/html/
[root@localhost ~]# ip addr add 192.168.2.159 dev ens33
[root@localhost ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:a4:84:0e brd ff:ff:ff:ff:ff:ff
inet 192.168.2.104/24 brd 192.168.2.255 scope global noprefixroute dynamic ens33
valid_lft 4761sec preferred_lft 4761sec
inet 192.168.2.159/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::74ad:6110:89fe:b8b2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]# vim /web/html/index.html
test page
[root@localhost ~]# vim /etc/httpd/conf.d/webtest.conf
<VirtualHost 192.168.2.159:8080>
DocumentRoot "/web/html"
<Directory "/web/html">
AllowOverride none
Options none
Require all granted
</Directory>
</VirtualHost>
[root@localhost ~]# systemctl restart httpd
2、基于port的方式实现:需要为每个虚拟主机使用至少一个独立的port。
示例:
基于port的方式实现/var/www/html目录和/web/html目录下的网页文件的同时访问。
[root@localhost ~]# vim /etc/httpd/conf.d/webporttest.conf
Listen 8188 #监听8188端口,
<virtualhost *:8188>
Documentroot /web/html
<Directory "/web/html">
AllowOverride none
Options none
Require all granted
</Directory>
</virtualhost>
[root@localhost ~]# systemctl restart httpd
3、基于FQDN的方式实现:为每个虚拟主机使用至少一个FQDN。其配置方式为:如果是httpd-2.2,需要在配置文件中添加NameVirtualHost IP:PORT
NameVirtualHost 172.16.100.6:80 #如果是httpd-2.2,需要在配置文件中添加此句
<VirtualHost 172.16.100.6:80>
ServerName www.a.com #指定FQDN
DocumentRoot "/www/a.com/htdocs"
</VirtualHost>
<VirtualHost 172.16.100.6:80>
ServerName www.b.net #指定FQDN
DocumentRoot "/www/b.net/htdocs"
</VirtualHost>
示例:
[root@localhost ~]# mkdir /web/html1
[root@localhost ~]# chcon -R --reference /var/www/html/
[root@localhost ~]# vim /web/html1/index.html
wawawawaw
qqwrw
test
[root@localhost ~]# vim /etc/httpd/conf.d/webstest.conf
<virtualhost *:8080>
Servername www.a.com
Documentroot /web/html
<Directory "/web/html">
AllowOverride none
Options none
Require all granted
</Directory>
</virtualhost>
<virtualhost *:8080>
Servername www.b.com
Documentroot /web/html1
<Directory "/web/html1">
AllowOverride none
Options none
Require all granted
</Directory>
</virtualhost>
[root@localhost ~]# systemctl restart httpd
修改window系统的hosts文件,并测试
6、基于用户的访问控制
基于用户的访问控制是通过http协议自身的认证来实现的。http协议的认证有两种方式:
- basic:基本认证,用户名和密码基于明文发送的
- digest:消息摘要认证。认证时客户端不会发送自己的密码,而是用自己的密码加密一个数据串发送给服务器端,服务器端用此前存储的密码能解密就表示认证通过。
由于并不是所有浏览器都支持摘要认证,所以一般使用较多的是basic认证方式。其设置过程如下:
1、用htpasswd命令生成提供账号和密码存储的文本文件
htpasswd
语法:
htpasswd [options] passwordfile username
选项:
-c:创建文件;如果密码文件则覆盖;
-m:使用md5算法加密密码;
-s:使用sha算法加密;
-d:使用对称加密,不安全,建议不使用;
-b:在htpassswd命令行中一并输入用户名和密码而不是根据提示输入密码
-D:删除指定用户;
设置过程:
[root@localhost ~]# htpasswd -cm /etc/httpd/conf/.webpasswd wxq
New password:
Re-type new password:
Adding password for user wxq
[root@localhost ~]# htpasswd -bm /etc/httpd/conf/.webpasswd root qwe123
Adding password for user root
[root@localhost ~]# htpasswd -bm /etc/httpd/conf/.webpasswd admin qweasd
Adding password for user admin
[root@localhost ~]# cat /etc/httpd/conf/.webpasswd
wxq:$apr1$p/JTxm/j$r6KzssyANlN5yCKHKaSkl/
root:$apr1$RoJP03bE$seDgbG2dRVPt05kh/Pfg/.
admin:$apr1$uAuj78ID$rzFH72mTYfiuw2L/0uvj40
2、编辑配置文件,设置用户认证,然后重启httpd。配置文件既可以是修改主配置文件/etc/httpd/conf/httpd.conf,也可以在/etc/httpd/conf.d/文件加下新建配置文件。
[root@localhost ~]# vim /etc/httpd/conf.d/webporttest.conf
<virtualhost *:8188>
Documentroot /web/html
<Directory "/web/html">
AllowOverride none
Options none
AuthType Basic
AuthName "welcome to my server.Please enter your account number and password"
AuthUserFile "/etc/httpd/conf/.webpasswd"
Require user wxq root admin
</Directory>
</virtualhost>
[root@localhost ~]# systemctl restart httpd
访问服务器测试
基于域的用户访问控制
有大量用户需要认证时,可使用基于域的认证方式,把用户加入到域中,将用户划分为相应的域组,并根据域组来做相应的访问控制。
1、先创建域组文件:
[root@localhost ~]# vim /etc/httpd/conf/.htgroup
gptest:wxq
2、修改配置文件,然后重启服务,登陆访问测试:
[root@localhost ~]# vim /etc/httpd/conf.d/webporttest.conf
<virtualhost *:8188>
Documentroot /web/html
<Directory "/web/html">
AllowOverride none
Options none
AuthType Basic
AuthName "welcome to my server.Please enter your account number and password"
AuthUserFile "/etc/httpd/conf/.webpasswd"
AuthGroupFile "/etc/httpd/conf/.htgroup"
Require user wxq root admin
</Directory>
</virtualhost>
[root@localhost conf.d]# systemctl restart httpd