nginx变量、日志和json格式日志、实现HTTPS、重定向、防盗链、HTTP反向代理、反向代理缓存、自定义首部

nginx变量

nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用,变量可以分为内置变量和自定义变量,内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值

常见内置变量
$remote_addr;#存放了客户端的地址,注意是客户端的公网IP
$args;#变量中存放了URL中的指令
示例:
http://www.test.com/index.html?id=10&a=b
id=10&a=b 即为 $args

$document_root;#保存了针对当前资源的请求的系统根目录,如/apps/nginx/html
$cookie_ name ; #表示key为 name 的cookie值
$document_uri;#保存了当前请求中不包含指令的URI,注意是不包含请求的指令,如http://www.test.com/index.html?id=10&a=b会被定义为/index.html
$host;#存放了请求的host名称
$http_user_agent;#客户端浏览器的详细信息
$http_cookie;#客户端的cookie信息
$limit_rate;#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;#客户端请求Nginx服务器时客户端随机打开的端口
$remote_user;#已经经过Auth Basic Module验证的用户名
$request_body_file;#做反向代理时发给后端服务器的本地资源的名称
$request_method;#请求资源的方式,GET/PUT/DELETE等
$request_filename;#当前请求的资源文件的路径名称,由root或alias指令与URI请求生成的文件绝对路径,如/apps/nginx/html/index.html
$request_uri;#包含请求参数的原始URI,不包含主机名如:main/index.do?id=090&partner=search。
$scheme;#请求的协议,如ftp,https,http等
$server_protocol;#请求资源的协议版本,如HTTP/.0,HTTP/.,HTTP/.0等
$server_addr;#保存了服务器的IP地址
$server_name;#请求的服务器的主机名
$server_port;#请求的服务器的端口

自定义变量:

自定义变量名称和值,使用指令set $variable value

格式如下:
set $variable value;
支持:server, location, if

示例:
set $name test;
echo $name;
set $my_port $server_port;
echo m y p o r t ; e c h o " my_port; echo " myport;echo"server_name:$server_port";

nginx日志和json格式日志

使用ngx_http_log_module模块指定日志格式记录请求

log_format name string …;
string可以使用nginx核心模块及其它模块内嵌的变量

access_log path [format [buffer=size] [gzip[=level]] [flush=time]
[if=condition]];
access_log off; #禁用访问日志
访问日志文件路径,格式及相关的缓冲的配置
buffer=size
flush=time

示例

log_format compression '$remote_addr-$remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

缓存各日志文件相关的元数据信息
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;

max:缓存的最大文件描述符数量
min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项
inactive:非活动时长
valid:验证缓存中各缓存项是否为活动项的时间间隔

自定义json日志格式

nginx 的默认访问日志记录内容相对比较单一,默认的格式也不方便后期做日志统计分析,生产环境中通常将nginx日志转换为json日志,然后配合使用ELK做日志收集-统计-分析

配置示例:

log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';

access_log /apps/nginx/logs/access_json.log access_json;

统计用的python代码示例:

#!/usr/bin/env python
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
	for line in f.readlines():
	line = eval(line)
	if line.get("status") == "200":
		status_200.append(line.get)
	elif line.get("status") == "404":
		status_404.append(line.get)
	else:
		print("状态码 ERROR")
f.close()
print "状态码200的有--:",len(status_200)
print "状态码404的有--:",len(status_404)

nginx实现HTTPS

HTTPS需要加载 ngx_http_ssl_module模块

模块配置:
ssl on | off;
为指定虚拟机启用HTTPS protocol, 建议用listen指令代替

ssl_certificate file;
当前虚拟主机使用PEM格式的证书文件

ssl_certificate_key file;
当前虚拟主机上与其证书匹配的私钥文件

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支持ssl协议版本,默认为后三个

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
none: 通知客户端支持ssl session cache,但实际不支持。
builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有。
[shared:name:size]:在各worker之间使用一个共享的缓存。

ssl_session_timeout time;
客户端连接可以复用ssl session cache中缓存的有效时长,默认5m

示例:
server {
listen 443 ssl;
server_name www.test.com;
root /vhosts/ssl/htdocs;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
}

重定向

需要加载ngx_http_rewrite_module模块
可将用户请求的URI基于PCRE regex所描述的模式进行检查,而后完成重定向替换

语法:
if () { … }
条件满足时,执行配置块中的配置指令.

比较操作符:
= 相同 != 不同
~ 模式匹配,区分字符大小写
~* 模式匹配,不区分字符大小写
!~ 模式不匹配,区分字符大小写
!~* 模式不匹配,不区分字符大小写

文件及目录存在性判断:
-e,!-e 存在与否(包括文件,目录,软链接)
-f,!-f 文件
-d,!-d 目录
-x,!-x 执行

注意: if (condition) { … } 语句中,如果$变量的值为空字符串或是以0开头的任意字符串,则 if 指令认为该条件为false,其它条件为true

示例:

location /test {
	index index.html;
	default_type text/html;
	if ( $scheme = http ){
		return 301 https://www.test.com/;
	}
	if ( $scheme = https ){
		echo "if ----> $scheme";
	}
	if (-f $request_filename) {
		echo "文件存在";
	}
	if (!-f $request_filename) {
		echo "文件不存在";
	return 409;
	}
}

return
return code [text]; #返回客户端指定的状态码和文本说明
return code URL;
return URL;
停止处理,并返回给客户端指定的响应码(包括: 204, 400, 402 — 406, 408,410, 411, 413, 416, 500 — 504),并对 301, 302, 303, 307, 308跳转到URL

rewrite_log on | off;
是否开启重写日志, 发送至error_log(notice level)

set $variable value;
用户自定义变量
注意:变量定义和调用都要以$开头

示例:

location /test {
	root /data/nginx/html;
	default_type text/html;
	index index.html;
	if ( $scheme = http ){
		#return 404;
		return 500 "service error";
		echo "if-----> $scheme"; #return后面的将不再执行
	}
}

rewrite regex replacement [flag] 将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI 注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查。 隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制。 如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端, 即永久重定向301。

[flag]:
last:对某个location的URL匹配成功后会停止当前location的后续rewrite规则,并结束当前location,然后将匹配生成的新URL跳转至其他location继续匹配,直到没有location可匹配后将最后一次location的数据返回给客户端

break:匹配成功后不再向下匹配,也不会跳转到其他的location,即直接结束匹配并给客户端返回结果数据

redirect:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;可使用相对路径,或http://或https://开头,此重定向信息不可缓存,状态码:302

permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,此重定向信息可缓存,状态码:301

示例:

location /break {
	rewrite ^/break/(.*) /test/$1 break; #break不会跳转到其他的location
	return 403 "break";
}

location /last {
	rewrite ^/last/(.*) /test/$1 last; #last会跳转到其他的location继续匹配新的URI
	return 403 "last";
}

location /test {
	return 200 "test";
	index index.html;
	root /data/nginx;
}

将 http 请求跳转到 https
location / {
	if ($scheme = http ) {
		rewrite / https://www.test.com/ redirect;
	}
}

当用户访问到公司网站的时输入了一个错误的URL,可以将用户重定向至官网首页
location / {
	root /data/nginx/html/pc;
	index index.html;
	if (!-f $request_filename) {
		#return 404 "No exsit";
		rewrite (.*) http://www.test.com/index.html;
	}
}

防盗链

需要加载ngx_http_referer_module模块,此模块用于阻止Referer首部无有效值的请求访问,可防止盗链。

配置语法:
valid_referers none|blocked|server_names|string …;
定义referer首部的合法可用值,不能匹配的将是非法值
none:请求报文首部没有referer首部
blocked:请求报文有referer首部,但无有效值
server_names:referer首部中包含本主机名
arbitrary_string:任意字符串,但可使用*作通配符
regular expression:被指定的正则表达式模式匹配到的字符串,要使用~开头,例如匹配test.com的子域名: ~.*\.test\.com

示例:

server{
	listen 80
	valid_referers none block server_names
	*.test.com  test.* ~\.google\. ~\.baidu\.com;
	if ($invalid_referer) {
		return 403 "Forbidden Access";
	}
}

HTTP反向代理

反向代理:reverse proxy,可代理外网用户的请求到内部的指定web服务器,并将数据返回给用户

nginx除了可以在企业提供高性能的web服务之外,另外还可以将本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是nginx服务器与其他服务器进行通信的一种规范

主要在不同的场景使用以下模块实现不同的功能:
ngx_http_proxy_module: 将客户端请求以http协议转发至后端服务器
ngx_http_fastcgi_module:将客户端对php请求以fastcgi协议转发至后端
ngx_http_uwsgi_module:将客户端对Python请求以uwsgi协议转发至后端
ngx_stream_proxy_module:将客户端请求以tcp协议转发至后端服务器

同构代理:不需要转换协议,例如nginx访问后端的nginx、apache都是http协议,mysql是TCP协议。

异构代理:需要转换协议,例如访问php需要使用fastcgi

ngx_http_proxy_module模块

1.proxy_pass后面路径不带uri时,会将location的uri传递(附加)给后端主机

示例:

server {
	server_name www.test.com;
	location /data/ {
		proxy_pass http://192.168.1.11:8080; 注意:最后没有/
	}
} 

上面示例:http://www.test.com/data --> http://192.168.1.11:8080/data,功能类似 root,
如果上面示例中有 /,即:http://192.168.1.11:8080/data/ 此方式较少使用意味着:http:/www.test.com/data --> http://192.168.1.11:8080/data/ ,功能类似 alias

2.proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri

server {
	server_name HOSTNAME;
	location /data/ {
		proxy_pass http://192.168.1.11:8080/admin/;
	}
}

http:/www.test.com/data/ --> http://192.168.1.11:8080/admin/

3.如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后不能使用uri; 用户请求时传递的uri将直接附加至后端服务器之后

server {
	server_name HOSTNAME;
	location ~|~* /data/ {
		proxy_pass http://192.168.1.11:8080; 不能加/
	}
}
http:/www.test.com/testdata/ --> http://192.168.1.11:8080/testdata/

其他配置

proxy_set_header
设定转发往后端主机的请求报文的请求首部的值,可以把客户端的IP也传给后端服务器。

语法:
proxy_set_header field value;

示例:

反向代理设置
location /data {
	proxy_set_header C-IP $remote_addr;
	proxy_pass http://192.168.1.11:8080; 
}

后端服务器添加日志格式
LogFormat "\"%{C-IP}i"

也可以使用$proxy_add_x_forwarded_for变量,这样会把途径的代理服务器IP也记下来
proxy_set_header X-Forwarded $proxy_add_x_forwarded_for;
请求报文的标准格式如下:
X-Forwarded: client1, proxy1, proxy2

proxy_hide_header field
用于隐藏后端服务器特定的响应首部,默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等
示例:
proxy_hide_header Etag;

proxy_pass_header field
默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端

proxy_connect_timeout time;
定义与后端服务器建立连接的超时时长,如超时会出现502错误,默认为60s,一般不建议超出75s

proxy_send_timeout time;
对后端服务器send,将请求发送给后端服务器的超时时长;默认为60s

proxy_read_timeout time;
从后端服务器read,等待后端服务器发送响应报文的超时时长,默认为60s

proxy_ignore_client_abort off;
当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后nginx也会中断客户端请求并立即记录499日志,默认为off

proxy_http_version 1.0;
用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0

proxy_headers_hash_bucket_size 128;
当配置了 proxy_hide_header和proxy_set_header的时候,用于设置nginx保存HTTP报文头的hash表的上限

proxy_headers_hash_max_size 512;
设置proxy_headers_hash_bucket_size的最大可用空间

server_namse_hash_bucket_size 512;
server_name hash表申请空间大小

server_names_hash_max_size 512;
设置服务器名称hash表的上限大小

反向代理缓存

定义可用于proxy功能的缓存:proxy_cache_path
只能写在http语句块中

配置说明:

proxy_cache_path /var/cache/nginx/proxy_cache
定义缓存保存路径,proxy_cache会自动创建

levels=1:2:2
定义缓存目录结构层次,1:2:2 可以生成2^4x2^8x2^8=1048576个目录

keys_zone=proxycache:20m
内存中缓存的大小,主要用于存放key和metadata,例如使用次数

inactive=120s;
缓存有效时间

max_size=1g;
最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值

proxy_cache zone | off; 默认off
开启或关闭缓存机制;可以写在http, server, location

proxy_cache_key string;
缓存中用于“键”的内容
默认值:proxy_cache_key $scheme$proxy_host$request_uri;

proxy_cache_valid [code …] time;
对特定响应码的响应内容的缓存时长,写在http中
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

proxy_cache_use_stale;
proxy_cache_use_stale error | timeout | invalid_header | updating |
http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off …
在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端

proxy_cache_methods GET | HEAD | POST …;
对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存

配置示例:

在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache
levels=1:2:2 
keys_zone=proxycache:20m
inactive=120s 
max_size=1g ;

调用缓存功能,需要定义在相应的配置段,如server
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;

自定义首部

需要加载ngx_http_headers_module模块,可向发往客户端的响应报文添加自定义首部,或修改指定首部的值。

add_header name value [always];
添加自定义首部
示例:
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;

add_trailer name value [always];
添加自定义响应信息的尾部, 1.13.2版后支持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值