linux发型版本:CentOS 6.10 x86_64
httpd版本:yum的base仓库的httpd2.2.15
Selinux状态:关闭
iptables状态:关闭
说明:重点以CentOS 6.x上演示httpd2.2为主,会有一小部分对上次在CentOS 7.x上编译安装
的httpd2.2进行基本说明。
参考引用:
https://httpd.apache.org/docs/2.4/programs/httpd.html
https://en.wikipedia.org/wiki/Apache_HTTP_Server
http://blog.51cto.com/xslwahaha/1548983
https://www.linuxidc.com/Linux/2015-02/114007.htm
http://blog.sina.com.cn/s/blog_56115979010160h3.html
https://www.cnblogs.com/zhuifeng/p/4072248.html
httpd is Apache HyperText Transfer Protocol(HTTP) server program.It is designed to be run as a standalone daemon process.When used like this it will create a pool of child processes or threads to handle requests.
httpd是ASF(Apache Software Foundation,Apache软件基金会)下的产品之一,也是比较有名的产品。httpd本身是超文本传输协议(HTTP)的服务端程序。httpd可以作为独立的守护进程运行。当用户的请求到来时,httpd可以创建进程池或线程池来处理请求。
让我们来回顾一下之前学习过的TCP/IP和ISO/OSI的模型。如图所示:
前面我们指出过,httpd是apache旗下的产品之一,然后它是http协议的应用程序实现。而我们的http协议,它在协议栈中的位置,是属于应用层。那为了完成http协议的报文发送,它大体是如何工作的呢?我们都知道,实现网络报文的传输属于网络通信的功能,而网络通信功能则是由内核来提供的,我们以TCP/IP的四层模型为例。内核可以按照其功能划分为通信子网和资源子网,通信子网对应我们的TCP/IP协议栈的底三层,而资源子网对应我们的TCP/IP协议栈的第四层(从下往上)。遵循TCP/IP协议栈模型的应用程序,大多数都是C/S架构的,所以实现http协议的应用程序httpd应该也有服务端和客户端之分,而我们现在生活中接触最多的,就是服务端,我不知道,可能是一个比较有名的主机名,然后我们通过本地的浏览器的导航栏直接输入这个主机名地址,然后就可以显示一个页面信息,其背后的机体是很复杂的。C/S架构,就有所谓的服务端和客户端,服务端和客户端是分开的主机也可以是同一单主机。其实啊,不管是同一台主机还是不同主机,服务端和客户端之间的通信都是基于进程间通信的概念。从协议栈的角度考虑,互联网地址(ip地址)可以标识一台主机,而对应端口可以标识一个进程地址。因为在C/S模式的程序中,服务端为了随时响应客户端的连接请求,它是首先向内核申请注册使用一个端口,这个端口注册后,应用程序启动,服务端一直处于监听状态。服务端要对应到具体的服务端进程。基于TCP/IP协议栈通信,首先在应用层,会添加一个应用层首部,资源子网的任务完成后,会发送给内核,内核的通信子网,从传输层开始,它会给报文添加一个传输层首部。传输层会标明进程使用的端口,往下走,在网络层,会添加一个IP首部,这层可以标识一个互联网地址。往下链路层就添加一个链路层首部,链路层首部包含帧信息,最终会通过层层路由传输到对端。对端每一层从上往下,会依次拆解各层首部,获取详细信息。在网络层,拆解首部后,会看到具体的服务器IP,在传输层拆解首部后,会看到端口信息,通过一个ip和端口就可以标记具体服务器的具体进程,在应用层会拆解之后给对应的应用层程序。
其实,在上面的过程中,我们还涉及一个主机名和ip地址的区别。在现代的知名站点中,没有谁是具体提供一个ip地址给客户端访问,而是一个主机名。那么它背后的机理又是如何的呢?
如果涉及到主机名,就要涉及到一个所谓的DNS服务器的概念。我们以下面的图进行简单讲解。
现在我们要去请求www.baidu.com这个主机名的时候,默认http协议的端口是80,浏览器做了特殊处理,如果省略主机名后面的端口,表示使用默认的80.完整的URL(后面会讲解什么是URL),我们浏览器要识别这种语法。假设baidu站点的默认主页为index.html。那么完成的URL应该是:
http://www.baidu.com:80/index.html
浏览器默认是不识别主机名的,那么这个时候所谓的DNS就其作用了。会先去本地的hosts文件中查找主机名和ip映射条目,如果没有找到,会通过本地配置的dns服务器去,让它去迭代查找dns记录,找到后会把ip地址返回给用户,这个时候假设ip地址为14.215.177.38.现在客户端就开始构建请求报文。要通过 本地的内核的网络通信功能,交由互联网路由层层传输到达httpd的主机。然后根据之前讲解的虚拟模型,TCP/IP,会层层拆解对应层次的首部,直到把报文交由对应的httpd进程,其中可能涉及TCP的三次握手,最终httpd进程会去想内核申请加载磁盘的index.html数据到内核的内存空间,然后再到进程的内核空间,然后经过特殊处理把响应报文交由内核去处理,然后发送给客户端。后面的过程就不详解了,大概就是这样,当然,其中的很多细节不是这么简单的。比如,客户端和服务端之间的报文传输使用http协议的什么版本,以及传输数据是否压缩处理,以及传输数据的格式以及为什么http协议使用的端口是80等等一些列规范和疑问都是有复杂的背后处理机制来完成的。
IANA分配的端口说明:
IANA,互联网数字分配机构,我们之前在了解DNS之前就已经知道过,它除了负责名称解析,而且指明协议的端口的分配都是由它来管理的。
(1) 特权端口,固定端口
0~1023这个区间段的端口属于众所周知的端口,是属于固定协议的端口,也属于特权端口。只有管理员权限用户才能向内核发起注册使用。比如http协议默认的80,https协议默认的443,dns协议的默认53等
(2) 半随机端口
1024~41951,这个区间段的端口,为半随机端口,普通用户也可以注册使用。分配给程序注册为某应用使用。应用程序mysql的默认tcp协议端口3306。
(3) 随机端口
41951以上,好像是小于65535,要看具体内核参数配置(/proc/sys/net/ipv4/ip_local_port_range)。这个区间段的端口属于随机端口或者叫动态端口,大部分的应用程序随机注册都是使用的这个端口范围内的。
上面有提到主机之前的通信其实就是进程间通信(同一个主机上的进程或者不同主机上的进程)。那么进程间通信有个套接字的概念,具体套接字可以根据不同层面进行分类:
(1) 根据传输层协议
SOCK_STREAM:tcp套接字;
SOCK_DGRAM:udp套接字;
SOCK_RAW:raw套接字;
(2) 根据套接字所使用的地址格式
AF_INET:ipv4
AF_INET6:ipv6
AF_UNIX:unix格式(同一主机上的不同进程间基于socket套接字通信使用的一种地址;Unix_SOCK)
上面有提到报文之间传输,服务端和客户端在建立连接时,会建立虚拟电路,TCP的三次握手,端口的时候会经历四次挥手:
引用:
https://baike.baidu.com/item/三次握手/5111559
在三次握手和四次挥手(会有对应专题详解三次握手和四次挥手)中,会涉及到一个TCP的状态,我们统称为TCP的有限状态机(TCP FSM)。一共有如下这些状态:
CLOSED, LISTEN,SYN_SENT, SYN_RECV, ESTABLISHED, FIN_WAIT1, CLOSE_WAIT, FIN_WAIT2, LAST_ACK, TIMEWAIT
TCP的协议特性:(记住就行)
建立连接:三次握手;
将数据打包成段:校验和(CRC32)
确认、重传及超时;
排序:逻辑序号;
流量控制:滑动窗口算法;
拥塞控制:慢启动和拥塞避免算法;
http的协议版本:
(1) http/0.9
http的原型版本。功能很简单。
(2) http/1.0
引入简单cache(缓存)。
引入对MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)的支持。
支持的方法:
GET, POST, HEAD,PUT, DELETE,TRACE, OPTIONS
(3) http/1.1
基于http/1.0的增强版,主要是增强来对cache的支持。不过还是会效率很低,等等其他问题。
谷歌在http/1.1是主流的时候,自己开发了基于TCP应用层协议SPDY。
(4) httpd/2.0
有望成为将来的主流,现在已经陆陆续续引入使用了,有充分参考spdy的设计。
httpd接收请求的模型(并发访问相应模型):
(1)单进程I/O模型
启动一个进程处理用户请求;这意味着,一次只能处理一个请求,多个请求被串行响应;
(2)多进程I/O模型
由父进程并行启动多个子进程,每个子进程响应一个请求;
(3) 复用的I/O模型
一个进程响应N个请求;实现方式有下面两种:
a) 多线程模式
一个进程生成n个线程,一个线程处理一个请求;
b)事件驱动(event-driven)
一个进程直接处理n个请求;
(4) 复用的多进程I/O结构
启动多个(m)个进程,每个进程生成(n)个线程;响应的请求的数量:m*n
在httpd的众多特性中,MPM算是非常重要的一个。MPM(Multipath processing Modules)为多路处理模块。三种比较应用广泛的MPM类型:prefork,worker,event
(1) prefork
多进程模型,每个进程响应一个请求;
一个主进程,负责生成子进程及回收子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;会有N个子进程,每个子进程处理一个请求。
工作模型:会预先生成几个空闲进程,随时等待用于响应用户请求;管理进程生成和销毁进程要符合预设最大空闲和最小空闲进程数量;对应上面的多进程I/O模型。
(2) worker
多进程多线程模型,每线程处理一个用户请求;
一个主进程,负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;多个子进程,每个子进程负责生成多个线程;每个线程:负责响应用户请求;
假设子进程数量为m,每个子进程所能创建的最大县城数量为n,那么并发响应数量:m*n
对应上面的复用I/O模型的多线程模型。
(3) event
事件驱动模型,多进程模型,每个进程响应多个请求;
一个主进程 ,负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;子进程,基于事件驱动机制直接响应多个请求;对应上面的复用I/O模型的事件驱动模型。
说明:在httpd2.2中,event模型属于测试阶段,功能完整性得不到保障,所以如果使用的是httpd2,2,建议生成环境,使用prefork或worker(其实单进程多线程的工作方式并不是非常理想,在httpd2.2,大部分人还是选择使用prefork)。而且在httpd2.2,prefork和worker的支持是静态编译进来的功能, 所以如果要使用二者,要提前都编译好,切换的时候只用对应的应用程序文件启动即可。而在了httpd2.4,不仅对prefork,worker以及event的完全支持,而且它们可以以模块的方式动态装卸切换,非常方便。而且建议在httpd2.4使用event模型。
http协议是超文本传输协议( HyperText Transfer Protocol),是一种应用程序的文本协议。使用http协议打开的网站现实的页面对应的资源是通过html(hypertext mark language,超文本标记语言)语言来编写的,在特定的客户端程序(比如浏览器)会显示出特定的格式。html格式语言类似于如此:
TITLE
blabla... bla...
可以让html配合js以及css设计出更加丰富的页面排版等,当然,详细的这些活属于前段工程师要做的。上面有提到了资源的概念,web服务器上资源分类:
(1) 静态资源
无须服务端做出额外处理,直接加载硬盘存储数据(有些要经过编码等特殊处理后发送)。比如常见以以下后缀结尾的都是静态资源: .jpg, .png, .gif, .html, txt, .js, .css, .mp3, .avi等。
(2) 动态资源
服务端需要通过执行程序做出处理,发送给客户端的是程序的运行结果。比如以以下后缀结尾的:.php,.jsp等。
请求加载的一个页面可能有多个资源,是通过URL来表示的,URL又叫统一资源标识符(Uniform Resource Locator),用于标识服务器特定资源的位置。我们在客户端浏览器键入就是URL。一个完整的URL格式如下:
Scheme://Server[:Port][/PATH/TO/SOME_RESOURCE]
其中scheme表示协议方案,比如可以为ftp,http,https,svn等;
server表示应用程序的主机名地址或ip地址;
port表示请求对应主机名上对应程序进程注册使用的端口号,如果是用默认协议的默认端口号,这个可以省略不写,到时候浏览器会自动加上;
/xxx:表示请求的资源目录,这个根(/)是相对于站点定义的文档路径的。比如/test/index.html,站点定义的文档路径为/var/www/html,那么这个请求服务器上的资源路径为:/var/www/html/test/index.html
一次完整的http请求处理过程:
(1) 建立或处理连接:接收请求或拒绝请求;
(2) 接收请求:接收来自于网络上的主机请求报文中对某特定资源的一次请求的过程;
(3) 处理请求:对请求报文进行解析,获取客户端请求的资源及请求方法等相关信息;
(4) 访问资源:获取请求报文中请求的资源;
(5) 构建响应报文
(6) 发送响应报文
(7) 记录日志
客户端向服务器发起请求,其请求的报文叫"请求报文(http request)";
服务器接受到客户端的请求后,向客户端响应的报文叫"响应报文(http response)";
而一次http事务则是由"请求报文"和"响应报文组成"。
请求报文和响应报文格式:
(1) 请求报文
起始行:<请求方法><请求的URL><请求使用的http协议版本>
请求报文头部:<请求报文头部>
空行:
请求报文主体部分:<请求报文主体>
(2) 响应报文
起始行:<响应使用的http协议版本><响应状态码><状态码的解释说明,原因短语>
响应报文头部:<响应报文头部>
空行:
响应报文主体部分:<响应报文主体>
1、方法(method)
请求方法,标明客户端希望服务器对资源执行的动作。例如,方法有:
GET,HEAD,POST,PUT(DAV)
2、请求的URL
要直接与服务器进行对话,只要请求URL是资源的绝对路径就可以了,服务器可以假定自己是URL的主机/端口。
3、httpd协议版本
HTTP/.
例如:
HTTP/1.1
4、状态码(status)
三位数字,如200,301,302,404,502。后面会列出详细的状态码的含义。
5、原因短语(reason-phrase)
状态码所标记的状态的简要描述。
6、头部
每个请求或响应报文可包含任意个首部;每个首部都有首部的名称。可以有零个或多个头部,每个首部都包含一个名字,后面跟着一个冒号(?,然后是一个可选的空格,接着是一个值,最后是一个CRLF首部是由一个空行(CRLF)结束的,表示了头部列表的结束和实体主体部分的开始。
7、实体的主体部分(entity-body)
体的主体部分包含一个由任意数据组成的数据块,并不是所有的报文都包含实体的主体部分,有时,报文只是以一个CRLF结束。
摘抄于:https://www.cnblogs.com/zhuifeng/p/4072248.html
头部和状态码介绍:
头部分为"通用头部","请求头部","响应头部"以及"实体首部"
通用头部:既可以出现在请求报文中,也可以出现在响应报文中,它提供了与报文相关的最基本的信息
Connection:允许客户端和服务器指定与请求/响应连接有关的选项
Date:提供日期和时间标志,说明报文是什么时间创建的
MIME-Version:给出了发送端使用的MIME版本
Trailer:如果报文采用了分块传输编码方式,就可以用这个首部列出位于报文拖挂部分的首部集合
Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
Update:给出了发送端可能想要“升级”使用的新版本或协议
Via:显示了报文经过的中间节点(代理、网关)
Cache-Control:用于随报文传送缓存指示
请求头部:请求头部是只在请求报文中有意义的头部。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力
Client-IP:提供了运行客户端的机器的IP地址
From:提供了客户端用户的E-mail地址
Host:给出了接收请求的服务器的主机名和端口号
Referer:提供了包含当前请求URI的文档的URL
UA-Color:提供了与客户端显示器的显示颜色有关的信息
UA-CPU:给出了客户端CPU的类型或制造商
UA-OS:给出了运行在客户端机器上的操作系统名称及版本
UA-Pixels:提供了客户端显示器的像素信息
User-Agent:将发起请求的应用程序名称告知服务器
Accept:告诉服务器能够发送哪些媒体类型
Accept-Charset:告诉服务器能够发送哪些字符集
Accept-Encoding:告诉服务器能够发送哪些编码方式
Accept-Language:告诉服务器能够发送哪些语言
TE:告诉服务器可以使用那些扩展传输编码
Expect:允许客户端列出某请求所要求的服务器行为
Range:如果服务器支持范围请求,就请求资源的指定范围
If-Match:如果实体标记与文档当前的实体标记相匹配,就获取这份文档
If-Modified-Sinec:除非在某个指定的日期之后资源被修改过,否则就限制这个请求
If-None-Match:如果提供的实体标记与当前文档的实体标记不相符,就获取文档
If-Range:允许对文档的某个范围进行条件请求
If-Unmodified-Since:除非在某个指定日期之后资源没有被修改过,否则就限制这个请求
Authorization:包含了客户端提供给服务器,以便对其自身进行认证的数据
Cookie:客户端用它向服务器传送数据
Cookie2:用来说明请求端支持的cookie版本
Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数
Proxy-Authorization:这个首部在与代理进行认证时使用的
Proxy-Connection:这个首部是在与代理建立连接时使用的
响应头部:响应头部为客户端提供了一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令
Age:(从最初创建开始)响应持续时间
Public:服务器为其资源支持的请求方法列表
Retry-After:如果资源不可用的话,在此日期或时间重试
Server:服务器应用程序软件的名称和版本
Title:对HTML文档来说,就是HTML文档的源端给出的标题
Warning:比原因短语更详细一些的警告报文
Accept-Ranges:对此资源来说,服务器可接受的范围类型
Vary:服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端
Proxy-Authenticate:来自代理的对客户端的质询列表
Set-Cookie:在客户端设置数据,以便服务器对客户端进行标识
Set-Cookie2:与Set-Cookie类似
WWW-Authenticate:来自服务器的对客户端的质询列表
实体首部:描述主体的长度和内容,或者资源自身
Allow:列出了可以对此实体执行的请求方法
Location:告知客户端实体实际上位于何处,用于将接收端定向到资源的位置(URL)上去
Content-Base:解析主体中的相对URL时使用的基础URL
Content-Encoding:对主体执行的任意编码方式
Content-Language:理解主体时最适宜使用的自然语言
Content-Length:主体的长度
Content-Location:资源实际所处的位置
Content-MD5:主体的MD5校验和
Content-Range:在整个资源中此实体表示的字节范围
Content-Type:这个主体的对象类型
ETag:与此实体相关的实体标记
Expires:实体不再有效,要从原始的源端再次获取实体的日期和时间
Last-Modified:这个实体最后一次被修改的日期和时间
状态码:
摘抄于:https://baike.baidu.com/item/http/243074?fromtitle=超文本传输协议&fromid=8535513
1xx:100-101,信息提示
100 Continue:服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。
101 Switching Protocols:服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。
2xx:200-206,成功
200 OK:请求成功(其后是对GET和POST请求的应答文档。)
201 Created:请求被创建完成,同时新的资源被创建。
202 Accepted:供处理的请求已被接受,但是处理未完成。
203 Non-authoritative Information:文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝。
204 No Content:没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的
205 Reset Content:没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它。
3xx:300-307,重定向
300 Multiple Choices:多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
301 Moved Permanently:所请求的页面已经转移至新的url。
302 Found:所请求的页面已经临时转移至新的url。
303 See Other:所请求的页面可在别的url下被找到。
304 Not Modified:未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
305 Use Proxy:客户请求的文档应该通过Location头所指明的代理服务器提取。
306 Unused:此代码被用于前一版本。目前已不再使用,但是代码依然被保留。
307 Temporary Redirect:被请求的页面已经临时移至新的url。
4xx:400-423,错误类信息,客户端错误
400 Bad Request:服务器未能理解请求。
401 Unauthorized:被请求的页面需要用户名和密码。
401.1:登录失败。
401.2:服务器配置导致登录失败。
401.3:由于 ACL 对资源的限制而未获得授权。
401.4:筛选器授权失败。
401.5:ISAPI/CGI 应用程序授权失败。
401.7:访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
402 Payment Required:此代码尚无法使用。
403 Forbidden:对被请求页面的访问被禁止。
403.1:执行访问被禁止。
403.2:读访问被禁止。
403.3:写访问被禁止。
403.4:要求 SSL。
403.5:要求 SSL 128。
403.6:IP 地址被拒绝。
403.7:要求客户端证书。
403.8:站点访问被拒绝。
403.9:用户数过多。
403.10:配置无效。
403.11:密码更改。
403.12:拒绝访问映射表。
403.13:客户端证书被吊销。
403.14:拒绝目录列表。
403.15:超出客户端访问许可。
403.16:客户端证书不受信任或无效。
403.17:客户端证书已过期或尚未生效。
403.18:在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
403.19:不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
403.20:Passport 登录失败。这个错误代码为 IIS 6.0 所专用
404 Not Found:服务器无法找到被请求的页面。
404.0:(无)–没有找到文件或目录。
404.1:无法在所请求的端口上访问 Web 站点。
404.2:Web 服务扩展锁定策略阻止本请求。
404.3:MIME 映射策略阻止本请求。
405 Method Not Allowed:请求中指定的方法不被允许。
406 Not Acceptable:服务器生成的响应无法被客户端所接受。
407 Proxy Authentication Required:用户必须首先使用代理服务器进行验证,这样请求才会被处理。
408 Request Timeout:请求超出了服务器的等待时间。
409 Conflict:由于冲突,请求无法被完成。
410 Gone:被请求的页面不可用。
411 Length Required:"Content-Length" 未被定义。如果无此内容,服务器不会接受请求。
412 Precondition Failed:请求中的前提条件被服务器评估为失败。
413 Request Entity Too Large:由于所请求的实体的太大,服务器不会接受请求。
414 Request-url Too Long:由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。
415 Unsupported Media Type:由于媒介类型不被支持,服务器不会接受请求。
416 Requested Range Not Satisfiable:服务器不能满足客户在请求中指定的Range头。
417 Expectation Failed:执行失败。
423:锁定的错误。
5xx:500-505,错误类信息,服务端错误
500 Internal Server Error:求未完成。服务器遇到不可预知的情况。
500.12:应用程序正忙于在 Web 服务器上重新启动。
500.13:Web 服务器太忙。
500.15:不允许直接请求 Global.asa。
500.16:UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。
500.18:URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。
500.100:内部 ASP 错误。
501 Not Implemented:请求未完成。服务器不支持所请求的功能。
502 Bad Gateway:请求未完成。服务器从上游服务器收到一个无效的响应。
502.1:CGI 应用程序超时。
502.2: CGI 应用程序出错。
503 Service Unavailable:请求未完成。服务器临时过载或当机。
504 Gateway Timeout:网关超时。
505 HTTP Version Not Supported:服务器不支持请求中指明的HTTP协议版本。
(1) 直接使用yum的base仓库的httpd2.2
yum install httpd
安装过程省略。
(2) 安装主要文件列表说明
配置文件:
/etc/httpd/conf/httpd.conf
/etc/httpd/conf.d/*.conf
服务脚本:
/etc/rc.d/init.d/httpd
脚本的配置文件:/etc/sysconfig/httpd
主程序文件:
/usr/sbin/httpd
/usr/sbin/httpd.event
/usr/sbin/httpd.worker
日志文件:
/var/log/httpd:
access_log:访问日志
error_log:错误日志
站点文档:
/var/www/html
模块文件路径:
/usr/lib64/httpd/modules
服务控制和启动:
chkconfig httpd on|off
service {start|stop|restart|status|configtest|reload} httpd
(1) 默认主配置文件语法
[root@yanhui_httpd ~]# grep '^###' /etc/httpd/conf/httpd.conf
### Section 1: Global Environment
### Section 2: 'Main' server configuration
### Section 3: Virtual Hosts
第一部分是:全局环境设定
第二部分是:主要服务端的配置
第三部分是:虚拟主机配置
(2) 配置指令格式
指令(directive) 值(value)
说明:其中指令不区分字符大小写;当值为路径时候,具体是否区分字符大小写取决于文件系统,比如linux的
文件路系统路径就区分字符大小写,windows的文件系统路径就不区分。
[root@yanhui_httpd ~]# grep -i -B 10 '^listen' /etc/httpd/conf/httpd.conf
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
Listen 80
Description: IP addresses and ports that the server listens to
Syntax: Listen [IP-address:]portnumber [protocol]
Context: server config
Status: MPM
Module: beos, mpm_netware, mpm_winnt, mpmt_os2, prefork, worker, event
Compatibility: Required directive since Apache 2.0
The protocol argument was added in 2.1.5
说明:
(1) 省略IP-address表示监听到通用网卡,及0.0.0.0;
(2) Listen指令可以重复出现多次,监听多个端口就可以使用这种机制;
(3) 修改监听的socket要重启才能生效;
(4) http协议配合ssl工作,这里的protocol部分要设置为https
例如:
Listen 192.168.56.90:443 https
Listen 192.168.56.90:1443 https
例如我启动我本地的http,配置支持http和https,并且http监听到80,8080端口,https监听到443和1443端口
[root@yanhui_httpd ~]# ss -nltu
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 :::443 :::*
tcp LISTEN 0 128 :::1443 :::*
tcp LISTEN 0 128 :::8080 :::*
tcp LISTEN 0 128 :::80 :::*
tcp LISTEN 0 128 :::22 :::*
tcp LISTEN 0 128 *:22 *:*
tcp LISTEN 0 100 ::1:25 :::*
tcp LISTEN 0 100 127.0.0.1:25 *:*
[root@yanhui_httpd ~]# grep '^Listen' /etc/httpd/conf/httpd.conf
Listen 80
Listen 8080
Listen 443
Listen 1443
持久连接又叫保持连接或长连接。所谓持久连接,就是tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行。特定业务场景,打开持久连接是可以节省每次建立连接带来的资源开销的。什么情况下会端口:
(1) 数量达到限制
(2) 时间达到会话时间限制
默认情况,httpd2.2的配置没有启用持久连接,持久连接带来的副作用:
对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常响应;实际生产中,使用较短的持久连接时长,以及较少的请求数量。
[root@yanhui_httpd ~]# grep -A 13 '^KeepAlive[[:blank:]]\+' /etc/httpd/conf/httpd.conf
KeepAlive Off
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 15
指令配置语法官方链接:
http://httpd.apache.org/docs/2.2/en/mod/core.html#keepalive
http://httpd.apache.org/docs/2.2/en/mod/core.html#maxkeepaliverequests
http://httpd.apache.org/docs/2.2/en/mod/core.html#keepalivetimeout
KeepAlive Off #设置为On表示启用持久连接
MaxKeepAliveRequests 100 #处于持久连接模式下最大的允许请求的连接数量,为了性能,要适当设置这个值,设置为0表示无限制。
KeepAliveTimeout 15 #持久连接模式下,同一个连接会话,两次连接请求的等待的时间秒数。httpd2.2只支持到秒级别,httpd2.4支持到毫秒级别。
httpd-2.2不支持同时编译多个MPM模块,所以只能编译选定要使用的那个;CentOS 6的rpm包为此专门提供了三个应用程序文件,httpd(prefork), httpd.worker, httpd.event,分别用于实现对不同的MPM机制的支持;确认现在使用的是哪下程序文件的方法:
ps aux|grep 'httpd'
[root@yanhui_httpd ~]# ps aux|grep 'httpd'
root 17630 0.0 0.7 177524 3840 ? Ss 21:10 0:00 /usr/sbin/httpd
apache 17632 0.0 0.5 177524 2496 ? S 21:10 0:00 /usr/sbin/httpd
apache 17633 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17634 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17635 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17636 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17637 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17638 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
apache 17639 0.0 0.5 177524 2476 ? S 21:10 0:00 /usr/sbin/httpd
root 17666 0.0 0.1 103320 888 pts/1 S+ 21:23 0:00 grep httpd
[root@yanhui_httpd ~]#
#我这里使用的默认值,默认值是prefork模型。 如果要切换成worker(event因为是测试阶段,所以我们不演示了。),只需要把/etc/sysconfig/httpd中关于HTTPD的注释启用即可,因为服务器脚本/etc/init.d/httpd默认的httpd变量如果HTTPD不为空,就设置为HTTPD的值,如果HTTPD为空,就设置为HTTPD的值。
[root@yanhui_httpd ~]# grep '^#.*httpd.worker' /etc/sysconfig/httpd
#HTTPD=/usr/sbin/httpd.worker
[root@yanhui_httpd ~]# grep -E '^httpd|\. /etc/sysconfig/httpd' /etc/init.d/httpd
. /etc/sysconfig/httpd
httpd=${HTTPD-/usr/sbin/httpd}
示例演示切换为worker:
[root@yanhui_httpd ~]# sed -i '/^#HTTPD=\/usr\/sbin\/httpd.worker/s/^#//' /etc/sysconfig/httpd
[root@yanhui_httpd ~]# grep '^.*httpd.worker' /etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.worker
[root@yanhui_httpd ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.worker: apr_sockaddr_info_get() failed for yanhui_httpd
httpd.worker: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
[ OK ]
[root@yanhui_httpd ~]#
[root@yanhui_httpd ~]# ps aux|grep httpd
root 17726 0.0 0.8 177732 4028 ? Ss 21:32 0:00 /usr/sbin/httpd.worker
apache 17728 0.0 0.6 521992 3312 ? Sl 21:32 0:00 /usr/sbin/httpd.worker
apache 17729 0.0 0.6 521992 3304 ? Sl 21:32 0:00 /usr/sbin/httpd.worker
apache 17731 0.0 0.6 521992 3312 ? Sl 21:32 0:00 /usr/sbin/httpd.worker
root 17841 0.0 0.1 103320 884 pts/1 S+ 21:32 0:00 grep httpd
PS:上面有个小问题,就是提示,无法检测可信赖的FQDN,使用127.0.0.1作为ServerName的值。
只要加一条主机名和ip地址的映射关系到/etc/hosts文件,然后把ServerName后边的值设置为主机名即可。
[root@yanhui_httpd ~]# hostname
yanhui_httpd
[root@yanhui_httpd ~]# grep 'yanhui_httpd' /etc/hosts
192.168.56.90 yanhui_httpd
[root@yanhui_httpd ~]# grep '^ServerName' /etc/httpd/conf/httpd.conf
ServerName yanhui_httpd
[root@yanhui_httpd ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
这里关于MPM的默认配置如下:
# prefork MPM
# StartServers: number of server processes to start(初始启动时管理进程产生的工作进程的数量,默认8个)
# MinSpareServers: minimum number of server processes which are kept spare
空闲时,最少存在的工作进程的数量。默认值5个。
# MaxSpareServers: maximum number of server processes which are kept spare
空闲时,最大存在的工作进程的数量,默认值为20个。
# ServerLimit: maximum value for MaxClients for the lifetime of the server
最大活动进程数。默认值为256。其值一般要大于等于MaxClients的值,如果比MaxClients的值小,那么MaxClients大于ServerLimit部分的数值无效。以ServerLimit为准。
# MaxClients: maximum number of server processes allowed to start
最大并发连接数,最多允许发起的连接请求的个数。默认值为256。
# MaxRequestsPerChild: maximum number of requests a server process serves
一个工作进程服务最多的请求数量(默认是4000个,超过这个值会工作进程会被销毁掉)
说明:prefork模式下,默认的最大并发为256。
#如果prefork.c存在(可以使用httpd -l查看),则这个容器内的参数设置有效。
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
# worker MPM
# StartServers: initial number of server processes to start
初始启动的工作进程数量。默认值为4
# MaxClients: maximum number of simultaneous client connections
最大并发连接数,最多允许发起的连接请求的个数。默认值为300
# MinSpareThreads: minimum number of worker threads which are kept spare
最少空闲线程数。默认值为25
# MaxSpareThreads: maximum number of worker threads which are kept spare
最大空闲线程数。默认值为75
# ThreadsPerChild: constant number of worker threads in each server process
每个子进程生成的线程数量。默认是25,默认启动进程数量为4,那么一共有4*25=100个线程。
# MaxRequestsPerChild: maximum number of requests a server process serves
每个子进程在声明周期内最大允许服务的最多请求个数。默认值为0表示不限定。
ps:这里默认是启动4个工作进程,然后每个工作进程会启动25个线程。所以默认情况,启动线程池有100个线程,而设置的最大空闲线程数位75,所以默认启动会处理掉25个线程,即设置运营于worker模式。则只会看到3个工作进程,有一个工作进程被杀掉了。这个默认配置很奇葩。
#如果worker.c存在,则这个容器内的参数设置有效。
StartServers 4
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
在worker模式下,也支持使用ServerLimit 指令,其值要大于等于:
ServerLimit >= (MaxClients)/(ThreadsPerChild )=12。表示在worker模式下,最大活动进程数要大于等于12。如果设置为12,表示最大活动线程数量为12*25=300,刚好处理最大的并发连接数300.
修改ServerLimi和ThreadLimit的值,要先stop掉所有的工作进程,然后再次启动。
[root@yanhui_httpd ~]# grep -A14 '^#.*(DSO.*' /etc/httpd/conf/httpd.conf
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# 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
LoadModule authn_alias_module modules/mod_authn_alias.so
#加载指定的模块语法为:
LoadModule
mod_name表示要加载的模块名称。mod_path表示要加载的模块路径,如果mod_path的路径是一个相对路径,
它表示相对于ServerRoot的路径,而ServerRoot默认的路径为/etc/httpd
root@yanhui_httpd ~]# grep '^ServerRoot' /etc/httpd/conf/httpd.conf
ServerRoot "/etc/httpd"
[root@yanhui_httpd ~]# ls -l /etc/httpd/modules
lrwxrwxrwx 1 root root 29 Dec 9 18:46 /etc/httpd/modules -> ../../usr/lib64/httpd/modules
[root@yanhui_httpd ~]# ls -l /etc/httpd/modules/|head -4
total 1524
-rwxr-xr-x 1 root root 10416 Jun 19 23:45 mod_actions.so
-rwxr-xr-x 1 root root 14608 Jun 19 23:45 mod_alias.so
-rwxr-xr-x 1 root root 10416 Jun 19 23:45 mod_asis.so
ServerName
语法格式: ServerName [scheme://]fully-qualified-domain-name[:port]
DocumentRoot ""
文档路径映射:
DoucmentRoot指向的路径为URL路径的起始位置
其相当于站点URL的根路径;
URL PATH与FileSystem PATH不是等同的,而是存在一种映射关系;
URL / --> FileSystem /var/www/html/
/images/logo.jpg --> /var/www/html/images/logo.jpg
[root@yanhui_httpd ~]# grep '^ServerName' /etc/httpd/conf/httpd.conf
ServerName yanhui_httpd
[root@yanhui_httpd ~]# grep '^DocumentRoot' /etc/httpd/conf/httpd.conf
DocumentRoot "/var/www/html"
可基于两种机制指明对哪些资源进行何种访问控制:
1、基于文件系统路径
...
...
...
2、基于URL路径
...
...
关于中“基于源地址”实现访问控制:
Options
AllowOverride
AllowOverride None 不禁用下面(Order,Allow,Deny等指令的设置)
AllowOverride AuthConfig 使用用户的认证,而不再完全基于IP做认证
order 次序,写在后面的为默认
allow,deny: 没有允许的都拒绝
deny,allow:没有拒绝的都允许
Allow from
Deny from
如果都匹配或都不匹配时以默认为准
否则则以匹配到的为准
order和allow、deny
order:定义生效次序;写在后面的表示默认法则;
Allow from, Deny from
来源地址:
IP
NetAddr:
172.16
172.16.0.0
172.16.0.0/16
172.16.0.0/255.255.0.0
控制页面资源允许所有来源的主机可访问:
httpd-2.2
...
Order allow,deny
Allow from all
控制页面资源拒绝所有来源的主机可访问:
...
Order allow,deny
Deny from all
Options:Configures what features are available in a particular directory
后跟1个或多个以空白字符分隔的“选项”列表;
Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户;
非下载站点,不建议使用这个选项,因为文件系统资源列表列出是比较危险的。
FollowSymLinks:允许跟踪符号链接文件所指向的源文件;
None:所有都不启用;
All:所有的都启用;
ExecCGI:允许使用mod_cgi模块执行CGI脚本;
Includes:允许使用mod_include模块实现服务器端包含(SSI);
IncludesNOEXEC:允许包含但不允许执行脚本;
MultiViews:允许使用mod_negotiation实现内容协商;
SymLinksIfOwnerMatch:在链接文件属主属组与原始文件的属主属组相同时,允许跟随符号连接所指向的原始文件;
[root@yanhui_httpd ~]# grep '^DirectoryIndex' /etc/httpd/conf/httpd.conf
DirectoryIndex index.html index.html.var
4.8和4.9的示例:
(1) 定义一个静态文件,访问测试
[root@yanhui_httpd html]# ls -l /var/www/html/yanhui_test.html
-rw-r--r-- 1 root root 31 Dec 9 22:28 /var/www/html/yanhui_test.html
[root@yanhui_httpd html]# cat /var/www/html/yanhui_test.html
This is a test pages.
(2) 自己配置一个目录,然后控制上述常用属性
[root@yanhui_httpd ~]# grep -A5 '/var/www/yanhui' /etc/httpd/conf/httpd.conf
Options Indexes FollowSymLinks
Order allow,deny
Allow from all
[root@yanhui_httpd ~]# grep '^DocumentRoot' /etc/httpd/conf/httpd.conf
DocumentRoot "/var/www" #修改来默认文档路径为/var/www,原先为/var/www/html
[root@yanhui_httpd ~]# service httpd configtest
Syntax OK
[root@yanhui_httpd ~]# service httpd reload
Reloading httpd:
[root@yanhui_httpd ~]# mkdir -p /var/www/yanhui
[root@yanhui_httpd ~]# cp /etc/fstab /etc/inittab /var/www/yanhui/
[root@yanhui_httpd ~]# cp /var/www/icons/patch.png /var/www/yanhui/
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/
total 12
-rw-r--r-- 1 root root 805 Dec 9 22:34 fstab
-rw-r--r-- 1 root root 884 Dec 9 22:34 inittab
-rw-r--r-- 1 root root 310 Dec 9 22:35 patch.png
[root@yanhui_httpd ~]# ln -sf /var/www/yanhui/fstab /var/www/yanhui/fstab.html
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/
total 12
-rw-r--r-- 1 root root 805 Dec 9 22:34 fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 fstab.html -> /var/www/yanhui/fstab
-rw-r--r-- 1 root root 884 Dec 9 22:34 inittab
-rw-r--r-- 1 root root 310 Dec 9 22:35 patch.png
去掉Options中的FollowsymLinks后的效果:
实际效果为,所有的特性不启动,不过对应访问已经存在的资源(不是符号链接),还是会响应的。
演示Options选项的SymLinksIfOwnerMatch:
a> 符号链接文件和原始文件属主和属组一样
[root@yanhui_httpd ~]# vim /etc/httpd/conf/httpd.conf
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/fstab*
-rw-r--r-- 1 root root 805 Dec 9 22:34 /var/www/yanhui/fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 /var/www/yanhui/fstab.html -> /var/www/yanhui/fstab
b> 符号链接文件和原始文件属主和属组不一样
[root@yanhui_httpd ~]# useradd centos
[root@yanhui_httpd ~]# chown centos:centos /var/www/yanhui/fstab
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/fstab*
-rw-r--r-- 1 centos centos 805 Dec 9 22:34 /var/www/yanhui/fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 /var/www/yanhui/fstab.html -> /var/www/yanhui/fstab
[root@yanhui_httpd ~]# chown root /var/www/yanhui/fstab
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/
total 12
-rw-r--r-- 1 root centos 805 Dec 9 22:34 fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 fstab.html -> /var/www/yanhui/fstab
-rw-r--r-- 1 root root 884 Dec 9 22:34 inittab
-rw-r--r-- 1 root root 310 Dec 9 22:35 patch.png
ps:要属主和属组都不相同,才禁止访问。否则,都可以访问。建议生产配置Options,非特殊业务,配置成None即可。
Alias /alias/ "/path/to/somewhere"
意味着访问http://Server_IP/alias时,其页面文件来自于/path/to/somewhere中
[root@yanhui_httpd ~]# grep '^Alias' /etc/httpd/conf/httpd.conf
Alias /icons/ "/var/www/icons/"
Alias /error/ "/var/www/error/"
示例:
(1) 简单查看
[root@yanhui_httpd imgs]# grep -A5 '/var/www/yanhui' /etc/httpd/conf/httpd.conf
Options SymLinksIfOwnerMatch
Order allow,deny
Allow from all
[root@yanhui_httpd imgs]# ls -l /var/www/yanhui/
total 16
-rw-r--r-- 1 root centos 805 Dec 9 22:34 fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 fstab.html -> /var/www/yanhui/fstab
drwxr-xr-x 2 root root 4096 Dec 9 22:55 images
-rw-r--r-- 1 root root 884 Dec 9 22:34 inittab
-rw-r--r-- 1 root root 310 Dec 9 22:35 patch.png
[root@yanhui_httpd imgs]# ls -l /var/www/yanhui/images/
total 172
-rw-r--r-- 1 root root 175056 Sep 19 22:58 linux2.png
(2) 配置别名后演示
[root@yanhui_httpd imgs]# grep -A4 -B1 '/var/www/yanhui' /etc/httpd/conf/httpd.conf
Alias /yanhui/images/ "/data/imgs/"
Options SymLinksIfOwnerMatch
Order allow,deny
Allow from all
[root@yanhui_httpd imgs]# ls -l /data/imgs/
total 332
-rw-r--r-- 1 root root 339657 Sep 19 22:58 linux1.png
[root@yanhui_httpd imgs]# grep '^AddDefaultCharset' /etc/httpd/conf/httpd.conf
AddDefaultCharset UTF-8
中文字符集:GBK, GB2312, GB18030
日志类型:访问日志 和 错误日志
错误日志:
ErrorLog logs/error_log
LogLevel warn
Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
访问日志:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog logs/access_log combined
LogFormat format strings:
http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats
%h:客户端IP地址;
%l:Remote User, 通常为一个减号(“-”);
%u:Remote user (from auth; may be bogus if return status (%s) is 401);非为登录访问时,其为一个减号;
%t:服务器收到请求时的时间;
%r:First line of request,即表示请求报文的首行;记录了此次请求的“方法”,“URL”以及协议版本;
%>s:响应状态码;
%b:响应报文的大小,单位是字节;不包括响应报文的http首部;
%{Referer}i:请求报文中首部“referer”的值;即从哪个页面中的超链接跳转至当前页面的;
%{User-Agent}i:请求报文中首部“User-Agent”的值;即发出请求的应用程序;
PS:具体日志应用到时候会写一个关于生产实现apache日志切割的时候举例。用到的时候速查上面的常用
选项即可,或者去官网通读日志设置文档。
认证质询:
WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码;
认证:
Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源;
认证方式有两种:
basic:明文
digest:消息摘要认证
安全域:需要用户认证后方能访问的路径;应该通过名称对其进行标识,以便于告知用户认证的原因;
用户的账号和密码存放于何处?
虚拟账号:仅用于访问某服务时用到的认证标识
存储:
文本文件;
SQL数据库;
ldap目录存储;
定义模板和用户设置:
basic认证配置示例:
(1) 定义安全域
Options None
AllowOverride None
AuthType Basic
AuthName "String“
AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE"
Require user username1 username2 ...
允许账号文件中的所有用户登录访问:
Require valid-user
(2) 提供账号和密码存储(文本文件)
使用专用命令完成此类文件的创建及用户管理
htpasswd [options] /PATH/TO/HTTPD_PASSWD_FILE username
-c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用;
-m:md5格式加密
-s: sha格式加密
-D:删除指定用户
-b:批模式添加用户
htpasswd -b [options] /PATH/TO/HTTPD_PASSWD_FILE username password
另外:基于组账号进行认证;
(1) 定义安全域
Options None
AllowOverride None
AuthType Basic
AuthName "String“
AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE"
AuthGroupFile "/PATH/TO/HTTPD_GROUP_FILE"
Require group grpname1 grpname2 ...
(2) 创建用户账号和组账号文件;
组文件:每一行定义一个组
GRP_NAME: username1 username2 ...
示例:
(1) 添加用户tom和jerry
[root@yanhui_httpd ~]# htpasswd -c /var/www/.yanhui_user tom
New password:
Re-type new password:
Adding password for user tom
上面是交互式模式输入用户密码。第一次创建可以是交互式或非交互式。如果要新增用户,只能使用-b非交互式
批处理创建用户,用户名和密码都显示在命令行了。在添加一个用户jerry:
[root@yanhui_httpd ~]# htpasswd -b /var/www/.yanhui_user jerry jerry123
Adding password for user jerry
我的站点配置信息:
[root@yanhui_httpd ~]# grep -A9 '/var/www/yanhui' /etc/httpd/conf/httpd.conf
Options None #表示没有特殊选项,不支持索引目录展开,不支持符号链接文件访问
AllowOverride None #表示下面的Order,Allow等基于IP的访问控制指令无效的。
Order allow,deny
Allow from all
AuthType Basic #认证类型,基本认证
AuthName "Pleas input Username And Passwd" #提示字符串
AuthUserFile "/var/www/.yanhui_user" #用户名和密码验证的存储文件
Require valid-user #表示允许所有上面用户和密码文件中的用户登录。
站点目录资源:
[root@yanhui_httpd ~]# ls -l /var/www/yanhui/
total 16
-rw-r--r-- 1 root centos 805 Dec 9 22:34 fstab
lrwxrwxrwx 1 root root 21 Dec 9 22:40 fstab.html -> /var/www/yanhui/fstab
drwxr-xr-x 2 root root 4096 Dec 9 22:55 images
-rw-r--r-- 1 root root 884 Dec 9 22:34 inittab
-rw-r--r-- 1 root root 310 Dec 9 22:35 patch.png
直接在URL中键入用户名和密码:
格式(schema://username:password@URL)
确认后结果:
PS:基于组的用户认证,我这里就不演示了,上面有介绍配置语法模板。
站点标识: socket
IP相同,但端口不同;
IP不同,但端口均为默认端口;
FQDN不同;
请求报文中首部
Host: www.yanhui.com
有三种实现方案:
基于ip:
为每个虚拟主机准备至少一个ip地址;
基于port:
为每个虚拟主机使用至少一个独立的port;
基于FQDN:
为每个虚拟主机使用至少一个FQDN;
注意(专用于httpd-2.2):一般虚拟机不要与中心主机混用;因此,要使用虚拟主机,得先禁用'main'主机;
禁用方法:注释中心主机的DocumentRoot指令即可;
虚拟主机的配置方法:
ServerName FQDN
DocumentRoot ""
其它可用指令:
ServerAlias:虚拟主机的别名;可多次使用;
ErrorLog:
CustomLog:
...
Alias
...
示例:
(1) 基于多个IP的,相同端口的虚拟记住
先配置多个ip地址,这里我的两个ip地址为192.168.56.90和192.168.56.98
[root@yanhui_httpd ~]# ifconfig eth0:0 192.168.56.98/24
[root@yanhui_httpd ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:5A:90:10
inet addr:192.168.56.90 Bcast:192.168.56.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe5a:9010/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:16902 errors:0 dropped:0 overruns:0 frame:0
TX packets:14177 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3264323 (3.1 MiB) TX bytes:2406634 (2.2 MiB)
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:5A:90:10
inet addr:192.168.56.98 Bcast:192.168.56.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:150 errors:0 dropped:0 overruns:0 frame:0
TX packets:150 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:14380 (14.0 KiB) TX bytes:14380 (14.0 KiB)
我配置的虚拟主机为:
ServerName www.a.com
DocumentRoot "/data/web/a.com/htdocs"
ServerName www.b.com
DocumentRoot "/data/web/b.com/htdocs"
创建目录和主页文件:
[root@yanhui_httpd ~]# httpd -t
Warning: DocumentRoot [/data/web/a.com/htdocs] does not exist
Warning: DocumentRoot [/data/web/b.com/htdocs] does not exist
Syntax OK
[root@yanhui_httpd ~]# mkdir -pv /data/web/{a,b}.com/htdocs
mkdir: created directory `/data/web'
mkdir: created directory `/data/web/a.com'
mkdir: created directory `/data/web/a.com/htdocs'
mkdir: created directory `/data/web/b.com'
mkdir: created directory `/data/web/b.com/htdocs'
[root@yanhui_httpd ~]# echo 'www.a.org
' >/data/web/a.com/htdocs/index.html
[root@yanhui_httpd ~]# echo 'www.b.org
' >/data/web/b.com/htdocs/index.html
[root@yanhui_httpd ~]# cat /data/web/a.com/htdocs/index.html
www.a.org
[root@yanhui_httpd ~]# cat /data/web/b.com/htdocs/index.html
www.b.org
[root@yanhui_httpd ~]# httpd -t
Syntax OK
[root@yanhui_httpd ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
(2) 基于相同IP,不同端口的虚拟主机
ServerName www.a.com
DocumentRoot "/data/web/a.com/htdocs"
ServerName www.b.com
DocumentRoot "/data/web/b.com/htdocs"
[root@yanhui_httpd ~]# httpd -t
Syntax OK
[root@yanhui_httpd ~]# service httpd reload
Reloading httpd:
(3) 基于不同的FQDN的虚拟主机
为了演示,我这里采用hosts文件映射的方式。
特殊说明:基于FQDN的虚拟主机,在httpd2.2中要启用以下选项:
启用前:
[root@yanhui_httpd ~]# grep '^#NameVirtualHost' /etc/httpd/conf/httpd.conf
#NameVirtualHost *:80
[root@yanhui_httpd ~]# vim /etc/httpd/conf/httpd.conf
[root@yanhui_httpd ~]# grep '^#NameVirtualHost' /etc/httpd/conf/httpd.conf
启用后:
[root@yanhui_httpd ~]# grep '^NameVirtualHost' /etc/httpd/conf/httpd.conf
NameVirtualHost *:80
而且要求,后边定义的虚拟主机,监听访问要与这个配置指令一样,这里配置的是*:80,那么虚拟主机那边
也要这样配置。我配置后的虚拟主机如下:
ServerName www.a.com
DocumentRoot "/data/web/a.com/htdocs"
ServerName www.b.com
DocumentRoot "/data/web/b.com/htdocs"
如果把linux作为客户端,可以去配置客户端的hosts文件,如果是windows浏览器,可以配置windows的hosts文件。
linux访问测试:
[root@yanhui_httpd ~]# tail -n2 /etc/hosts
192.168.56.90 www.a.com
192.168.56.90 www.b.com
[root@yanhui_httpd ~]# elinks -dump www.b.com
www.b.org
[root@yanhui_httpd ~]# elinks -dump www.a.com
www.a.org
elinks可能需要yum安装一下。
先要保证模块有载入。
LoadModule status_module modules/mod_status.so
然后按照下面的配置模板配置:
SetHandler server-status
Order allow,deny
Allow from 192.168
因为状态页面比较重要,建议配合IP的访问认证或者用户的访问认证。只能特殊网段或者特殊的用户验证后
才能访问,这样做比较安全。我们这里测试,所以我是基于IP,最终的配置为:
SetHandler server-status
Order allow,deny
Allow from 192.168
加入以下两行配置:
ServerTokens Prod
ServerSignature Off
默认值:
[root@yanhui_httpd ~]# grep -E '^ServerTokens|^ServerSignature' /etc/httpd/conf/httpd.conf
ServerTokens OS
ServerSignature On
修改后:
[root@yanhui_httpd ~]# grep -E '^ServerTokens|^ServerSignature' /etc/httpd/conf/httpd.conf
ServerTokens Prod
ServerSignature Off
[root@yanhui_httpd ~]# httpd -t
Syntax OK
[root@yanhui_httpd ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]