显示标签为“Nginx”的博文。显示所有博文
显示标签为“Nginx”的博文。显示所有博文

2014年4月5日星期六

在Nginx为WordPress配置Rewrite

比较暴力。为防遗忘,作文以记之:
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    root /var/www/wordpress;
    index index.php;
    client_max_body_size 16m;
    error_page 400 /index.php?error=400;
    error_page 403 /index.php?error=403;
    error_page 404 /index.php?error=404;
    try_files $uri $uri/ =404;
    rewrite ^/index.php$ /index.php break;
    rewrite ^/index.php\?(.*)$ /index.php?$1 break;
    rewrite ^/wp-(.*)$ /wp-$1 break;
    rewrite ^/(.*)$ /index.php?q=/$1;
    location ~ \.php(/.*)?$ {
        fastcgi_split_path_info ^(.+?\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 听说有的版本的nginx不加这行会出现空白页面
        include fastcgi_params;
    }
}

这个配置在 Debian 6、7、8 上试验通过。Fedora 的 php-fpm 默认配置有些不同,把 fastcgi_split_path_info 稍微换一下就好了。
至于 CentOS 嘛,看看和我一样恨 CentOS 的有多少人:
这人和我一样是CentOS黑没错。

2013年10月7日星期一

Nginx 根据 User-Agent 屏蔽访问

有以下的需求:
  • 对所有的机器人、爬虫、蜘蛛屏蔽内部测试用的站点。
  • 对使用 Microsoft Windows Internet Explorer 浏览器的用户展示一个“请更换浏览器”的页面。
set $botblocker_flag "0";
if ($http_user_agent ~* "bot|spider|crawl") {
    set $botblocker_flag "${botblocker_flag}1";
}
if ($uri !~ "/robots.txt(\?.*)?") {
    set $botblocker_flag "${botblocker_flag}2";
}
if ($botblocker_flag = "012") {
    return 403;
}
set $botblocker_flag "";
location = /noie.html {
    return 403;
    error_page 403 =403 @noie;
}
location @noie {
    root /var/www/error;
    index noie.html;
}
if ($http_user_agent ~* "MSIE| (360)?se |360spider|sou?gou|tencenttraveler") {
    rewrite .* /noie.html;
}
把上面的内容放到 /etc/nginx/botblocker 里。某一个站点需要用的时候就 include botblocker; 插在 server{} 块内。
然后写一个劝说用户更换浏览器的页面放在 /var/www/error/noie.html 里面。

2013年7月9日星期二

Nginx alias try_files php-fpm work together

There is such a configuration on my Nginx 1.2.1 server:
server {
 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;
 root /var/www;
 index index.php index.html;
 autoindex on;
 autoindex_localtime on;
 try_files $uri $uri/ =404;
 location ~ ^/~([^/]+)(/.*)?\.php(/.*)?$ {
  alias /home/$1/public_html$2.php;
  fastcgi_pass unix:/var/run/php5-fpm.sock;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME /home/$1/public_html$2.php;
  fastcgi_param PATH_INFO $3;
 }
 location ~ ^/~([^/]+)(/.*)?$ {
  alias /home/$1/public_html$2;
 }
}
It aims to map /~username/ to /home/username/public_html/ so that users on my server can access and manage their own files.
However, this brought a problem. If one tried to access a non-exist .php file, such as /~username/asdfasdf.php, php-fpm would complain about “Invalid Argument” instead of displaying the “404 Not Found” page of Nginx.
I have browsed Nginx Wiki and found:
Note that there is a longstanding bug that alias and try_files don't work together.
But I would never give up!
I observed the environment variables that Nginx passed to PHP and found that $_SERVER["DOCUMENT_ROOT"] became the same value as $_SERVER["SCRIPT_FILENAME"] instead of /var/www.
try_files directive tries files from $document_root. For example, try_files $uri =404; tests the existence of the file named $document_root$uri.
It is clear after I noticed this. The workaround is just append try_files "" =404; after the line of alias.

Nginx alias try_files php-fpm 共存

Nginx 1.2.1 服务器有这么一个配置:
server {
 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;
 root /var/www;
 index index.php index.html;
 autoindex on;
 autoindex_localtime on;
 try_files $uri $uri/ =404;
 location ~ ^/~([^/]+)(/.*)?\.php(/.*)?$ {
  alias /home/$1/public_html$2.php;
  fastcgi_pass unix:/var/run/php5-fpm.sock;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME /home/$1/public_html$2.php;
  fastcgi_param PATH_INFO $3;
 }
 location ~ ^/~([^/]+)(/.*)?$ {
  alias /home/$1/public_html$2;
 }
}
目的是把所有的 /~username/ 映射到 /home/username/public_html/,让服务器的用户能够存放自己的文件。
但这样带来了一个问题,如果访问一个不存在的 .php 文件,比如 /~username/asdfasdf.php,php-fpm 就会报错,显示“Invalid Argument”而不是 Nginx 的“404 Not Found”页面。
查看了 Nginx 的 Wiki,有这么一句话:
Note that there is a longstanding bug that alias and try_files don't work together.
但是我不会就此罢休的!
于是我观察了 Nginx 传递给 PHP 的环境变量,发现 $_SERVER["DOCUMENT_ROOT"] 变成了和 $_SERVER["SCRIPT_FILENAME"] 一样的值,而不是 /var/www 了。
try_files 指令是从 $document_root 算起的,比如 try_files $uri =404; 就是检测 $document_root$uri 是否存在。
弄明白了这个,就豁然开朗了。在 alias 那一行后面加上 try_files "" =404; 即可。