首页 > 代码库 > Linux之Web服务(2)Httpd服务配置之四
Linux之Web服务(2)Httpd服务配置之四
Linux之Web服务(2)Httpd服务配置之四
前言
接上一篇的虚拟主机,本片主要介绍虚拟主机的一些搭建和部署,本篇通过一个具体的案例来显示虚拟主机的作用和特性。
案例功能介绍:
(1) 准备DNS解析3个域名或者添加/etc/hostst/3条主机名IP档案,解决域名解析
(2) 基于主机名实现三个虚拟主机
(3) 每虚拟主机使用独立的访问日志和错误日志
(4) 在第二个虚拟主机上提供/status;
(5) 在第三个虚拟主机提供路径别名/bbs,访问其它文件系统路径;
(6) 第三个虚拟主机的/admin要进行用户访问认证
(7) 尝试使用混合类型的虚拟主机:基于IP,PORT和ServerName
具体实践实现
基于主机名实现三个虚拟主机
准备工作:
1、搭建DNS域名解析。
#添加一个NDS配置文件路径并在/etc/named.conf及DNS主配置文件中引用
[root@root ~]# grep ‘^include.*vhost‘ /etc/named.conf include "/etc/named.vhost.zones";
#在named.vhost.zones创建对应的zone定义3个zone(badu.com meng.com goole.com)
[root@root ~]# cat /etc/named.vhost.zones zone "baidu.com" IN { type master; file "baidu.com.zone"; }; zone "meng.com" IN { type master; file "meng.com.zone"; }; zone "google.com" IN { type master; file "google.com.zone"; };
#调整配置文件的权限及属组
[root@root ~]# chown :named /etc/named.vhost.zones [root@root ~]# chmod 640 /etc/named.vhost.zones
#根据配置区域的路径创建对应的区域数据库文件,这里使用循环查看3个区域数据库文件
[root@root ~]# ls /var/named/{baidu,meng,google}.com.zone | while read line;do echo "---->$line<----";cat $line; done
解析:这里为了区分,每个区域数据库,个别都使用了不同的IP及主机名用于区分。分别定义了3个zone配置,而其中的web地址及www域每个都有设置,分别为:
www.badiu.com
www.meng.com
www.google.com
#修改对应的区域数据文件的权限位也属组
[root@root ~]# chmod 640 /var/named/{baidu,meng,google}.com.zone [root@root ~]# chgrp named /var/named/{baidu,meng,google}.com.zone
#检查数据库配置语法
[root@root ~]#named-checkzone ‘baidu.com’ /var/named/named.baidu.zone
注意:当然目前只有三个域,以后构建虚拟主机可能要更多,那么每一条近似重复的命令如:
named-checkzone ‘zone1’ /var/named/zone1.zone
named-checkzone ‘zone2’ /var/named/zone2.zone
....................
提示:从上面可以退出结论,那么以后每个域都要前一次named-checkzone命令,只是2个参数不一样,那么即使编程很差也要先一些解决的方法,好像named-checkzone有一个-w还是什么的选项,可以指定目录进行检查,但是一直不知道怎用,于是只好写个小脚本喽。
#于是编写一个小脚本,用于批量检查一个指定配置文件中的zone对应的数据库文件配置格式:
[root@root ~]# vim named-checkzone.sh #!/bin/bash #如果脚步参数小于1则提示错误并退出 [ $# -lt 1 ] && echo "Usage `basename $0` /path/to/zone_namedfile" && exit 1 #如果传来的参数不是一个文件文件或者不存在则提示错误并退出 [ ! -e $1 -o ! -f $1 ] && echo "$1 no such zone_name_file!" && exit 2 prog=$1 #介绍传来的zone类型定义配置文件,如/etc/named.rfc1912.zone #下面两种方法都可以通过过滤主配置文件找出数据库文件相对路径目录 zonedir=`grep ‘^[[:space:]]*directory‘ /etc/named.conf | sed -n ‘s/^.*\"\(.*\)\";.*$/\1/p‘` zonedir=`grep ‘^[[:space:]]*directory‘ /etc/named.conf | awk -F‘"‘ ‘{print $2}‘` #如果目录后面没有/结尾,则追加,方便以后调用 if [[ ! $zonedir =~ /$ ]]; then zonedir+=‘/‘ fi #这里同时取出每个zone 定义的名称、对应zone数据库路径,一般为相对路径,且显示为 #第一行为名称,第二行为名称对应的数据库路径。因此可以而判断奇数行位名称,而偶数 #行对上一行名称对应的路径。取出多行传入while循环逐行读取 grep ‘^[[:space:]]*\(zone\|file\)‘ /etc/named.vhost.zones | sed -n ‘s/^.*\"\(.*\)\".*$/\1/p‘ | while read line; do let i++; #第一次i++后i=1表示行数的累计,第一行为奇数行 if [ $[i%2] -eq 1 ]; then #判断如果为奇数行则将名称存入 zone=$line else #偶数行其进行检查zone数据库 if [[ $line =~ ^/ ]]; then #这里检查如果数据库路径为绝对路径,则 named-checkzone "$zone" "$line" else #如果为相对路径,则相对于 zonedir取出的目录 named-checkzone "$zone" "${zonedir}${line}" fi fi done
补充:named-checkzone有两个参数,第一个则为zone类型定义的名称,而第二个则是配置中指定的路径,两种必须同时指定并匹配,否则会检查出错误。
#测试一下脚步进行检查刚才建立的3个zone区域数据库文件格式
[root@root ~]# bash named-checkzone.sh /etc/named.vhost.zones zone baidu.com/IN: loaded serial 2016100601 OK zone meng.com/IN: loaded serial 2016100601 OK zone google.com/IN: loaded serial 2016100601 OK
说明:从上面可以看出配置应该没有什么问题,于是可以重新加载named服务来检测解析。
#让named守护进程重载配置文件
[root@root ~]# systemctl reload named.service
#调整hosts主机名解析的优先级为DNS服务器解析优先,在/etc/nsswitch.conf中的hosts条目中将dns设置在前面及优先DNS解析主机。
[root@root ~]# vim /etc/nsswitch.conf
#查看当前使用的网卡设备
[root@root ~]# ip -o link show up | awk -F‘[ :]‘ ‘{print $3}‘ | grep -v ‘^lo‘ eno16777736
#查看当前eno16677736网卡的IP地址
[root@root ~]# ip addr show dev eno16777736 | grep ‘^[ ]\+inet‘ inet 10.1.249.223/16 brd 10.1.255.255 scope global eno16777736 inet 10.1.249.10/16 scope global secondary eno16777736
说明:从上面可以看出以及有刚才知道的两个IP了,如果没有可以使用ip或者ifconfig命令对指定网卡进行添加一个IP,这里不细说,下面来测试正向解析完整域名。
#使用ping命令来测试主机名,但有多个,因此就使用循环+判断
[root@root ~]# for i in `echo www.{baidu,meng,google}.com`;do if ping -c 1 -W 1 $i &> /dev/null;then echo "$i nds ok"; fi; done www.baidu.com nds ok www.meng.com nds ok www.google.com nds ok
解析:这里因为有多个主机,而且都是www开始.com结尾,于是使用echo将其打印出空格隔开的一个数组来供for循环进行多次ping,如果ping通就输出ok。
说明:当DNS一些最基本的正向解析搭建好了,那么模拟的域名也就才可以在本机上使用了,于是下面就可以来使用这些域名来当站点网址了。
2、配置httpd虚拟主机
配置3个web服务虚拟文件配置文件
说明:这里每个VirtualHost标签开始到结尾为一个虚拟主机配置的定义,当同时匹配时,配置在最前面的虚拟被优先使用,配置如下:
[root@root ~]# vim /etc/httpd/conf.d/virtualtest.conf <VirtualHost 10.1.249.223:80>#指定IP地址 10.1.249.223 端口80 ServerName www.baidu.com #指定完整域名 www.baidu.com DocumentRoot "/vhosts/baidu" #指定站点根目录 /vhostst/baidu.com <Directory "/vhosts/baidu.com"> #设置权限 Options None AllowOverride None Require all granted #允许所有人访问,默认为显式搜权,及默认拒绝所有 </Directory> </VirtualHost> <VirtualHost *:80> #所有地址端口80 ServerName www.meng.com #指定完整域名为 www.meng.com DocumentRoot "/vhosts/meng" #指定站点根目录为 /vhosts/baidu <Directory "/vhosts/baidu"> Options None AllowOverride None Require all granted </Directory> </VirtualHost> <VirtualHost 10.1.249.10:8080> #IP地址为10.1.249.10端口8080 ServerName www.google.com #站点名称为www.google.com DocumentRoot "/vhosts/google" #站点根目录为/vhosts/google <Directory "/vhosts/google"> Options None AllowOverride None Require all granted </Directory> </VirtualHost>
#上面有主机地址设置为8080端口,因此要在/etc/httpd.conf添加一个Listen 8080
[root@root ~]# vim /etc/httpd/conf/httpd.conf
部署VirtualHost定义的DocumentRoot目录
#创建站点的根目录
[root@root ~]# mkdir -pv /vhosts/{baidu,meng,google} mkdir: created directory ‘/vhosts/baidu’ mkdir: created directory ‘/vhosts/meng’ mkdir: created directory ‘/vhosts/google’
#检查配置信息并重载服务配置
[root@root ~]# httpd -t Syntax OK [root@root ~]# systemctl reload httpd.service
#修改根目录的selinux安全上下文,让httpd进程能够进行访问此目录
[root@root ~]# chcon -R -reference=/var/www/html /vhosts/
#一般默认主页在/etc/httpd/conf/httpd.conf配置的DirectoryIndex 节点配置
[root@root ~]# grep ‘^[[:space:]]*DirectoryIndex‘ /etc/httpd/conf/httpd.conf DirectoryIndex index.html
解析:站点目录的默认页面为index.html命名的文档文件,于是可以建立几个文件。
#使用for循环快速同时建立3个站点的默认web首页
[root@root ~]# for i in baidu meng google;do echo $i > /vhosts/${i}/index.html; done
下面使用curl或者links进行访问测试
#访问www.baidu.com
[root@root ~]# curl http://www.baidu.com baidu
#访问www.meng.com
[root@root ~]# curl http://www.meng.com meng
#访问www.google.com时要注意,上面设置了8080端口,因此要指定端口
[root@root ~]# curl http://www.google.com:8080 google
3、各自配置独立功能
说明:给每个主机有独立的日志存放路径
www.baidu.com主机日志配置
<VirtualHost 10.1.249.223:80> ServerName www.baidu.com DocumentRoot "/vhosts/baidu" <Directory "/vhosts/baidu"> Options None AllowOverride None Require all granted </Directory> ErrorLog "logs/baidu_error_log"#错误日志 CustomLog "logs/baidu_access_log" #访问日志 </VirtualHost>
注意:这里相对路径一般相对于/etc/httpd/下的logs目录,默认ServerRoot 设置为 /etc/httpd。
奇怪的猜想
说明并探测
在配置了一个虚拟主机之后,发现,只是设置了不同的路径,而且接下来的都是添加了两条日志配置,只是路径不同,如果规格好相同的目录,如都是/etc/httpd/logs目录下,只是文件名不同,那么可以借助也许文本处理工具来快速实现。
进一步的推测
在上篇处理输出行间截取是写了个subline.sh脚本,那么这里这次,换一种工具,但是发现while循环对于读取于大量的标准输出文本好像速度有些慢,而且只是把固定不变的内容给过滤格式并打印出来,而这次需要修改文件,并且每个文件都在变,于是可以通过递归算法来完成。为什么呢?因为每次所有变量都在变,这时候什么if判断都不行了呀。
多次失败的结论
#使用递归循环判断每个VitualHost标签中是否已经定义了日志信息,然后不断进行重读配置并再次判断然后进行修改。因为此方法好像awk可以实现,但是本人尝试并未成功,于是只好使用这种笨办法啦:
[root@root conf.d]# vim ~/awk.sh #!/bin/bash # path=/etc/httpd/conf.d/virtualtest.conf; #定义死对指定虚拟主机配置做更新处理 declare -a linenums; #定义一个索引数组,用来存放行号 #last函数用来支持当前配置文件状态的virtualhost标签的起始和开头,并用:组合,及每个索引存放的值为”标签开始行号:标签结尾行号” last() { linenums=(`grep -n ‘^[[:space:]]*</\?Vir‘ /etc/httpd/conf.d/virtualtest.conf | cut -d‘:‘ -f 1 | sed ‘N;s/\n/:/‘`) } #声明一个变量 i=0 用来与对应的linenums行号索引的做比较统计判断 let i=0; #主要的更新函数,会采用递归来重复调用,动态的修改指定虚拟主机文件,解决了平常使用的循环无法进行动态变量值的判断。如一个文件不段修改,任能准配找到对应匹配的行号。 update() { last #取得当前文件"<状态>"的taget start、end行号 if [ $i -eq ${#linenums[@]} ]; then #如果i等于行号记录的属组长度,则退出此函数 return fi if [ $i -lt ${#linenums[@]} ]; then #如果i小于行号,则 s=${linenums[$i]%:*} #取得第i+1 次的vh标签star\end行号,及第i+1对vh标签 e=${linenums[$i]#*:} echo $s #测试打印第i+1对vh标签起始行号 echo $e #测试打印第i+1对vh标签结束行号 #记录第i+1此vh标记里的定义的 servername及站点主机名 servername=`sed -n "$s,$[e-1]"p $path | grep ‘^[[:space:]]*Server‘ | awk -F‘.‘ ‘{print $2}‘` #判断第i+1 对标记中是否已经定义了错误日志,如果有则记录其返回值 sed -n "$s","$[e-1]"p $path | grep -Eq ‘^[[:space:]]*ErrorLog‘ err_result=$? #判断第i+1 对标记中是否已经定义了访问日志,如果有则记录其返回值 sed -n "$s","$[e-1]"p $path | grep -Eq ‘^[[:space:]]*CustomLog‘ acc_result=$? echo "--------修改中---------" #因为相对路径文件名过程,这里通过循环来不断读取 for j in logs/${servername}_{errorlog,accesslog}; do let k++; #奇数则进行错误日志处理,偶数则进行访问日志处理 if [ $[k%2] -ne 0 ]; then if [ $err_result -ne 0 ]; then #如果未定义则添加一个对应的日志指令 sed -i "${e}i \ \tErrorLog $j" $path fi else if [ $acc_result -ne 0 ]; then sed -i "${e}i \ \tCustomLog $j " $path fi fi done let i++; #处理一轮后i累计,准备解析来的判断 update #递归自己调用自己,重新生成最新的标签起始行和结束行 fi } update #调用此函数
#执行此脚本,来测试其修改效果
[root@root conf.d]# ~/awk.sh 1#第一个Vitrual标记起始行号 11#第一个Vitrual标记结尾行号 --------修改中--------- 12#第二个Vitrual标记起始行号 22 #第二个Vitrual标记结尾行号 --------修改中--------- 23#第三个Vitrual标记起始行号 34#第三个Vitrual标记起始行号 --------修改中---------
说明:以此类推有多少个VitrualHost虚拟主机标签就会进行对应次数的处理。当然本章主要介绍虚拟主机的作用以及其部署为主,然后进行下一步配置的检查。
#查看刚才经过修改过的虚拟主机配置文件/etc/httpd/conf.d/virtualtest.conf
[root@root conf.d]# grep -E -e ‘[[:space:]]*ServerName‘ -e ‘^[[:space:]]*(Error|Custom)Log‘ /etc/httpd/conf.d/virtualtest.conf
说明:grep过滤是自上而下的,这里配置时因为每一个虚拟主机VitrualHost都设置了一个站点域名,所有3个主机对应各种的2个配置文件个数是不会错的。这里再次强调一下,这里的相对路径是指ServerRoot指定路径,那么日志路径就为/etc/httpd/logs/下。
#检查配置文件的语法格式及信息
[root@root conf.d]# httpd -t AH00526: Syntax error on line 9 of /etc/httpd/conf.d/virtualtest.conf: CustomLog takes two or three arguments, a file name, a custom log format string or format name, and an optional "env=" or "expr=" clause (see docs)
解析:当看到这里感觉白忙活了,忘记了如果为访问日志需要指定日志的一个格式的,及需要记录访问来源的哪些响应、请求信息。当然访问的格式有点多,而且难以记忆,大部分在官方文档上,在编写脚本的时候也就以为会有默认值。当然也可以完善一下脚本,不过这里还是看看主配置文件/etc/httpd/conf/httpd.conf有没有预设一些全局配置的访问日志格式来供参考。
#查看产看主配置文件下是否有已经有日志格式配置
[root@root conf.d]# grep ‘^[[:space:]]*LogFormat‘ /etc/httpd/conf/httpd.conf
说明:这里有三种Apache官方已经预留设置好的格式,发现第2列的格式信息相对少一点,为了方便理解,选择第二种及common,当然可以加入到脚步文件中,但是要把配置中的访问日志CumostLog给删除掉才行,不然不会写入。
#可以使用sed删除多行CustomLog配置
[root@root conf.d]# sed -i ‘/^[[:space:]]*CustomLog.*/d‘ virtualtest.conf
#然后修脚本中判断是否有访问控制的if语句块中的sed插入命令中添加一个common字符
注意:这里主要是判断对应的VitrualHost虚拟主机是否已经有了CustomLog标签及访问日志的配置,如果没有将插入新的配置。
#修改完成后,可以重新执行此脚本
[root@root conf.d]# ~/awk.sh 1 10 --------修改中--------- 12 21 --------修改中--------- 23 33 --------修改中---------
#再次查看配置信息文件中的CustomLog访问日志参数配置
[root@root conf.d]# grep ‘^[[:space:]]*CustomLog‘ /etc/httpd/conf.d/virtualtest.conf
说明:这里显示已经成功修改了对应的CustomLog配置,那么下面再次进行检查。
#再次检查配置语法及信息的规则性
[root@root conf.d]# httpd -t Syntax OK
说明:输出了OK,表示配置以及符合规则,语法也没有什么错误了。
#重载Httpd服务配置文件
[root@root conf.d]# systemctl reload httpd.service
#没有显示其它的信息,表示已经重新载入,查看日志文件是否已经自动生成
[root@root conf.d]# ls -l /etc/httpd/logs/{baidu,meng,google}*log -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/baidu_accesslog -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/baidu_errorlog -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/google_accesslog -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/google_errorlog -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/meng_accesslog -rw-r--r--. 1 root root 0 Oct 1 17:56 /etc/httpd/logs/meng_errorlog
说明:这里生成的时间都是刚刚并且一致,说明日志已经生效。
#下面测试访问日志是否真的可以记录访问信息,使用curl进行直接访问www.baidu.com站点的文档资源源码
[root@root conf.d]# curl http://www.baidu.com baidu
#访问成功,下面查看www.baidu.com对应的访问日志文件
[root@root conf.d]# cat /etc/httpd/logs/baidu_accesslog 10.1.249.223 - - [01/Oct/2016:17:58:39 -0400] "GET / HTTP/1.1" 200 6
说明:这里已经记录了日志的信息,请求用户的IP地址、请求的时间、以及请求的第几次次数,还有curl默认不指定选项实用的GET方法获取其资源。HTTP1.1表示了Httpd使用的http1.1协议。200则表示OK及放回的请求成功的响应状态码,6表示发送的字节数量,因为没有任何提交信息,只有6字节表示请求头报文吧。
4、给www.meng.com虚拟主机配置一个状态(server-status)查看页面
提示:要使用server-status配置需要加载一个功能模块及status_module,否则无法使用。
#查看当前是否以及加载status_module模块
[root@root conf.d]# httpd -M | grep ‘\<status‘ status_module (shared)
说明:httpd -M专门用来查看当前服务开启时加载的所有相关模块。
#如果发现没有加载,可以在配置文件中添加,一般在/etc/httpd/conf.modules.d/*.conf下配置一条加载信息,如:
LoadModule status_module modules/mod_status.so
提示:当然一般不会随便添加,这里先查看一下默认的conf.modules.d目录下的文件:
[root@root conf.d]# ls /etc/httpd/conf.modules.d/ 00-base.conf 00-dav.conf 00-lua.conf 00-mpm.conf 00-proxy.conf 00-systemd.conf 01-cgi.conf
#从上面看出有多个文件,因此可以用for循环来对此目录下所有文件进行内容过滤来判断
[root@root conf.d]# for i in /etc/httpd/conf.modules.d/*.conf;do grep ‘^LoadModule.*status‘ $i; done LoadModule status_module modules/mod_status.so
解析:这里显示了有一个文件以及配置了加载mod_status模块,因此可以进行下面的具体配置,在配置之前,注意一点,LoadModule指令有两个参数,一个为名称,一个则为路径,这里为相对路径,则是相对于ServerRoot指令指定的路径,默认为/etc/httpd/modules/下。
#查看/etc/httpd/modules目录文件列表
[root@root conf.d]# ls /etc/httpd/modules/
说明:如果以后有自定义或新的模块,可以放入此目录方便管理,然后再对应的路径添加配置文件或在已有配置文件添加对应的LoadModule指令即可。
#给www.meng.com虚拟主机配置Location指令
[root@root conf.d]# vim /etc/httpd/conf.d/virtualtest.conf
说明:这里的Location指令的路径为相对于对应主机的DocumentRoot指令指定的站点文档主目录路径下,当然这个文件无需要建立,通过模块功能会自动识别。而SetHandler指令是专门用户指定对应的模块信息,及使用了server-status模块功能。下面的RequireAll进行了对显示只有10.1.249.223IP地址主机能查看此状态,而本机其中一个IP就是这个地址,也就是本机能访问,而all granted表示启用允许所有。使用 RequireAll 封装表示只允许指定的用户,这里指明的IP 10.1.249.223 才能访问,也就是本机。
注意:使用RequrireAll标签包装,要允许指定用户访问,必须同时加上Require all granted。
#下面任然需要检查语法
[root@root conf.d]# httpd -t Syntax OK
#然后重载服务配置
[root@root conf.d]# systemctl reload httpd.service
#访问此http://www.meng.com/status及查看meng站点的主机站点状态
[root@root conf.d]# links http://www.meng.com/status
说明:显示对应的服务各类状态信息说明已经以及成功通过访问控制来访问。下面再另一台主机上同样使用links浏览器去尝试访问此站点。
#使用另一台主机去访问,其IP地址为10.1.249.50而非对应的10.1.249.223
[root@mzf ~]# hostname -I 10.1.249.50
#为了指定DNS服务器来解析www.meng.com域名,访问前要添加nameserver对应的ip
[root@mzf ~]# cat /etc/resolv.conf
说明:这里有多个nameserver建议放在第一个及最前面,会优先使用此DNS服务器来解析域名,否则可能会针对解析到www.meng.com网站了。
#添加上面的地址之后,测试是否可以解析此域名
[root@mzf ~]# ping -c 1 -W 1 www.meng.com
说明:这有可以通过完整主机名来正向解析到对应的IP,才算可以建立通信。
#下面同样使用浏览器来访问www.meng.com下的/status服务状态
[root@mzf ~]# links http://www.meng.com/status
说明:这里系显示了403状态码,为forbidden,表示无权限访问此资源或站点路径。表示访问控制以及生效,那么除了www.meng.com虚拟主机本机指定的IP才能访问,除此其它任何想访问都不行了,这样就保证了站点服务的安装,防止有用户通过查看服务状态信息来进行请求工具等。
#当然这时出现了请求的拒绝,在对应的web站点是有日志记录的
[root@root conf.d]# cat /etc/httpd/logs/meng_errorlog | tail -n 1 [Sat Oct 01 19:20:38.184219 2016] [authz_core:error] [pid 9528] [client 10.1.249.50:52109] AH01630: client denied by server configuration: /vhosts/meng/status
说明:这里明确记录了刚才IP为10.1.249.50的主机通客户端浏览器进行访问此虚拟主机站点,而且被拒绝访问别拦截。而且访问的资源路径为/vhosts/meng/status。因此可以通过查看错误日志信息来不断完善站点的安全和稳定。
5、给www.google.com虚拟主机站点提供Alias别名/bbs路径
提示:要使用别名路径访问方式,可以说有两种:
方法1:就是使用专门的Alias指令来定义指定别名名称和命令指定的本地系统路径。
方法2:同样可以在Options指令添加一个FollowSymLisks指令表示可以运行在指定的Directory标签指定的目录下建立符合连接文件并指向的具体文件系统的路径。
先来使用方法一:Alias指令
#准备好一个测试的本地文件系统路径/test/bss目录
[root@root conf.d]# mkdir /test/bbs
#添加一个默认首页
[root@root conf.d]# echo "hello bbs" /test/bbs/index.html hello bbs /test/bbs/index.html
#给/test/bbs/目录添加httpd指定的安全上下文
[root@root conf.d]# chcon -R -t httpd_sys_content_s /test/bbs/
#要通过访问别名路径http://www.google.com/bbs/,则需要配置www.google.com虚拟主机的具体配置,添加Alias访问控制
[root@root conf.d]# vim virtualtest.conf
解析:默认一般设置的别名会在/etc/httpd/conf/httpd.conf下指定的IfModule标签,但是这一般定义在全局配置,如果全局有,可以直接去掉<IfModule alias_module>标签,及:
Alias /bbs/ "/test/bbs/"
<Directory "/test/bbs">
Options None
AllowOverride None
Require all granted
</Directory>
注意:需要添加别名指定路径下的目录对应的访问控制Directory,不然默认为拒绝访问。
Alias指令定义的格式:
Alias 别名路径 “别名指定调用的路径”
那么这里设置别名为Alias /bbs/ “/test/bbs/”,则表示:
别名名称为/bbs/ ,而通过/bbs/别名访问的则是指定的路径文件系统下的/test/bbs/目录。
注意:
1、在定义Alias指令时有个问题,如果指定的路径后面结尾没有加 / ,则别名的名称后面也不要添加 /;如果指定路径后面结尾添加了 / ,则别名名称的结尾一定要加 /。
2、同样默认如果不对指定的目录设置Directory标签做访问控制,默认此路径是被拒绝所有人访问的,因此需要添加指定的访问控制,访问上面有结束,这里设定的为允许所有。
#测试访问http://www.google.com:8080/bbs/,因为google设置了IP+8080端口,所有要指定端口进行访问。
[root@root conf.d]# links http://www.google.com:8080/bbs
说明:这里访问的资源路径表面看是google的站点文档根路径下的/vhosts/google/bbs目录,实则访问的为文件系统下的/test/bbs,只是隐藏了决定资源文件的路径而已。
注意:假如在 google站点文档路径下再创建一个/vhosts/google/bbs/目录,那么当通过上面的网址访问的资源会发送冲突,当同时设置了Alias指令后,Alias 优先生效。
下面使用方法二:
说明:在Options指定添加 FollowSymLinks 参数,及允许符号链接。然后对于的google 站点的文档根目录(/vhosts/google/)下创建一个bbs符号链接文件。
#在www.google.com 的文档主目录 <Directory >标准设置Options指令配置为;
Options FollowSymLinks
#配合完成后检查配置信息
[root@root conf.d]# httpd -t Syntax OK
#重载Httpd配置文件
[root@root conf.d]# systemctl reload httpd.service
#创建一个准备此测试的目录
[root@root conf.d]# mkdir /mybbs/
#给此目录一个Httpd定义的默认页
[root@root conf.d]# echo "This is Mybbs \!" > /mybbs/index.html
#给这些路径添加httpd需要的selinux安全上下文
[root@root conf.d]# chcon -R -t httpd_sys_concent_t /mybbs/
#查看/mybbs/目录及目录下的index.html安全上下文是否生效
[root@root conf.d]# ls -aZ --ignore=‘..‘ /mybbs/ drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_concent_t:s0 . -rw-r--r--. root root unconfined_u:object_r:httpd_sys_concent_t:s0 index.html
#在DIrecotry指定的/vhosts/google/目录下创建符号链接文件执行/mybbs/
[root@root google]# ln -sv /mybbs /vhosts/google/mybbs
#设置selinux上下文
[root@root google]# chcon -t httpd_sys_content_t /vhosts/google/mybbs
#访问www.google.com:8080/mybbs
[root@root google]# links http://www.google.com:8080/mybbs
6、第三个虚拟主机www.google.com文档根路径下/admin要进行用户访问认证
#在www.google.com站点的DocumentRoot 指令指定的路径 /vhosts/google/下添加/admin
[root@root google]# mkdir /vhosts/google/admin
#添加一个默认页面用于测试显示效果
[root@root google]# echo "<html><head><>title>Admin</title></head>><body><h1>Admin Page</h1></body></html>" > /vhosts/google/admin/index.html
#给/vhosts/google/admin/目录及下所有文件添加httpd对应安全上下文
[root@root google]# chcon -R -t httpd_sys_content_t /vhosts/google/admin/
#配置www.google.com的<VirtualHost>标签下添加访问认证控制:
<Directory "/vhosts/meng/admin"> Options None AllowOverride None AuthType Basic #基本口令验证 AuthName "please you inut uname and passwd login server:" #验证登录界面的提示语 AuthUserFile /vhost/meng/.htpasswd #使用的单项加密口令文件 Require user tom hadoop #基于tom、hadoop用户进行验证,其它拒绝访问 </Directory>
#htpasswd命令创建口令指定AuthUserFile指定的口令文件路径,添加tom用户
[root@root google]# htpasswd -cm /vhosts/google/.htpasswd tom New password: #这里输入两此密码 Re-type new password: Adding password for user tom
注意:这里了-c为create及创建新口令文件,而-m表示使用md5加密算法进行加密,一次需要创建,则使用-c选项。若再次使用-c创建则覆盖之前的配置。
#再次添加hadoop 用户及生成口令,这里不要使用-c选项,否则会重新覆盖
[root@root google]# htpasswd -m /vhosts/google/.htpasswd hadoop New password: Re-type new password: Adding password for user hadoop
#添加成功之后测试配置
[root@root google]# httpd -t Syntax OK
#重载httpd服务配置文件
[root@root google]# systemctl reload httpd.service
#在本地windows主机添加一个dns地址执行linux DNS服务器IP
#进行/vhosts/google/admin/访问,测试其认证,先打开浏览器输入对应的地址:
http://www.google.com:8080/admin
#输入配置的用户密码后点击确定,如果正确才会显示默认主页index.html
#使用curl命令测试,先查看默认主页
[root@root google]# curl http://www.google.com:8080 google
#成功则访问admin目录下的index.html
[root@root google]# curl http://www.google.com:8080/admin/index.html <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>401 Unauthorized</title> #401表示拒绝访问,及权限不够 </head><body> <h1>Unauthorized</h1> <p>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn‘t understand how to supply the credentials required.</p> </body></html>
说明:使用此验证同样不仅可以保证指定用户验证来访问对应的资源路径,还可以防止其它用户使用curl等类似命令来直接抓取资源文件源代码。保证了相应的安全性。
7、尝试使用混合类型的虚拟主机:基于IP,PORT和ServerName
#其实在开始已经设置成了混合主机:
[root@root google]# grep -E ‘^[[:space:]]*(<VirtualHost|ServerName)‘ /etc/httpd/conf.d/virtualtest.conf <VirtualHost 10.1.249.223:80> #第一个虚拟主机为Ip: 10.1.249.223 port:默认80 ServerName www.baidu.com #第一个虚拟主机FQDN:www.baidu.com <VirtualHost *:80> #第二个虚拟主机任意ip 端口为80 ServerName www.meng.com #第二个虚拟主机FQDN:www.meng.com <VirtualHost 10.1.249.10:8080> #第三个虚拟主机IP:10.1.249.10 port 端口80 ServerName www.google.com #第三个虚拟主机DQDN:www.google.com
#而dns服务配置中又定义了各自主机名对应的IP地址,及:
#baidu主机www.badiu.com对应IP 10.1.249.223
[root@root google]# host -t A wwww.baidu.com wwww.baidu.com has address 10.1.249.223
#meng主机www.meng.com对应IP 10.1.249.10
[root@root google]# host -t A wwww.meng.com wwww.meng.com has address 10.1.249.10
#google主机www.google.com对应也是IP 10.1.249.10
[root@root google]# host -t A wwww.google.com wwww.google.com has address 10.1.249.10
说明:上面的VirtualHost配置以及ServerNname被DNS解析的主机IP地址来看,可以进行一些混合模式的访问。
具体访问测试
#当访问http://10.1.249.223时
[root@root google]# curl http://10.1.249.223 baidu
说明:因为www.baidu.com对应的VirtualHost在最前面,而且默认端口为80,且指定了IP地址为10.1.249.223。所有优先会使用www.baidu.com虚拟主机站点配置。
#当访问http://www.badiu.com,同样根据DNS解析的IP地址10.1.249.223去寻找配置
[root@root google]# curl http://www.baidu.com baidu
#当访问http://10.1.249.10时
[root@root google]# curl http://10.1.249.10 meng
说明:因为www.meng.com对应的为任意地址,但是端口为80,读取第一个主机配置及baidu时因为指定了IP与其不匹配,读取下一个,而下一个为任意IP且端口为80则符合,因此可以匹配为www.meng.com.
#当然访问直接的主机名会被DNS服务解析为对应的IP及10.1.249.10,因此同上访问
[root@root google]# curl http://www.meng.com meng
#但是当指定端口号,如http://www.meng.com:8080,则
[root@root google]# curl http://www.meng.com:8080 google
说明:这时因为www.meng.com和 www.google.com在dns服务配置中设置的正向解析数据库中对应的IP地址都为10.1.249.10,所有,当端口为8080时,第二个主机名会根据正向DNS服务器解析IP地址为10.1.249.10后接:8080端口,此时读取下一个虚拟主机标签及<VirtaulHost>IP指定了10.1.249.10的且端口为8080,因此与其匹配则建立连接。读取的资源则为www.google.com根站点默认网页。
#同样访问http://10.1.249.10:8080,则也应还是www.google.com,因为只有此虚拟主机同时匹配IP和对应的端口。而且其VitrualHost标签前面已经没有优先符合的配置了,则:
[root@root google]# curl http://10.1.249.10:8080 google
#当然指定www.google.com 网站后跟8080端口,则也只有www.google.com优先匹配
[root@root google]# curl http://www.google.com:8080 google
#那么不指定端口访问www.google.com呢
[root@root google]# curl http://www.google.com meng
说明:当找不到对应的主机名的端口匹配,将通过DNS解析为对应IP-->10.1.249.10,让后找到同样NDS记录对应IP地址为此地址的www.meng.com,因此就会访问www.meng.com站点下的文档资源了。
总结:这里配置有一个优先级,如果配置标签写在文件的最开头,且请求访问的地址信息如果匹配会以及生效,相同的也只会优先匹配最前面的配置,因为服务重载会从头开始读取每个配置文件的信息。当然配置文件有多个,会安装目录下的配置文件名排序来读取信息。
本文出自 “孟天霸-IT的垃圾回收站” 博客,谢绝转载!
Linux之Web服务(2)Httpd服务配置之四