httpd服务器的架设

实验前提

a、关闭iptables和selinux

b、httpd服务器的ip为192.168.108.251,本机测试机为192.168.108.15。

 

1、安装httpd软件

# yum install httpd

这里的httpd版本为httpd-2.2.15

 

在/var/www/html/目录下生产两个文件

# echo "good nice" > /var/www/html/index.html

# echo “<h1>hello</h1>” /var/www/html/test.html

 

启动httpd服务

# service httpd start

 

2、开启httpd的长连接功能

默认httpd-2.2版本上,httpd的长连接功能是关闭的。因此,当httpd处理完一个请求时,其连接就会断开。

如:

Xshell:\> telnet 192.168.108.251 80


Connecting to 192.168.108.251:80...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
GET /test.html http/1.1
Host:192.168.108.251

HTTP/1.1 200 OK
Date: Wed, 14 Oct 2015 16:04:43 GMT
Server: Apache/2.2.15 (CentOS) DAV/2
Last-Modified: Wed, 14 Oct 2015 15:57:54 GMT
ETag: "210a5-f-52212a01d5b51"
Accept-Ranges: bytes
Content-Length: 15
Connection: close           //没有启用长连接
Content-Type: text/html; charset=UTF-8

<h1>hello</h1>              //此处为响应的内容

Connection closed by foreign host.

Type `help' to learn how to use Xshell prompt.
Xshell:\>

在这个例子中,当请求http:192.168.108.251/test.html这个URL时,服务器端响应完成之后,就断开了连接。

 

启用长连接,需要编辑httpd的主配置文件/etc/httpd/conf/httpd.conf。

将# KeepAlive Off这一行改为KeepAlive on即可。改完之后在进行测试。

如:

Xshell:\> telnet 192.168.108.251 80


Connecting to 192.168.108.251:80...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
GET /index.html http/1.1                 //第一次请求

Host:192.168.108.251

HTTP/1.1 200 OK
Date: Wed, 14 Oct 2015 16:19:15 GMT
Server: Apache/2.2.15 (CentOS) DAV/2
Last-Modified: Wed, 14 Oct 2015 16:16:14 GMT
ETag: "210a6-a-52212e1afee97"
Accept-Ranges: bytes
Content-Length: 10
Content-Type: text/html; charset=UTF-8

good nice

GET /test.html http/1.1             //第二次请求
Host:192.168.108.251

HTTP/1.1 200 OK
Date: Wed, 14 Oct 2015 16:19:43 GMT
Server: Apache/2.2.15 (CentOS) DAV/2
Last-Modified: Wed, 14 Oct 2015 15:57:54 GMT
ETag: "210a5-f-52212a01d5b51"
Accept-Ranges: bytes
Content-Length: 15
Content-Type: text/html; charset=UTF-8

<h1>hello</h1>

当设置了长连接之后,发现当服务器响应了一个请求之后,没有立即断开此连接,这样当下一次客户端发起http请求,就不需要再一次的通过tcp的三次握手来建立连接,服务器端就可以直接响应给客户端了。这样就大大的提高了请求报文的响应速度。但是,长连接也有其弊端,那就是如果此客户端一直没有发生http请求,那么服务器就会一直维护这个空连接,导致其他的客户端无法与服务器建立连接,也就会导致更多的http请求无法得到立即响应,因此,过量的占用长连接也会最终的影响响应速度的。在主配置文件中有2种机制可以用来断开长连接。

KeepAliveTimeout:用来设等待下一个请求的超时时间,在这个时间内,如果没有发起任何请求的话,则会断开长连接。

KeepAliveRequests:设置该长连接允许的最大请求数。一旦请求数超过此值,长连接也是断开。 

这两者机制中任何一种机制只要满足,长连接都会断开。

 

3、启用特定的MPM机制

httpd的MPM机制有三种:prefork、worker、event。

默认的MPM机制为prefork,如果要想修改其MPM机制,需要编辑httpd启动脚本的配置文件/etc/sysconfig/httpd。

如将MPM机制修改为worker模式,编辑/etc/sysconfig/httpd。

# /etc/sysconfig/httpd

#HTTPD=/usr/sbin/httpd.worker将这一行的#字符去掉。

然后在重启httpd服务

# service httpd restart


查看当前的httpd进程

wKioL1YhApDyWOeSAAGdQDR7BO8739.jpg

这里属主为root的httpd进程称作主进程,属主为apache的httpd进程为工作进程。

注意:在httpd-2.4之前的版本是不支持event模式,即使有event模式,该MPM机制也是处于测试阶段,并未真正应用。

 

 


4、定义默认主页面

DirectoryIndex  index.html  index.php 

##当用户访问文档根目录时,返回的就是默认主页面的内容。默认主页面依次向右查找。如index.html存在的话,则index.html就是主页面;如果index.html页面不存在的话,而index.php存在的话,那么index.php就是默认主页面。



5、设定基于ip的访问控制

首先定义文档根目录

DocumentRoot "/var/www/html"

<Directory "/var/www/html">

    options none

    AllowOverride none

    order allow,deny

    allow from 192.168.108.15  (这里我的主机为192.168.108.15,设置允许访问)

</Directory>


测试访问http://192.168.108.251/

wKiom1YhCl_w_qfJAABxsX5B95c292.jpg 



6、设置路径别名

Alias  /alias/  /path/to/somefile/

所以当访问http://Server_ip/alias/其中访问的就是http://Server_ip/path/to/somefile/

如:

Alias /test/ "/www/abc/"

<Directory "/www/abc">

        options indexes

        allowoverride none

        order allow,deny

        allow from all

</Directory


创建目录

# mkdir /www/abc -pv

# mkdir /test

# echo "<h1>hello,www.abc</h1>" > /www/abc/index.html


然后重启httpd服务

# service httpd restart


测试访问http://192.168.108.251/test/index.html

wKiom1YhCfXADw9HAAClRpGMfa4333.jpg

 

 

7、定义用户目录

将/etc/httpd/conf/httpd.conf中的UserDir disabled这一行改为如下行:

UserDir public //public为指定用户下的目录名称

创建hadoop用户

# useradd hadoop


切换用户

# su - hadoop

$ mkdir public

$ cd public

$ echo "<h1>hello,Public</h1>" > hadoop.html


由于hadoop的家目录是不允许apache访问的,因此,必须给apache这个用户赋予进入hadoop家目录的权限。

su - root

# setfacl -m u:apache:x ~hadoop  (用户的家目录使用这种写法)

最后重载httpd服务

# service httpd reload


测试访问hadoop家目录页面时,使用这种方式进行访问

http://server_ip/~username/file

如:http://192.168.108.251/~hadoop/hadoop.html

wKioL1YhHi6AswAzAACjyfO-o-0713.jpg



 

 

8、定义脚本路径别名

在httpd服务中,定义脚本路径别名使用ScriptAlias来定义的。如在httpd的配置文件中有这么一行:

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

其中"/var/www/cgi-bin"这个目录就是cgi脚本目录,而/cgi-bin/是前面目录的别名。

在访问"/var/www/cgi-bin/"这些目录下的资源(或web对象)时,我们需要通过的别名的方式来访问,如访问"/var/www/cgi-bin/test.sh"这个资源时,我们需要这样指定:http://server_ip/cgi-bin/test.sh。

那么这些cgi脚本有什么用呢?

这些cgi脚本可以动态的生成html文件,服务器将这些动态生成的html文件响应给客户端。想了解cgi脚本的作用,需要了解cgi是什么?

cgi:common gateway interface,通用网关接口,其实它是一个api接口,用于实现web服务器与应用程序通信的一种协议。由于web服务器只负责响应静态页面,因此,对于动态页面的请求需要借助额外的协议来完成,这个协议就是cgi协议(当然现在也有其他更好的协议来完成此功能)。如果某个脚本或程序的执行结果返回的第一行是Content-Type:text/html等类似内容时,那么此脚本或程序就遵循cgi格式,遵循cgi格式的程序或脚本就会cgi程序。

如果客户端请求的是一个非cgi脚本,如后缀为.html的文件,则表示请求的是一个静态页面,那么此时就不需要调用cgi协议了,直接由web服务器响应给客户端;如果请求的是一个cgi程序(或叫cgi脚本),这些cgi程序不会直接响应给客户端,而是通过cgi协议将这些cgi程序加载到相应的应用环境(如bash解释器环境)下执行,并生产相应的html文件,再由cgi协议将这些html文件返回给web服务器,web服务器再将这些文件响应给客户端。这就是cgi的工作原理,以及动态网页的实现流程。

通常,这些cgi程序由c、c++、bash、perl、php语言编写,最终,由于perl语言具有跨操作系统、易于修改的特性成为cgi主流编写的语言,因此,一般的cgi程序都是perl程序。

 

如:编写一个简单的cgi程序。

# cd /var/www/cgi-bin

# vim test.sh

#!/bin/bash

##

cat << EOF

Content-Type:text/html 

##一个cgi程序必须在第一行写入echo "Content-Type:text/html"这样的语句,上述写法也可以。

(此处空行不能少)

<pre>       //这个表示输出时先执行这个符号内的命令

The time is: `date`

</pre>

EOF

 

#chmod +x test.sh

 

测试访问http://192.168.108.251/cgi-bin/test.sh,测试结果如下:

wKiom1YjspLABwUyAAB7_FThc44720.jpg

此外,由于脚本路径别名需要借助mod_alias和mod_cgi这两个模块来完成,因此,别忘记加载这两个模块了。修改/etc/httpd/conf/httpd.conf。启用如下两行:

LoadModule alias_module modules/mod_alias.so

LoadModule cgi_module modules/mod_cgi.so

 

 

 

9、基于用户的访问控制

所谓基于用户的访问控制就是说客户端在访问httpd服务器上的web资源时,需要输出用户名和密码完成验证后,才可以获取资源。这些用户不是系统用户,仅仅是为了获取web服务器上一些web资源而存在的用户。这些用户我们将其称为虚拟用户。

通常用户的认证过程需要通过3步来完成:

(1)、指定认证类型

认证类型有2种:基本认证类型和摘要认证

基本认证:basic,用户名以明文传输 ,密码是经过加密传输。

摘要认证:digest,摘要认证,用户名和密码经过hash编码之后传输,不过众多的程序都不支持这种认证方式。

在/etc/httpd/conf/httpd.conf文件中,如下这些行是与认证类型相关的模块:

LoadModule auth_basic_module modules/mod_auth_basic.so

LoadModule auth_digest_module modules/mod_auth_digest.so

 

(2)、指定认证提供者

认证提供者:指的是用户名和密码存放在何处。

通常用户名和密码都可以存在至file、sql数据库、dbm和ldap中。

与认证提供者相关的模块有:

LoadModule authn_file_module modules/mod_authn_file.so

LoadModule authn_alias_module modules/mod_authn_alias.so

LoadModule authn_anon_module modules/mod_authn_anon.so

LoadModule authn_dbm_module modules/mod_authn_dbm.so

LoadModule authn_default_module modules/mod_authn_default.so

 

(3)、指定授权机制

授权机制:即根据什么来进行授权,授权机制一般由2种:一是基于用户来授权;而是基于组来授权。

 

如:只允许openstack这个用户访问/var/www/html/这个目录下的资源。

<Directory "/var/www/html">

    AllowOverride Authconfig

    AuthType basic                //指定认证类型

    AuthName "First web..."       //提示语

    AuthUserFile  /etc/httpd/conf/.htpasswd   //用户名和密码存储文件

    Require user openstack                  //授权,授权用户可以访问

 ###Require vaild-user  //只要是位于/etc/httpd/conf/.htpasswd这个文件中的用户都可以访问

</Directory>

 

创建存储用户名和密码的文件,这个文件使用htpasswd这个命令来创建。

# htpasswd -c -m "/etc/httpd/conf/.htpasswd" openstack

 

重载httpd服务

# service  httpd reload

 

测试访问http://192.168.108.251/

wKiom1YjxZSirkhZAAHdnK4GHeM661.jpgwKioL1YjxdeR6Fg9AABqq_0bJbg744.jpg

 

 

10、配置基于组的访问控制

如:允许属于myweb组中的用户访问/var/www/html/目录下的资源。

配置如下:

</Directoy "/var/www/html/">

   AllowOverride AuthConfig

   AuthType Basic

   AuthName "First Web..."

   AuthUserFile "/etc/httpd/conf/.htpasswd"

   AuthGroupFile "/etc/httpd/conf/.htgroup"

   Require group myweb

</Directory>

 

# htpasswd -m "/etc/httpd/conf/.htpasswd" hadoop

# vim /etc/httpd/conf/.htgroup

myweb:hadoop

 

最后重载服务即可

# service httpd reload

 

11、虚拟主机配置

所谓虚机主机:就是将一个web服务器做成多个站点来使用,一个apache服务来服务多个不同的站点。其实通俗的理解就是把一个web服务器当作多个web服务器的意思。

 

在搭建虚拟主机时需要注意的事项:

    a、由于虚拟主机和物理主机(中心主机)不能同时生效,因此在搭建虚拟主机时,需要注销物理主机(中心主机),即在/etc/httpd/conf/httpd.conf文件中将DocumentRoot这一行注释掉即可。

    b、搭建基于主机的虚拟主机时,需要启用apache配置文件中的NameVirtualHost *:80这一行,且NameVirtualHost后面接的ip:port要和虚拟主机中保持一致。

    c、定义虚拟主机时,用户认证、ip认证、访问日志、错误日志、脚本别名、路径别名等功能都可以在虚拟主机中定义。

    d、对于基于主机名的虚拟主机来说,当客户端访问主机上的资源时,首先会对该主机名进行解析,解析出来的ip有可能和其他站点的ip是一样的。那么此时需要一种机制来决定,客户端如何将请求正确的发送到相应的虚拟主机上。需要借助http的请求首部Host:主机名来完成区分。

 

虚拟主机的类型:

(1)、基于ip的虚拟主机

基于ip的虚拟主机ip地址不同,端口号(80)是相同的。

由于ipv4地址紧缺,因此一般不使用这是方式来构建虚拟主机。

例如:ip1:80

      ip2:80

 

(2)、基于端口的虚拟主机

这种方式的虚拟主机,ip地址是相同的,但是端口号是不同的。一般的我们常说的web服务器的端口号是80,所以当你使用另一个端口号时,这会导致可能很多人不知道,因此也无法访问你的web服务器,一般在互联网上这种虚拟主机类型也不常用。

例如:ip:80

      ip:8080

 

 

3、基于主机名的虚拟主机

基于主机名的虚拟主机,ip地址和80端口是一样的,唯一不一样的是ServerName不一样。使用基于主机名的虚拟主机,该主机名必须能够被DNS解析的到,否则会出错。所以要么修改本地的hosts文件,要么假设一台DNS服务器。在这里我直接修改本地的hosts文件,添加几条映射关系即可。这种方式的虚拟主机是使用最多的。

例如  ip:80

      ServerName:www.a.com

      ip:80

      ServerName:www.b.net         

 

 

虚拟主机的定义格式

<VirtualHost ip:port>

这里面可以存放多个参数或者指令,形式与定义<Directory></Directory>一样

</VirtualHost>

 

如:手动实现三中不同类型的虚拟主机

首先将主配置文件中的DocumentRoot这一行注释掉,然后添加如下行:

NameVirtualHost 192.168.108.251:80     配置基于主机名的虚拟主机时,需要启用这行。

然后在创建/etc/httpd/conf.d/virtual.conf文件,文件内容如下:

<VirtualHost 192.168.108.251:80>
        ServerName www.a.com
        CustomLog "/etc/httpd/logs/access_log.a" combined
        ErrorLog "/etc/httpd/logs/error.log.a"
        DocumentRoot "/www/a/com"
        <Directory "/www/a/com">
                Options none
                Allowoverride none
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>

 

<VirtualHost 192.168.108.25:80>
        Servername www.b.com
        Customlog "/etc/httpd/logs/access_log.b" combined
        Errorlog "/etc/httpd/logs/error.log.b"
        DocumentRoot "/www/b/com"
        <Directory "/www/b/com">
                options none
                allowoverride none
                order allow,deny
                allow from all
        </directory>
</VirtualHost>


<VirtualHost 192.168.108.251:8080>
        Servername www.c.com
        Customlog "/etc/httpd/logs/access_log.c" combined
        Errorlog "/etc/httpd/logs/error.log.c"
        DocumentRoot "/www/c/com"
        <Directory "/www/c/com">
                options none
                allowoverride none
                order allow,deny
                allow from all
        </directory>
</VirtualHost>

 

<VirtualHost 192.168.108.251:80>
        Servername www.d.com
        Customlog "/etc/httpd/logs/access_log.d" combined
        Errorlog "/etc/httpd/logs/error.log.d"
        DocumentRoot "/www/d/com"
        <Directory "/www/d/com">
                options none
                allowoverride none
                order allow,deny
                allow from all
        </directory>
</VirtualHost>

说明:在这个文件中,配置了三种不同的虚拟主机。第一个和最后一个实现的是基于主机名的虚拟主机;第一个和第二个实现的是基于ip的虚拟主机;第一个和第三个实现的是基于port的虚拟主机。

其中定义日志文件时,日志文件必须是位于/etc/httpd目录下的,否则会报错。

 

 

然后,创建相应的目录

# mkdir /www/{a,b,c,d}/com

# ehco "hello,<h1>a</h1>"  >  /www/a/com/index.html  

# ehco "hello,<h1>b</h1>"  >  /www/a/com/index.html  

# ehco "hello,<h1>c</h1>"  >  /www/a/com/index.html  

# ehco "hello,<h1>d</h1>"  >  /www/a/com/index.html  

 

然后重启httpd服务

# service  httpd restart

 

测试时,先确保这些主机名可以被解析,如果本地没有dns,那么直接修改测试机的hosts文件,添加相关的映射关系即可。这里就不在给出测试结果了,按照上述步骤应该是没有问题的。

 

虚拟主机的额外补充:默认虚拟主机

定义默认虚拟主机方式:

<VirtualHost  _default_:80>
        DocumentRoot "/www/default80"
</VirtualHost>

 

 

12、配置httpd服务的status页面

在httpd服务中,有一个内置的服务器status信息,这个信息可以通过web页面的形式予以展示。这个web页面并不是文件系统上的文件,而是由apache内部表现形成的 。访问status信息,需要通过url的形式来访问。启用服务器的status功能,需要加载mod_status模块。

mod_status模块可以让管理员查看服务器的执行状态,它通过一个HTML页面展示了当前服务器的统计数据。这些数据通常包括但不限于:
(1) 处于工作状态的worker进程数;
(2) 空闲状态的worker进程数;
(3) 每个worker的状态,包括此worker已经响应的请求数,及由此worker发送的内容的字节数;
(4) 当前服务器总共发送的字节数;
(5) 服务器自上次启动或重启以来至当前的时长;
(6) 平均每秒钟响应的请求数、平均每秒钟发送的字节数、平均每个请求所请求内容的字节数;

在apache的配置文件有一个<Location></Location>这样的容器,Location容器专门用来定义url属性的,处于安全性考虑,服务器状态信息不应该被所有的人查看,应该只允许足够信任的人查看。

如:定义服务器的status属性信息

<Location /server-status>
    SetHandler server-status   //SetHandler表示显式定义处理器
    Order allow,deny
    Allow from 192.168.108.0/24

</Location>

这个容器是用来定义URL,在<Directory></Directory>这个容器中,定义的是本地文件系统路径,记住URL和本地文件系统路径不是一码事,只是写法上相同罢了。

 

说明:也可以使用<LocationMatch ""></LocationMatch>来实现正则表达式的配置。

 

 

13、配置httpd的页面压缩功能实现优化传输

在httpd中有一个专门的模块用来实现页面压缩功能,这个模块就是mod_deflate。因此,要想在传输前对页面进行压缩,需要在httpd的配置文件中加载该模块。即在配置文件中启用如下行:

LoadModule deflate_module modules/mod_deflate.so

当某个服务器的带宽不够时,页面压缩功能有利于节约带宽。但是由于页面在压缩过程中,会消耗一定的系统资源,因此,当某个服务器比较繁忙的时候,最好就不需要启用压缩功能了。因此,是否需要配置httpd的页面压缩功能需要根据服务器的运行环境来决定。

启用压缩功能,一般通过如下步骤完成:

(1)、启用并设定过滤器

SetOutputFilter  DEFLATE

 

(2)、指定过滤器对哪些类型的文件进行压缩

AddOutputFilterByType  DEFLATE    text/html

AddOutputFilterByType  DEFLATE    text/plain

AddOutputFilterByType  DEFLATE    text/css

AddOutputFilterByType  DEFLATE    text/javascript

AddOutputFilterByType  DEFALTE    text/xml

AddOutputFilterByType  DEFLATE    application/xhtml+xml

AddOutputFilterByType  DEFLATE    application/xml

AddOutputFilterByType  DEFLATE    application/x-javascript

 

(3)、指定压缩比

压缩比范围是[1-9],默认压缩比为6。

DeflateCompressionLevel 9

 

(4)、对浏览器进行限定,允许对哪些浏览器支持压缩功能,哪些浏览器不支持压缩功能

 DeflateCompressionLevel 9
 
 # Netscape 4.x has some problems.
 BrowserMatch ^Mozilla/4 gzip-only-text/html
 
 # Netscape 4.06-4.08 have some more problems
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 
 # MSIE masquerades as Netscape, but it is fine
 BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html