nginx 高级配置

其他配置
keepalive_disable none | browser ...;
对某种浏览器禁用长连接
limit_except method ... {...},只用于location
限制客户端使用除了制定的请求方法之外的其他方法;
method:GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
#默认访问方式为HEAD ,除了GET和HEAD外其他方法仅允许192.168.10.99,192.168.0.0网段使用。
limit_except GET {
allow 192.168.10.99;
allow 192.168.0.0/24;
deny all;
}

#是否启用asynchronous file I/O(AIO)功能,需要重新编译开启
aio on | off
linux 2.6以上内核提供一下几个系统调用来支持aio;
1、SYS_io_setup: 建立aio 的context
2、SYS_io_submit: 提交I/O操作请求
3、SYS_io_getevents: 获取已完成的I/O事件
4、SYS_io_cancel: 取消I/O操作请求
5、SYS_io_destroy: 销毁aio的context
#操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接I/O,默认为关闭,当文件大于邓宇给定大小时,如:
directio 4m,同步(直接)写磁盘,而非缓存。
direction size | off;
open_file_cache off; #是否缓存打开过的文件信息
open_file_cache max=N [inactive=time];
nginx可以缓存一下三种信息
1、文件元数据:文件的描述符、文件大小和最近一次的修改时间。
2、打开的目录结构
3、没有找到的或者乜有权限访问的文件的相关信息
max=N:可缓存的缓存项上限数量;达到上限后悔使用LRU(Least recently used,最近最少使用)算法实现
inactive=time: 缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指定所
指定的次数的缓存项即为非活动向,将被删除。
open_file_cache_errors on | off;
是否缓存查找时发生错误的文件一类的信息,默认 off
open_file_cache_min_uses number;
open_file_cache指令的inactive参数指定的时长内,至少被命中次数指定的次数方可被归类为活动项默认为1
open_file_cache_vali time;
缓存项有效性的检查验证频率,默认为60s

open_file_cache max=10000 inactive=60s; 最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid 60s; 每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5; 60s内至少被命中访问5次才被标记为活动数据
open_file_cache_errors on; 缓存错误信息

server_tokens off; 隐藏nginx server版本。


高级配置
nginx状态页
ngx_http_auth_basic_module
location /nginx_status {
stub_status;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}

curl 127.0.0.1/status
Active connections: 1
server accepts handled requests
1 1 1
Reading: 0 Writing: 1 Waiting: 0

上⾯三个数字分别对应accepts,handled,requests三个值
Active connections: 当前处于活动状态的客⼾端连接数,包括连接等待空闲连接数。
accepts:统计总值,Nginx⾃启动后已经接受的客⼾端请求的总数。
handled:统计总值,Nginx⾃启动后已经处理完成的客⼾端请求的总数,通常等于accepts,除⾮有因 worker_connections限制等被拒绝的连接。
requests:统计总值,Nginx⾃启动后客⼾端发来的总的请求数。
Reading:当前状态,正在读取客⼾端请求报⽂⾸部的连接的连接数。
Writing:当前状态,正在向客⼾端发送响应报⽂过程中的连接数。
Waiting:当前状态,正在等待客⼾端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于 active – (reading+writing),

第三方模块
nginx功能模块扩展(定制开发或开源)需重新编译
--add-module=PATH(模块路径)

内置变量
$remote_addr 存放了库环段的地址,公网IP
$args 存放了URL中的指令, http://www.baidu.com/main/index.do?id=20932849023894&partner=search 中id=20932849023894&partner=search
$document_root 保存了针对当前资源的请求的系统根目录,如 /apps/nginx/html
$document_url 保存了当前请求中不包含指令的URI 如 http://www.admin.net/main/index.do?id=20190221&partner=search 会被定义为/main/index.do
$host 存放了请求的host名称
$http_user_agent 客户端浏览器的详细信息
$http_cookie 客户端的cookie信息
limit_rate_10240
echo $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请求生成文件绝对路径,如 /app/nginx/html/main/index.html
$request_uri 包含请求参数的原始URI,不包含主机名,如: /main/index.do?id=3424234&partner=search
$scheme 请求的协议,如 ftp,https,http等
$server_protocol 保存了客户端请求资源使用的协议的版本,如 HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr 保存了服务器的IP地址
$server_name 请求的服务器的主机名
$server_port 请求的服务器的端口号

自定义变量
指令 set $variable value
set $name magedu
echo $name
set $my_port $server_port
echo $my_port
echo $server_name:$server_port

自定义访问日志
log_format access_json '{"@timestamp": "$time_iso8601",'
'"host": "$server_addr",'
'"clintip": "$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 /usr/local/nginx/logs/access_json.log access_json;

curl 127.0.0.1/status
{"@timestamp": "2020-12-16T14:18:22+08:00","host": "127.0.0.1","clintip": "127.0.0.1","size":"97","responsetime":"0.000","upstreamtime":"-","upstreamhost":"-","http_host":"127.0.0.1","uri":"/status","domain":"127.0.0.1","xff":"-","referer":"-","tcp_xff":"","http_user_agent":"curl/7.29.0","status":"200",}

json格式的日志访问统计
#!/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压缩功能
可以设置压缩比例,降低出口带宽利用率,占用响应的CPU资源
ngx_http_gizp_module

#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高1到9,默认1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\."
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1
#指定nginx服务需要向服务器申请的缓存空间的个数*大小,默认32 4k|16 8k
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_type test/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启动压缩,是否在响应报文收不插入"Vary: Accept-Encoding"
gzip_vary on | off

https功能
https 有两部分组成: http + SSL/TLS 服务端和客户端的信息传输都会通过TLS进行加密,所以传输逇数据都是加密后的数据

ssl配置参数
ngx_http_ssl_module
#为指定的虚拟主机配置是否启用sll功能,此功能在1.15.0废弃,使用 listen [ssl] 代替
ssl on | off
#当前虚拟主机使用的公钥文件,一般是crt文件
ssl_certificate /path/to/file;
#当前虚拟主机使用的私钥文件,一般是 key 文件
ssl_certificate_key /path/to/file;
#只吃ssl协议版本,早期为sll,现在是TSL,默认为后三个
ssl_protocols [SSLv2] [SSLv3] [TLSv1.1] [TLSv1.2];
#配置sll缓存
ssl_session_cache off | none | [builtin[:size]] [shared:name:size]
off: 关闭缓存
none: 通知客户端支持ssl session cache,但实际不支持
builtin[:size]: 使用openSSL内建缓存,为worker进程私有
[shared:name:size]: 在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存控件大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
#客户端连接可以服用ssl session cache中缓存的有效时长 默认5m
ssl_seeion_timeout time;

自签名证书
自签名CA证书
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
自制key和csr文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.magedu.net.key -out www.magedu.net.csr
签发证书
openssl x509 -req -days 3650 -in www.magedu.net.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.magedu.net.crt
验证证书内容
openssl x509 -in www.magedu.net.crt -noout -text

nginx证书配置
listen 80;
listen 443 ssl;
ssl_certificate /usr/local/nginx/ssl/www.magedu.net.crt;
ssl_certificate_key /usr/local/nginx/ssl/www.magedu.net.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;

实现多域名HTTPS
nginx只吃基于单个IP实现多域名的功能,并且还支持单IP多域名的基础之上实现HTTPS,其实是基于nginx的SNI功能实现,
SNI是为了解决一个nginx服务器内使用一个IP绑定多个域名和整数的功能,其具体功能是客户端在连接到服务器建立SSL连
接之前先发送要访问站点的域名 HOSTNAME,服务器再根据这个域名放回给客户端一个合适的证书。


favicon.ico问题
favicon.ico 文件是浏览器收藏网址时显示的图标。当客⼾端使⽤浏览器问⻚⾯时,浏览器会⾃⼰主动发起请求获取
⻚⾯的favicon.ico⽂件,但是当浏览器请求的favicon.ico⽂件不存在时,服务器会记录404⽇志,⽽且浏览器也会
显⽰404报错。
解决办法:
一、服务器不记录访问日志
location = /favicon.ico {
log_not_found off;
access_log off;
}
二、图标保存到指定目录访问
#location - ^/favicon\.ico$ {
location = /favicon.ico{
root /data/nginx/html/pc/images;
expires 90d;设置文件过期时间
}


安全选项
隐藏nginx版本号
更改nginx源码信息并重新编译nginx
vim src/http/ngx_http_header_filter_module.c
#定义响应报文中的server 字段信息
49 static u_char ngx_http_server_string[] = "Server: linux38" CRLF;

升级OpenSSL版本:
只要 使⽤的是存在缺陷的OpenSSL实例,⽆论是服务器还是客⼾端,都可能因此⽽受到攻击。此问题的原因是在实现
TLS的⼼跳扩展时没有对输⼊进⾏适当验证(缺少边界检查),因此漏洞的名称来源于“⼼跳”(heartbeat)。该程
序错误属于缓冲区过读,即可以读取的数据⽐应该允许读取的还多。
准备OpenSSL源码包:
# pwd
/usr/local/src
# tar xvf openssl-1.1.1d
编译安装Nginx并制定新版本OpenSSL路径:
# cd /usr/local/src/nginx-1.16.1/
#./configure --prefix=/apps/nginx --user=nginx --group=nginx \
--with-http_ssl_module -- with-http_v2_module --with-http_realip_module \
--with-http_stub_status_module --with- http_gzip_static_module --with-pcre \
--with-stream --with-stream_ssl_module --with- stream_realip_module \
--with-select_module --with-file-aio --add- module=/usr/local/src/echo-nginx-module \
--with-openssl=/usr/local/src/openssl-1.1.1d # make && make install
验证并启动Nginx:
# /apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
# /apps/nginx/sbin/nginx

aio on | off #是否启⽤asynchronous file I/O(AIO)功能,需要编译开启
linux 2.6以上内核提供以下⼏个系统调⽤来⽀持aio:
1、SYS_io_setup:建⽴aio 的context
2、SYS_io_submit: 提交I/O操作请求
3、SYS_io_getevents:获取已完成的I/O事件
4、SYS_io_cancel:取消I/O操作请求
5、SYS_io_destroy:毁销aio的context
directio size | off; 操作完全和aio相反,aio是读取文件而direction是写文件到磁盘,启用直接I\O,默认为关闭
当文件大于等于给定大小时,如 direction 4m,同步写磁盘 而非写缓存
open_file_cache off; 是否缓存打开过的文件信息
open_file_cache max=N [inactive=time];
nginx可以缓存以下三种信息:
(1) ⽂件元数据:⽂件的描述符、⽂件⼤⼩和最近⼀次的修改时间
(2) 打开的⽬录结构
(3) 没有找到的或者没有权限访问的⽂件的相关信息 max=N:可缓存的缓存项上限数量;达到上限后会使⽤LRU(Least recently used,最近最少使⽤)算法实现
管理
inactive=time:缓存项的⾮活动时⻓,在此处指定的时⻓内未被命中的或命中的次数少于
open_file_cache_min_uses指令所指定的次数的缓存项即为⾮活动项,将被删除
是否缓存查找时发⽣错误的⽂件⼀类的信息 默认值为off
open_file_cache_errors on | off;
open_file_cache_min_uses number;
open_file_cache指令的inactive参数指定的时⻓内,⾄少被命中此处指定的次数⽅可被归类为活动项 默认值为1
open_file_cache_valid time;
缓存项有效性的检查验证频率,默认值为60s
open_file_cache max=10000 inactive=60s; #最⼤缓存10000个⽂件,⾮活动数据超时时⻓60s
open_file_cache_valid 60s; #每间隔60s检查⼀下缓存数据有效性
open_file_cache_min_uses 5; #60秒内⾄少被命中访问5次才被标记为活动数据
open_file_cache_errors on; #缓存错误信息
server_tokens off; #隐藏Nginx server版本。

nginx rewrite相关功能
ngx_http_rewrite_module
用于实现URL的重写,URL的重写是非常用的功能
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

if指令
if (条件匹配) {
action
}
=: #⽐较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false。
!=: #⽐较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false。
~: #表⽰在匹配过程中区分⼤⼩写字符,(可以通过正则表达式匹配),满⾜匹配条件为真,不满⾜为假。
!~:#为区分⼤⼩写字符且匹配结果不匹配,不满⾜为真,满⾜为假。
~*: #表⽰在匹配过程中不区分⼤⼩写字符,(可以通过正则表达式匹配),满⾜匹配条件为真,不满⾜为假。
!~*: #为不区分⼤⼩字符且匹配结果不匹配,满⾜为假,不满⾜为真。
-f 和 ! -f: #判断请求的⽂件是否存在和是否不存在
-d 和 ! -d: #判断请求的⽬录是否存在和是否不存在。
-x 和 ! -x: #判断⽂件是否可执⾏和是否不可执⾏。
-e 和 ! -e: #判断请求的⽂件或⽬录是否存在和是否不存在(包括⽂件,⽬录,软链接)。
实例:
location /main {
index index.html;
default_type text/html;

if ( $scheme = http ){
echo "if------> $scheme";
}
if ( $scheme = https ){
echo "if -----> $scheme";
}
if ( -f $request_filename){
echo "file is exist";
}
if (!-f $request_filename){
echo "file is not exist";
return 409;
}
}
如果$变量的值为空字符串或是以0开头的任意字符串,则if指令认为该条件为false,其他条件为true。

set指令:
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name magedu;
echo $name; set $my_port $server_port;
echo $my_port;
}

break指令
⽤于中断当前相同作⽤域(location)中的其他Nginx配置,与该指令处于同⼀作⽤域的Nginx配置中,
位于它前⾯的 配置⽣效,位于后⾯的指令配置就不再⽣效了,Nginx服务器在根据配置处理请求的过程中
遇到该指令的时候,回 到上⼀层作⽤域继续向下读取配置,该指令可以在server块和location块以及if块中使⽤,使⽤语法如下:
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name magedu;
echo $name; break;
set $my_port $server_port;
echo $my_port;
}

return指令
return⽤于完成对请求的处理,并直接向客⼾端返回响应状态码,⽐如其可以指定重 定向URL(对于特殊重定向状态码,301/302等)
或者是指定提⽰⽂本内容(对于特殊状态码403/500等),处于此指令 后的所有配置都将不被执⾏,
return可以在server、if和location块进⾏配置,⽤法如下:
return code; #返回给客⼾端指定的HTTP状态码
return code (text); #返回给客⼾端的状态码及响应体内容,可以调⽤变量
return code URL; #返回给客⼾端的URL地址
例如:
location /main {
root /data/nginx/html/pc;
default_type text/html;
index index.html;
if ( $scheme = http ){
#return 666;
#return 666 "not allow http";
#return 301 http://www.baidu.com;
return 500 "service error";
echo "if-----> $scheme";
#return后⾯的将不再执⾏
}
if ( $scheme = https ){
echo "if ----> $scheme";
}

rewrite_log指令
设置是否开启记录ngx_http_rewrite_module 模块日志记录到error_log日志文件当中,可以配置在http、server、location或if
当中,需要日志级别为notice
location /main {
index index.html;
default_type text/html;
set $name magedu;
echo $name;
rewrite_log on;
break;
set $my_port $server_port;
echo $my_port;
}

rewrite指令
rewrite regex replacement [flag];
rewrite ^(.*) http://www.baidu.com break;
注意: 如果在同⼀级配置块中存在多个rewrite规则,那么会⾃下⽽下逐个检查;被某条件规则替换完成后,
会重新⼀轮 的替换检查,隐含有循环机制,但不超过10次;如果超过,提⽰500响应码,
[flag]所表⽰的标志位⽤于控制此循环 机制,如果替换后的URL是以http://或https://开头,则替换结果会直接以重向返回给客⼾端, 即永久重定向301

rewrite flag 介绍
rewrite regex replacement [flag];
nginx的rewrite的指令,实现url的重新跳转,rewrite有四种flag redirect(临时重定向) permanem(永久重定向) break last
前两种是跳转型flag,后两种是达理型,条转型是指有客户端浏览器重新对新地址进行请求, 代理型是在WEB服务器内部实现跳转的。
redirect; #临时重定向,重写完成后以临时重定向⽅式直接返回重写后⽣成的新URL给客⼾端,由客⼾端重新发起请求;使⽤相对 路径,或者http://或https://开头,状态码:302
permanent; #重写完成后以永久重定向⽅式直接返回重写后⽣成的新URL给客⼾端,由客⼾端重新发起请求,状态码:301
last; #重写完成后停⽌对当前URI在当前location中后续的其它重写操作,⽽后对新的URL启动新⼀轮重写检查,不建议在 location中使⽤
break; #重写完成后停⽌对当前URL在当前location中后续的其它重写操作,⽽后直接将匹配结果返还给客⼾端即结束循环并 返回数据给客⼾端,建议在location中使⽤

rewrite案例 域名永久与临时重定向
永久重定向: 会缓存DNS解析记录
临时重定向: 不会缓存当前域名的解析记录
将访问源域名 www.magedu.net 的请求永久重定向到 www.magedu.com
临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
location / {
root /data/nginx/html/pc;
index index.html;
rewrite / http://www.magedu.com permanent;
#rewrite / http://www.magedu.com redirect;
}

rewrite案例 break与last
访问about的请求被转发至images,而访问images传递请求再次转发至images1

break案例
cat /usr/local/nginx/break/index.html
break
cat /usr/local/nginx/test1/index.html
test1
cat /usr/local/nginx/test2/index.html
test2
location /break {
root /usr/local/nginx;
index index.html;
#break匹配成功后不再向下匹配,也不会跳转到其他的location,即直接结束匹配并给客户端返回结果数据。
rewrite ^/break/(.*) /test1/$1 break;
#break 不会屁屁额后面的rewrite规则也不匹配其他location
rewrite ^/test1/(.*) /test2/$1 break;
}
location = /test1 {
retrun 999 "new test1";
}
location = /test2 {
return 666 "new test2";
}
#最终的结果不会超过break的location而且不会继续匹配当前location后续的write规则,而且直接返回数据给客户端。
curl -L http://www.magedu.net/break/index.html
test1
break使用于不改变客户端访问方式,但是要将访问的目的URL做单词重写的场景,比如有v1/v2两个版本的网站前端页面
并存,旧版本的网站数据已经保存到了statics不能丢失,但是要将访问新版本的资源重写到新的静态资源路径到新的目录static:
location /statics {
root /data/nginx;
index index.html;
rewrite ^/statics/(.*) /static/$1 break;
}

last案例:
last 使用于要不改变客户端访问方式但是需要做多次目的的URL重写的场景,场景不是很多。
对某个location的URL匹配成功后悔停止当前location的后端rewrite规则,病结束当前location,然后将匹配生成的新URL跳转
至其他location继续匹配,知道没有location可匹配后将最后一次location的数据返回给客户端。
location /test1 {
index index.html;
root /usr/local/nginx;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test2 {
return 666 "new test2";
}
location /last {
root /usr/local/nginx;
index index.html;
rewrite ^/last/(.*) /test1/$1 last;
#rewrite ^/test1/(.*) /test2/$1 last;#如果第一条rewrite规则匹配成功则不执行本条,否则执行本条rewrite规则。
}
curl -L http://www.magedu.net/last/index.html
new test2 #会匹配多个location,直到最终全部匹配完成,返回最后一个location的匹配结果给科幻短。

rewrite案例-自动跳转https:
http强制跳转https
server块内
server {
listen 80;
server_name www.magedu.net;
}
rewrite ^(.*)$ https://$host$1;
另外一只节省资源的做法
index.html
<html>
<meta http-equiv="refresh" content="0;url=https://www.baidu.com">
</html>

location块内
server {
listen 443 ssl;
listen 80;
server_name www.magedu.net;
...
location / {
root /usr/local/nginx/html/pc;
index index.html;
if {$scheme = http }{ #不加条件判断会导致死循环
rewrite / https://www.magedu.net pernament;
}
}
}

rewrite-判断文件是否存在-跳转
location {
root /usr/local/nginx/html/pc;
index index.html;
if (!-f $request_filename){
#return 404 '页面不存在'
rewrite (.*) http://www.magedu.net/index.html;
}
}

nginx 防盗链
防盗链基于客户端鞋带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,
如果别人只连接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是倒链,referer就是之前
的那个网站域名,正常的referer信息有以下几种:
none: 请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息
blocked: 请求报文有referer首部,但无有效值,比如为空
server_names: referer首部中包含本主机名及即nginx监听的server_name
arbitrary_string: 自定义指定字符串,但可使用*作通配符
regular expression: 被指定的正则表达式模式匹配到的字符串,要使用~开头,如: ~.*\.magedu\.com.
访问日志中 referer: https://www.baidu.com/...

实现防盗链
ungx_http_referer_module
location ^~ /images {
root /data/nginx;
index index.html;
#定义有效的referer
valid_referers none blocked server_names *.magedu.com www.magedu.* api.online.test/v1/hostlist ~\.google\. ~\.baidu\.;
#加入是使用其他的无效的referer访问;
if ($invalid_referer) {
#返回状态码403
return 403;
}
}

nginx反向代理功能:
反向代理: reverse proxy,指的是代理外网用户的请求到内部的指定web服务器,并将数据返回给用户的一种方式。
不同的场景使用不同的模块功能
ngx_http_proxy_module: 将客户端的请求以http协议转发至服务器进行处理
ngx_stream_proxy_module: 将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module: 将客户端对php的请求以fastcgi协议转发至指定服务器处理
ngx_http_uwsgi_module: 将客户端对python的请求以uwsgi协议转发至指定服务器处理

nginx http 反向代理
官⽅⽂档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
将用户访问 www.magedu.net 的访问转发到后端服务器
配置参数
proxy_pass;
用来设置将客户端请求转发给的后端服务器的主机,可以是主机名、IP地址:端口 的方式,
也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持。
location /web {
index index.html;
proxy_pass http://192.168.7.103:80;
不带斜线将访问的/web,等于访问后端服务器 http://192.168.7.103:80/web/index.html,即
后端服务器配置的站点根目录要有web目录才可以被访问,这事一个追加/web到后端服务器。
http://servername:port/WEB/INDEX.HTML

proxy_pass http://192.168.7.103:80/;
带斜线,等于访问后端服务器的http://192.168.7.103:80/index.html内容返回给客户端
}
proxy_hide_header field;
用于nginx作为反向代理的时候,在返回给客户端http响应的时候,隐藏后端服务版本相应头部
的信息,可以设置在 http/server或location块
location /web {
index index.html;
proxy_pass http://192.168.7.103:80/;
proxy_hide_header ETag;
}
proxy_pass_header field;
默认nginx在响应报文中不传递后端服务器的首部字段Date,server, x-pad, x-accel等参数
如果要传递的话则要使用proxy_pass_header field声明将后端服务器返回的值传递给客户端
proxy_pass_request_body on | off
是否向后端服务器发送HTTP body 不分,可以设置在http/server或location块,默认为开启
proxy_pass_request_headers on | off
是否将客户端的请求头部转发给后端服务器,可以设置在http/server或location块默认开启
proxy_set_header;
可以更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客
户端的真实IP的时候,就要更改每一个报文的头部,如:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;
添加HOST到报文头部,如果客户端为NAT上网那么其值为客户端的共用的公网IP地址,常用于在
日志中记录客户端的真实IP地址。
proxy_connect_timeout time;
配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒,用法如:
proxy_connect_timeout 60s;
60s为自定义nginx与后端服务器建立连接的超时时间。
proxy_read_time time;
配置nginx服务器向后端服务器或服务器组成发起read请求后,等待的超时时间,默认60s
proxy_sed_time time;
配置nginx向后端服务器或服务器组发起write请求后,等待的超时时间,默认 60s
proxy_http_version 1.0;
用于设置nginx提供代理服务器的HTTP协议的版本,默认http 1.0
proxy_ignore_client_abort off;
当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求,即如果此项设置为on开启
则服务器会忽略客户端中断并一直等着代理服务之星返回,如果设置为off,则客户端中断后nginx
也会中断客户端请求并立即记录499日志,默认为off
proxy_headers_heash_bucket_size 128;
当配置了 proxy_hide_header和 proxy_set_header的时候,用于设置nginx保存HTTP报文头
的hash表的上限
proxy_headers_hash_max_size 512;
设置proxy_headers_hash_bucket_size的最大可用空间
server_names_hash_bucket_size 512;
server_name hash 表申请空间大小
server_names_hash_max_sieze 512;
设置服务器名称hash表的上限大小

反向代理-缓存功能
proxy_cache zone | off;默认off
指明调用的缓存,或关闭缓存机制;Context:http,server,location
proxy_cache_key string;
缓存中用于“键”的内容,默认值 proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
定义对特定响应码的响应内容的缓存市场,定义在http{...}中
proxy_cache_path;
定义可用于proxy功能的缓存; Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size]
[manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time]
[loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
实例:
在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; #最大磁盘占用空间,磁盘存入文件内容的缓存控件最大值。

调用缓存功能,需要定义在响应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间。
proxy_cache_valid any 1m;

proxy_cache_use_stale error http_502 http_503;
在被代理的后端服务器出现哪种情况下, 可直接使用过期的缓存响应客户端。
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 |
http_503 | http_504 | http_403 | http_404 | off; #默认是off
#对哪些客户端请求方法对应的响应警醒缓存,GET和HEAD方法总是被缓存。
proxy_cache_methods GET | HEAD | POST ...;

添加头部报文信息:
ngx_http_headers_module
syntax: add_header name value [always];
Dfault: -
Context: http, server, location, if in location

添加自定义首部;
add_header name value [always];
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
添加自定义响应信息的尾部,1.13.2版本后支持
add_trailer name value [always];

nginx实例配置:
location /web {
proxy_pass http://192.168.0.99/;
proxy_set_header clientip $remote_addr;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status; #缓存后标记为HIT 为缓存是 MISS
add_header X-Accel $server_name;
}

http upstream配置参数;
upstream name {
#定义一组服务器,配置在http内
}
#设置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
server address [parameters];

#server支持的parameters如下
weight=number #设置权重,默认为1
max_consns=number #给当前server设置最大活动连接数,默认0表示没有限制
max_fails=number #对后端服务器连续监测失败多少次就标记为不可用
fail_timeout=time #对后端服务器的单词监测超时时间,默认为10秒
backup #设置备份服务器,当前所有服务器不可用时将重新启用次服务器
down #标记为down状态
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx

hash KEY consistent;
#基于指定key做hash计算,使用consistent参数,将使用ketama一致性hash算法,使用于后端是Cache服务器
(如varnish)时使用,consistent定义使用已执行hash运算,一致性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
ip_hash; #原地址hash调度方法,基于客户端的remote_addr(源地址)做hash计算,以实现会话保持
least_conn; #最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器。
实例:
upstream webserver {
#hash $request_uri consistent;
#ip_hash;
#least_conn;
server 192.168.7.003:80 weight=1 fail_timeout=5s max_fils=3 #后端服务器状态监测
server 192.168.7.104:80 weight=1 fail_timeout=5s max_fails=3;
server 192.168.7.101:80 weight=1 fail_timeout=5s max_fails=3 backup;
}

server {
listen 80;
server_name www.magedu.net;
location / {
index index.html index.php;
root /data/nginx/html/pc;
}

location /web {
index index.html;
proxy_pass http://webserver/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #添加客户端IP到报文头部传给后端服务器
}
}

nginx tcp负载均衡
ngx_stream_proxy_module

stream { #定义stream
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法

server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 192.168.0.1:53535; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 123456; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}

负载均衡--redis;
stream {
upstream redis_server {
#hash $remote_addr consistent;
server 192.168.7.104:6379 max_fails=3 fail_timeout=30s;
}
server {
listen 192.168.7.102:6379;
proxy_connect_timeout 3s;
proxy_timeout 3s;
proxy_pass redis_server;
}
}

负载均衡--mysql
stream {
upstream redis_server {
server 192.168.7.104:6379 max_fails=3 fail_timeout=30s;
}
upstream mysql_server {
least_conn;
server 192.168.7.104:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 192.168.7.102:3306;
proxy_connect_timeout 6s;
proxy_timeout 15s;
proxy_pass mysql_server;
}
server {
listen 192.168.7.102:6379;
proxy_connect_timeout 3s;
proxy_timeout 3s;
proxy_pass redis_server;
}
}

FastCGI配置指令:
fastcgi_pass address;
#转发请求到后端服务器,address为后端的fastcgi server 的地址,可用位置:location,if in location

fastcgi_index name;
#fastcgi 默认的主页资源,示例: fastcgi_index index.php;

fastcgi_param parameter value [if_not_empty];
#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将nginx的内置变量赋值给自定义key
fastcgi_param REMOTE_ADDR #remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT #remote_port; #客户端源端口
fastcgi_param SERVER_ADDR #server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT #server_port; #请求的服务器端口
fastcgi_param SERVER_NAME #server_name; #请求额server name

nginx默认配置示例:
location - \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径
include fastcgi_params;
}
缓存定义指令:
fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time]
[max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time]
[purger_threshold=time];
定义fastcgi的缓存;
path #缓存位置为磁盘上的⽂件系统路径
max_size=size #磁盘path路径中⽤于缓存数据的缓存空间上限
levels=levels:#⼗六进制的缓存⽬录的层级数量,以及每⼀级的⽬录数量,levels=ONE:TWO:THREE,⽰ 例:leves=1:2:2
keys_zone=name:size #设置缓存名称及k/v映射的内存空间的名称及⼤⼩
inactive=time #缓存有效时间,默认10分钟,需要在指定时间满⾜fastcgi_cache_min_uses 次数被视为 活动缓存。

缓存调用指令:
fastcgi_cache zone | off;
#调用指定的缓存控件来缓存数据,可用位置: http, server, location
fastcgi_cache_key string;
#定义用作缓存项的key的字符串,示例: gastcgi_cache_key $request_uri;
fastcgi_cache_methods GET | HEAD | POST ...;
#为哪些请求方法使用缓存
fastcgi_cache_min_uses number;
#缓存控件中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项
fastcgi_keep_conn on | off;
#收到后端服务器响应后,fastcgi服务器是否关闭连接,建议启用长连接
fastcgi_cache_valid [code...] time;
#不通的响应码各自的缓存时长
fastcgi_hide_header field; #隐藏响应头指定信息
fastcgi_pass_header field; #返回响应偷指定信息,默认不会将Status、X-Accel-...返回

FastCGI⽰例--Nginx与php-fpm在同⼀服务器
php相关配置优化
[root@s2 ~]# grep "^[a-Z]" /etc/php-fpm.conf
include=/etc/php-fpm.d/*.conf
pid = /run/php-fpm/php-fpm.pid
error_log = /var/log/php-fpm/error.log
daemonize = yes #是否后台启动
[root@s2 ~]# cat /etc/php-fpm.d/www.conf
[www] listen = 127.0.0.1:9000 #监听地址及IP
listen.allowed_clients = 127.0.0.1 #允许客⼾端从哪个源IP地址访问,要允许所有⾏⾸加 ;注释即可
user = nginx #php-fpm启动的⽤⼾和组,会涉及到后期⽂件的权限问题
group = nginx pm = dynamic #动态模式进程管理
pm.max_children = 500 #静态⽅式下开启的php-fpm进程数量,在动态⽅式下他限定php-fpm的最⼤进程数
pm.start_servers = 100 #动态模式下初始进程数,必须⼤于等于pm.min_spare_servers和⼩于等于 pm.max_children的值。
pm.min_spare_servers = 100 #最⼩空闲进程数
pm.max_spare_servers = 200 #最⼤空闲进程数
pm.max_requests = 500000 #进程累计请求回收值,会回收并重新⽣成新的⼦进程
pm.status_path = /pm_status #状态访问URL ping.path = /ping #ping访问动地址
ping.response = ping-pong #ping返回值
slowlog = /var/log/php-fpm/www-slow.log #慢⽇志路径
php_admin_value[error_log] = /var/log/php-fpm/www-error.log #错误⽇志
php_admin_flag[log_errors] = on php_value[session.save_handler] = files #phpsession保存⽅式及路径
php_value[session.save_path] = /var/lib/php/session #当时使⽤file保存session的⽂件路径
Nginx配置转发:
[root@s2 ~]# vim /apps/nginx/conf/conf.d/pc.conf #在指定⽂件配置fastcgi
location ~ \.php$ {
root /data/nginx/php; #$document_root调⽤root⽬录
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /data/nginx/php$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#如果SCRIPT_FILENAME是绝对路径则可以省略root /data/nginx/php;
include fastcgi_params;
}
fastcgi_pass常⻅的错误:
File not found. #路径不对
502: php-fpm处理超时、服务停⽌运⾏等原因导致的⽆法连接或请求超时

php-fpm 的运⾏状态⻚⾯
location ~ ^/(pm_status|ping)$ {
#access_log off;
#allow 127.0.0.1;
#deny all;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param PATH_TRANSLATED
$document_root$fastcgi_script_name;
}

Nginx与php不在同⼀个服务器:
修改php-fpm配置
#php56修改监听配置
[root@s4 ~]# vim /opt/remi/php56/root/etc/php-fpm.d/www.conf
39 listen = 192.168.7.104:9000 #指定监听IP
65 #listen.allowed_clients = 127.0.0.1 #注释运⾏的客⼾端
#php72修改监听配置
[root@s4 ~]# vim /etc/opt/remi/php72/php-fpm.d/www.conf
user = apache
group = apache
listen = 172.18.0.202:9000 ;
listen.allowed_clients = 127.0.0.1
nginx转发
location ~ \.php$ {
root /data/nginx/php;
fastcgi_pass 192.168.7.104:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /data/php$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

posted @ 2021-01-15 17:37  风儿飘  阅读(679)  评论(0编辑  收藏  举报