主要介绍Nginx核心配置文件
配置文件说明
nginx 官方文档:http://nginx.org/en/docs/
nginx 配置文件组成:
- 主配置文件: nginx.conf
- 子配置文件: conf.d/*.conf
- fastcgi,, uwsgi,scgi 等协议的相关配置文件
- mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用指定应用程序来打开的方式类型,当带有某种扩展名的文件被访问的时候,浏览器会自动使用指定应用程序打开(比如:应用程序会被下载,文本文件会直接显示内容)。简单来说,MIME就是利用扩展名标识文件类型,然后根据文件的类型做响应的处理。MIME 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_Types
nginx 配置文件格式说明:
- 配置文件由指令和指令块构成
- 每条指令以分号;结束,指令和值之间以空格分隔
- 多条指令可以放在同一行,以分号分隔。但可读性差,不推荐这样配置
- 指令块以{ } 括号作为开始和结束的标识,将多条指令组织在一起,且支持嵌套
- 可通过include引入其他配置文件内容,提升配置文件的可维护性(如子配置文件conf.d/*.conf)
- 配置文件使用# 作为注释符,使用$引用变量
- 部分指令的参数支持正则表达式
nginx 主配置文件指令格式:
directive value [value1 ...];
说明:
1、指令必须以分号;结束
2、支持变量:
1)内建变量:由Nginx模块引入,可直接引用
2)自定义变量:由用户使用set指定定义,格式: set variable_name value;
3) 引用变量的方式:$variable_name
主配置文件结构:四部分
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
默认的nginx.conf 配置文件说明
##全局配置块,对全局生效。主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,nginx的pid文件路径等。
user nginx nginx;
worker_processes 1; #启动工作进程的数量,一般与CPU核心数一致
##events块,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型,每个工作进程最大支持并发连接数,是否开启对多工作进程下的网络连接进行序列化等。
events {
worker_connections 1024; #单个worker进程的最大并发连接数。作为web服务器时,nginx的最大并发数为:worker_connections * worker_processes。作为反向代理的时候为(worker_connections * worker_processes)/2
}
##http块是nginx服务器配置中的重要组成部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都在这里配置。http块可以包含多个server块,而一个server块又可以包含多个location块,server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和单个链接的请求上限等。
http {
include mime.types;
default_type application/ostet-stream;
sendfile on; #作为web服务器时打开sendfile加快静态文件传输,指定是否使用sendfile系统调用传输文件。sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核空间进程),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,效率很高,是零拷贝技术的一种。
keepalive_timeout 65; #长连接超时时间,单位:秒
##server块可用于配置虚拟主机,有自己的全局配置,可以包含多个location块。可配置本虚拟机监听的端口,设置虚拟机名称,多个server监听同一个端口。
server {
listen 80; #监听端口
server_name; localhost; #server的域名,配置多个虚拟主机时用到
location / {
root html;
index index.html index.htm; #网站默认主页
}
error_page 500 502 503 504 /50x.html; #错误页面
##location处理对应的不同错误码的页面定义到50x.html,指示了50.html文件所在目录
location = /50x.html {
root html; #错误页面文件所在目录
}
}
##和邮件相关的配置
#mail {
# ...
#} mail 协议相关配置段
#tcp代理配置,1.9版本以上支持
#stream {
# ...
#} stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}
全局配置
main 全局配置块常见的配置指令分类
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试定位问题相关的配置
- 事件驱动相关的配置
全局配置说明
user nginx nginx; #启动nginx工作进程的用户和组
worker_processes [number | auto]; #启动nginx工作进程的数量,一般和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000; #将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
CPU MASK: 00000001:0号CPU
00000010:1号CPU
10000000:7号CPU
##示例:
[root@test conf]# egrep "processes|affinity" nginx.conf
worker_processes 4; #启动四个worker进程
worker_cpu_affinity 0001 0010; #将workr进程绑定到 0号CPU和1号CPU
[root@test conf]# lscpu | grep CPU\(s\) # CPU核数为2
CPU(s): 2
On-line CPU(s) list: 0,1
NUMA node0 CPU(s): 0,1
[root@test conf]# nginx -t #语法检查出现警告,因为worker进程数比CPU核心数多。多出的worker进程将绑定在‘上一个CPU核心‘也即0010上。对于‘上一个CPU核心’(last mask for remaining worker)的解释: processes:nginx分别将worker进程绑定到worker_cpu_affinity 指定的CPU核心上(从左至右的顺序),而从第三个work进程起并未指定对应的CPU核心,因此全部绑定到‘上一个CPU核心’ 0010这个CPU核心。
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: [warn] the number of "worker_processes" is not equal to the number of "worker_cpu_affinity" masks, using last mask for remaining worker processes
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@test conf]# ps axo pid,cmd,psr | grep nginx
827 nginx: master process /apps 0
1226 nginx: worker process 0
1227 nginx: worker process 1
1228 nginx: worker process 1
1229 nginx: worker process 1
1249 grep --color=auto nginx 0
#将worker进程数量改为2
[root@test conf]# vim nginx.conf
[root@test conf]# egrep "processes|affinity" nginx.conf
worker_processes 2;
worker_cpu_affinity 0001 0010;
#语法检查不再警告
[root@test conf]# nginx -s reload
[root@test conf]# 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
[root@test conf]# ps axo pid,cmd,psr | grep nginx
827 nginx: master process /apps 1
1261 nginx: worker process 0
1262 nginx: worker process 1
1265 grep --color=auto nginx 1
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg] #括号内为日志记录详细级别(从左至右逐渐提高)
##示例配置
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /apps/nginx/logs/error.log error;
#pid文件保存路径
pid /apps/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接。该值最好与ulimit -n 或者limits.conf的值保持一致,
#通过pam限制文件打开数量上限
[root@centos8 ~]#cat /etc/security/limits.conf
* soft nofile 1000000
* hard nofile 1000000
#worker进程优先级
[root@test conf]# grep priority nginx.conf
worker_priority 0;
[root@test conf]# ps -axo pid,cmd,nice | grep nginx
827 nginx: master process /apps 0
1391 nginx: worker process 0
1392 nginx: worker process 0
1449 grep --color=auto nginx 0
daemon off; #前台运行Nginx服务,通常在测试环境或者docker环境中使用
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
events {
worker_connections 65536; #设置单个工作进程的最大并发连接数
use epoll; #使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
accept_mutex on; #on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on; #on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}
范例:实现nginx的高并发配置
[root@localhost conf]# ulimit -n
10
[root@localhost conf]# cat /apps/nginx/conf/nginx.conf | grep rlimit
worker_rlimit_nofile 100;
#默认配置不支持高并发,当worker_rlimit_nofile设置的值大于ulimit -n的值,会出现以下错误日志
[root@localhost conf]# ab -c 5000 -n 10000 http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
socket: Too many open files (24) #打开的文件描述符过多
http 配置块
http 协议相关的配置结构
http {
...
...
server { #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
...
}
server {
...
server_name #虚拟主机名
root #主目录
alias #路径别名
location [OPERATOR] URL { #指定URL的特性
...
if CONDITION {
...
}
}
}
}
http 协议配置说明
http {
include mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf目录
default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件
#日志配置部分
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#自定义优化参数
sendfile on;
#tcp_nopush on; #在开启了sendfile的情况下,合并请求后统一发送给客户端,必须开启sendfile
#tcp_nodelay off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
#keepalive_timeout 0;
keepalive_timeout 65 66; #设置会话保持时间,第二个值为响应首部:keep-Alived:timeout=65,可以和第一个值不同
#gzip on; #开启文件压缩
server {
listen 80; #设置监听地址和端口
server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.magedu.com www.magedu.* ~^www\d+\.magedu\.com$ default_server
#charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; #定义错误页面
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ { #以http的方式转发php请求到指定web服务器
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { #以fastcgi的方式转发php请求到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;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。
# deny all;
#}
location ~ /passwd.html {
deny all;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server { #自定义虚拟server
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm; #指定默认网页文件,此指令由ngx_http_index_module模块提供
# }
#}
# HTTPS server
#
#server { #https服务器配置
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
MIME
MIME参考文档: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_Types
#在响应报文中将指定的文件扩展名映射至MIME对应的类型
include mime.types;
default_type application/octet-stream;#除mime.types中的类型外,指定其它文件的默认MIME类型,浏览器一般会提示下载
types {
text/html html;
image/gif gif;
image/jpeg jpg;
}
范例:
#未定义mime.types类型
[root@localhost nginx]# ll html/mime.types
ls: cannot access html/mime.types: No such file or directory
[root@localhost nginx]# curl localhost/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 28 Jul 2022 11:23:54 GMT
Content-Type: application/octet-stream #mime未定义的类型默认视为二进制文件处理(如果是浏览器访问,则会下载test.php文件)
Content-Length: 20
Last-Modified: Thu, 28 Jul 2022 11:19:48 GMT
Connection: keep-alive
Keep-Alive: timeout=66 #长连接显示的时长,由keepalive_timeout 65 66; 配置
ETag: "62e270d4-14"
Accept-Ranges: bytes
#修改默认文件类型
[root@localhost nginx]# cat conf/nginx.conf | grep default_type
default_type text/html;
[root@localhost nginx]# nginx -s reload
[root@localhost nginx]# curl localhost/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 28 Jul 2022 11:32:15 GMT
Content-Type: text/html #将test.php识别为文本文件(如果是浏览器访问,直接显示文件内容)
Content-Length: 20
Last-Modified: Thu, 28 Jul 2022 11:19:48 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e270d4-14"
Accept-Ranges: bytes
指定响应报文
#是否在响应报文中的Content-Type显示指定的字符集,默认off不显示
charset charset | off;
#示例
charset utf-8;
#是否在响应报文的Server首部显示nginx版本
server_tokens on | off | build | string;
范例:源码修改server字段
#如果想自定义响应报文的nginx版本信息,需要修改源码文件,重新编译
#如果server_tokens on,修改 src/core/nginx.h 修改第13-14行,如下示例
#define NGINX_VERSION "1.68.9"
#define NGINX_VER "mynginx/" NGINX_VERSION
#如果server_tokens off,修改 src/http/ngx_http_header_filter_module.c 第49行,如下示例:
static char ngx_http_server_string[] = "Server: nginx" CRLF;
#把其中的nginx改为自己想要的文字即可,如:mynginx
核心配置示例
虚拟主机的实现
基于不同的IP、不同的端口以及不用域名实现不同的虚拟主机,依赖于核心模块ngx_http_core_module实现。
新建两个虚拟主机
# 添加域名解析
[root@localhost conf.d]# cat /etc/hosts |grep test
172.16.16.88 pc.test.org mobile.test.org
## 开始新建虚拟主机
root@localhost nginx]# mkdir /apps/nginx/conf/conf.d
[root@localhost nginx]# cd /apps/nginx/conf/conf.d/
[root@localhost conf.d]# vim /apps/nginx/conf/nginx.conf
......
include /apps/nginx/conf.d/*.conf; #在配置文件的最后面添加此行,注意不要放在最前面,会导致前面的配置无法生效(文件配置从上到下依次生效)
[root@localhost conf.d]# cat pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
}
[root@localhost conf.d]# mkdir /apps/nginx/html/pc
[root@localhost conf.d]# echo pc_page > /apps/nginx/html/pc/index.html
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org #虚拟主机pc
pc_page
[root@localhost conf.d]# cat mobile.conf
server {
listen 80;
server_name mobile.test.org;
location / {
root html/mobile;
}
}
[root@localhost conf.d]# mkdir /apps/nginx/html/mobile #虚拟主机mobile
[root@localhost conf.d]# echo mobile_page > /apps/nginx/html/mobile/index.html
mobile_page
root 与 alias 的区别
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
范例:
[root@localhost conf.d]# cat pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
location /about {
root /opt/html; #实际路径为/opt/html/about/index.html
}
}
[root@localhost conf.d]# ll /opt/html/about/
total 4
-rw-r--r-- 1 root root 11 Jul 28 23:24 index.html
[root@localhost conf.d]# cat /opt/html/about/index.html
about_page
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org/about/
about_page
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少
范例:
[root@localhost conf.d]# cat pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
location /about {
alias /opt/html; #实际路径为/opt/html/index.html
}
}
[root@localhost conf.d]# cat /opt/html/index.html
about_page
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# curl pc.test.org/about/
about_page
localtion 的匹配规则
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请
求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配,而后进行处理。
location 官方帮助: http://nginx.org/en/docs/http/ngx_http_core_module.html#location
#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大小写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
官方范例
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
The “/” request will match configuration A(?), the “/index.html” request will
match configuration B,
the “/documents/document.html” request will match configuration C, the
“/images/1.gif” request will match configuration D, and the “/documents/1.jpg”
request will match configuration E.
匹配案例-精确匹配
在server部分使用location配置一个web界面,例如:当访问nginx服务器的/logo.jpg的时候要显示指定html文件的内容
精确匹配一般用于匹配网站logo等相对固定的URL
范例:精确匹配
[root@localhost images]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
location /logo.jpg {
root html/images;
}
}
[root@localhost images]# ll /apps/nginx/html/images/logo.jpg
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/logo.jpg
#访问成功
[root@localhost images]# curl pc.test.org/logo.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:17:35 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes
匹配案例-区分大小写
~ 实现区分大小写的模糊匹配
[root@localhost images]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
location ~ /A.?\.jpg { #匹配字母A开头的jpg图片,后面?表示A后面零次或一个字符
root html/images;
}
}
#确保资源存在
[root@localhost images]# ll /apps/nginx/html/images/A.jpg
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/A.jpg
[root@localhost images]# nginx -s reload
#以大写URI访问成功
[root@localhost images]# curl -I pc.test.org/A.jpg
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:27:52 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes
#以小写URI访问失败
[root@localhost images]# curl -I pc.test.org/a.jpg
HTTP/1.1 404 Not Found
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:27:55 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=66
匹配案例-不区分大小写
~* 用来对用户请求的uri做模糊匹配。
注意:尽管匹配时不区分大小写,但实际请求是仍会以用户请求的uri去寻找相应的磁盘文件,如用户访问uri为/A.jpg,在location条件通过后就在对应路径下寻找磁盘中的A.jpg文件,如果磁盘上是a.jpg,则请求是失败的(在window系统中,文件名不区分大小写,该请求会成功——受文件系统影响)。
[root@localhost images]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/pc;
}
location ~* /A.?\.jpg { #匹配规则不区分大小写
root html/images;
}
}
[root@localhost images]# ll /apps/nginx/html/images/a.jpg #磁盘中仅存在a.jpg文件
-rw-r--r-- 1 root root 13110 Jul 29 15:11 /apps/nginx/html/images/a.jpg
[root@localhost images]# nginx -s reload
#访问/a.jpg成功
[root@localhost images]# curl -I pc.test.org/a.jpg
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:41:25 GMT
Content-Type: image/jpeg
Content-Length: 13110
Last-Modified: Fri, 29 Jul 2022 07:11:49 GMT
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e38835-3336"
Accept-Ranges: bytes
#访问/A.jpg失败。location匹配成功,但磁盘上并无A.jpg文件
[root@localhost images]# curl -I pc.test.org/A.jpg
HTTP/1.1 404 Not Found
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 15:41:48 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=66
nginx 四层访问控制
访问控制基于模块ngx_http_access_module实现,可以通过匹配客户端源IP地址进行限制
注意: 如果能在防火墙设备控制, 最好就不要在nginx上配置,可以更好的节约资源
官方帮助: http://nginx.org/en/docs/http/ngx_http_access_module.html
范例:
## 匹配时按从上至下的规则进行匹配,匹配到相应规则即停止———与防火墙的匹配规则类似
#如:有客户端(IP:10.1.1.0)访问配置了以下规则的web服务器时(访问URI:/about),触发location /about语句块,匹配到allow 10.1.1.0/16,访问控制生效,访问成功。
location = /login/ {
root /data/nginx/html/pc;
allow 10.0.0.0/24;
deny all;
}
location /about {
alias /data/nginx/html/pc;
index index.html;
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all; #按先小范围到大范围排序
}
nginx 账户认证功能
由 ngx_http_auth_basic_module 模块提供此功能
官方帮助:http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
范例:
#CentOS安装包
[root@centos8 ~]#yum -y install httpd-tools
#Ubuntu安装包
[root@Ubuntu ~]#apt -y install apache2-utils
#创建用户
#-b 非交互式方式提交密码
#-c 重新生成文件,覆盖已有文件。首次创建时使用
[root@localhost html]# htpasswd -bc /apps/nginx/conf/.htpasswd user1 passwd1
Adding password for user user1
[root@localhost html]# htpasswd -b /apps/nginx/conf/.htpasswd user2 passwd2
Adding password for user user2
#生成了带有两个用户的验证文件
[root@localhost html]# tail /apps/nginx/conf/.htpasswd
user1:$apr1$vzRe30iJ$jF8BZbra6pI8O0JBqlmiP/
user2:$apr1$i2ON7LYs$pxzkeH.xxCdgj670m5cSW/
#网站登录页面配置
[root@localhost html]# cat /apps/nginx/html/index.html
hello
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location /login {
alias html/;
index index.html;
auth_basic "login password"; #指定提示文本信息
auth_basic_user_file /apps/nginx/conf/.htpasswd; #指定使用的验证文件
}
}
#直接访问登录页,失败。未通过验证
[root@localhost html]# curl pc.test.org/login/
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
##分别使用两种方式输入用户名和密码验证
[root@localhost html]# curl http://user1:passwd1@pc.test.org/login/
hello
[root@localhost html]# curl -u user2:passwd2 pc.test.org/login/
hello
自定义错误页面
自定义错误页,同时也可以用指定的响应状态码进行响应, 可在如下语句块配置:http, server, location, if in
location
格式:
error_page code ... [=[response]] uri;
范例:
# 准备站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
error_page 404 400 /error.html; #访问不存在的页面,发生404错误,返回error.html错误页面
location /error.html {
root html/;
}
}
#准备错误页面
[root@localhost html]# cat /apps/nginx/html/error.html
error-page
[root@localhost html]# nginx -s reload
#访问不存在的页面,触发404报错
[root@localhost html]# curl -I pc.test.org/dd
HTTP/1.1 404 Not Found #查看错误码
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:02:12 GMT
Content-Type: text/html
Content-Length: 11
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e411d9-b"
#触发404错误,返回错误页面(如果是浏览器测试,建议用google)
[root@localhost html]# curl pc.test.org/dd
error-page
范例:如果发生404 ,将错误码定义为502,且跳转到主页/index.html
#站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
error_page 404 =502 /index.html;
location /index.html {
root html/;
}
}
#主页配置
[root@localhost html]# cat /apps/nginx/html/index.html
hello
[root@localhost html]# nginx -s reload
[root@localhost html]# curl pc.test.org/dd/
hello
#验证错误码
[root@localhost html]# curl pc.test.org/dd/ -I
HTTP/1.1 502 Bad Gateway #错误码为自定义的502
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:31:49 GMT
Content-Type: text/html
Content-Length: 6
Connection: keep-alive
Keep-Alive: timeout=66
ETag: "62e40fa4-6"
#重定向成功
[root@localhost html]# cat /apps/nginx/html/index.html
hello
自定义错误日志
错误日志格式
Syntax: error_log file [level]; #格式
Default: #默认值
error_log logs/error.log error;
Context: main, http, mail, stream, server, location #可配置的语句块
level: debug, info, notice, warn, error, crit, alert, emerg #日志记录等级
范例:
#站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
error_page 404 400 /error.html;
access_log /apps/nginx/logs/test-access.log; #自定义正常访问日志
error_log /apps/nginx/logs/test-error.log; #自定义错误日志
location /error.html {
root html/;
}
}
#当前已有日志文件
[root@localhost html]# ls /apps/nginx/logs/
access.log error.log nginx.pid
#重启nginx后生成自定义的错误日志
[root@localhost html]# nginx -s reload
[root@localhost html]# ls /apps/nginx/logs/
access.log error.log nginx.pid test-access.log test-error.log
#访问站点
[root@localhost html]# curl pc.test.org
hello
#日志成功记录
[root@localhost html]# tail /apps/nginx/logs/{test-access,test-error}.log
==> /apps/nginx/logs/test-access.log <==
172.16.16.88 - - [30/Jul/2022:01:17:55 +0800] "GET / HTTP/1.1" 200 6 "-" "curl/7.29.0"
==> /apps/nginx/logs/test-error.log <==
检测文件是否存在
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如
果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一
个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内
部500错误。
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
范例: 如果不存在页面, 就转到default.html页面
#准备站点配置
[root@localhost html]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/;
index index.html;
try_files $uri $uri.html $uri/index.html /about/default.html;
}
}
#准备默认页面
[root@localhost html]# cat /apps/nginx/html/default.html
default
#访问测试
[root@localhost ~]# cat /apps/nginx/html/about/default.html
about_page
[root@localhost ~]# curl pc.test.org/xx/
about_page
[root@localhost ~]# curl pc.test.org/xx.html
about_page
##自定义响应码
[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location / {
root html/;
index index.html;
try_files $uri $uri.html $uri/index.html =555; #自定义响应码为555
}
}
#验证结果
[root@localhost ~]# curl pc.test.org/xx.html -I
HTTP/1.1 555 #响应码为555
Server: nginx/1.18.0
Date: Mon, 01 Aug 2022 10:00:03 GMT
Content-Length: 0
Connection: keep-alive
Keep-Alive: timeout=66
长连接配置
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,默认为75s,通常配置在http字段作为站点全局配置
keepalive_requests number; #在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适
当调大,比如:500
范例:
#站点主配置项
[root@localhost ~]# cat /apps/nginx/conf/nginx.conf | grep keepalive
keepalive_requests 3;
keepalive_timeout 65 60;
[root@localhost ~]# cat /apps/nginx/html/index.html
hello
#长连接测试
[root@localhost ~]# telnet localhost 80
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1 #发起get请求,重复三次或者时间到达65秒后,本次链接自动终止
HOST: localhost #域名为localhost
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Mon, 01 Aug 2022 11:03:09 GMT
Content-Type: text/html
Content-Length: 6
Last-Modified: Fri, 29 Jul 2022 16:49:40 GMT
Connection: keep-alive
Keep-Alive: timeout=60 #显示的超时时间
ETag: "62e40fa4-6"
Accept-Ranges: bytes
hello #返回的页面内容
作为下载服务器
ngx_http_autoindex_module 模块处理以斜杠字符 “/” 结尾的请求,并生成目录列表,可以做为下载服务
配置使用
官方链接:http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
相关指令
autoindex on | off; #自动文件索引功能,默为off
autoindex_exact_size on | off; #计算文件精确大小(单位bytes),off 显示大概大小(单位K、M),默认on
autoindex_localtime on | off ; #显示本机时间而非GMT(格林威治)时间,默认off
autoindex_format html | xml | json | jsonp; #显示索引的页面文件风格,默认html
limit_rate rate; #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位B/s,即bytes/second,默认值0,表示无限制,此指令由ngx_http_core_module提供
set $limit_rate 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高于limit_rate
###Rate limit can also be set in the $limit_rate variable, however, since version 1.17.0, this method is not recommended:
范例:将nginx作为下载服务器
#注意:download不需要index.html文件
[root@centos8 ~]# mkdir -p /data/nginx/html/pc/download
[root@localhost ~]# touch /apps/nginx/html/download/{t1,t2,t3}.txt
[root@localhost ~]# mkdir /apps/nginx/html/download/{d1,d2,d3}
[root@localhost ~]# tree /apps/nginx/html/download
/apps/nginx/html/download
├── d1
├── d2
├── d3
├── t1.txt
├── t2.txt
└── t3.txt
3 directories, 3 files
[root@centos8 ~]# cat /apps/nginx/conf.d/pc.conf
location /download {
autoindex on; #自动索引功能
autoindex_exact_size off; #计算文件确切大小(单位bytes),此为默认值,off只显示大概大
小(单位kb、mb、gb)
autoindex_localtime off; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT
时间
limit_rate 1024k; #限速,默认不限速
root html/;
}
结果验证
作为上传服务器
相关指令
client_max_body_size 1m; #设置允许客户端上传单个文件大小的上限值,默认值为1m,上传文件超过此值会出413错误
client_body_buffer_size size; #用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置
client_body_temp_path path [level1 [level2 [level3]]];
#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名
[root@centos8 ~]# md5sum /data/nginx/html/pc/index.html
95f6f65f498c74938064851b1bb 96 3d 4 /data/nginx/html/pc/index.html
1级目录占1位16进制,即2^4=16个目录 0-f
2级目录占2位16进制,即2^8=256个目录 00-ff
3级目录占2位16进制,即2^8=256个目录 00-ff
#配置示例:
client_max_body_size 100m; #如果太大,上传时会出现413错误。注意:如果php上传(如WordPress),还需要修改/etc/php.ini的相关配置
client_body_buffer_size 1024k;
client_body_temp_path /apps/nginx/client_body_temp/ 1 2 2; #上传时,Nginx会自动创建相关目录
##上传文件后,会自动生成相关目录
[root@wang-liyun-pc ~]# tree /apps/nginx/client_body_temp/
/apps/nginx/client_body_temp/
├── 5
│ └── 00
│ └── 00
└── 6
└── 00
└── 00
其他配置
keepalive_disable none | browser ...; #对哪种浏览器禁用长连接
limit_except method ... { ... } #仅用于location语句块,禁止客户端使用除了指定的请求方法之外的其它方法, 如果使用会出现403错误
method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
##示例:除了GET之外的其它方法仅允许172.16.16.0/24网段主机使用
[root@localhost ~]# hostname -I #本机IP
172.16.16.88
[root@localhost ~]# ll /apps/nginx/html/upload/ #新建upload目录用于存储上传的文件
total 0
[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location /upload {
root html/;
index index.html;
limit_except GET {
allow 172.16.16.88;
deny all;
}
}
}
[root@localhost ~]# nginx -s reload
[root@localhost ~]# curl -XPUT /etc/issue pc.test.org/upload
curl: (3) <url> malformed
<html>
<head><title>405 Not Allowed</title></head> #PUT方法具有访问权限,但是程序本身不支持文件上传功能
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@localhost ~]# cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.test.org;
location /upload {
root html/;
index index.html;
limit_except GET {
#allow 172.16.16.88; #禁止所有主机使用GET以外的方法
deny all;
}
}
}
[root@localhost ~]# curl -XPUT /etc/issue pc.test.org/upload
curl: (3) <url> malformed
<html>
<head><title>403 Forbidden</title></head> #再次访问测试,nginx拒绝访问
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
aio on | off #是否启用asynchronous file I/O(AIO)功能,需要编译时添加参数开启 --with-file-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是读取文件而directio是写文件到磁盘,默认为关闭,当文件大于等于给定大小时,例如:directio 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 #指令所指定的次数的缓存项即为非活动项,将被删除
open_file_cache_valid time; #缓存项有效性的检查验证频率,默认值为60s
open_file_cache_errors on | off; #是否缓存查找时发生错误的文件一类的信息,默认值为off
open_file_cache_min_uses number; #open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1
范例:
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; #缓存错误信息