Linux学习78 基于apache实现linux平台web服务实战操练
一、http相应配置(续)
1、基于用户的访问控制
a、认证质询。正常情况下客户端向服务器请求一个页面资源时,如果服务端存在这个资源,就应该通过200说这个资源存在然后发给客户端,如果不存在的话那么客户端就没权限访问,一旦开启认证功能以后就会出现这种情况,客户端第一次访问的时候我们服务端会发还一个40x的响应,4开头的响应表示客户端请求有问题,即服务端会发还一个认证质询的请求,此时我们的服务端会弹出一个对话框给客户端浏览器让客户端输入账号和密码,为了让客户端输入账号和密码通常还会告诉客户端说这是什么地方,为什么不允许随便访问以及你有没有带密码。如果有的话填入进来确定就可以了。即服务端会发一个 www.authenticate响应报文,向客户端要求提供账号和密码,客户端填入账号和密码后重新请求原来的资源,此时请求中就包含了authorized(请求授权的报文守护)。服务端再次受到对应内容以后如果在本地验证正确了就把资源发送给客户端,这个认证在浏览器端是可以保存的,只要浏览器不断开就可以不用再验证而访问此资源。
(1)、WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码
(2)、示例
1)、我们可以通过htpasswd命令创建相应的用户和密码
[root@www ~]# htpasswd -c /tmp/test.users tom #创建第二个用户时不要加-c否则会删掉这个文件这样tom用户就没了 New password: Re-type new password: Adding password for user tom [root@www ~]# cat /tmp/test.users tom:$apr1$O9r44yY6$TwO9oRy/wTIWW6/4ASME./
2)、我们也可以一次写上账号了密码,比如我们创建obama用户密码为123456
[root@www ~]# htpasswd -b -m /tmp/test.users obama 123456 Adding password for user obama [root@www ~]# cat /tmp/test.users tom:$apr1$O9r44yY6$TwO9oRy/wTIWW6/4ASME./ obama:$apr1$.FVLQBC/$BDNrvNAqvM1FntwLyCoMU0
-b表示不用交互式界面输密码,-m表示使用md5加密
b、认证
(1)、Authorization:客户端用户填入账号和密码后再次发送请求报文,认证通过时,则服务器发送响应的资源;
(2)、认证方式有两种
1)、basic:明文认证
2)、digest:消息摘要认证,但是有些浏览器不支持此种方式的认证
c、安全域:需要用户认证后方能访问的路径,应该通过名称对其进行标识,以便于告知用户认证原因
d、用户的账号和密码存放于何处?
(1)、虚拟账号:仅用于访问某服务时用到的认证标识
(2)、存储:
文本文件
SQL数据库
ldap目录存储
2、basic认证配置示例
a、定义安全域(httpd-2.2和httpd-2.4都一样)
(1)、配置格式
<Directory “”>
Options None
AllowOverride None
AuthType Basic #类型为Basic(明文)认证
AuthName "String" #用户认证时提醒用户的内容为String
AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" #密码文件路径,下面这行用户认证时需要依赖文件中的密码
Require user username1 username2... #想访问目录下对应的资源需要对应用户认证成功才能访问。这是用户名,用户密码在上一行定义的文件中
</Directory>
(2)、如果要允许账号文件中的所有用户登录访问配置下面字段即可:
Require valid-user
(3)、实际定义
1)、首先将我们刚刚创建的账号密码文件作为隐藏文件放置在/etc/httpd/conf.d/中
[root@www ~]# mv /tmp/test.users /etc/httpd/conf.d/.htpasswd
2)、接下来我们在网站上创建路径/data/web/www/admin/并且创建index.html文件
[root@www ~]# mkdir /data/web/www/admin [root@www ~]# echo "Admin Area" >> /data/web/www/admin/index.html
3)、我们不做认证之前是可以直接访问的
4)、现在我们配置需要用户tom认证才能被访问
[root@www ~]# cat /etc/httpd/conf.d/admin.conf <Directory "/data/web/www/admin"> Options None AllowOverride None AuthType basic AuthName "Admin Area, plz enter username and passwd:" AuthUserFile "/etc/httpd/conf.d/.htpasswd" Require user tom </Directory>
5)、检查无语法错误后重启服务,然后访问时就会弹出。我们输入tom账号和密码即可
[root@www ~]# httpd -t
Syntax OK
[root@www ~]# systemctl restart httpd
6)、当然我们也可以通过定义所有用户都可以访问让所有账号都可以访问
[root@www ~]# cat /etc/httpd/conf.d/admin.conf <Directory "/data/web/www/admin"> Options None AllowOverride None AuthType basic AuthName "Admin Area, plz enter username and passwd:" AuthUserFile "/etc/httpd/conf.d/.htpasswd" Require valid-user </Directory>
然后清理缓存你会发现tom和obama账号都可以登录
b、提供账号和密码存储(文本文件)
(1)、使用专用命令完成此类文件的创建及用户管理
htpasswd [options] /PATH/TO/HTTPD_PASSWD_FILE username
-c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用
-m:md5格式加密
-s:sha格式加密
-D:删除指定用户
-b:批模式添加用户
htpasswd -b [options] /PATH/TO/HTTPD_PASSWD_FILE username passwd
c、另外,基于组账号进行认证
(1)、定义安全域
<Directory “”>
Options None
AllowOverride None
AuthType Basic #类型为Basic(明文)认证
AuthName "String" #用户认证时提醒用户的内容为String
AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" #密码文件路径,下面这行组中用户认证时需要依赖文件中的密码
AuthGroupFile "/PATH/TO/HTTPD_GROUP_FILE" #组文件
Require group grpname1 grpname2 ... #想访问目录下对应的资源需要对应组中的用户认证成功才能访问。这是组名,用户密码在上一行定义的文件中
</Directory>
(2)、创建用户账号和组账号文件
1)、组文件:每一行定义一个组
GRP_NAME:username1 username2 ...
(3)、具体实验
1)、我们先创建/etc/httpd/conf.d/.htgroup组文件,里面添加animals组,并且把tom和obama用户添加进去,这个用户名可不能随便写,一定得是刚刚账号文件中所包含的用户
[root@www ~]# cat /etc/httpd/conf.d/.htgroup animals: tom obama
2)、现在我们来添加对应的组认证,然后检查语法是否有错然后再重启服务即可
[root@www ~]# cat /etc/httpd/conf.d/admin.conf <Directory "/data/web/www/admin"> Options None AllowOverride None AuthType basic AuthName "Admin Area, plz enter username and passwd:" AuthUserFile "/etc/httpd/conf.d/.htpasswd" AuthGroupFile "/etc/httpd/conf.d/.htgroup" Require group animals </Directory> [root@www ~]# httpd -t Syntax OK [root@www ~]# systemctl restart httpd
3)、然后我们发现用tom和obama登陆都可以
3、虚拟主机
a、站点标识:socket
(1)、IP相同,但端口不同;
(2)、IP不同,但端口均为默认端口
(3)、FQDN不同:
1)、请求报文中首部
2)、Host:www.wohaoshuai.com
b、有三种实现方案
(1)、基于IP:
为每个虚拟主机准备至少一个ip地址。由httpd监听,如果请求的是ip1+port,那么就将其路由到第一个虚拟主机,如果请求的是ip2+port,那么就将其路由到第二个虚拟主机
(2)、基于port:
为每个虚拟主机使用至少一个独立的port
(3)、基于FQDN:(前面两种一般都不怎么理想,一般都用后面这种)
为每个虚拟主机使用至少一个FQDN。
我们客户端访问我们服务器的时候host字段是不会变的,即用什么访问host值就是什么,即假如我们用了www1.wohaoshuai.com和www2.wohaoshuai.com访问了我们的服务器,就算两个域名解析出来的IP是一样的,但是不同的域名访问服务端时host字段的值都是他访问时的域名。因此我们服务器会根据客户端访问时报文里的host字段来分析客户端请求时到底用的是哪个域名了。
c、注意(专用于httpd-2.2):一般虚拟主机不要与中心主机混用,因此,要使用虚拟主机,得先禁用"main"主机.httpd-2.4没必要
禁用方法:注释中心主机的DocumentRoot指令即可
d、虚拟主机的配置方法
(1)、方法
<VirtualHost IP:PORT> #基于哪个地址哪个端口来接收请求,如果是基于FQDN的虚拟主机那么每个主机的ServerName要有区别,IP:PORT两个虚拟主机可以一样。如果要基于IP来做,那么各个虚拟主机的IP应该不同,基于端口来做端口就应该不同。
ServerName FQDN
DocumentRoot ""
</VirtualHost>
(2)、其它可用命令
ServerAlias:虚拟主机的别名,可多次使用
ErrorLog:
CustomLog:
<Directory>
...
</Directory>
Alias
...
(3)、配置示例
1)、基于IP的虚拟主机示例
2)、基于端口的虚拟主机示例
3)、基于FQDN的虚拟主机示例
e、配置示例
(1)、我们现在基于IP来做规划:
IP分别为:192.168.10.13:80和192.168.10.23:80
两个主机名分别为:www.wohaoshuai1.com和www.wohaoshuai2.com
站点资源分别在:/data/web/wohaoshuai1和/data/web/wohaoshuai2目录下
(2)、基于IP的虚拟主机实验开始
1)、创建相应的目录和测试页。(记得首先添加两张网卡并配置好IP)
[root@www network-scripts]# mkdir -v /data/web/{wohaoshuai1,wohaoshuai2} mkdir: 已创建目录 "/data/web/wohaoshuai1" mkdir: 已创建目录 "/data/web/wohaoshuai2" [root@www network-scripts]# echo "wohaoshuai1.com" >> /data/web/wohaoshuai1/index.html [root@www network-scripts]# echo "wohaoshuai2.com" >> /data/web/wohaoshuai2/index.html
2)、定义虚拟主机配置文件1
[root@www conf.d]# cat wohaoshuai1.conf <VirtualHost 192.168.10.13:80> ServerName www.wohaoshuai1.com DocumentRoot "/data/web/wohaoshuai1" <Directory /data/web/wohaoshuai1> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai1_access_log" combined </VirtualHost>
3)、定义虚拟主机配置文件2
[root@www conf.d]# cat wohaoshuai2.conf <VirtualHost 192.168.10.23:80> ServerName www.wohaoshuai2.com DocumentRoot "/data/web/wohaoshuai2" <Directory /data/web/wohaoshuai2> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai2_access_log" combined </VirtualHost>
4)、然后我们重启服务并查看端口监听
[root@www conf.d]# systemctl restart httpd [root@www conf.d]# netstat -anpt |grep 80 tcp6 0 0 :::8080 :::* LISTEN 12355/httpd tcp6 0 0 :::80 :::* LISTEN 12355/httpd
5)、我们通过不同的IP访问可以发现可以访问不同的页面
[root@www conf.d]# curl 192.168.10.13 wohaoshuai1.com [root@www conf.d]# curl 192.168.10.23 wohaoshuai2.com
(3)、基于端口的虚拟主机实验开始,比如一个在80上,一个在10080上,此处我们两个虚拟主机IP配置成同一个IP监听
1)、编辑我们wohaoshuai1.conf
[root@www conf.d]# cat wohaoshuai1.conf <VirtualHost 192.168.10.13:80> ServerName www.wohaoshuai1.com DocumentRoot "/data/web/wohaoshuai1" <Directory /data/web/wohaoshuai1> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai1_access_log" combined </VirtualHost>
2)、编辑我们wohaoshuai2.conf,监听10080即可
[root@www conf.d]# cat /etc/httpd/conf.d/wohaoshuai2.conf Listen 10080 <VirtualHost 192.168.10.13:10080> ServerName www.wohaoshuai2.com DocumentRoot "/data/web/wohaoshuai2" <Directory /data/web/wohaoshuai2> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai2_access_log" combined </VirtualHost>
3)、检查语法是否有错并重启服务后查看端口
[root@www conf.d]# httpd -t Syntax OK [root@www conf.d]# systemctl restart httpd [root@www conf.d]# netstat -anpt|grep 80 tcp6 0 0 :::8080 :::* LISTEN 12428/httpd tcp6 0 0 :::80 :::* LISTEN 12428/httpd tcp6 0 0 :::10080 :::* LISTEN 12428/httpd
4)、然后我们开始访问
[root@www conf.d]# curl 192.168.10.13 wohaoshuai1.com [root@www conf.d]# curl 192.168.10.13:10080 wohaoshuai2.com
(4)、现在我们来配置地址和端口相同但是主机名不同
1)、我们来编辑配置文件wohaoshuai1.conf
[root@www conf.d]# cat /etc/httpd/conf.d/wohaoshuai1.conf <VirtualHost *:80> #这样写表示本机所有地址,写某个IP也可以 ServerName www.wohaoshuai1.com DocumentRoot "/data/web/wohaoshuai1" <Directory /data/web/wohaoshuai1> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai1_access_log" combined </VirtualHost>
2)、我们来编辑配置文件wohaoshuai2.conf
[root@www conf.d]# cat /etc/httpd/conf.d/wohaoshuai2.conf <VirtualHost *:80> ServerName www.wohaoshuai2.com DocumentRoot "/data/web/wohaoshuai2" <Directory /data/web/wohaoshuai2> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai2_access_log" combined </VirtualHost>
3)、我们检查语法是否有错然后重启服务
[root@www conf.d]# httpd -t Syntax OK [root@www conf.d]# systemctl restart httpd [root@www conf.d]# netstat -anpt|grep 80 tcp6 0 0 :::8080 :::* LISTEN 12504/httpd tcp6 0 0 :::80 :::* LISTEN 12504/httpd
4)、我们访问时要记得先添加相应的域名解析,如果我们通过ip访问的话他会默认自上而下找第一个,只有通过不同的域名访问才会访问到对应的虚拟主机
[root@www /]# cat /etc/hosts |grep "192.168.10.13" 192.168.10.13 node1.wohaoshuai.com 192.168.10.13 www.wohaoshuai1.com 192.168.10.13 www.wohaoshuai2.com
[root@www /]# curl 192.168.10.13 wohaoshuai1.com [root@www /]# curl 192.168.10.13 wohaoshuai1.com [root@www /]# curl www.wohaoshuai1.com wohaoshuai1.com [root@www /]# curl www.wohaoshuai2.com wohaoshuai2.com
4、status页面,即当前网站的详细状态
LoadModule status_module modules/mod_status.so
[root@www /]# httpd -M|grep status status_module (shared)
a、httpd-2.2
<Location /server-status>
SetHandler server-status #打开httpd内建的一个处理器
Order all,deny
Allow from 192.168.10
</Location>
b、httpd-2.4。我们Location中也可以做认证
<Location /server-status>
SetHandler server-status
<RequireAll>
Require ip 192.168.10 #我们一般不用Require all granted,只开放某个网段来访问
</RequireAll>
</Location>
c、示例
(1)、我们接着上面的示例来编辑wohaoshuai1.conf
[root@www /]# cat /etc/httpd/conf.d/wohaoshuai1.conf <VirtualHost *:80> ServerName www.wohaoshuai1.com DocumentRoot "/data/web/wohaoshuai1" <Directory /data/web/wohaoshuai1> Options None AllowOverride None Require all granted </Directory> CustomLog "logs/wohaoshuai1_access_log" combined <Location /server-status> SetHandler server-status <RequireAll> Require ip 192.168.10 </RequireAll> </Location> </VirtualHost> [root@www /]# httpd -t Syntax OK [root@www /]# systemctl restart httpd
(2)、然后我们来访问我们的status