[web] nginx (2)
Nginx 有一个主线程( master process)和几个工作线程(worker process)。
主线程的目的是加载和验证配置文件、维护工作线程。
工作线程处理实际的请求,
Nginx 采用基于事件的模型和依赖操作系统的机制在工作线程之间高效地分发请求。
工作线程的数量可配置,也可自动调整为服务器CPU的数量。
基本命令
nginx -s stop — 快速关闭
nginx -s quit — 优雅关闭
nginx -s reload — 重新加载配置文件
nginx -s reopen — 重新打开日志文件
当运行nginx -s quit
时,Nginx 会等待工作进程处理完成当前请求,然后将其关闭。
当你修改配置文件后,并不会立即生效,而是等待重启或者收到nginx -s reload
信号。
当 Nginx 收到 nginx -s reload
信号后,首先检查配置文件的语法。
语法正确后,主线程会开启新的工作线程并向旧的工作线程发送关闭信号,
如果语法不正确,则主线程回滚变化并继续使用旧的配置。
当工作进程收到主进程的关闭信号后,会在处理完当前请求之后退出。
配置文件
Nginx 配置的核心是定义要处理的 URL 以及如何响应这些 URL 请求,
即定义一系列的虚拟服务器(Virtual Servers)控制对来自特定域名或者 IP 的请求的处理。
每一个虚拟服务器定义一系列的 location 控制处理特定的 URI 集合。
每一个location定义了对映射到自己的请求的处理场景,可以返回一个文件或者代理此请求。
Nginx 由不同的模块组成,这些模块由配置文件中指定的指令控制。
指令分为简单指令和块指令。
简单指令包含指令名称和指令参数,以空格分隔,以分号;
结尾。
块指令与简单指令类似,但是由大括号{ }
包围。
如果块指令大括号中包含其他指令,则称该指令为上下文(如: events, http, server 和 location)。
配置文件中的放在上下文之外的指令默认放在主配置文件中(类似继承主配置文件)。
events 和 http 放置在主配置文件中,server 放置在http块指令中,
location放置在server块指令中。
配置文件的注释以#
开始。
静态内容
location 也定义了如何处理匹配的请求:返回静态文件 或者 交给代理服务器处理。
#创建一个 server 块
http {
server {
}
}
配置文件可以包括多个 server 块,它们以端口和服务器名称来区分。
当 Nginx 决定某一个 server 处理请求后,
它将请求头中的 URI 和 server 块中的 location 块进行对比。
root 指令定义了静态文件的根目录,并且和 URI 拼接形成最终的本地文件路径。
proxy_pass 指令将请求传递到 URL 指向的代理服务器。
让后将来自代理服务器的响应转发给客户端。
http {
server {
#读取/data/www目录中的静态文件
location / {
root /data/www;
}
#匹配以/images/(/ 也匹配这样的请求,但具有较短的前缀)开始的请求。
location /images/ {
root /data;
}
}
}
上面的 location 块指定 /
前缀与请求中的 URI 对比。
对于匹配的请求,URI 将被添加到 root 指令中指定的路径,即/data/www
,
以此形成本地文件系统的路径,如访问http://localhost/hello.html
,
对应服务器文件路径为/data/www/hello.html
。
如果 URI 匹配多个 location 块,Nginx 采用最长前缀匹配原则(类似计算机网络里面的IP匹配),
上面的 location 块前缀长度为 1,因此只有当所有其他 location 块匹配时,才使用该块。
对于 http://localhost/images/example.png
请求,
nginx 将响应 /data/images/example.png
文件。
如果不存在,nginx 将返回404
URI 不以/images/
开头的请求将映射到 /data/www
目录。
代理服务器
Nginx 的一个常见应用是将其设置为代理服务器(Proxy Server),
即接受客户端的请求并将其转发给代理服务器,再接受代理服务器发来的响应,将它们发送到客户端。
server {
listen 8080;
root /data/up1;
location / {
}
}
服务器侦听端口8080,并将所有请求映射到本地文件系统上的 /data/up1
目录。
root 指令放在 server 上下文中,
这样 当 location 块中不含 root 指令时将使用所属 server 的 root 指令。
server {
location / {
# proxy_pass指令的参数为:协议+主机名+端口号
proxy_pass http://localhost:8080;
}
#匹配以.gif,.jpg或.png结尾的所有URI。
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
正则表达式应该以 ~
开头。
当 Nginx 选择一个 location 块来处理请求时,它首先检查指定 location 块的前缀,
记住具有最长前缀的 location 块,然后检查正则表达式。
如果与正则表达式匹配, Nginx 选择此 location 块,
否则,选择先前记住的 location 块。
FastCGI代理
Nginx 可用于将请求路由到 FastCGI 服务器。
快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。
因此 Nginx 可以将请求路由到 FastCGI 运行的应用程序,如 PHP 程序。
使用 FastCGI 服务器的最基本的 Nginx 配置包括使用fastcgi_pass
指令而不是proxy_pass
指令,
以及使用fastcgi_param
指令来设置传递给FastCGI
服务器的参数。
假设FastCGI服务器可在localhost:9000
上访问。
使用fastcgi_pass
指令替换``proxy_pass指令,并将参数更改为localhost:9000
。
在 PHP 中, SCRIPT_FILENAME
参数用于确定脚本名称,
而 QUERY_STRING
参数用于传递请求参数。
生成的配置将是:
server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
设置虚拟服务器
listen
server 配置块使用 listen 命令监听本机 IP 和端口号(包括 Unix domain socket and path),
支持 IPv4、IPv6,IPv6地址需要用方括号括起来
如果不写端口号,默认使用80端口,如果不写 IP ,则监听本机所有 IP。
server {
listen 127.0.0.1:8080; # IPv4地址,8080端口
# listen [2001:3CA1:10F:1A:121B:0:0:10]:80; # IPv6地址,80端口
# listen [::]:80; # 听本机的所有IPv4与IPv6地址,80端口
# The rest of server configuration
}
server_name
如果多个 server 的 listen IP 和端口号一模一样,
Nginx 通过请求头中的 Host 与 server_name 定义的主机名进行比较,
来选择合适的虚拟服务器处理请求
server {
listen 80;
server_name example.com www.example.com;
...
}
server_name 的参数可以为:
完整的主机名,如:api.example.com 。
含有通配符(含有 *),如:*.example.com 或 api.* 。
正则表达式,以 ~ 开头。
通配符只能在开头或结尾,而且只能与一个 . 相邻。
www.*.example.org 和 w*.example.org 均无效。
但是,可以使用正则表达式匹配这些名称,
例如 ~^www\..+\.example\.org$ 和 ~^w.*\.example\.org$ 。
而且 * 可以匹配多个部分。
名称 * .example.org 不仅匹配 www.example.org,还匹配www.sub.example.org。
对于正则表达式:Nginx 使用的正则表达式与 Perl 编程语言(PCRE)使用的正则表达式兼容。
要使用正则表达式,且必须以 ~ 开头。
命名的正则表达式可以捕获变量,然后使用:
server {
server_name ~^(www\.)?(?<domain>.+)$;
location / {
root /sites/$domain;
}
}
小括号 () 之间匹配的内容,也可以在后面通过 $1 来引用,$2 表示的是前面第二个 () 里的内容。
因此上述内容也可写为:
server {
server_name ~^(www\.)?(.+)$;
location / {
root /sites/$2;
}
}
如果多个名称匹配 Host 头部, Nginx 采用下列顺序选择:
完整的主机名,如 api.example.com。
最长的,且以 * 开头的通配名,如:*.example.com。
最长的,且以 * 结尾的通配名,如:api.* 。
第一个匹配的正则表达式。(按照配置文件中的顺序)
即优先级:api.example.com > *.example.com > api.* > 正则。
如果 Host 头部不匹配任何一个 server_name ,Nginx 将请求路由到默认虚拟服务器。
默认虚拟服务器是指:nginx.conf 文件中第一个 server 或者 显式用 default_server 声明:
server {
listen 80 default_server;
...
}
变量(Variables)
常用的变量
$uri 请求中的当前URI(不带请求参数),它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如 /foo/bar.html。
$arg_name 请求中的的参数名,即“?”后面的arg_name=arg_value形式的arg_name
$hostname 主机名
$args 请求中的参数值
$query_string 同 $args
$request 代表客户端的请求地址
$request_uri 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,不包含主机名,如:/cnphp/test.php?arg=freemouse。
返回特定状态码
return 的第一个参数是响应代码。
可选的第二个参数可以是重定向(对应于代码301,302,303和307)的 URL 或在响应正文中返回的文本。
location /wrong/url {
return 404;
}
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
错误处理
error_page 命令可以配置特定错误码的错误页面,或者重定向到其他的页面。
404 错误发生时返回 /404.html 页面。
error_page 404 /404.html;
error_page 命令定义了如何处理错误,因此不会直接返回,而 return 确实会立即返回。
当代理服务器或者 Nginx 处理时产生相应的错误的代码,均会返回相应的错误页面。
当 Nginx 找不到页面时,使用代码301替换代码404,
并将客户端重定向到 http://example.com/new/path.html 。
此配置很有用,比如当客户端仍尝试用旧的 URI 访问页面时,
301代码通知浏览器页面已永久移除,并且需要自动替换为返回的新地址。
location /old/path.html {
error_page 404 =301 http:/example.com/new/path.html;
}
location
当选择好 server 之后,Nginx 会根据 URIs 选择合适的 location 来决定代理请求或者返回文件。
location 指令接受两种类型的参数:
前缀字符串(路径名称)
正则表达式
对于前缀字符串参数, URIs 必须严格的以它开头。
例如对于 /some/path/ 参数,可以匹配 /some/path/document.html ,
但是不匹配 /my-site/some/path,因为 /my-site/some/path 不以 /some/path/ 开头。
正则表达式的优先级大于前缀字符串。
如果找到匹配的前缀字符串,仍继续搜索正则表达式,
但如果前缀字符串以 ^~
开头,则不再检查正则表达式。
具体的搜索匹配流程如下:
将 URI 与所有的前缀字符串进行比较。
=
修饰符表明 URI 必须与前缀字符串相等(不是开始,而是相等),如果找到,则搜索停止。
如果找到的最长前缀匹配字符串以 ^~ 开头,则不再搜索正则表达式是否匹配。
存储匹配的最长前缀字符串。
测试对比 URI 与正则表达式。
找到第一个匹配的正则表达式后停止。
如果没有正则表达式匹配,使用 4 存储的前缀字符串对应的 location。
=
修饰符拥有最高的优先级。
如网站首页访问频繁,
我们可以专门定义一个 location 来减少搜索匹配次数(因为搜索到 = 修饰的匹配的 location 将停止搜索),
提高速度
匹配规则
~ 波浪线表示执行一个正则匹配,区分大小写
~* 表示执行一个正则匹配,不区分大小写
^~ ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
= 进行普通字符精确匹配
@ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
匹配优先级
= 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。
~ ~* 普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
^~ 只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。
/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到
最后匹配理带有"~"和"~*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;
当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。
顺序 优先级:
location = >
location 完整路径 >
location ^~ 路径 >
location ~,~* 正则顺序 >
location 部分起始路径 >
location /
location = / {
# 精确匹配 / ,主机名后面不能带任何字符串
[ configuration A ]
}
location / {
# 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
# 但是正则和最长字符串会优先匹配
[ configuration B ]
}
location /documents/ {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration C ]
}
location ~ /documents/Abc {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration CC ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif,jpg或jpeg 结尾的请求
# 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
[ configuration E ]
}
location /images/ {
# 字符匹配到 /images/,继续往下,会发现 ^~ 存在
[ configuration F ]
}
location /images/abc {
# 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
# F与G的放置顺序是没有关系的
[ configuration G ]
}
location ~ /images/abc/ {
# 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
[ configuration H ]
}
location ~* /js/.*/\.js
/ -> config A
精确完全匹配,即使/index.html也匹配不了
/downloads/download.html -> config B
匹配B以后,往下没有任何匹配,采用B
/images/1.gif -> configuration D
匹配到F,往下匹配到D,停止往下
/images/abc/def -> config D
最长匹配到G,往下匹配D,停止往下
你可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序
/documents/document.html -> config C
匹配到C,往下没有任何匹配,采用C
/documents/1.jpg -> configuration E
匹配到C,往下正则匹配到E
/documents/Abc.jpg -> config CC
最长匹配到C,往下正则顺序匹配到CC,不会往下到E
常用正则
. : 匹配除换行符以外的任意字符
? : 重复0次或1次
+ : 重复1次或更多次
*: 重复0次或更多次
\d :匹配数字
^ : 匹配字符串的开始
$ : 匹配字符串的结束
{n} : 重复n次
{n,} : 重复n次或更多次
[c] : 匹配单个字符c
[a-z]: 匹配a-z小写字母的任意一个
try_files
try_files指令是按顺序检测文件的存在性,并且返回第一个找到文件的内容,
如果第一个找不到就会自动找第二个,依次查找.其实现的是内部跳转.
#页面跳转
server {
listen 8000;
server_name 10.10.10.10;
root html;
index index.html index.php;
location /abc {
#检测文件4.html和5.html,如果存在正常显示,不存在就去查找@qwe值
try_files /4.html /5.html @qwe;
}
location @qwe {
#跳转到指定页面
rewrite ^/(.*)$ http://www.example.com;
}
}
rewrite
重写 URIs
rewrite只能放在server{},location{},if{}
中,
并且只能对域名后边的除去传递的参数外的字符串起作用。
语法rewrite regex replacement [flag]
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。
表明看rewrite和location功能有点像,
都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,
而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。
很多情况下rewrite也会写在location里,它们的执行顺序是:
执行server块的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;
循环超过10次,则返回500 Internal Server Error错误。
rewrite 指令可以多次修改请求的 URI。
rewrite 的第一个参数是 URI需要匹配的正则表达式,
第二个参数是将要替换的 URI。
第三个参数可选,指示是否继续可以重写或者返回重定向代码(301或302)。
location /users/ {
rewrite ^/users/(.*)$ /show?user=$1 break;
}
可以在 server 和 location 上下文中包括多个 rewrite 指令。
Nginx 按照它们发生的顺序一个一个地执行指令。
当选择 server 时,server 中的 rewrite 指令将执行一次。
在 Nginx 处理一组 rewrite 指令之后,它根据新的 URI 选择 location 。
如果所选 location 仍旧包含 rewrite 指令,它们将依次执行。
如果 URI 匹配所有,则在处理完所有定义的 rewrite 指令后,搜索新的 location 。
/download/some/media/file 的 URI 被改为 /download/some/mp3/file.mp3 。
由于 last 标志,后续指令(第二个 rewrite 指令和 return 指令)被跳过,
但 Nginx 继续以更改后的 URI 处理请求。
类似地,诸如 /download/some/audio/file 的 URI 被替换为 /download/some/mp3/file.ra。
如果 URI 不匹配 rewrite 指令,Nginx 将403 错误代码返回给客户端。
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
flag标志位
last : 相当于Apache的[L]标记,表示完成rewrite
break : 停止执行当前虚拟主机的后续rewrite指令集
redirect : 返回302临时重定向,地址栏会显示跳转后的地址
permanent : 返回301永久重定向,地址栏会显示跳转后的地址
因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。。
last一般写在server和if中,而break一般使用在location中
last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
break和last都能阻止继续执行后面的rewrite指令
last 与 break的区别是:
last : 在当前 server 或 location 上下文中停止执行 rewrite 指令,但是 Nginx 继续搜索与重写的URI匹配的 location,并应用新 location 中的任何 rewrite 指令(这意味着 URI 可能再次改变)。
break :停止当前上下文中 rewrite 指令的处理,并取消搜索与新 URI 匹配的 location。 不会执行新 location中的 rewrite 指令。
全局变量
$args : #这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php
if指令
if判断指令
语法为if(condition){...}
,对给定的条件condition进行判断。
如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:
当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
直接比较变量和内容时,使用=或!=
~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的不匹配
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} //如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
} //防盗链
}
对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,
于是匹配到location /data,先看/data/images/test.png文件存不存在,
如果存在则正常响应,如果不存在则重写tryfiles到新的image404 location,
直接返回404状态码。
http {
# 定义image日志格式
log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
# 开启重写日志
rewrite_log on;
server {
root /home/www;
location / {
# 重写规则信息
error_log logs/rewrite.log notice;
# 注意这里要用‘’单引号引起来,避免{}
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
# 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
set $image_file $3;
set $image_type $4;
}
location /data {
# 指定针对图片的日志格式,来分析图片类型和大小
access_log logs/images.log mian;
root /data/images;
# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
try_files /$arg_file /image404.html;
}
location = /image404.html {
# 图片不存在返回特定的信息
return 404 "image not found\n";
}
}
对形如/images/bla_500x400.jpg的文件请求,
重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
nginx配置ssl加密
默认nginx是没有安装ssl模块的,需要编译安装nginx时加入--with-http_ssl_module选项。
全站ssl
全站做ssl是最常见的一个使用场景,默认端口443,而且一般是单向认证。
server {
listen 443;
server_name example.com;
root /apps/www;
index index.html index.htm;
ssl on;
ssl_certificate ../SSL/ittest.pem;
ssl_certificate_key ../SSL/ittest.key;
# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
}
如果想把http的请求强制转到https的话:
server {
listen 80;
server_name example.me;
rewrite ^ https://$server_name$request_uri? permanent;
### 使用return的效率会更高
# return 301 https://$server_name$request_uri;
}
部分页面ssl
root /apps/www;
index index.html index.htm;
server {
listen 80;
server_name example.com;
location ^~ /account/login {
rewrite ^ https://$server_name:443$request_uri? permanent;
}
location / {
proxy_pass http://localhost:8080;
### Set headers ####
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
}
server {
listen 443 ssl;
server_name example.com;
ssl on;
ssl_certificate ../SSL/ittest.pem;
ssl_certificate_key ../SSL/ittest.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location ^~ /account/login {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
### Most PHP, Python, Rails, Java App can use this header -> https ###
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
rewrite ^ http://$server_name$request_uri? permanent;
}
}
当访问的文件和目录不存在时,重定向到某个php文件
if( !-e $request_filename )
{
rewrite ^/(.*)$ index.php last;
}
目录对换 /123456/xxxx ====> /xxxx?id=123456
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
如果客户端使用的是IE浏览器,则重定向到/ie目录下
if( $http_user_agent ~ MSIE)
{
rewrite ^(.*)$ /ie/$1 break;
}
禁止访问多个目录
location ~ ^/(cron|templates)/
{
deny all;
break;
}
禁止访问以/data开头的文件
location ~ ^/data
{
deny all;
}
禁止访问以.sh,.flv,.mp3为文件后缀名的文件
location ~ .*\.(sh|flv|mp3)$
{
return 403;
}
设置某些类型文件的浏览器缓存时间
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)$
{
expires 1h;
}
给favicon.ico和robots.txt设置过期时间;
这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志
location ~(favicon.ico) {
log_not_found off;
expires 99d;
break;
}
location ~(robots.txt) {
log_not_found off;
expires 7d;
break;
}
设定某个文件的过期时间;这里为600秒,并不记录访问日志
location ^~ /html/scripts/loadhead_1.js {
access_log off;
root /opt/lampp/htdocs/web;
expires 600;
break;
}
文件反盗链并设置过期时间
这里的return412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求
“rewrite ^/ http://img.linuxidc.net/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力
“expires 3d”所有文件3天的浏览器缓存
location ~*^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
valid_referers none blocked *.linuxidc.com*.linuxidc.net localhost 208.97.167.194;
if ($invalid_referer) {
rewrite ^/ http://img.linuxidc.net/leech.gif;
return 412;
break;
}
access_log off;
root /opt/lampp/htdocs/web;
expires 3d;
break;
}
只允许固定ip访问网站,并加上密码
root /opt/htdocs/www;
allow 208.97.167.194;
allow 222.33.1.2;
allow 231.152.49.4;
deny all;
auth_basic “C1G_ADMIN”;
auth_basic_user_file htpasswd;
将多级目录下的文件转成一个文件,增强seo效果
/job-123-456-789.html 指向/job/123/456/789.html
rewrite^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}
将根目录下某个文件夹指向2级目录
如/shanghaijob/ 指向 /area/shanghai/
如果你将last改成permanent,那么浏览器地址栏显是/location/shanghai/
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
上面例子有个问题是访问/shanghai时将不会匹配
rewrite ^/([0-9a-z]+)job$ /area/$1/ last;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
这样/shanghai 也可以访问了,但页面中的相对链接无法使用,
如./list_1.html真实地址是/area/shanghia/list_1.html会变成/list_1.html,导至无法访问。
那我加上自动跳转也是不行咯
(-d $request_filename)它有个条件是必需为真实目录,而我的rewrite不是的,所以没有效果
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/permanent;
}
知道原因后就好办了,让我手动跳转吧
rewrite ^/([0-9a-z]+)job$ /$1job/permanent;
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
域名跳转
server
{
listen 80;
server_name jump.linuxidc.com;
index index.html index.htm index.php;
root /opt/lampp/htdocs/www;
rewrite ^/ http://www.linuxidc.com/;
access_log off;
}
多域名转向
server_name www.linuxidc.comwww.linuxidc.net;
index index.html index.htm index.php;
root /opt/lampp/htdocs;
if ($host ~ "linuxidc\.net") {
rewrite ^(.*) http://www.linuxidc.com$1permanent;
}