也谈rsync

目前工作的公司上线是通过rsync来同步代码的,前公司则是用ftp发布代码到预发布环境然后再用rsync实时同步到线上环境,今天就来看下rsync这个强大的工具

what’s rsync

rsync(remote synchronization)是*nix下一款同步软件,用于远程同步,备份文件,当然也可以本地做同步备份操作。

rsync 可以在中断之后恢复传输;它只传输源文件和目标文件之间不一致的部分;rsync 可以执行完整备份或增量备份。更棒的是,在所有风格的 UNIX 上都可以使用 rsync,包括 Mac OS X,所以很容易连接任何系统。

how to use rsync

shell模式(本地模式)

先来看下目录结构

[root@localhost tmp]# tree -L 2
.
├── rsync1
│   ├── 1.txt
│   ├── a.txt
│   ├── c.txt
│   └── v.txt
├── rsync2
│   └── 1.txt

要将rsync1中的内容完全同步到rsync2中

[root@localhost tmp]# rsync -avz rsync1/ rsync2
sending incremental file list
./
a.txt
c.txt
v.txt

sent 189 bytes  received 72 bytes  522.00 bytes/sec
total size is 0  speedup is 0.00

远程shell模式

[root@localhost tmp]# rsync -avz rsync1/ root@192.168.22.81:/tmp
root@192.168.22.81's password: 
sending incremental file list
./
1.txt
a.txt
c.txt
v.txt

sent 225 bytes  received 91 bytes  9.16 bytes/sec
total size is 0  speedup is 0.00

列表模式

[root@localhost tmp]# rsync rsync1/
drwxr-xr-x        4096 2014/02/20 13:42:21 .
-rw-r--r--           0 2014/02/18 16:41:47 1.txt
-rw-r--r--           0 2014/02/20 13:42:21 a.txt
-rw-r--r--           0 2014/02/20 13:42:21 c.txt
-rw-r--r--           0 2014/02/20 13:42:21 v.txt

这个和ll命令是一样的

服务器模式

在rsyncd下有下列rsync服务的配置

[root@localhost rsyncd]# pwd && ll
/etc/rsyncd
total 12
-rw-r--r-- 1 root root 808 Feb 19 16:21 rsyncd.conf
-rw-r--r-- 1 root root  36 Feb 19 15:10 rsyncd.motd
-rw------- 1 root root  12 Feb 19 15:10 rsyncd.secrets

rsyncd.conf是主要配置文件,

pid file = /var/run/rsyncd.pid  
port = 873
#address = *
uid = root  
gid = root  
use chroot = yes
read only = yes

#limit access to private LANs
hosts allow=*
#hosts deny=*

max connections = 5
motd file = /etc/rsyncd/rsyncd.motd

#This will give you a separate log file
log file = /var/log/rsync.log

#This will log every file transferred - up to 85,000+ per user, per sync
#transfer logging = yes

log format = %t %a %m %f %b
syslog facility = local3
timeout = 300

[root_tmpTrans]  
path = /tmp/rsnctrans
list=yes
ignore errors
auth users = root
secrets file = /etc/rsyncd/rsyncd.secrets
comment = balabala
exclude =   .git/ .svn/

rsyncd.secrets是执行同步、备份的账号,格式为user:password

root:123456

rsyncd.motd是执行时的欢迎信息(message of the day)

hi---------------------------------

现在我们启动rsync服务

rsync --daemon --config=/etc/rsyncd.conf

现在从另一台机器上看这个守护进程

root@ubuntu:/tmp# rsync 192.168.22.81::
hi---------------------------------

root_tmpTrans   balabala

指定模板名称

root@ubuntu:/tmp# rsync 192.168.22.81::root_tmpTrans
hi---------------------------------

Password: 
drwxr-xr-x        4096 2014/02/19 16:43:38 .
-rw-r--r--           0 2014/02/19 15:13:19 a.txt
-rw-r--r--           0 2014/02/19 16:43:38 c.txt
-rw-r--r--           0 2014/02/19 16:37:40 v.txt

注意上面两个例子,访问服务器模式的时候,有两个冒号
此时,直接利用rsync服务器模式,来备份,同步文件,和前面的模式类似

联系上crontab,写好需要的shell脚本,将备份和同步自动话,定时执行,这样就可以应用到更多的场景中。

题外话:1.这篇文章已经在草稿箱躺了2个月了,OMG.2.今天装了markdown插件,第一次用markdown写wordpress,有些地方不是很好用.3.最近心情不好,状态极差.

sed的模式空间和暂存空间

关于sed(stream editor):

————sed是一个批处理(非交互式)编辑器。它可以变换来自文件或者标准输入的输入流。它常被用作管道中的过滤器。由于sed仅仅对其输入扫描一次,因此它比其他交互式编辑器(如ed)更高效。大多数linux发行版都提供了GNU sed,Mac OS X提供了BSD sed。『A Practical Guide to Linux Commands, Editors, and Shell Programming, chapter 13』

sed和awk一样,都是经典的linux神器,网上有大量相关教程,比如很不错的左耳朵耗子博客。今天想记录下之前并没有理解透的暂存空间和模式空间相关的操作(感觉自己智商一直在下降- -)。

模式空间[pattern space]是一个缓冲区,该缓冲区最初保存sed刚刚从输入中读取的行。在将数据放入暂存空间之前,他的内容为空。

暂存空间[hold space]也是一个缓冲区,该缓冲区可以在操作模式空间中的数据时用来暂存数据。

几个命令:

g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容

看这样一个文件

aladdin@ubuntu:~/tmp$ cat sedtext 
line one
line two
line three

我们看这样一条命令

aladdin@ubuntu:~/tmp$ sed '2,$G;h;$!d' sedtext 
line three
line two
line one

我们来分析一下:

首先,这边sed对sedtext有3个命令的操作

2,$G:从第二行到最后一行执行G命令

h:执行h命令

$!d:删除除了最后一行的所有行

然后看其中具体操作

第一步,sed扫描到第一行,直接执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间中是line one,暂存空间中是line one,然后执行第三个命令,删除了模式空间中的第一行,此时模式空间中为空,暂存空间中为line one,

第二步,sed扫描到了第二行,会执行第一个命令G了,此时模式空间中是line two,暂存空间中是line one,G将换行符和暂存空间内容追加到模式空间中,此时模式空间是line two\nline one,暂存空间是line one,然后执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间不变,暂存空间为line two\nline one,执行第三个命令之后,模式空间为空,暂存空间为line two\nline one

第三步,sed扫描到第三行,会执行第一个命令G,模式空间为line three,暂存空间是line two\nline one,执行之后模式空间是line three\nline two\nline one,暂存空间是line two\nline one,然后h命令,模式空间不变,暂存空间line three\nline two\nline one然后不执行第三条命令,ok,结束,打印的就是最后模式空间爱你中的内容line three\nline two\nline one

我们可以看下sed '1!G;h;$!d' sedtext也可达到同样效果。

如何用linux神器AWK查询开房记录

前一段时间火热的2000w开房记录,加菲同学给了我一份,话说当初拿到文件的时候,我二话没说,写了一个php脚本,在windows下往mysql插,不曾想,插了1w余条便502而死。而后又改进脚本,在cli模式下,开了11个窗口,跑了十几分钟的样子终于都入了mysql,但是在未建索引的情况下,搜索varchar类型的字段,每次搜索都超过2分钟。如此低效,令人发指。正好近期学习完awk章节,期间拿记录文件来测试,效率极高,今日总结此文,权当巩固知识之用了,如若看官能从此文习得一招两式,荣幸之至。

关于AWK,介绍如下:

AWK的作者(Alfred V.Aho && Peter J.Weinberger && Brain W.Kernighan),他是一种模式扫描与处理语言,搜索一个或者多个文件,以查看这些文件中是否存在匹配指定模式的记录(通常是文本行)。每次发现匹配的记录时,它通过执行动作的方式(比如将该记录写到标准输出或者将某个计数器递增)来处理文本行。与过程语言相反,AWK属于数据驱动语言:用户描述想要处理的数据并告诉AWK当它发现这些数据时如何处理他们。

我手里拿到的是一份2000w开放记录的csv文件压缩包(对于其完整性不要太抱期望),因为此次泄漏的记录本身只是部分时间段的部分文件而已。文件列表如下

-rw-------  1 aladdin aladdin 303M Jun 27 21:23 1000W-1200W.csv
-rw-------  1 aladdin aladdin 294M Jun 27 21:30 1200W-1400W.csv
-rw-------  1 aladdin aladdin 333M Jun 27 20:24 1-200W.csv
-rw-------  1 aladdin aladdin 306M Jun 27 21:43 1400W-1600W.csv
-rw-------  1 aladdin aladdin 296M Jun 27 22:07 1600w-1800w.csv
-rw-------  1 aladdin aladdin 285M Jun 27 22:20 1800w-2000w.csv
-rw-------  1 aladdin aladdin 297M Jun 27 20:32 200W-400W.csv
-rw-------  1 aladdin aladdin 297M Jun 27 20:49 400W-600W.csv
-rw-------  1 aladdin aladdin 295M Jun 27 21:02 600W-800W.csv
-rw-------  1 aladdin aladdin 297M Jun 27 21:15 800W-1000W.csv
-rw-------  1 aladdin aladdin 7.2M Jun 27 22:25 last5000.csv

如果你迫不及待想用你的姓名,生日,身份证号等等信息查询你是否在记录中,一条语句便可

awk '/王X/ && /靖江/' 1000W-1200W.csv 1200W-1400W.csv 1-200W.csv 1400W-1600W.csv 1600w-1800w.csv 1800w-2000w.csv 200W-400W.csv 400W-600W.csv 600W-800W.csv 800W-1000W.csv last5000.csv

这语句很易懂,就是在这些数据文件中将匹配模式  ‘/王X/ && /靖江/’  的记录打印出来,我们先来看结果,10秒多的时间,搜寻近3G的文件内容之后,cpu和内存占用没有明显的数据变化,结果已然如列:

王X,,,ID,321XXXXXXXXXXX5028,F,19xxxxxx,江苏省靖江市XXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2012-12-29 17:50:49,13773207
王X,,,ID,321XXXXXXXXXXX5218,M,19xxxxxx,江苏省靖江市XXXXXXXXXXXX,,F,,CHN,32,321282,,,,,,,,,,汉,,,,,,,0,2012-6-6 13:52:38,14885090
王X,,,ID,321XXXXXXXXXXX043X,M,19xxxxxx,江苏省靖江市XXXXXXXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2011-1-19 3:05:42,5593856
王X,,,ID,321XXXXXXXXXXX1817,M,19xxxxxx,江苏省靖江市XXXXXXXXXX,,F,,CHN,32,320105,,,,,,,***********,,,汉,,,,,,,0,2011-6-12 13:52:38,8115281
王X,,,ID,320XXXXXXXXXXXX92X,F,19xxxxxx,江苏省靖江市XXXXXXXXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2011-9-14 7:21:50,9908197

姓名,身份证号,性别,生日,户口住址,开房时间……一目了然,我们来分析下这个语句

awk '/pattern/' file-lists  # 这里的pattern支持与/或等各种逻辑,斜杠表示:这里是个正则表达式

其实这里是有个缺省动作{print}的,打印(即复制到标准输出)匹配出的记录,原理了然。

 

为方便实验,我们下面拷贝下last5000.csv这个文件,用拷贝的文件来做实验。假定拷贝的文件是test.csv.用下面这个命令

awk '{print}' test.csv | less

大概看下文件,列一下字段名,内容截屏就不放了

Name,CardNo,Descriot,CtfTp,CtfId,Gender,Birthday,Address,Zip,Dirty,District1,District2,District3,District4,District5,District6,FirstNm,LastNm,Duty,Mobile,Tel,Fax,EMail,Nation,Taste,Education,Company,CTel,CAddress,CZip,Family,Version,id

将文件中的字段分割符用制表符代替,生成tmp.csv文件

sed 's/,/\t_/g' test.csv > tmp.csv

通过awk得到我们需要的字段,存到dealed.csv文件中

awk '{print $1,$5,$6,$7,$8,$32}' > dealed.csv

好的,现在有了处理好的文件dealed.csv,那么我们来把玩一番

先来看下男女比例

 awk '$3 ~ /_M/' dealed.csv | wc && awk '$3 ~ /_F/' dealed.csv | wc

输出

31179  187081 2792791
16085   96513 1455873

我们看到,是31179:16085,没有性别的忽略了,仅最小的这个文件来看,男比女大概是2:1的样子,额,说明了什么问题?看官自己发挥想象力吧

再来看看年份情况

awk '$4 ~ /^(_196)/' dealed.csv | wc && awk '$4 ~ /^(_197)/' dealed.csv | wc && awk '$4 ~ /^(_198)/' dealed.csv | wc && awk '$4 ~ /^(_199)/' dealed.csv | wc

输出

4885   29310  447630
9706   58239  884200
20533  123201 1831734
8100   48601  784771

明显看出80后占据开房主力地位!

再来看各年龄层女性占比

awk '$4 ~ /^(_196)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_197)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_198)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_199)/ && $3 ~ /_F/' dealed.csv | wc

输出

   1359    8154  122638
   2922   17533  259771
   7124   42746  634798
   3736   22416  360216

擦,90后女生比例明显高了。

ok,这边先这样。

 

来看看awk 带有-f选项的用法,又能对开放记录做什么手术呢?

引入文件ald

{
if ($4 ~ /^(_199)/ && $3 ~ /_F/) $1 = "阿拉丁和"$1"开房了,今天是"$6
if ($1 ~ /阿拉丁/) print
}

然后awk -f之

awk -f ald dealed.csv | less

xx

我靠,楼主一下子和n个90后妹纸开房了,开个玩笑~

楼主表示,不会泄漏任何信息,也别向楼主提出任何查询请求,本文仅用于技术探讨,over。

 

Nginx,CodeIgniter,PATH_INFO

1.什么是PATH_INFO?

PATH_INFO是一个CGI 1.1的标准,经常用来做为传参载体.

例如www.coderaladdin.com/test.php,并且test.php这个文件存在.当服务器接收这样的请求www.coderaladdin.com/test.php/path/info,那么PATH_INFO的值就是/path/info.

2.Nginx中的PATH_INFO

ngxin中默认配置中式没有PATH_INFO的设置的,在默认配置下,接收到如上请求是则会报404,那么如何解决这个问题呢,网上有多种方法可以参考,nginx官方的方法是通过fastcgi_split_path_info 来配置PATH_INFO

fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

默认配置中的

location ~ .php$ {
    ……
}

要记得改成

location ~ .php {
    ……
}

3.CodeIgniter中的路由原理

具体路由原理不详述,只说在lnmp中CI能够正常使用rewrite的方法有二

  1. 如上所述,配置nginx支持PATH_INFO
  2. 在CI中修改/application/config/config.php,将
    $config['uri_protocol']	= 'AUTO';

    修改为

    $config['uri_protocol']	= 'REQUEST_URI';

     

nginx php 502 bad gateway

今天配centos6.3+nginx+php5.4.15(fpm),蛋碎了无数次,其中一个问题就是配PMA的时候,访问phpMyAdmin时,出现下面错误。

phpMyAdmin – Error

Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.第一次打开提示,刷新提示:

502 bad gateway

查看nginx error log:

[error]  recv() failed (104: Connection reset by peer) while reading response header from upstream, client:, server: , request: “GET / HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “mysql.veryi.com”

查看php session.save_path的设置,默认是/var/lib/php/session。修改该目录nginx进程的用户有读写权限。问题解决。

参考

 

Apache虚拟主机中NameVirtualHost指令

说明 为一个基于域名的虚拟主机指定一个IP地址(和端口)
语法 NameVirtualHost addr[:port]
作用域 server config
状态 核心(C)
模块 core

如果您要配置基于域名的虚拟主机,NameVirtualHost指令就是您必须的指令之一。

尽管addr参数可以使用主机名,但建议您还是使用IP地址。比如:

NameVirtualHost 111.22.33.44

使用NameVirtualHost指令,您可以指定一个基于域名的虚拟主机将使用哪个IP地址来接受请求。在一个防火墙或是其它代理接受了请求并把它转到服务器所在的另外一个IP地址上的情况下,您必须指定伺服请求的机器物理界面上的IP地址。如果您对于多个地址使用了多个基于域名的虚拟主机,您应该为每个地址使用这个指令。

注意

“主服务器”和任何其它”_default_“服务器都不会伺服发送到NameVirtualHost IP地址的请求。(除非您指定了NameVirtualHost,但没有为这个地址指定任何VirtualHost)。

另外,您还可以为您使用的基于域名的虚拟主机指定一个端口号。比如:

NameVirtualHost 111.22.33.44:8080

IPv6地址必须封装在一对方括号内,如下例所示:

NameVirtualHost [2001:db8::a00:20ff:fea7:ccea]:8080

为了接受所有界面的请求,您可以使用”*“:

NameVirtualHost *

<VirtualHost>指令的参数

请注意,<VirtualHost>指令的参数必须与NameVirtualHost指令的参数完全匹配。

NameVirtualHost 1.2.3.4
<VirtualHost 1.2.3.4>
# ...
</VirtualHost>

[来源]

ubuntu和centos下关于lamp的一些常规操作

本文中centos环境是在root账户下操作的

安装Apache, MySQL, PHP

sudo apt-get install apache2 mysql-server-5.0 php5 libapache2-mod-php5 php5-mysql ...(需要别的模块自己添加)
yum -y install httpd php mysql mysql-server php-mysql httpd-manual mod_ssl mod_perl mod_auth_mysql php-mcrypt php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc mysql-connector-odbc mysql-devel libdbi-dbd-mysql...(相关模块自己取舍,需要再加)

重启apache服务(其他服务类似)

sudo /etc/init.d/apache2 restart(或sudo service apache2 restart)
/etc/init.d/httpd restart(或 service httpd restart)

Apache相关配置

路径:

/etc/apache2/apache2.conf
/etc/httpd/conf/httpd.conf

虚拟主机配置

可以直接写到上述配置文件中,也可以单独写,我在centos中是直接写到apache主配置文件的,在ubuntu中,配置文件同路径中有两个文件夹,分别是

sites-available和sites-enabled,具体作用不言而喻(同目录中的mods-available和mods-enable文件夹也类似)

在sites-available中配好相关虚拟主机,我一般单独文件一个主机,然后运行

sudo a2ensite 虚拟主机配置文件名

然后restart或者reload apache服务都可以使配置生效。

用户和组

centos下一般是apache:apache

ubuntu下一般是www-data:www-data

mysql复合查询结果集顺序的一个问题

刚到家,@冰冻的狐狸在qq上给我留言,问这两句SQL为什么查询结果的排序不同

SELECT * FROM `pp_user_history` order by id desc;
SELECT * from (SELECT * FROM `pp_user_history` order by id desc) as hh GROUP BY hh.item_id;

我在本地用两条sql测试了下

SELECT * FROM words ORDER BY id ASC;
SELECT * FROM (SELECT * FROM `words` ORDER BY id ASC) AS hh GROUP BY hh.pinyin_s;

果然是不同的

仔细结果集发现
YJ1_21]E_LOZ6ET7`L`VRI7
通过红框圈出来的那个字段得到如下结论:

结果集排序默认按照主查询的group by字段升序排

BTW.明天年会,尼玛还有一个项目要赶着上线,哥要是不是请了将近三天假陪老娘在医院哥也搞完了啊,催个毛线!今天组里有个同事提离职了,我也和老大说了自己的想法和看法。人是需要成长的,路,也该是不断探索的,我想如果我不按照寻常路走下去,或许我是会遭受许多的挫折和磨难,但是我想也会得到更多。

在此新年之际,谢过老大一年来对我的悉心教导。谢谢!

Apache虚拟主机支持rewrite的设置

今天在用CI写东西的时候,要优化下url,结果.htaccess中rewrite无效,google了很多文章,看了很多CI中国的帖子,没一个说到虚拟主机的apche配置的,甚至社区里面的“前辈大牛”还说和apche配置无关。经过多番尝试,发现在虚拟主机中对url重写的配置需要在虚拟主机配置的前面才行,不知道我得出的这个结论是否正确,请各位访客指正。

顺便感慨下,今天也和斌哥说到的,虽然在公司里面做的产品有这么大流量,看起来是个很好的平台,但是有关服务器,有关负载均衡等方面的东西我们毫不涉及,这些都是需要我们自己平时去充实的知识。当然,写好当下自己该写好的代码是最重要的。

apache配置如下

<VirtualHost *:80>
<Directory "D:/wamp/www/CodeIgniter">
    AllowOverride All
</Directory>
ServerName loc.ci.com
DocumentRoot "D:/wamp/www/CodeIgniter"
</VirtualHost>

母亲周三又要过来这边医院检查了,希望一切都好,努力挣钱!!!

更正下,刚突然想到去看了下vps上本博客的apache virtualhost配置,发现顺序是可以不放前面的
像这样

<VirtualHost *:80>
ServerName loc.ci.com
DocumentRoot "D:/wamp/www/CodeIgniter"
<Directory "D:/wamp/www/CodeIgniter">
    AllowOverride All
</Directory>
</VirtualHost>

Directory后面的路径要写全

Apache的Order Allow,Deny 详解

Allow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等),用来控制目录和文件的访问授权。

所以,最常用的是:
Order Deny,Allow
Allow from All

注意“Deny,Allow”中间只有一个逗号,也只能有一个逗号,有空格都会出错;单词的大小写不限。上面设定的含义是先设定“先检查禁止设定,没有禁止的全部允许”,而第二句没有Deny,也就是没有禁止访问的设定,直接就是允许所有访问了。这个主要是用来确保或者覆盖上级目录的设置,开放所有内容的访问权。

按照上面的解释,下面的设定是无条件禁止访问:
Order Allow,Deny
Deny from All

如果要禁止部分内容的访问,其他的全部开放:
Order Deny,Allow
Deny from ip1 ip2
或者
Order Allow,Deny
Allow from all
Deny from ip1 ip2

apache会按照order决定最后使用哪一条规则,比如上面的第二种方式,虽然第二句allow允许了访问,但由于在order中allow不是最后规则,因此还需要看有没有deny规则,于是到了第三句,符合ip1和ip2的访问就被禁止了。注意,order决定的“最后”规则非常重要,下面是两个错误的例子和改正方式:

Order Deny,Allow
Allow from all
Deny from domain.org
错误:想禁止来自domain.org的访问,但是deny不是最后规则,apache在处理到第二句allow的时候就已经匹配成功,根本就不会去看第三句。
解决方法:Order Allow,Deny,后面两句不动,即可。

Order Allow,Deny
Allow from ip1
Deny from all
错误:想只允许来自ip1的访问,但是,虽然第二句中设定了allow规则,由于order中deny在后,所以会以第三句deny为准,而第三句的范围中又明显包含了ip1(all include ip1),所以所有的访问都被禁止了。
解决方法一:直接去掉第三句。
解决方法二:
Order Deny,Allow
Deny from all
Allow from ip1

 

下面是测试过的例子:
——————————–
Order deny,allow
allow from all
deny from 219.204.253.8
#全部都可以通行
——————————-
Order deny,allow
deny from 219.204.253.8
allow from all
#全部都可以通行
——————————-
Order allow,deny
deny from 219.204.253.8
allow from all
#只有219.204.253.8不能通行
——————————-
Order allow,deny
allow from all
deny from 219.204.253.8
#只有219.204.253.8不能通行
——————————-
——————————-
Order allow,deny
deny from all
allow from 219.204.253.8
#全部都不能通行
——————————-
Order allow,deny
allow from 219.204.253.8
deny from all
#全部都不能通行
——————————-
Order deny,allow
allow from 219.204.253.8
deny from all
#只允许219.204.253.8通行
——————————-
Order deny,allow
deny from all
allow from 219.204.253.8
#只允许219.204.253.8通行
——————————-
——————————–
Order deny,allow
#全部都可以通行(默认的)
——————————-
Order allow,deny
#全部都不能通行(默认的)
——————————-
Order allow,deny
deny from all
#全部都不能通行
——————————-
Order deny,allow
deny from all
#全部都不能通行
——————————-
对于上面两种情况,如果换成allow from all,则全部都可以通行!
——————————-
Order deny,allow
deny from 219.204.253.8
#只有219.204.253.8不能通行
——————————-
Order allow,deny
deny from 219.204.253.8
#全部都不能通行
——————————-
Order allow,deny
allow from 219.204.253.8
#只允许219.204.253.8通行
——————————-
Order deny,allow
allow from 219.204.253.8
#全部都可以通行
——————————-
——————————-
order deny,allow
allow from 218.20.253.2
deny from 218.20
#代表拒绝218.20开头的IP,但允许218.20.253.2通过;而其它非218.20开头的IP也都允许通过。
——————————-
order allow,deny
allow from 218.20.253.2
deny from 218.20
#和上面的差不多,只是掉换的order语句中的allow、deny先后顺序,但最终结果表示全部都拒绝!

form:http://hi.baidu.com/enjoypain/blog/item/f48c7aecdba298d12f2e21ac.html

前段时间做了个Apache的HTTP代理服务器,其中的order allow,deny这部分弄的不太懂,于是上网找资料看,谁知道越看越糊涂,其中有些难以分辨对错甚至是误导。就像破解windows系统密码的一些文章那样,很多都是人云亦云的,并没有经过测试。废话少说,先把我经过测试后分析总结出来的结论show出来,相信这对大家的理解非常有帮助。

 

总则——

影响最终判断结果的只有两点:

1. order语句中allow、deny的先后顺序;

2. allow、deny语句中各自包含的范围。

 

温馨提醒——

1. 修改完配置后要保存好并重启Apache服务,配置才能生效;

2. 开头字母不分大小写;

3. allow、deny语句不分先后顺序,谁先谁后不影响最终判断结果;但都会被判断到;

4. order语句中,“allow,deny”之间“有且只有”一个逗号(英文格式的),而且先后顺序很重要;

5. Apache有一条缺省规则,“order allow,deny”本身就默认了拒绝所有的意思,因为deny在allow的后面;同理,“order deny,allow”本身默认的是允许所有;当然,最终判断结果还要综合下面的allow、deny语句中各自所包含的范围;(也就是说order语句后面可以没有allow、deny语句)

6. allow、deny语句中,第二个单词一定是“from”,否则Apache会因错而无法启动,

7. “order allow,deny”代表先判断allow语句再判断deny语句,反之亦然。

 

上面说的都是要记住的,而下面说的是我独创的理解方法。如果有人看了而没有豁然开朗的感觉,那算是我的失败!

 

判断原则分4步走——

1. 首先判断默认的;

2. 然后判断逗号前的;

3. 最后判断逗号后的;

4. 最终按顺序叠加而得出判断结果。

 

上面三点我说的简单而形象,主要是为了便于记忆。暂时不理解不要紧,继续看下面详细的解说自然会明白。下面以一个普通例子来做解释——

order deny,allow

allow from 218.20.253.2

deny from 218.20

1. 所谓“首先判断默认的”,就是判断“order deny,allow”这句,它默认是允许所有;

2. 所谓“然后判断逗号前的”,因为在本例子中的order语句里面,deny在逗号的前面,所以现在轮到判断下面的deny语句了——“deny from 218.20”;

3. 所谓“最后判断逗号后的”,因为在本例子中的order语句里面,allow在逗号的后面,所以最后轮到判断下面的allow语句了——“allow from 218.20.253.2”。

4. 所谓“最终按顺序叠加而得出判断结果”,这是一个形象化了的说法,我把每一步判断都看作一个“不透明的图层”,然后一步步按顺序叠加上去,最终得出的“图像”就是判断结果。

 

用过作图软件的人应该都知道“图层”是怎么回事,我估计Apache关于order allow deny这方面的设计理念和photoshop等作图软件关于图层的设计理念是一样的。即“游戏规则”是一样的。

那么上面的例子就可以是这么一个步骤和图像——

1. 先画一个白色的大圆,代表“order deny,allow”语句,默认意思是允许所有;

2. 然后画一个小一点的黑色圆,代表“deny from 218.20”语句,意思是拒绝所有以218.20开头的IP,放进白色的大圆里面;

3. 最后再画一个白色的圆,代表“allow from 218.20.253.2”语句,意思是允许218.20.253.2通过,放在黑色圆的上面。

4. 到此为止,我们已经可以看到一个结果了,白色大圆上面有一个黑色圆,黑色圆上面还有一个白色圆。最后,我们所能看到的黑色部分就是拒绝通行的,剩下的白色部分都是允许通行的。判断的结果就是这么简单形象!

 

如果不懂的用作图软件,我们再来个非常贴近生活的比喻——

把上面的例子改动一点点,以便更好的理解:

order deny,allow

allow from 218.20.253.2

deny from 219.30

1. 首先拿一张A4白纸,代表第order语句,意思是允许全部;

2. 然后拿一张黑色纸剪一个圆,放在A4纸里面的某个位置上,代表deny语句,意思是拒绝所有以219.30开头的IP;

3. 最后拿白纸再剪一个圆,放在黑色圆的旁边,代表allow语句,意思是允许218.20.253.2通过;注意,这个例子不是放进黑色圆里面了,因为deny和allow语句不再有相互包含的关系了。

4. A4纸上面有一个黑色圆和一个白色圆,结果自然很明显了。不过白色的A4纸上再放一个白色的圆,显然是多余的了,因为大家都是白色的,都代表允许,所以就重复了,可以去掉白色的圆而不会影响判断结果。

 

如果看到这里还没明白,那一定是我还有什么没说清楚的。那么请好好分析我所做过的测试例子,将在最后列出来。

在这里再啰嗦一下,allow、deny语句后面跟的参数有多种形式,有不同的表达方式,我在网上看到的做法是deny from IP1 IP2 IP3或allow from domain.com等。其它的表达方式大家再找别的资料看吧。我想说的是另一种表达方式:

order deny,allow

allow from IP1 IP2

allow from domain.info

allow from 219.20.55.0/24

deny from all

我没具体验证过这是否对,不过这样是可以正常启动Apache服务的,按道理应该是正确的表达方式。哈哈,像我这样的入门者只能这样了,还希望大家多多指教!

下面是测试过的例子:
——————————–
Order deny,allow
allow from all
deny from 219.204.253.8
#全部都可以通行
——————————-
Order deny,allow
deny from 219.204.253.8
allow from all
#全部都可以通行
——————————-
Order allow,deny
deny from 219.204.253.8
allow from all
#只有219.204.253.8不能通行
——————————-
Order allow,deny
allow from all
deny from 219.204.253.8
#只有219.204.253.8不能通行
——————————-
——————————-
Order allow,deny
deny from all
allow from 219.204.253.8
#全部都不能通行
——————————-
Order allow,deny
allow from 219.204.253.8
deny from all
#全部都不能通行
——————————-
Order deny,allow
allow from 219.204.253.8
deny from all
#只允许219.204.253.8通行
——————————-
Order deny,allow
deny from all
allow from 219.204.253.8
#只允许219.204.253.8通行
——————————-
——————————–
Order deny,allow
#全部都可以通行(默认的)
——————————-
Order allow,deny
#全部都不能通行(默认的)
——————————-
Order allow,deny
deny from all
#全部都不能通行
——————————-
Order deny,allow
deny from all
#全部都不能通行
——————————-
对于上面两种情况,如果换成allow from all,则全部都可以通行!
——————————-
Order deny,allow
deny from 219.204.253.8
#只有219.204.253.8不能通行
——————————-
Order allow,deny
deny from 219.204.253.8
#全部都不能通行
——————————-
Order allow,deny
allow from 219.204.253.8
#只允许219.204.253.8通行
——————————-
Order deny,allow
allow from 219.204.253.8
#全部都可以通行
——————————-
——————————-
order deny,allow
allow from 218.20.253.2
deny from 218.20
#代表拒绝218.20开头的IP,但允许218.20.253.2通过;而其它非218.20开头的IP也都允许通过。
——————————-
order allow,deny
allow from 218.20.253.2
deny from 218.20
#和上面的差不多,只是掉换的order语句中的allow、deny先后顺序,但最终结果表示全部都拒绝!