首页 > Nginx > 备案时批量反向代理网站支持Range回源

备案时批量反向代理网站支持Range回源


最近个人备案需要转成企业备案,过程中需要注销备案再转入备案,导致该域名暂时不可用,于是使用了一个备用域名(com.cn来代替com进行访问)。

问题来了,源网站的html文件都是静态生成,所有的超链接为绝对路径不可更改,使用备用域名后希望仍然使用纯静态的html,而非使用动态替换技术。因此,只能在nginx配置文件上进行修改,刚好有这么一款“小偷程序”满足需求。


ngx_http_substitutions_filter_module是nginx的一个模块,提供了文本正则替换功能,可以替换网页上超链接,因此,常用于网站镜像(小偷程序,偷换广告)。


该模块是中国人写的,跟apache的mod_substitute模块一样,使用举例:

location / {
	subs_filter_types text/html text/css text/xml; subs_filter st(\d*).example.com $1.example.com ir; subs_filter a.example.com s.example.com;
}

涉及指令:

* subs_filter_types

* subs_filter

subs_filter_types 语法: *subs_filter_types mime-type [mime-types] *

默认: *subs_filter_types text/html*

内容: *http, server, location*

*subs_filter_types* 是用来指定替换文件类型的 默认仅仅替换 text/html 类型的文件。


proxy_set_header Accept-Encoding “”;

subs_filter 语法: *subs_filter source_str destination_str [gior] *

默认: *none*

内容: *http, server, location*


*subs_filter* 是用来替换文本的,可以使用正则

* *g*(默认):替换匹配项。

* *i*:区分大小写的匹配

* *o*: 只匹配发现的第一个。

* *r*: 正则。


先下载这个包:https://github.com/yaoweibin/ngx_http_substitutions_filter_module

解压到/home/data目录下:

unzip ngx_http_substitutions_filter_module-master.zip

由于之前nginx没有安装这个模块,因此需要重新编译添加这个模块,我们先看看当前nginx里面有哪些模块:

mkdir -p /var/tmp/nginx/client
mkdir -p /var/tmp/nginx/proxy
mkdir -p /var/tmp/nginx/fastcgi
mkdir -p /var/tmp/nginx/uwsgi
mkdir -p /var/tmp/nginx/scgi
chown -R www:www /var/tmp/nginx/client
chown -R www:www /var/tmp/nginx/proxy
chown -R www:www /var/tmp/nginx/fastcgi
chown -R www:www /var/tmp/nginx/uwsgi
chown -R www:www /var/tmp/nginx/scgi
/usr/local/nginx/sbin/nginx -V
--user=www --group=www --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_gzip_static_module --with-http_ssl_module --with-http_realip_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi

进入nginx源码目录,编译的时候,根据上面列出来的还需要增加以下参数:

cd /home/data/nginx-1.12.1
./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--with-http_ssl_module \
--with-http_realip_module \
--http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx/scgi \
--add-module=/home/data/ngx_http_substitutions_filter_module-master
make

千万不要make install,因为是动态编译会产生一个nginx二进制文件,make install会覆盖之前的,我们先备份一下。

cp -pR /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp -pR ./objs/nginx /usr/local/nginx/sbin/
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx -s reload

如果提示cp: cannot create regular file ‘/usr/local/nginx/sbin/nginx’: Text file busy
kill -9 $(ps -ef | grep nginx | grep -v grep | awk '{print $2}')
/usr/local/nginx/sbin/nginx

重启前先验证一下配置文件有没有问题,没有问题再重启。


开始修改配置文件,以镜像百度为例:

server
{
	listen       80;
	server_name www.example.com;

	index index.html index.htm index.php default.html default.htm default.php;
	root  /home/www/html/wordpress;

	#默认首页

	location / {
		subs_filter_types text/css text/xml;
		subs_filter www.baidu.com www.example.com gi;
		#替换模块,下文详解。

		proxy_cache_key "$scheme://$host$request_uri";
		#缓存 key 规则,用于自动清除缓存。

		proxy_cache cache_one; 
		#缓存区名称,必须与前面定义的相同

		proxy_cache_valid  200 304 3h;
		proxy_cache_valid 301 3d;
		proxy_cache_valid any 10s;
		#200 304 状态缓存 3 小时
		#301 状态缓存 3 天
		#其他状态缓存(如 502 404)10 秒

		proxy_set_header   X-Real-IP  $remote_addr;
		proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
		#向后端传递访客 ip

		proxy_set_header   Referer http://www.baidu.com;	
		#强制定义 Referer,程序验证判断会用到

		proxy_set_header   Host www.baidu.com;
		#定义主机头

		proxy_pass http://www.baidu.com;	
		#指定后端 ip

		proxy_set_header Accept-Encoding "";	
		#清除编码

		proxy_cache_use_stale invalid_header error timeout http_502;
		#当后端出现错误、超时、502 状态时启用过期缓存
    }
	
	access_log  /var/logs/nginx/example/www.example.com.log main;
}


如果是全新安装nginx时希望带上此扩展:

#解压编译安装
unzip -o /home/data/ngx_http_substitutions_filter_module-master.zip

cd ${nginxPackage}
./configure \
--user=www \
--group=www \
--prefix=${installPath} \
--sbin-path=${installPath}/sbin/nginx \
--conf-path=${installPath}/conf/nginx.conf \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--with-http_ssl_module \
--with-http_realip_module \
--http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx/scgi \
--with-http_sub_module \
--add-module=/home/data/ngx_http_substitutions_filter_module-master



后续,需要给代理站添加限流、反向代理缓存功能、反向代理缓存清除、Range回源功能,并将nginx升级到1.14.0版本。

nginx的Range回源在1.9.8版本开始有ngx_http_slice_module模块、编译时添加--with-http_slice_module参数,然后配置proxy_cache_key和添加Range的header转发。

注意:nginx反向代理建议只对静态文件使用反向代理缓存,动态请求尽量不要设置缓存。


nginx-1.14.0下载:nginx-1.14.0.tar.gz


替换模块下载:ngx_http_substitutions_filter_module-master.zip


缓存清除模块下载:ngx_cache_purge-2.3.tar.gz


nginx.conf配置文件如下:

user www www;

worker_processes 1;

error_log  /var/logs/nginx_error.log  crit;

pid        /usr/local/nginx/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process. 
worker_rlimit_nofile 102400;

events 
{
	use epoll;
	worker_connections 102400;
}

http 
{
	include       mime.types;
	default_type  application/octet-stream;
	server_tokens off;
	#charset  utf-8; 
	  
	server_names_hash_bucket_size 128;
	client_header_buffer_size 32k;
	large_client_header_buffers 4 32k;
	client_max_body_size 5m;
	client_body_buffer_size 256k;
	client_body_temp_path /var/tmp/nginx/client;
	  
	sendfile on;
	tcp_nopush     on;

	keepalive_timeout 100;
	autoindex off;
	tcp_nodelay on;
  
  
	fastcgi_connect_timeout 300;
	fastcgi_send_timeout 300;
	fastcgi_read_timeout 300;
	fastcgi_buffer_size 512k;
	fastcgi_buffers 8 512k;
	fastcgi_busy_buffers_size 512k;
	fastcgi_temp_file_write_size 512k;

	proxy_connect_timeout 300;
	proxy_send_timeout 300;
	proxy_read_timeout 300;
	proxy_buffer_size 64k;
	proxy_buffers 4 512k;
	proxy_busy_buffers_size 512k;
	proxy_temp_file_write_size 512k;
	proxy_temp_path   /home/cache/temp;
	proxy_cache_path  /home/cache/one levels=1:2 keys_zone=cache_one:20m inactive=3d max_size=5g;

	gzip  on;
	gzip_min_length 1k;
	gzip_buffers 4 16k;
	gzip_http_version 1.1;
	gzip_comp_level 2;
	gzip_types text/plain application/x-javascript text/css application/xml;
	gzip_vary on;

	#limit_zone  crawler  $binary_remote_addr  10m;
	#limit_conn_zone $binary_remote_addr zone=addr:10m;
	limit_conn_zone $binary_remote_addr zone=perip:10m;
	limit_conn_zone $server_name zone=perserver:10m;

	## 这里取得原始用户的IP地址
	map $http_x_forwarded_for  $clientRealIp {
			""      $remote_addr;
			~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
	}
	
	## 针对原始用户 IP 地址做限制
	limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ;
	limit_conn  TotalConnLimitZone  50;
	limit_conn_log_level notice;

	## 针对原始用户 IP 地址做限制
	limit_req_zone $clientRealIp zone=ConnLimitZone:20m  rate=400r/m;
	#limit_req zone=ConnLimitZone burst=10 nodelay; #如果开启此条规则,burst=10的限制将会在nginx全局生效
	limit_req_log_level notice;

	server{
		listen	80;
		server_name	localhost;
		root   /www;
        index  index.php index.html index.htm;
	}
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
	'$status $body_bytes_sent "$http_referer" '
	'"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
	'"$upstream_addr" "$upstream_response_time" $upstream_cache_status';
	include	vhost/*.conf;
}


vhost/baidu.zhengshuiguang.com.conf配置文件如下:

server
{
    listen       80;
    server_name baidu.zhengshuiguang.com;

    index index.html index.htm index.php default.html default.htm default.php;
    root  /home/www/html;
    
    location / {
        # 静态请求处理交给nginx缓存
        location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|ico|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma|css|js)$ {
            proxy_cache cache_one;                                  #使用缓存配置
            proxy_cache_key $host$uri$is_args$args$slice_range;     #通过key来hash,定义KEY的值
            proxy_cache_valid  200 304 301 302 7d;                  #哪些状态服务端缓存多长时间  
            proxy_cache_valid  any 1d;                              #其他的服务端缓存多长时间
            proxy_set_header Range $slice_range;
            add_header X-Cache-Status $upstream_cache_status;
            proxy_ignore_headers Set-Cookie Cache-Control;          #如果静态资源有设置缓存或者cookie服务端缓存将失效
            proxy_hide_header Cache-Control;
            proxy_hide_header Set-Cookie;
            expires 7d;                                              #客户端缓存时间
            proxy_pass http://www.baidu.com;
        }
        
        subs_filter_types text/css text/xml;
        subs_filter www.baidu.com baidu.zhengshuiguang.com gi;
        proxy_set_header   Referer http://www.baidu.com;
        proxy_set_header Accept-Encoding "";
        proxy_set_header   Host www.baidu.com;
        proxy_cache_use_stale invalid_header error timeout http_502; #当后端出现错误、超时、502 状态时启用过期缓存
        
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        expires -1;                                                  #动态请求客户端不缓存
        proxy_pass http://www.baidu.com;
    }
    access_log  /var/logs/nginx/zhengshuiguang/baidu.zhengshuiguang.com.log main;
}


进入nginx源码目录,编译:

cd /home/data/nginx-1.14.0
./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_slice_module \
--http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx/scgi \
--add-module=/home/data/ngx_http_substitutions_filter_module-master \
--add-module=/home/data/ngx_cache_purge-2.3
make

升级:

cp -pR /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp -pR ./objs/nginx /usr/local/nginx/sbin/
/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx -s reload

如果提示cp: cannot create regular file ‘/usr/local/nginx/sbin/nginx’: Text file busy
kill -9 $(ps -ef | grep nginx | grep -v grep | awk '{print $2}')
/usr/local/nginx/sbin/nginx

验证:

先删除缓存目录,再访问百度首页,以首页logo为例:http://baidu.zhengshuiguang.com/img/bd_logo1.png


/home/cache/one目录下,新增了两个子目录,里面就是反向代理缓存。

再查看nginx日志:


nginx反向代理缓存目录测试.png

第一次请求为MISS,后面再次请求为HIT,查看对应的nginx日志:

nginx反向代理日志.png

第一次请求MISS时回源并写入缓存,后面直接读缓存。

添加purge代理缓存功能:

在vhost/baidu.zhengshuiguang.com.conf前半部分中添加:

		location ~ /purge(/.*) {
			allow              127.0.0.1;
			allow              192.168.55.0/24;
			deny               all;
			proxy_cache_purge  cache_one $host$1$is_args$args$slice_range;
		}	

重启nginx,在控制台先建立缓存,保证缓存存在,再访问purge加资源名:

清除代理缓存功能.png


如果需要使用浏览器访问清除指定代理缓存,建议使用代理。

另外还可以通过nginx跳过缓存配置proxy_cache_bypass功能实现无缓存访问。

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

还可以针对含有指定参数(如preview,cauth)的资源实现无缓存访问:

proxy_cache_bypass $arg_preview $arg_cauth;

还可以通过编写条件判断实现nginx缓存规则:

set $nocache 0;
if ($arg_type = "4") {
	set $nocache 1;
}
proxy_cache_bypass $nocache;


通过指定参数跳过代理缓存.png

使用其他参数会被当做成一个新资源,仅type=4的时候BYPASS。

本来想通过条件语句来判断参数中nocache=1的情况下执行proxy_cache_purge指令,却被提示

nginx: [emerg] "proxy_cache_purge" directive is not allowed here

所以,还是使用之前的方式清除缓存更加合适。


我的配置文件如下:

我的nginx配置文件.zip




本文地址:http://blog.zhengshuiguang.com/nginx/nginx-proxy.html

转载随意,但请附上文章地址:-)

标签:镜像

评论已关闭