标签 nginx 下的文章

来自nginx限制并发连接数以及下载带宽

在nginx.conf里的http{}里加上如下代码:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

在需要限制并发数和下载带宽的网站配置server{}里加上如下代码:

server {
    limit_conn perip 10;
    limit_conn perserver 100;
    limit_rate 100k;
}

参数说明:

$binary_remote_addr是限制同一客户端ip地址;

$server_name是限制同一server最大并发数;

limit_conn为限制并发连接数;

limit_rate为限制下载速度;



VeryNginx的GitHub地址: https://github.com/alexazhou/VeryNginx

VeryNginx 基于 lua_nginx_module(openrestry) 开发,实现了高级的防火墙、访问统计和其他的一些功能。 强化了 Nginx 本身的功能,并提供了友好的 Web 交互界面。

VeryNginx在线演示地址: http://alexazhou.xyz/vn/index.html

用户名 / 密码: verynginx / verynginx
下面的安装教程是基于CentOS 6 64位系统进行的

安装依赖

yum install -y gcc gcc-c++ make cmake autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel libaio readline-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5-devel libidn libidn-devel openssl openssl-devel libxslt-devel libicu-devel libevent-devel libtool libtool-ltdl bison gd-devel vim-enhanced pcre-devel zip unzip ntpdate sysstat patch bc expect rsync git lsof lrzsz

进入/tmp目录

cd /tmp/

下载OpenResty

wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz

解压OpenResty

tar -xvzf ngx_openresty-1.9.7.1.tar.gz

进入OpenResty源代码目录

cd ngx_openresty-1.9.7.1

配置configure及变量信息

./configure --prefix=/usr/local/openresty --user=nginx --group=nginx --with-http_stub_status_module --with-luajit

编译安装OpenResty

gmake && gmake install

退回到/tmp目录中

cd ..

克隆VeryNginx

git clone https://github.com/alexazhou/VeryNginx.git

删除OpenResty中的nginx.conf默认配置文件

rm -rf /usr/local/openresty/nginx/conf/nginx.conf

下载VeryNginx的nginx.conf配置文件

wget https://dl.m69w.com/scripts/nginx.conf -O /usr/local/openresty/nginx/conf/nginx.conf

复制VeryNginx到OpenResty中

cp -r ~/VeryNginx/VeryNginx /usr/local/openresty/VeryNginx

修改/usr/local/openresty/目录的所有者为nginx用户

chown -R nginx:nginx /usr/local/openresty/

启动VeryNginx

/usr/local/openresty/nginx/sbin/nginx

打开浏览器访问 http://你的服务器IP/VeryNginx/index.html
默认用户名和密码是 verynginx / verynginx
登录之后就可以查看状态,并对配置进行修改了。修改配置后,记得到 「Config > System > All Configuration」去保存.
如果需要详细的配置说明,请查看 VeryNginx Wiki

相关:
https://github.com/jgmdev/ddos-deflate说明
Linux被DDOS&CC攻击解决实例
通过nginx配置文件抵御攻击
防CC的收集以及实现基于js的CC攻击


2016-03-25 00:00更

好吧,有时候想不出名都不容易
在后台看到python-requestsCPython竟然还有UA为空的爬虫,哥们,不带这么玩的
看了一下浏览器User-Agent大全,您就不能随便模仿一个UA来爬吗

2015-11-22 22:36

看了下日记
好多爬虫,个人小站
爬什么爬!有什么好爬的

不要流量不要出名!!!

果断ban之:在域名.confserver设置为

server {
server_tokens off; # 不透露 nginx 的版本
#禁止指定UA及UA为空的访问
if ($http_user_agent ~ "WinHttp|WebZIP|FetchURL|node-superagent|java|Jullo|Apache-HttpAsyncClient|UniversalFeedParser|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|HaosouSpider|AhrefsBot|MQQBrowser|Mobile Safari|bingbot|Digincore bot|Python-urllib|python-requests|CPython|micromessenger|YandexBot|meanpathbot|360Spider|YisouSpider|qihoobot|Baiduspider|UptimeRobot|Twitterbot|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|linkdexbot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|MSIE 6.0|Tomato Bot|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|^$" )
        { 
        return 403; 
        }
#禁止Scrapy等工具的抓取
if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) {
     return 403;
}
#禁止非GET|HEAD|POST方式的抓取
if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 403;
}
    ssl on;
...

重启nginx:service nginx restart
在ssh下测试:curl -I -A "YisouSpider" https://m69w.com
返回403则生效,看到没googlebot不止一个IP,禁IP段还要手动添加!!!

66.249.67.173 - - [23/Nov/2015:11:51:11 +0800] "GET /21.html HTTP/1.1" 403 162 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;
+http://www.google.com/bot.html)"
66.249.67.164 - - [23/Nov/2015:12:47:09 +0800] "GET /reprint/2/ HTTP/1.1" 403 162 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;
+http://www.google.com/bot.html)"

屏蔽360、scanv、QQ管家等IP扫描

这个方法需要开启 iptables ,把下面的IP段加入到 iptables 中。
如果没有启动可以联系联系服务商帮忙开启。独立的服务器和云主机可以自行安装启动。

vi banip.sh

#!/bin/bash
echo "banip"
iptables -A INPUT -s 221.204.203.0/24 -j DROP
iptables -A INPUT -s 183.136.133.0/24 -j DROP
iptables -A INPUT -s 183.60.211.0/24 -j DROP
iptables -A INPUT -s 220.181.55.0/24 -j DROP
iptables -A INPUT -s 101.226.4.0/24 -j DROP
iptables -A INPUT -s 140.207.197.0/24 -j DROP
iptables -A INPUT -s 220.170.91.0/24 -j DROP
iptables -A INPUT -s 171.8.167.0/24 -j DROP
iptables -A INPUT -s 180.153.235.0/24 -j DROP
iptables -A INPUT -s 122.143.15.0/24 -j DROP
iptables -A INPUT -s 27.221.20.0/24 -j DROP
iptables -A INPUT -s 222.186.189.0/24 -j DROP
iptables -A INPUT -s 202.102.85.0/24 -j DROP
iptables -A INPUT -s 61.160.224.0/24 -j DROP
iptables -A INPUT -s 112.25.60.0/24 -j DROP
iptables -A INPUT -s 182.140.227.0/24 -j DROP
iptables -A INPUT -s 221.204.14.0/24 -j DROP
iptables -I INPUT -s 123.151.39.0/24 -j DROP
iptables -I INPUT -s 182.140.168.0/24 -j DROP
iptables -I INPUT -s 219.153.15.0/24 -j DROP
iptables -I INPUT -s 220.181.158.0/24 -j DROP
iptables -I INPUT -s 111.161.51.0/24 -j DROP
iptables -I INPUT -s 123.125.160.0/24 -j DROP
service iptables save
echo "ok"

chmod +x banip.sh && ./banip.sh

nginx下添加禁止访问IP列表,屏蔽soso蜘蛛

新建 /usr/local/nginx/conf/blockips.conf 需要屏蔽的ip列表文件

vi /usr/local/nginx/conf/blockips.conf

加入以下代码:

#屏蔽soso蜘蛛IP
deny 113.108.12.154;    #此为搜搜蜘蛛IP
deny 124.115.0.0/24;    #此为屏蔽搜搜蜘蛛124.115.0.1 ~ 124.115.0.255整个网段IP
deny 124.115.4.0/24;    #此为屏蔽搜搜蜘蛛124.115.4.1 ~ 124.115.4.255整个网段IP

单独网站屏闭IP的方法:

在server"{}",在这个大括号内加入deny IP地址是限制某IP地址访问;allow IP地址是只允许某IP地址访问;
#屏蔽单个IP的命令是
deny 123.45.6.7
#封整个段即从123.0.0.1到123.255.255.254的命令
deny 123.0.0.0/8
#封IP段即从123.45.0.1到123.45.255.254的命令
deny 124.45.0.0/16
#封IP段即从123.45.6.1到123.45.6.254的命令是
deny 123.45.6.0/24

屏蔽整个网段的IP时有可能会造成错杀,不过几率很低。
继续,将blockips.conf 加入到nginx配置中

vi /usr/local/nginx/conf/nginx.conf

在http中加入代码

http {
    #载入禁止访问的IP配置
    include blockips.conf;    #处理好相对目录问题

    ...(以下省略)

相关百度搜索引擎蜘蛛所有ip作用的分析详解

http://help.baidu.com/webmaster/add#1







转自:LNMP防止图片盗链的方法
今天再介绍下如何lnmp架构下防止图片被其他网站盗链。

首先要检查/etc/nginx/nginx.conf或/etc/nginx/conf.d/example.com.conf有没有如下代码:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ 
{ 
expires 30d; 
}

如果有的话把这段话删除,没有的话更好。

然后在/etc/nginx/conf.d/example.com.conf里添加如下防盗链代码:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ 
{ 
valid_referers none blocked *.example.com *.youdao.com *.zhuaxia.com *.xianguo.com *.google.cn *.google.com *.google.com.tw *.google.com.sg *.google.com.hk *.bloglines.com image.soso.com cn.bing.com image.baidu.com *.feedburner.com *.feedsky.com; 
if ($invalid_referer) { 
rewrite ^/ http://www.tennfy.com/404.png; 
#return 404; 
} 
expires 30d; 
}

解释下以上代码:
第一行gif|jpg|jpeg|png……这些是您需要防止盗链的文件类型,您可以补充一些后缀类型;

第三行是你的网站的域名,就是说放行的域名,如果有多个,请添加,注意空格;

第五行是给盗链看到的图片,返回一个404.jpg,这个图片源地址是要可以外链的哦,不然,别人看到的也就一个XX。

保存文件,重启lnmp:

/etc/init.d/nginx restart

Nginx中rewrite规则是很多人头痛的问题,最近tennfy就被codeigniter在nginx中的伪静态问题折磨了挺长时间。因此,tennfy在这篇文章介绍下nginx rewrite基础教程。

Nginx rewrite基本语法

Nginx的rewrite语法其实很简单.主要用到如下指令

set
if
return
break
rewrite

下面来挨个介绍下这几个命令。

1.set

set主要是用来设置变量。

2.if

if主要用来判断一些在rewrite语句中无法直接匹配的条件,比如检测文件存在与否,http header,cookie等。

其用法为:

用法:if(条件) {…}
 
- 当if表达式中的条件为true,则执行if块中的语句
 
- 当表达式只是一个变量时,如果值为空或者任何以0开头的字符串都会当作false
 
- 直接比较内容时,使用 = 和 !=
 
- 使用正则表达式匹配时,使用
 
      ~ 大小写敏感匹配 
      ~* 大小写不敏感匹配 
      !~ 大小写敏感不匹配 
      !~* 大小写不敏感不匹配 
 
- 使用-f,-d,-e,-x检测文件和目录
 
      -f 检测文件存在
      -d 检测目录存在
      -e 检测文件,目录或者符号链接存在
      -x 检测文件可执行

举例分析一下:

if ($http_user_agent ~ MSIE) {
  rewrite  ^(.*)$  /msie/$1  break;
}

如果UA包含”MSIE”,rewrite 请求到/msie目录下

if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
  set  $id  $1;
}

如果cookie匹配正则,设置变量$id等于正则引用部分

if ($request_method = POST ) {
  return 405;
}

如果提交方法为POST,则返回状态405 (Method not allowed)

if (!-f $request_filename) {
  break;
  proxy_pass  http://127.0.0.1;
}

如果请求文件名不存在,则反向代理localhost

if ($args ~ post=140){
  rewrite ^ http://example.com/ permanent;
}

如果query string中包含”post=140″,永久重定向到example.com

3.return

return可用来直接设置HTTP返回状态,比如403,404等(301,302不可用return返回,这个下面会在rewrite提到)。

4.break

立即停止rewrite检测,跟下面讲到的rewrite的break flag功能是一样的,区别在于前者是一个语句,后者是rewrite语句的flag

5.rewrite

这是最为重要的知识点

用法: rewrite 正则 替换 标志位
 
其中标志位有四种
 
break – 停止rewrite检测,也就是说当含有break flag的rewrite语句被执行时,该语句就是rewrite的最终结果
last – 停止rewrite检测,但是跟break有本质的不同,last的语句不一定是最终结果,这点后面会跟nginx的location匹配一起提到
redirect – 返回302临时重定向,一般用于重定向到完整的URL(包含http:部分)
permanent – 返回301永久重定向,一般用于重定向到完整的URL(包含http:部分)

因为301和302不能简单的只单纯返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。作为替换,rewrite可以更灵活的使用redirect和permanent标志实现301和302。

举例说明:

rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;

如果请求为 /download/eva/media/op1.mp3,则请求被rewrite到 /download/eva/mp3/op1.mp3。

rewrite在使用中还有很多值得注意的地方:

  • rewrite的生效区块为sever, location, if
  • rewrite只对相对路径进行匹配,不包含hostname
  • 使用相对路径rewrite时,会根据HTTP header中的HOST跟nginx的server_name匹配后进行rewrite,如果HOST不匹配或者没有HOST信息的话则rewrite到server_name设置的第一个域名,如果没有设置server_name的话,会使用本机的localhost进行rewrite
  • 前面提到过,rewrite的正则是不匹配query string的,所以默认情况下,query string是自动追加到rewrite后的地址上的,如果不想自动追加query string,则在rewrite地址的末尾添加?

    rewrite ^/users/(.*)$ /show?user=$1? last;

Nginx location 和 rewrite retry

nginx的rewrite有个很奇特的特性 — rewrite后的url会再次进行rewrite检查,最多重试10次,10次后还没有终止的话就会返回HTTP 500。

1、location基础

用过nginx的朋友都知道location区块,location区块有点像Apache中的RewriteBase,但对于nginx来说location是控制的级别而已,里面的内容不仅仅是rewrite。location是nginx用来处理对同一个server不同的请求地址使用独立的配置的方式。

举例说明:

location  = / {
  ....配置A
}
 
location  / {
  ....配置B
}
 
location ^~ /images/ {
  ....配置C
}
 
location ~* \.(gif|jpg|jpeg)$ {
  ....配置D
}

访问 / 会使用配置A
访问 /documents/document.html 会使用配置B
访问 /images/1.gif 会使用配置C
访问 /documents/1.jpg 会使用配置D

现在我们只需要明白一个情况: nginx可以有多个location并使用不同的配置。

2、location匹配命中规则

server区块中如果有包含rewrite规则,则会最先执行,而且只会执行一次, 然后再判断命中哪个location的配置,再去执行该location中的rewrite, 当该location中的rewrite执行完毕时,rewrite并不会停止,而是根据rewrite过的URL再次判断location并执行其中的配置。

location并非像rewrite那样逐条执行,而是有着匹配优先级的,当一条请求同时满足几个location的匹配时,其只会选择其一的配置执行.

其寻找的方法为:

1. 首先寻找所有的常量匹配,如location /, location /av/, 以相对路径自左向右匹配,匹配长度
   最高的会被使用

2. 然后按照配置文件中出现的顺序依次测试正则表达式,如 
   location ~ download\/$, location ~* \.wtf, 第一个匹配会被使用 

3. 如果没有匹配的正则,则使用之前的常量匹配

而下面几种方法当匹配时会立即终止其他location的尝试

1. = 完全匹配,location = /download/ 

2. ^~ 终止正则测试,如location ^~ /download/ 如果这条是最长匹配,则终止正则测试,这个符号
   只能匹配常量 

3. 在没有=或者^~的情况下,如果常量完全匹配,也会立即终止测试,比如请求为 /download/ 会完全
   命中
   location /download/而不继续其他的正则测试

总结:

1. 如果完全匹配(不管有没有=),尝试会立即终止

2. 以最长匹配测试各个常量,如果常量匹配并有 ^~, 尝试会终止
 
3. 按在配置文件中出现的顺序测试各个正则表达式 

4. 如果第3步有命中,则使用其匹配location,否则使用第2步的location

另外还可以定义一种特殊的named location,以@开头,如location @thisissparta 不过这种location定义不用于一般的处理,而是专门用于try_file, error_page的处理,这里不再深入.

举例说明:

location  = / {
  ....配置A
}
 
location  / {
  ....配置B
}
 
location ^~ /images/ {
  ....配置C
}
 
location ~* \.(gif|jpg|jpeg)$ {
  ....配置D
}

访问 / 会使用配置A -> 完全命中
访问 /documents/document.html 会使用配置B -> 匹配常量B,不匹配正则C和D,所以用B
访问 /images/1.gif 会使用配置C -> 匹配常量B,匹配正则C,使用首个命中的正则,所以用C
访问 /documents/1.jpg 会使用配置D -> 匹配常量B,不匹配正则C,匹配正则D,使用首个命中的正则,所以用D

3、rewrite retry

这里就存在一个问题,如果rewrite写的不正确的话,是会在location区块间造成无限循环的.所以nginx才会加一个最多重试10次的上限. 比如这个例子

location /download/ {
  rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;
}

如果请求为 /download/eva/media/op1.mp3 则请求被rewrite到 /download/eva/mp3/op1.mp3

结果rewrite的结果重新命中了location /download/ 虽然这次并没有命中rewrite规则的正则表达式,但因为缺少终止rewrite的标志,其仍会不停重试download中rewrite规则直到达到10次上限返回HTTP 500。

这里需要介绍一下last标志位与break标志位的区别。

  • break是终止当前location的rewrite检测,而且不再进行location匹配
    – last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则

举例说明:

location /download/ {
  rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  ;
  rewrite  ^(/download/.*)/movie/(.*)\..*$  $1/avi/$2.mp3  ;
  rewrite  ^(/download/.*)/avvvv/(.*)\..*$  $1/rmvb/$2.mp3 ;
}

如果请求为 /download/acg/moive/UBW.avi

last的情况是: 在第2行rewrite处终止,并重试location /download..死循环
break的情况是: 在第2行rewrite处终止,其结果为最终的rewrite地址。

虽然如此,但是很多情况下还是需要使用last。典型的例子就是wordpress的permalink rewrite。

常见的情况下, wordpress的rewrite是放在location /下面,并将请求rewrite到/index.php

这时如果这里使用break就会出现问题,因为nginx返回的是没有解释的index.php的源码。

这里一定要使用last才可以在结束location / 的rewrite, 并再次命中location ~ .php$,将其交给fastcgi进行解释.其后返回给浏览器的才是解释过的html代码。

WordPress的Permalink+Supercache rewrite实现

这个rewrite写法其实是来自supercache作者本家的某个评论中,网上很容易查到,做了一些修改. 先给出该配置文件的全部内容..部分内容码掉了..绝对路径什么的你知道也没啥用对吧?

server {
    listen   80;
    server_name  cafeneko.info www.cafeneko.info;
 
    access_log  ***;
    error_log   *** ;
 
    root   ***;
    index  index.php;
 
    gzip_static on;
 
    if (-f $request_filename) {
        break;
    }
 
    set $supercache_file '';
    set $supercache_uri $request_uri;
 
    if ($request_method = POST) {
        set $supercache_uri '';
    }
 
    if ($query_string) {
        set $supercache_uri '';
    }
 
    if ($http_cookie ~* "comment_author_|wordpress_logged_|wp-postpass_" ) {
        set $supercache_uri '';
    }
 
    if ($supercache_uri ~ ^(.+)$) {
        set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
    }
 
    if (-f $document_root$supercache_file) {
        rewrite ^(.*)$ $supercache_file break;
    }
 
    if (!-e $request_filename) {
        rewrite . /index.php last;
    }
 
    location ~ \.php$ {
 
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  ***$fastcgi_script_name;
        include        fastcgi_params;
    }
 
    location ~ /\.ht {
        deny  all;
    }
}

下面是解释:

gzip_static on;

如果浏览器支持gzip,则在压缩前先寻找是否存在压缩好的同名gz文件避免再次压缩浪费资源,配合supercache的压缩功能一起使用效果最好,相比supercache原生的Apache mod_rewrite实现,nginx的实现简单的多. Apache mod_rewrite足足用了两套看起来一模一样的条件判断来分别rewrite支持gzip压缩和不支持的情况.

if (-f $request_filename) {
    break;
}

如果是直接请求某个真实存在的文件,则用break语句停止rewrite检查

set $supercache_file '';
set $supercache_uri $request_uri;

用$request_uri初始化变量 $supercache_uri.

if ($request_method = POST) {
    set $supercache_uri '';
}

如果请求方式为POST,则不使用supercache.这里用清空$supercache_uri的方法来跳过检测,下面会看到

if ($query_string) {
    set $supercache_uri '';
}

因为使用了rewrite的原因,正常情况下不应该有query_string(一般只有后台才会出现query string),有的话则不使用supercache

if ($http_cookie ~* "comment_author_|wordpress_logged_|wp-postpass_" ) {
    set $supercache_uri '';
}

默认情况下,supercache是仅对unknown user使用的.其他诸如登录用户或者评论过的用户则不使用.

comment_author是测试评论用户的cookie, wordpress_logged是测试登录用户的cookie. wp-postpass不大清楚,字面上来看可能是曾经发表过文章的?只要cookie中含有这些字符串则条件成立.

原来的写法中检测登录用户cookie用的是wordpress_,但是我在测试中发现登入/登出以后还会有一个叫wordpress_test_cookie存在,不知道是什么作用,我也不清楚一般用户是否会产生这个cookie.由于考虑到登出以后这个cookie依然存在可能会影响到cache的判断,于是把这里改成了匹配wordpress_logged_

if ($supercache_uri ~ ^(.+)$) {
    set $supercache_file /wp-content/cache/supercache/$http_host$1index.html;
}

如果变量$supercache_uri不为空,则设置cache file的路径

这里稍微留意下$http_host$1index.html这串东西,其实写成 $http_host/$1/index.html 就好懂很多

以这个rewrite形式的url为例

domain.com/year/month/postname/

其中

$http_host = ‘domain.com’ , $1 = $request_uri = ‘/year/month/postname/’

$http_host$1index.html = ‘domain.com/year/month/postname/index.html’

$http_host/$1/index.html = ‘domain.com//year/month/postname//index.html’

虽然在调试过程中两者并没有不同,不过为了保持正确的路径,还是省略了中间的/符号.

最后上例rewrite后的url为

‘domain.com/wp-content/cache/supercache/domain.com/year/month/postname/index.html’

if (-f $document_root$supercache_file) {
    rewrite ^(.*)$ $supercache_file break;
}

检查cache文件是否存在,存在的话则执行rewrite,留意这里因为是rewrite到html静态文件,所以可以直接用break终止掉.

if (!-e $request_filename) {
    rewrite . /index.php last;
}

执行到此则说明不使用suercache,进行wordpress的permalink rewrite

检查请求的文件/目录是否存在,如果不存在则条件成立, rewrite到index.php

顺便说一句,当时这里这句rewrite看的我百思不得其解. .

只能匹配一个字符啊?这是什么意思?

一般情况下,想调试nginx rewrite最简单的方法就是把flag写成redirect,这样就能在浏览器地址栏里看到真实的rewrite地址.

然而对于permalink rewrite却不能用这种方法,因为一旦写成redirect以后,不管点什么链接,只要没有supercache,都是跳转回首页了.

后来看了一些文章才明白了rewrite的本质,其实是在保持请求地址不变的情况下,在服务器端将请求转到特定的页面.

乍一看supercache的性质有点像302到静态文件,所以可以用redirect调试.

但是permalink却是性质完全不同的rewrite,这跟wordpress的处理方式有关. 我研究不深就不多说了,简单说就是保持URL不变将请求rewrite到index.php,WP将分析其URL结构再对其并进行匹配(文章,页面,tag等),然后再构建页面. 所以其实这条rewrite。

rewrite . /index.php last;

说的是,任何请求都会被rewrite到index.php.因为”.”匹配任意字符,所以这条rewrite其实可以写成任何形式的能任意命中的正则.比如说

rewrite . /index.php last;
rewrite ^ /index.php last;
rewrite .* /index.php last;

效果都是一样的,都能做到permalink rewrite.

最后要提的就是有人可能注意到我的rewrite规则是放在server块中的.网上能找到的大多数关于wordpress的nginx rewrite规则都是放在location /下面的,但是上面我却放在了server块中,为何?

原因是WP或某个插件会在当前页面做一个POST的XHR请求,本来没什么特别,但问题就出在其XHR请求的URL结构上.

正常的permalink一般为: domain.com/year/month/postname/ 或者 domain.com/tags/tagname/ 之类.

但这个XHR请求的URL却是 domain.com/year/month/postname/index.php 或者 domain.com/tags/tagname/index.php

这样一来就命中了location ~ .php$而交给fastcgi,但因为根本没有做过rewrite其页面不可能存在,结果就是这个XHR返回一个404

鉴于location之间匹配优先级的原因,将主要的rewrite功能全部放进了server区块中,这样就得以保证在进行location匹配之前是一定做过rewrite的.

所以要解决这个问题最简单的方法就是把rewrite规则放在比location先执行的server块里面就可以了。

参考文章:Nginx Rewrite研究笔记


转载:Nginx 配置文件nginx.conf的完整配置说明
今天来介绍下关于Nginx 配置文件nginx.conf 的具体内容

#定义Nginx运行的用户和用户组
user www www;
#工作进程,根据硬件调整,几核cpu,就配几个
worker_processes 5;
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log logs/error.log;
#pid文件位置
pid logs/nginx.pid;
worker_rlimit_nofile 8192;</code>
 
events {
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型
use epoll;
#工作进程的最大连接数量,根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行
worker_connections 4096;
}
 
#设定http服务器
http {
#文件扩展名与文件类型映射表
include conf/mime.types;
#反向代理配置,可以打开proxy.conf看看
include /etc/nginx/proxy.conf;
#fastcgi配置,可以打开fastcgi.conf看看
include /etc/nginx/fastcgi.conf;
 
default_type application/octet-stream;
#日志的格式
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#访问日志
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
#根据实际情况调整,如果server很多,就调大一点
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
 
#这个例子是fastcgi的例子,如果用fastcgi就要仔细看
server { # php/fastcgi
listen 80;
#域名,可以有多个
server_name domain1.com www.domain1.com;
#访问日志,和上面的级别不一样,应该是下级的覆盖上级的
access_log logs/domain1.access.log main;
root html;
 
location / {
index index.html index.htm index.php;
}
 
#所有php后缀的,都通过fastcgi发送到1025端口上
#上面include的fastcgi.conf在此应该是有作用,如果你不include,那么就把fastcgi.conf的配置项放在这个下面。
location ~ .php$ {
fastcgi_pass 127.0.0.1:1025;
}
}
 
#这个是反向代理的例子
server { # simple reverse-proxy
listen 80;
server_name domain2.com www.domain2.com;
access_log logs/domain2.access.log main;
 
#静态文件,nginx自己处理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root /var/www/virtual/big.server.com/htdocs;
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
expires 30d;
}
 
#把请求转发给后台web服务器,反向代理和fastcgi的区别是,反向代理后面是web服务器,fastcgi后台是fasstcgi监听进程,当然,协议也不一样。
location / {
proxy_pass http://127.0.0.1:8080;
}
}
 
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。据说nginx可以根据后台响应时间调整。后台需要多个web服务器。
upstream big_server_com {
server 127.0.0.3:8000 weight=5;
server 127.0.0.3:8001 weight=5;
server 192.168.0.1:8000;
server 192.168.0.1:8001;
}
 
server {
listen 80;
server_name big.server.com;
access_log logs/big.server.access.log main;
 
location / {
proxy_pass http://big_server_com;
}
}
}