10. 访问控制
10.1 简介
如果网站上有些敏感信息或只希望为一个小群体所访问,您需要将服务器配置为用户只能访问被允许的资源。
10.2 使用 .htaccess 控制
这里涉及的配置方式主要是使用 .htaccess 文件 , 要使用.htaccess文件,则必须设置服务器以允许在这些文件中使用认证指令,即用AllowOverride指令指定哪些指令在针对单个目录的配置文件中有效。 首先将对应的AllowOverride这样设置:
AllowOverride All
首先,应该创建一个用于认证的密码文件,并且这个文件不应该置于DocumentRoot目录下,以避免被下载。例如可以创建/etc/apache2/passwd/目录,并将密码文件置于其下。
Apache2 为我们提供了/usr/bin/htpasswd命令用于创建密码文件,命令的具体操作方法请参阅htpasswd的手册页:http://httpd.apache.org/docs/1.3/programs/htpasswd.html 这里仅做简单的应用。
首次添加用户需要使用 ?c 参数,以创建密码文件,再次添加用户则不要 -c参数了:
# mkdir /etc/apache2/passwd
# htpasswd -c /etc/apache2/passwd/passwords tony
New password: [mypassword]
Re-type new password: [mypassword]
Adding password for user tony
# htpasswd /etc/apache2/passwd/passwords etony
New password: [mypassword]
Re-type new password: [mypassword]
Adding password for user etony
必要时,使用htpasswd 命令需要加入完整路径/usr/bin/htpasswd
修改对应.htaccess文件,加入如下内容:
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /etc/apache2/passwd/passwords
Require user tony
让我们逐个解释这些指令。
AuthType指令选择对用户实施认证的方法,最常用的是由mod_auth_basic提供的Basic 。AuthName指令设置了使用认证的域(Realm),它起两个作用,首先,此域会出现在显示给用户的密码提问对话框中,其次,也帮助客户端程序确定应该发送哪个密码。
AuthUserFile指令设置了密码文件的位置,也就是刚才我们用htpasswd建立的文件。
最后,Require指令设置了允许访问受保护区域的用户。
上述指令只允许一个人(一个叫tony的用户)访问这个目录,但是多数情况下。都需要允许多人访问,这时可以调整Require选项为:
Require valid-user
可以允许密码文件中的所有用户使用正确的密码进行访问。
可能存在的问题
由于采用了Basic认证的方法,每次向服务器请求甚至刷新一个受保护的页面或图片时都必须校验用户名和密码,为此,必须打开密码文件并逐行搜索用户名,因此,服务器响应速度会受一些影响,受影响的程度与密码文件的大小成正比。
所以,对密码文件中的用户总数存在一个实际上的上限,此上限取决于特定的服务器机器的性能,但是一般有几百个用户就会对响应速度有非常明显的影响,在这种情况下,可以考虑用其他认证方法。
10.3 使用MySQL数据库控制
基于MySQL数据库的访问控制需要使用mod-auth-mysql认证模块, 首先安装认证模块
tony@tonybox:~$sudo aptitude install libapache2-mod-auth-mysql
然后启用该模块
a2enmod auth_mysql
修改主配置文件/etc/apache2/apache2.conf
,在文件尾部加入一下内容
Auth_MySQL_Info localhost a2_user password
<Directory "/var/www/apache2-default/">
Options +Indexes FollowSymLinks MultiViews
AllowOverride AuthConfig Options FileInfo Limit
Order allow,deny
Allow from all
</Directory>
在/var/www/apache2-default/目录下创建.htaccess文件, 内容如下:
AuthMYSQL on
AuthMySQL_Authoritative on
AuthMySQL_DB auth
AuthMySQL_Password_Table clients
AuthMySQL_Group_Table clients
AuthMySQL_Empty_Passwords off
AuthMySQL_Encryption_Types Plaintext Crypt_DES
AuthBasicAuthoritative Off
AuthName "default"
AuthType Basic
<Limit GET POST>
require group tony
</Limit>
然后重启apache服务
tonybox:~# /etc/init.d/apache2 restart
在MySQL数据库中添加认证数据库
$ mysql -uroot -p
mysql> grant all on auth.* to a2_user@localhost identified by 'password';
mysql> flush privileges;
mysql> create database auth;
CREATE TABLE `clients` (
`username` varchar(25) NOT NULL default '',
`passwd` varchar(25) NOT NULL default '',
`groups` varchar(25) NOT NULL default '',
PRIMARY KEY (`username`),
KEY `groups` (`groups`)
) ENGINE=MyISAM;
INSERT INTO `clients` VALUES ('tony', '123456', 'tony');
此时,访问访问web服务器的默认站点, 您会发现,需要输入用户名(tony),密码(123456)方可登录.
10.4 其他认证方法
基于用户名和密码的认证只是方法之一,时常会有不需要知道来访者是谁,只需要知道来自哪里的情况。
Allow和Deny指令可以允许或拒绝来自特定主机名或主机地址的访问,同时,Order指令告诉Apache处理这两个指令的顺序,以改变过滤器。
这些指令的用法:
Allow from address
address可以是一个IP地址(或者IP地址的一部分),也可以是一个完整的域名(或者域名的一部分),还可以同时指定多个IP地址和域名。
比如,要拒绝不受欢迎的兜售垃圾的站点:
Deny from 205.252.46.165
这样,这个指令所管辖的区域将拒绝所有来自该地址的访问。除了指定IP地址,也可以指定域名,如:
Deny from host.example.com
另外,还可以指定地址或域名的一部分来阻止一个群体:
Deny from 192.168.2 //这是我们隔壁部门使用的网段 :)
Deny from msn.com microsoft.com //不喜欢它们
Deny from du //对面的那个家伙
Order可以组合Deny和Allow指令,以保证在允许一个群体访问的同时,对其中的一些又加以限制:
Order deny,allow
Deny from all
Allow from dev.example.com
只列出Allow指令不会得到你想要的结果,因为它在允许指定对象访问的同时并不禁止其他未列出的对象的访问。所以上例使用的方法是:首先拒绝任何人,然后允许来自特定主机的访问。