http协议及httpd-2.2基本功能实现

时间:2021-09-28 01:50:52

       超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1。(摘自百度http)
HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。
通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。


HTTP协议版本:
   HTTP/0.9 已过时。只接受 GET 一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持 POST 方法,所以客户端无法向服务器传递太多信息。
HTTP/1.0 这是第一个在通讯中指定版本号的HTTP 协议版本,至今仍被广泛采用,特别是在代理服务器中。
   HTTP/1.1 当前版本。持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
   HTTP/1.1相较于 HTTP/1.0 协议的区别主要体现在:
     1 缓存处理
     2 带宽优化及网络连接的使用
     3 错误通知的管理
     4 消息在网络中的发送
     5 互联网地址的维护
     6 安全性及完整性
  HTTP/2.0:采用二进制格式传输数据,非1.1的文本格式;多路复用,多个请求都是通过一个TCP连接并完成;服务端能够更快把资源推送给客户端
     rfc:是一系列以编号排定的文件。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件


HTTP:应用层协议, 80/tcp,  文本协议

HTML:hyper text mark language, 编程语言,超文本标记语言;

HTML的标签:    
  标签是由尖括号包围的关键词,比如:
 <html>
   <head>
   <title>TITLE</title>
   </head>
HTML 标签通常是成对出现的,比如:
   <body>
   <h1></h1>
   <p> blabla... <a href="http://www.123.com/download.html">           bla...</a> </p>
   <h2> </h2>
   </body>

标签对中的第一个标签是开始标签,第二个标签是结束标签:
 </html>
开始和结束标签也被称为开放标签和闭合标签
 

工作模式:
    http请求报文:http request
    http响应报文: http response
    一次http事务:请求<-->响应       

一次完整的http请求处理过程:

1:建立或处理连接:接收请求或拒绝请求;

2:接收请求:接收来自于网络上的主机请求报文中对某特定资源的一次请求的过程
3:处理请求:对请求报文进行解析,获取客户端请求的资源及请求方法等相关信息;

4:访问资源:获取请求报文中请求的资源;
5:构建响应报文:
6:发送响应报文:
7:记录日志:


TCP协议的特性:
 建立连接:三次握手;
 将数据打包成段:校验和(CRC32)
 确认、重传及超时;
 排序:逻辑序号;
 流量控制:滑动窗口算法;
 拥塞控制:慢启动和拥塞避免算法;


接收请求的模型:
并发访问响应模型:

单进程I/O模型:启动一个进程处理用户请求;这意味着,一次只能处理一个请求,多个请求 被串行响应;

多进程I/O结构:并行启动多个进程,每个进程响应一个请求;

复用的I/O结构:一个进程响应n个请求;
多线程模式:一个进程生成n个线程,一个线程处理一个请求;

事件驱动(event-driven):一个进程直接n个请求;
复用的多进程I/O结构:启动多个(m)个进程,每个进程生成(n)个线程;
   响应的请求的数量:m*n
                    

httpd2.2的特性:
  高度模块化: core + modules
  DSO:dynamic shared object支持动态装载和卸载
  MPM:Multipath processing Modules (多路处理模块)
  prefork:多进程模型,每个进程响应一个请求;
    一个主进程:负责生成子进程及回收子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
    n个子进程:每个子进程处理一个请求;
   工作模型:会预先生成几个空闲进程,随时等待用于响应用户请求;最大空闲和最小空闲;
    worker:多进程多线程模型,每线程处理一个用户请求;
    一个主进程:负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
   多个子进程:每个子进程负责生成多个线程;
   每个线程:负责响应用户请求;
   并发响应数量:m*n
       m:子进程数量
        n:每个子进程所能创建的最大线程数量;
    event:事件驱动模型,多进程模型,每个进程响应多个请求;
    一个主进程 :负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
    子进程:基于事件驱动机制直接响应多个请求;
         httpd-2.2: 仍为测试使用模型;
         httpd-2.4:event可生产环境中使用;
                             

httpd的功能特性:
    CGI:Common Gateway Interface
    虚拟主机:IP,PORT, FQDN
    反向代理
    负载均衡
    路径别名
    丰富的用户认证机制
    basic
    digest
    支持第三方模块
     ......
            

# yum -y install httpd

注意:在安装httpd之前,需要先安装apr以及apr-util,这两个包是httpd运行时环境。
接下来我们看一看安装了哪些httpd的相关软件包,以及这些软件包在我们的Linux中安装了哪些文件?    
# rpm -qa httpd*
# rpm -ql httpd


CentOS 6:httpd-2.2(MPM不支持DSO机制)

配置文件:
  /etc/httpd/conf/httpd.conf
  /etc/httpd/conf.d/*.conf

sysinit服务脚本:
  /etc/rc.d/init.d/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


常用的配置指令:

httpd-2.2的常用配置
主配置文件:/etc/httpd/conf/httpd.conf
  rep -i "#\{2,\} Section" httpd.conf
  ### Section 1: Global Environment  (httpd进程。全局配置)
  ### Section 2: 'Main' server configuration(中心服务配置)
  ### Section 3: Virtual Hosts(虚拟配置)
配置格式:
   directive  value
   directive:不区分字符大小写;
   value:为路径时,是否区分字符大小写,取决于文件系统;

1、修改监听的IP和PORT
  # ss -tnl
     vim /etc/httpd/conf/httpd.conf
     Listen  [IP:]PORT: 该指令可以在配置文件中多次定义,注意,如果省略IP,表示0.0.0.0/0;
      Listen  80
      Listen  8080
    修改监听socket,重启服务进程方可生效;
      httpd -t 检测         
    重启配置,修改后生效:reload
      restart:通常仅修改了监听的地址和端口    
      service httpd reload    

2、持久连续:
   Persistent Connection:tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行;
   如何断开?
      数量限制
      时间限制
      副作用:对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常 响应;
      折衷:使用较短的持久连接时长,以及较少的请求数量;
                        
   KeepAlive  On|Off  (通常为off)
   MaxKeepAliveRequests  100(数量限制)
   KeepAliveTimeout  15 (时间限制)
   

测试:
    yum install telnet -y
    telnet  WEB_SERVER_IP  PORT
    GET  /URL(/test1.html)  HTTP/1.1
    Host: WEB_SERVER_IP 连续回车两次 (各种守护,响应报文)    
        
      HTTP/1.1 200 OK
 Date: Thu, 14 Jul 2016 04:40:29 GMT
      Server: Apache/2.2.15 (CentOS)
 Last-Modified: Thu, 14 Jul 2016 04:34:17 GMT
      ETag: "20104-b-5379103cb9aec"
      Accept-Ranges: bytes
 Content-Length: 11
 Connection: close
 Content-Type: text/html; charset=UTF-8

 test1.html
 Connection closed by foreign host.
如果KeepAlive  On|Off 为On,则下两行不会出现;

3、MPM :
  httpd-2.2不支持同时编译多个MPM模块,所以只能编译选定要使用的那个;CentOS 6的rpm   包为此专门提供了三个应用程序文件,httpd(prefork), httpd.worker, httpd.event,分别用于实现对不同的MPM机制的支持;确认现在使用的是哪下程序文件的方法:
     ps  aux  | grep httpd
默认使用的为/usr/sbin/httpd,其为prefork的MPM模块 ;
    查看httpd程序的模块列表:
     查看静态编译的模块:
         # httpd  -l
     查看静态编译及动态编译的模块:
         # httpd  -M

更换使用httpd程序,以支持其它MPM机制;
    /etc/sysconfig/httpd
   HTTPD=/usr/sbin/httpd|httpd.worker|httpd.event
   注意:重启服务进程方可生效 service httpd start
               

MPM配置:
 prefork的配置        
  <IfModule prefork.c>
  StartServers       8 (预先创建多少个子进程)
  MinSpareServers    5 (最小控制进程数)
  MaxSpareServers   20 (最大控制进程数)
  ServerLimit      256 (在同一时间存在的最多服务器进程数)
  MaxClients       256
  MaxRequestsPerChild  4000 (每一个子进程能响应最大请求)
  </IfModule>        
               

worker的配置:
  <IfModule worker.c>
  StartServers         4
  MaxClients         300
  MinSpareThreads     25
  MaxSpareThreads     75
  ThreadsPerChild     25
  MaxRequestsPerChild  0
  </IfModule>                       

#loadModule env_module modules/mod_env.so (注释模块进程,禁用 前加#)    


4、DSO
配置指定实现模块加载
   LoadModule  <mod_name>  <mod_path>
   loadModule Mod_Name modules/module_File.s

模块文件路径可使用相对路径:
  相对于ServerRoot(默认/etc/httpd)


5、定义'Main' server的文档页面路径
  DocumentRoot  ""
    文档路径映射:
  DoucmentRoot指向的路径为URL路径的起始位置
    其相当于站点URL的根路径;
  (FileSystem) /web/host1/index.html  -->  (URL)  /index.html

    定义一个主机的基本指令:ServerName FQDN
   DocumentRoot /var/www/html


6、站点访问控制常见机制
  可基于两种机制指明对哪些资源进行何种访问控制
  文件系统路径:
  <Directory  "/PATN/TO/SOME_DIR">
   ...
  </Directory>
                
  <File  "">
   ...
  </File>
                        
  <FileMatch  "PATTERN">
   ...
  </FileMatch>


 例: mkdir -pv /data/web
   vim /data/web/index.html
   <h1>New DocRoot</h1>
    wq
    vim /etc/httpd/conf/httpd.conf
    DocumentRoot "/data/web"
    重启
    浏览器刷新 IP.index.html,显示:New DocRoot
                  

URL路径:
   <Location  "">
   ...
   </Location>
                        
   <LocationMatch "">
    ...
   </LocationMatch>
                        
   <Directory>中“基于源地址”实现访问控制:
       

(1) Options
     后跟1个或多个以空白字符分隔的“选项”列表;
     Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户;
     FollowSymLinks:允许跟踪符号链接文件所指向的源文件;
     ExecCGI:允许执行CGI脚本
     None:
     All:
  

(2) AllowOverride
     与访问控制相关的哪些指令可以放在.htaccess文件(每个目录下都可以有一个)中;
     All:
     None:
                           

(3) order和allow、deny
     order:定义生效次序;写在后面的表示默认法则;
     Allow from IP/NETWORK/FQDN

     deny from  IP/NETWORK/FQDN
  来源请求遵循最佳匹配法则机制
                            


7、定义站点主页面:
     DirectoryIndex  index.html  index.html.var                


8、定义路径别名
     Alias  /URL/  "/PATH/TO/SOMEDIR/                                                    


9、日志设定
  日志类型:访问日志 和 错误日志
                
  错误日志:
    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:
  %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”的值;即发出请求的应用程序;
                                            

10:http-manual
   #yum install httpd-manual
   配置文件:/etc/httpd/conf.d/manual.conf
   #service httpd reload

   访问路径:http://SERVER_IP/manual/                                


11、基于用户的访问控制        
   认证质询:
   WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码;
   认证:
   Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源;
   认证方式有两种:
      basic:明文
      digest:消息摘要认证
            
安全域:需要用户认证后方能访问的路径;应该通过名称对其进行标识,以便于告知用户认证的原因;
  用户的账号和密码存放于何处?
  虚拟账号:仅用于访问某服务时用到的认证标识
                   

存储:
   文本文件;
   SQL数据库;
   ldap目录存储;
                
basic认证配置示例:
  (1) 定义安全域
      <Directory "">
       Options None
       AllowOverride None
       AuthType Basic
       AuthName "String“
       AuthUserFile  "/PATH/TO/HTTPD_USER_PASSWD_FILE"
       Require  user  username1  username2 ...
      </Directory>
                        
允许账号文件中的所有用户登录访问:
       Require  valid-user
                        
 (2) 提供账号和密码存储(文本文件)
      使用专用命令完成此类文件的创建及用户管理
      htpasswd  [options]   /PATH/TO/HTTPD_PASSWD_FILE  username
       -c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用;
       -m:md5格式加密
       -s: sha格式加密
       -D:删除指定用户
                                
另外:基于组账号进行认证;
  定义安全域
      <Directory "">
      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 ...
      </Directory>
                           
                                            
12:虚拟主机
   有三种实现方案:
      基于ip:为每个虚拟主机准备至少一个ip地址;
      基于port:为每个虚拟主机使用至少一个独立的port;
      基于FQDN:为每个虚拟主机使用至少一个FQDN;
  注意:一般虚拟机不要与中心主机混用;因此,要使用虚拟主机,得先禁用'main'主机;
      禁用方法:注释中心主机的DocumentRoot指令即可;
                    
虚拟主机的配置方法:
   <VirtualHost  IP:PORT>
      ServerName FQDN
      DocumentRoot  ""
   </VirtualHost>
                    
其它可用指令:
   ServerAlias:虚拟主机的别名;可多次使用;
      ErrorLog:
      CustomLog:
      <Directory "">
       ...
      </Directory>
       Alias
       ...
                        
基于IP的虚拟主机示例:
    <VirtualHost 172.16.253.3:80>
       ServerName www.a.com
       DocumentRoot "/www/a.com/htdocs"
    </VirtualHost>

    <VirtualHost 172.16.253.4:80>
       ServerName www.b.net
       DocumentRoot "/www/b.net/htdocs"
    </VirtualHost>

基于端口的虚拟主机:
    <VirtualHost 172.16.253.3:80>
       ServerName www.a.com
       DocumentRoot "/www/a.com/htdocs"
    </VirtualHost>

    <VirtualHost 172.16.253.3:808>
       ServerName www.b.net
       DocumentRoot "/www/b.net/htdocs"
    </VirtualHost>
                   
基于FQDN的虚拟主机:
    NameVirtualHost 172.16.253.3:80

    <VirtualHost 172.16.253.3:80>
        ServerName www.a.com
        DocumentRoot "/www/a.com/htdocs"
    </VirtualHost>

    <VirtualHost 172.16.253.3:80>
       ServerName www.b.net
       DocumentRoot "/www/b.net/htdocs"
    </VirtualHost>

CA服务器上操作:

生成密钥对密钥对
[root@lilei CA]# (umak 077; openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048)

1:生成自签证书:    
[root@lilei CA]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3655
 
 Country Name (2 letter code) [XX]:CN 国家
 State or Province Name (full name) []:beijing 省
 Locality Name (eg, city) [Default City]:beijin  市
 Organization Name (eg, company) [Default Company Ltd]:magedu.com 公司名称
 Organizational Unit Name (eg, section) []:yunwei  部门
 Common Name (eg, your name or your server's hostname) []:lilei 域名
 Email Address []:admin@qq.com 邮箱

2:为CA提供所需目录及文件:   
[root@lilei CA]# touch {serial,index.txt}
[root@lilei CA]# echo 01 > serial


httpd服务器上操作:

1)生成密钥:   
[root@lilei ~]# mkdir /etc/httpd/ssl
[root@lilei ~]# cd /etc/httpd/ssl/
[root@lilei ssl]# (umask 077;openssl genrsa -out /etc/httpd/)
conf/    conf.d/  logs/    modules/ run/     ssl/     
[root@lilei ssl]# (umask 077;openssl genrsa -out /etc/httpd/ssl/httpd.key 2048)

2)生成证书签署请求:  
[root@lilei ssl]# openssl req -new -key /etc/httpd/ssl/httpd.key -out /etc/httpd/ssl/httpd.csr -days 365
 
 Country Name (2 letter code) [XX]:CN
 State or Province Name (full name) []:beijing
 Locality Name (eg, city) [Default City]:beijin
 Organization Name (eg, company) [Default Company Ltd]:magedu.com
 Organizational Unit Name (eg, section) []:yunwei
 Common Name (eg, your name or your server's hostname) []:lilei
 Email Address []:admin@qq.com


3)在CA上签署证书,并将证书方式给请求:    
[root@lilei tmp]# openssl ca -in /tmp/httpd.csr -out /etc/pki/CA/certs/httpd.crt -days 365
[root@lilei certs]# scp httpd.crt root@172.16.12.100:/etc/httpd/ssl


4)httpd要支持SSL需要安装mod_ssl模块    
[root@lilei ~]# yum -y install mod_ssl

   

5)配置/etc/httpd/conf.d/ssl.conf    
 <VirtualHost 172.16.253.3> ##此行IP地址需要按照你自己需求更改
 DocumentRoot "/web/vhosts/www1"
 ServerName
 
 SSLCertificateFile /etc/httpd/ssl/httpd.crt
 SSLCertificateKeyFile /etc/httpd/ssl/httpd.key  ##证书私钥

6)检查配置文件,重新加载,测试即可    
[root@lilei ssl]# httpd -t
[root@lilei ssl]# service httpd