nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.

Nginx安装

Nginx目录结构

  • src目录: 存放nginx源码。
  • man目录: 存放nginx帮助文档。
  • html目录: 存放默认网站文件。
  • contrib目录: 存放其它机构或组织贡献的文档资料。
  • conf目录: 存放nginx服务器的配置文件。
  • auto目录: 存放大量的脚本文件,和configure脚本程序相关。
  • configure文件: Nginx自动安装脚本,用于环境检查,生成编译代码需要的makefile文件。
  • CHANGES,CHANGES.ru,LICENSE和README都是Nginx服务器的相关资料。

编译安装Nginx

依赖库安装

1
2
3
4
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install libtool
sudo apt-get install libpcre3 libpcre3-dev zlib1g-dev openssl

下载并安装nginx

1
2
3
4
5
wget http://nginx.org/download/nginx-1.14.2.tar.gz
tar -zxvf nginx-1.14.2.tar.gz
cd nginx-1.14.2
./configure --prefix=/usr/local/nginx
make && make install

Nginx启停配置

1
2
3
4
5
6
7
cd /usr/local/nginx/sbin
./nginx
ps -aux | grep nginx
./nginx -s top	//立即停止
./nginx -s quit //从容停止
kill nginx 主进程pid
killall nginx
命令 说明
nginx -s reload 在nginx已经启动的情况下重新加载配置文件(平滑重启)
nginx -s reopen 重新打开日志文件
nginx -c /xxx/nginx.conf 以特定目录下的配置文件启动nginx
nginx -t 检查当前配置文件是否正确
nginx -t /xxx/nginx.conf 检查特定的nginx配置文件是否正确
nginx -v 显示版本信息
nginx -V 显示版本信息和编译选项

端口号查看

1
netstat -tlnp

创建软连接后可在任意目录下使用nginx

1
2
echo  $PATH
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx  

添加系统服务

1
vi /etc/init.d/nginx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /bin/bash
DAEMON=/usr/local/nginx/sbin/nginx
case "$1" in
	start)
		echo "Starting nginx daemon..."
		$DAEMON && echo "SUCCESS"
	;;
	stop)
		echo "Stoping nginx daemon..."
		$DAEMON -s quit && echo "SUCCESS"
	;;
	reload)
		echo "Starting nginx daemon..."
		$DAEMON -s reload && echo "SUCCESS"
	;;
	restart)
		echo "Starting nginx daemon..."
		$DAEMON -s quit
		$DAEMON && echo "SUCCESS"
	;;
	*)
		echo "Usage:service nginx(start|stop|restart|reload)"
		exit 2
	;;
esac
1
chmod +x /etc/init.d/nginx

设置开机自启

在/etc/init.d/nginx中添加

1
#chkconfig: 35 85 15
1
chkconfig --add nginx

Nginx基本配置

nginx.conf配置文件

nginx.conf的基本模块结构:

1
2
3
4
5
6
7
main
events {...}
http{
	server {
		location{ ... }
	}
}
说明
main 主要控制nginx子进程所属的用户和用户组,派生子进程数,错误日志位置与级别,pid位置,子进程优先级,进程对应CPU,进程能够打开的文件描述符数目等。
events 控制nginx处理🔗的方式
http nginx处理http请求的主要配置块,大多数配置都在这里进行
server nginx中主机的配置块,可用于配置多个虚拟主机
location server中对应目录级别的控制块,可以有多个

默认配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
worker_processes 1;
events{
	worker_connections 1024;
}
http{
	include  mime.types;
	default_type application/octet-stream;
	sendfile  on;
	keepalive_timeout 65;
	server{
		listen 80;
	server_name localhost;
	location / {
		root html;
		index index.html index.htm;
	}
	error_page 500 502 503 504	/50x.html;
	location=/50x.html{
		root html;
	}
	}
}

默认配置指令

指令 说明
worker_processes 配置nginx的工作进程数,一般设置为cpu总核数或者总核数的两倍
worker_connections 配置nginx允许单个进程并发连接的最大请求数
include 用于引入配置文件
default_type 设置默认文件类型
sendfile 默认值位on,表示开启高效文件传输模式
keepalive_timeout 设置长连接超时时间(单位:秒)
listen 监听端口,默认监听80端口
server_name 设置主机域名
root 设置主机站点根目录地址
index 设置默认索引文件
error_page 自定义错误页面

访问控制

allowdeny指令用于nginx访问权限控制。

  1. 单个ip指定作用范围最小,all指定作用范围最大。
  2. 同一块下,存在多个权限指令时,先出现的先生效,且对后出现的设置进行覆盖,未覆盖的依然生效。
  3. 当多个块中出现权限设置指令,则内层块中的权限级别比外层的高。

location控制块

1
2
location [=|~|~*|^~] URI {...}
location @name {...}

精准匹配

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server{
  listen 80;
  server_name localhost;
  root html;
  index index.html index.htm;
  location =/js {
	deny 192.168.0.1
  }
  location =/admin/auth {
	deny 192.168.1.1
  }
  deny all;
}

正则匹配

1
2
3
4
5
6
location ~\.html${
  allow all;
}
location ~^/aaa/.*\.html${
  deny all;
}

最大前缀匹配

1
2
3
4
5
6
location /ng.test{
  allow all;
}
location /ng.test/log{
  deny all;
}

禁用正则匹配

1
2
3
4
5
6
7
8
9
location =/aaa/test.html{
  allow all;
}
location ^~/{
  deny all;
}
location ~\.html${
  allow all;
}
前缀 说明
= 根据其后的指定模式进行精准匹配
~ 使用正则表达式完成location的匹配,区分大小写
~* 使用正则表达式完成location的匹配,不区分大小写
^~ 不适用正则表达式,完成以指定模式开头的location匹配
@ 用于定义一个location块,且该块不能被外部客户端所访问,只能被nginx内部配置指令访问

日志文件

访问日志

/usr/local/nginx/logs

1
2
3
4
5
log_format main 'xxxx'

access_log logs/access.log main;

access_log off; //关闭日志
内置变量 含义
$remote_addr 客户端ip地址
$remote_usr 客户端用户名
$time_local 访问时的服务器时区
$request 请求的url和http协议
$status 记录请求返回的http状态码
$body_bytes_sent 发送给客户端的文件主体内容的大小
$http_referer 来路url地址
$http_user_agent 客户端浏览器信息
$http_x_forwarded_for 客户端ip地址列表(包括中间经过的代理)

错误日志

nginx.conf文件的error_log默认配置

1
2
3
4
5
6
7
error_log logs/error.log

error_log logs/error.log notice;

error_log logs/error.log info;

error_log /dev/null;

日志文件切割

手动切割
1
2
mv access.log 201xxxx.log
nginx -s reopen
自动切割

编写autolog.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

logs_path = "/usr/local/nginx/logs/xxx"

mv $logs_path/access.log $logs_path/'date+"%Y%m%d%H%M"'.log

/usr/local/nginx/sbin/nginx -s reopen


chmod +x autolog.sh

crontab -e

0 0 * * * /usr/local/nginx/logs/xxx/autolog.sh > /dev/null 2>&1

虚拟主机

基于端口配置虚拟主机

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server{
	listen 8001;
	server_name 192.168.78.3;
	root html/html8001;
	index index.html index.htm;
}
server{
	listen 8002;
	server_name 192.168.78.3;
	root html/html8002;
	index index.html index.htm;
}

基于ip配置nginx虚拟主机

1
2
3
4
cd /etc/sysconfig/network-scripts/
vim xxx
DEVICE = 
IPADDR = 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server{
	listen 80;
	server_name 192.168.78.3;
	root html/192.168.78.3;
	index index.html index.htm;
}
server{
	listen 80;
	server_name 192.168.78.4;
	root html/192.168.78.4;
	index index.html index.htm;
}

基于域名配置虚拟主机

1
2
3
vim /etc/hosts
127.0.0.1 www.ng.test
127.0.0.1 ng.test
1
2
3
4
5
6
server{
	listen 80;
	server_name *.ng.test
	root html/www.ng.test
	index index.html index.htm;
}

设置目录列表

Nginx默认不允许列出整个目录。如果该站点目录下没有指定的文件,会报403错误。当开启目录列表功能后,上述情况不会报错,可以让该站点或目录下的文件以列表的形式展示。开启配置指令:autoindex on;

上述指令在http块中,表示对所有站点有效;在server块中,对指定站点有效。在location块中,表示对某个目录有用。

1
2
autoindex_exact_size off;	//以kB/MB/GB为单位显示文件大小
autoindex_localtime;		//显示文件的服务器时间

子配置文件引入

1
2
3
4
5
6
7
mkdir /usr/local/nginx/conf/vhost
cd vhost
touch www.ng.text.conf
vi www.ng.text.conf
server{
	xxxx;
}
1
2
include vhost/www.ng.test.conf;
include vhost/*.conf;

负载均衡与缓存

反向代理

正向代理:客户端将发送的请求和指定的目标服务器发送给代理服务器,代理服务器向目标服务器发起请求,并将获得的响应结果返回给客户端的过程。

反向代理:反向代理对于客户端来说就是目标服务器,客户端向反向代理服务器发送请求后,反向代理服务器将该请求转发给内部网络上的后端服务器,并将后端服务器上得到的响应结果返回给客户端。

在nginx配置文件中,proxy_pass指令通常在location块中进行设置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
server{
	listen 80;
	server_name test.ng.test;
	location / {
		proxy_pass http://192.168.78.128;
	}
}

server{
	listen 80;
	server_name test.web.com;
	location / {
		proxy_pass http://192.168.78.200;
	}
}
指令 说明
proxy_set_header 在讲客户端请求发送给后端服务器之前,更改来自客户端的请求头信息
proxy_connect_timeout 配置nginx与后端代理服务器尝试建立连接的超时时间
proxy_read_timeout 配置nginx向后端服务器组发出read请求后,等待响应的超时时间
proxy_send_timeout 配置nginx向后端服务器组发出write请求后,等待响应的超时时间
proxy_redirect 用于修改后端服务器返回的响应头中的location和refresh

负载均衡

nginx不仅可以作为一个web服务器或反向代理服务器,还可以按照权重,轮询,ip hash,URL hash等多种方式实现对后端服务器的负载均衡。

负载均衡(load balance)就是将负载分摊到多个操作单元上执行。nginx使用upstream指令实现负载均衡。

配置方式 说明
轮询方式 默认方式,每个请求按照时间顺序逐一分配到不同的后端服务器进行处理,如有宕机自动剔除。
权重方式 利用weight指定轮询的权重比率,与访问率成正比,用于后端服务器性能不均的情况。
ip_hash方式 每个请求按访问ip的hash结果分配,这样可以使每个访问固定一个后端服务器,可以解决session共享问题。
第三方模块 第三方模块采用fair时,按照每台服务器的响应时间来分配请求,响应时间短的优先分配,当第三方模块采用url_hash时,按照访问url的hash值来分配请求。

一般轮询

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#配置域名为test.ng.test的虚拟主机
server{
	listen 80;
	server_name test.ng.test;
	location / {
		proxy_pass http://web_server;
	}
}
#配置负载均衡服务器组
upstream web_server{
	server 192.168.78.100;
	server 192.168.78.101;

}

加权轮询

1
2
3
4
5
upstream web_server{
	server 192.168.78.100 weight=1 max_fails=1 fail_timeout=2;
	server 192.168.78.101 weight=2 max_fails=3 fail_timeot=3;
	server 192.168.78.102 backup;
}
配置方式 说明
max_fails 允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream指令定义的错误。
fail_timeout 经历max_fails失败后,暂停服务的时间。且在实际应用中max_fails一般与fail_timeout一起使用。
backup 预留的备份机器。
down 表示当前server不参与负载均衡

ip_hash

1
2
3
4
5
6
7
upstream web_server{
	ip_hash;
	server 192.168.78.100;
	server 192.168.78.101;
	server 192.168.78.102;
	server 192.168.78.103 down;
}

第三方模块

fair方式(web服务器响应时间)

  • 备份以安装的nginx。cp -r /usr/local/nginx /usr/local/nginx_old
  • 重新编译安装nginx。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
unzip nginx-upstream-fair-mastre.zip
mv nginx-upstream-fair-master nginx-upstream-fair

cd nginx-1.10.1
./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--add-module=/root/nginx-upstram-fair

make && make install
  • 配置fair负载均衡
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server{
	listen 80;
	server_name test.ng.test;
	location / {
		proxy_pass http://web_server;
	}
}

upstream web_server{
	server 192.168.78.100;
	server 192.168.78.102;
	fair;
}

缓存配置

利用反向代理服务对访问频率较多的内容进行缓存,有利于节省后端服务器资源。nginx提供两种web缓存方式:永久性缓存与临时性缓存。

永久性缓存配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server{
	listen 80;
	server_name 192.168.78.3;
	location / {
		root cache; #nginx的cache目录
		proxy_store on;
		proxy_store_access user:rw group:rw all:r;
		proxy_temp_path cache_tmp;
		if(!-e $request_filename){
			proxy_pass http://192.168.78.100;
		}
	}
}

临时性缓存配置

nginx使用proxy_cache指令设置临时缓存,采用md5算法将请求连接进行哈希(hash)后,更具配置生成缓存文件目录。

  1. 在nginx.conf的http块中添加:
1
2
3
4
#代理缓存内容源的临时目录
proxy_temp_path /usr/local/nginx/proxy_temp_dir;
proxy_cache_path /usr/local/nginx/proxy_cache_dir \
levels=1:2 keys_zone=cache_one:50m inactive=1m max_size=500m;

proxy_cache_path:

  • /usrlocal/nginx/proxy_cache_dir参数: 表示用户自定义的缓存文件保存目录。
  • levels参数:表示缓存目录下的层级目录结构,它是根据哈希后的请求url地址创建的,目录名称从哈希后的字符串结尾开始截取。 假设哈希后的url地址为ad70998a15e…ce0 ,则levels=1:2表示,第一层子目录的名称是长度为1的字符0,第二层子目录的名称是长度为2的字符ce。
  • keys_zone参数:指定缓存区名称及长度。例如cache_one:50m表示缓存区名称为cache_one,在内存中的空间是50MB。
  • inactive参数:表示主动清空在指定时间内未被访问的缓存。1m表示清空在1分钟内未被访问过的缓存(1h,1d)。
  • max_size:表示指定磁盘空间大小(500m,10g)。
  1. 在server块中添加临时缓存配置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
server{
	listen 80;
	server_name test.nd.test;
	#增加两个响应头信息,用于获取访问的服务器地址与缓存是否成功。
	add_header X-Via $server_addr;
	add_header X-Cache $upstream_cache_status;
	location / {
		#设置缓存区域名称
		proxy_cache cache_one;
		#以域名,uri,参数组合成web缓存的key值,nginx根据key值哈希
		proxy_cache_key $host$uri$is_args$args;  #is_args有参数时为?否则为空
		#对不同的http状态码设置不同的缓存时间
		proxy_cache_valid 200 10m; #200缓存10分钟
		proxy_cache_valid 304 1m;
		proxy_cache_valid 301 302 1h;
		proxy_cache_valid any 1m;	#其余未设置的状态码缓存1m
		#设置反向代理
		proxy_pass http://192.168.78.128;
	}
}

X-Via表示服务器地址,利用内置变量$server_addr获取,另一个X-Cache表示缓存资源状态,利用内置变量$upstream_cache_status获取。$upstream_cache_status的返回值:HIT,MISS,EXPIRED,UPDATING,STALE,BYPASS,REVALIDATED。

指令 说明
proxy_cache_bypass 用于配置nginx向客户端发送响应数据时,不从缓存中获取条件。
proxy_cache_lock 用于设置是否开启缓存的锁🔒功能。
proxy_cache_lock_timeout 用于设置缓存的🔒功能开启以后的超时时间。
proxy_no_cache 配置在什么情况下不使用缓存功能
proxy_cache_min_uses 当同一个url被重复请求达到指定的次数后,才对该url进行缓存
proxy_cache_revalidate 用于当缓存内容过期时,nginx通过一次if-modified-since的请求头去验证缓存内容是否过期。
proxy_cahce_use_stale 设置状态,用于内容源web服务器处于这些状态时,nginx向客户端响应历史缓存数据。

缓存清理配置

目前nginx提供缓存相关指令不支持清理url的缓存,需要借助第三方模块。

ngx_cache_purge模块下载地址:https://github.com/FRiCKLE/ngx_cache_purge_releases 。

1
2
3
cp -r /usr/local/nginx /usr/local/nginx_old2
unzip ngx_cache_pure-master.zip
mv ngx_cache_purge-master /usr/local/ngx_cache_purge
1
2
3
4
5
6
7
cd nginx-1.10.1
./configure \
--prefix=/usr/local/nginx \ 
--with-http_ssl_module \ 
--add-module=/usr/local/ngx_cache_purge

make && make install
1
2
3
4
5
location ~/purge(/.*){
	allow 192.168.78.1;
	deny all;
	proxy_cache_purge cache_one$host$1$is_args$args;
}

$1表示location正则表达式中的子模式(/.*)的匹配结果,对应生成缓存key时的$uri。

模块化配置

模块概述

通常将Nginx分为5大模块:核心模块,标准http模块,可选http模块,邮件服务模块和第三方模块。

查看nginx默认加载的核心模块和标准http模块:

1
2
# cd ~/nginx-1.10.1/objs
# less ngx_modules.c
1
2
3
4
5
6
7
8
9
extern ngx_module_t ngx_core_module;
extern ngx_module_t ngx_errlog_module;
extern ngx_module_t ngx_conf_module;
extern ngx_module_t ngx_openssl_module;
extern ngx_module_t ngx_regex_module;
extern ngx_module_t ngx_events_module;
extern ngx_module_t ngx_event_core_module;
extern ngx_module_t ngx_epoll_module;
...

网页压缩

Nginx服务器为网页压缩专门提供了gzip模块,并且模块中的相关指令均可以设置在http,server或location块中,实现服务器端安装指定的设置进行压缩。

指令 说明
gzip 开启或关闭gzip模块
gzip_buffers 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流
gzip_comp_level gzip的压缩比,压缩级别是1-9,1最低9最高,压缩级别越高压缩率越大,压缩时间越长
gzip_disable 对一些特定的User-Agent不实用压缩功能
gzip_min_length 设置允许压缩页面的最小字数,页面字节数从响应消息头的Content-Length中进行获取
gzip_http_version 识别http协议版本,其值可以是1.1(默认)或1.0
gzip_proxied 用于设置启用或禁用从服务器上收到响应内容的gzip压缩功能
gzip_types 匹配MIME类型进行压缩。且无论是否指定,text/html类型总是会被压缩的
gzip_vary 用于在响应消息头中添加Vary:Accept-Encoding,使代理服务器根据请求头中的Accept-Encoding识别是否启用gzip压缩

用于客户端访问网页时,对文本,javascript和css文件进行压缩输出。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
http{
	...
	gzip on;
	gzip_types text/plain application/javascript text/css;
	...
}

gzip_buffers 4 16k;		//表示原始数据大小以16K为单位的4倍申请内存。
gzip_comp_level 4;
gzip_disable "MSIE[1-6].";
gzip_min_length 5k;
gzip_http_version 1.0;
gzip_proxied any;
gazip_vary on;

Nginx作为反向代理时,gzip_proxied指令的常用参数值如下

指令 说明
any 无条件压缩所有响应数据
off 关闭反向代理的压缩
expired 如果消息头中包含Expires则启用压缩
no-cache 如果消息头中包含Cache-Control:no-cache则启用压缩
no-store 如果消息头中包含cache-control:no-store则启用压缩
private 如果消息头中包含cache-control:private则启用压缩
no_last_modified 如果消息头中不包含Last-Modified则启用压缩
no_etag 如果消息头中不包含ETag则启用压缩
auth 如果消息头中不包含Authorization头信息则启用压缩

rewrite重写&重定向

1
resrite regex replacement [flag];
参数值 说明
last 终止rewrite,继续匹配其他规则
break 终止rewrite,不在继续匹配
redirect 临时重定向,返回的http状态码为302
permanent 永久重定向,饭后http状态码为301

当flag的值为last或break时,表示当前的设置为 重写,当flag的值为redirect或permanent时表示重定向

1
2
3
4
5
6
7
8
9
server{
	listen 80;
	server_name test.ng.test;
	index index.html index.htm;
	root html;
	if(!-e $request_filename){
		rewrite "^/.*" /default/default.html break;
	}
}
判断符号 说明 判断符号 说明
= 判断变量是否相等 != 判断变量是否不想等
~ 判断大小写正则匹配 ~* 不区分大小写正则匹配
!~ 区分大小写正则不匹配 !~* 不区分大小写正则不匹配
-f 判断文件是否存在 !-f 判断文件不存在
-d 判断目录是否存在 !-d 判断目录不存在
-e 判断文件或者目录存在 !-e 判断文件或者目录不存在
-x 判断可执行文件 !-x 判断不可执行文件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
server{
	listen 80;
	server_name test.ng.test;
	root html;
	location /break/{
		rewrite ^/break/(.*)/test/$1 break;
		echo "break page";
	}
	location /last/{
		rewrite ^/last/(.*)/test/$1 last;
		echo "last page";
	}
	location /test/{
		echo "test page";
	}
}

rewrite的重定向就是将用户访问的url修改为重定向的地址,只需将flag的可选参数设置为redirect或permanent即可实现。

1
2
3
4
5
6
7
server{
	listen 80;
	server_name test.ng.test;
	root html;
	set $name $1;
	rewrite ^/img-([0-9]+)\.jpg$/img/$name.jpg permanent;
}

上述示例中,利用set指令为变量$name赋值,$s1表示符合正则表达式第一个子模式的值。

redirect返回http状态码是302(临时重定向),使得搜索引擎在抓取新内容的同时保留旧的网址。permanent饭后的http状态码是301(永久重定向),会让搜索引擎在抓取新内容的同时也将旧的网址永久替换为重定向之后的网址。

防盗链配置

http请求消息中的referer字段,用于保存当前网页的来源url地址。当用户打开一个含有图片内容的网页时,浏览器会在图片的请求消息中将网页的url放在referer中,从而使图片所在的服务器能够追踪它被显示的网页地址。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server{
	listen 80;
	server_name www.ng.test;
	root html/ng.test;
	index index.html index.htm;
}

server{
	listen 80;
	server_name www.test.com;
	root html/test.com;
	index index.html index.htm;
}
1
2
<h1>welcome to www.ng.test!</h1>
<img src="img/2.jpg" width="200" />
1
2
<h1>welcome to www.test.com!</h1>
<img src="http://www.ng.test/img/2.jpg" width="200" />
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server{
	listen 80;
	server_name www.ng.test;
	root html/ng.test;
	index index.html index.htm;

	location ~* \.(gif|jpg|png|swf|flv)${
		valid_referers www.ng.test ng.test;
		if($invalid_referer){
			return 403;
		}
	}
}
参数值 说明
none 匹配没有referer的http请求,如valid_referers none;
blocked 匹配http请求中含有referer,但是被防火墙或者代理服务器修改,去掉了https://或http://的情况,如valid_referers blocked;
server_names 允许文件资源链出的域名白名单,如valid_referers www.ng.test ng.test;
string 任意的字符串,如valid_referers *.ng.test ng.*;
regular expression 正则表达式,如valid_referers ~.img.;

图片防盗链如果只根据referer进行验证,这种方式存在伪造referer的问题。而对于图片之外的下载资源,如果不需要考虑资源链接的长期有效性,可以使用nginx提供的secure_link和secure_link_md5指令来实现下载地址的加密和时效性。

下载防盗链的实现原理就是在服务器端根据特定规则对下载地址进行加密,并在用户请求下载链接时,验证加密链接是否有效,防止用户伪造下载链接。同时,为了避免加密后的链接被盗链,在加密时添加过期时间,使得下载地址只在一定时间内有效,过期后只能到原网站获取新的地址。

1.重新编译nginx,然后重新生成nginx的二进制可执行文件,替换掉nginx安装目录中的可执行文件/usr/local/nginx/sbin/nginx即可。

1
--with-http_secure_link_module

2.创建php文件cdown.php,用于生成加密的下载链接

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
$secret='ng.test';		//自定义密钥
$path='/down/web/nginx-1.10.1.tar.gz';	//下载文件路径
$expire=time()+60;	//生成过期时间,60表示60秒
//用文件路径,密钥,过期时间生成加密串
$md5=base64_encode(md5($secret.$path.$expire, true));	
$md5=strtr($md5,'+/','-_');
$md5=str_replace('=','',$md5);
//生成加密后的下载链接
echo '<a href="http://www.ng.test/down/web/nginx-1.10.1.tar.gz?st='.$md5.'&e='.expire.'">nginx-1.10.1</a>'
//输出加密后的下载地址
echo '<br>http://www.ng.test/down/web/nginx-1.10.1.tar.gz?st='.$md5.'&e='.$expire;
?>

3.修改nginx配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
location / {
	secure_link $arg_st,$arg_e;
	secure_link_md5 ng.test$uri$arg_e;
	if($secure_link=""){
		return 403;		#处理加密串不等的情况
	}
	if($secure_link="0"){
		return 403;		#加密串相等时,处理下载链接过期的情况
	}
}

配置HTTPS

HTTPS(Hypertext Transfer Protocol Secure)超文本传输安全协议是HTTP(超文本传输协议),SSL(Secure Sockets Layer)安全套接层和TLS(Transport Layer Security)传输安全的组合,用于提供加密通信和鉴定网络服务器的身份。

要想实现HTTPS加密网站,在服务器端首先要获得CA(CertificationAuthority)认证机构颁发的服务器数字证书(CRT)。Nginx服务器中的ngx_http_ssl_module模块用于提供HTTPS网站的配置。

OpenSSL是一个非常强大的安全套接字层密码库,它包含了主要的密码算法,常用的密钥,证书封装管理以及SSL协议,证书签发等多种功能。其中,OpenSSL程序是由3部分组成的,分别为openssl命令行工具,libcrypto公共加密库和libssl实现SSL协议。

1.生成服务器的RSA私钥

1
2
3
mkdir /usr/local/nginx/conf/ssl
cd /usr/local/nginx/conf/ssl
openssl genrsa -out server.key 2048
参数 说明
genrsa 表示用于生成RSA私钥
out server.key 表示输出的文件名为server.key,文件所在目录为执行当前openssl命令时所在目录
2048 密钥长度为2048(长度越长,安全性越强)

2.生成服务器的CSR证书请求文件 CSR证书请求文件是服务端的公钥,用于提交给CA机构进行签名。

1
openssl req-new-key server.key -out server.csr
参数 说明
Country Name(2 letter code) 符合ISO的2个字母的国家代码,如中国CN
State or Province Name(full name) 省份,如Beijing
Locality Name 城市
Organization Name 公司名称
Organizational Unit 组织单位
Common Name 使用SSL加密的网站域名
Email Address 邮箱地址
A challenge password 有些CA机构需要密码,通常省略
An optional company name 可选公司名称

在填写信息时要删除字符时,通过ctrl+backspace键进行操作。

3.CA为服务器认证证书

1
2
openssl x509 -req-days 30 \
-in server.csr -signkey server.key -out server.crt

4.配置HTTPS网站

1
2
3
4
5
6
7
8
server{
	listen 443;
	server_name www.test.com;
	root html/test.com;
	ssl on;
	ssl_certificate			/usr/local/nginx/conf/ssl/server.crt;
	ssl_certificate_key		/usrlocal/nginx/conf/ssl/server.key;
}

其它