nginx服务及其配置
nginx服务:
如果对nginx程序不了解,可阅读博主前面的文章了解详情,点击 nginx相关概念
nginx模块介绍:
高度模块化,早期不支持DSO机制,1.9.11以后才支持动态装载和卸载
模块分类:
核心模块:
- core module 提供报错日志记录、配置文件解析、时间驱动机制、进程管理
标准模块:
- http modules:
- standard http modules 默认使用 。端口配置、网页编码设置、http响应头设置等
- optional http modules 需编译时指定。扩展功能,https、flash、解析genip、传输压缩等
- mail modules
- stream modules
- tcp传输层代理
- 3rd party modules(第三方模块)
nginx程序:
执行程序:
/usr/sbin/nginx
nginx [选项]
-t 测试配置文件语法错误
-T 测试配置文件,并显示配置内容
-s signal 传递一个信号,支持:stop、quit、reopen、reload
-c 配置文件 启动时以该配置文件为主,默认为:/etc/nginx/nginx.conf,或编译安装时指定的位置
-g 指令 运行时直接指定指令。-g "worker_processes 6;",运行时指定worker数量
-p 路径 指定nginx的目录
-V 显示编译的选项
配置文件:
主配置文件:
- /etc/nginx/nginx.conf
- include conf.d/*.conf
- fastcgi,uwsgi,scgi(反向代理)等配置文件
- mime.types 支持mime类型(互联网多类型格式,如图片、mp3...)
主配置文件格式:
配置格式: 指令 值1 值2;
注意:
- 指令必须以分号结尾
- 支持使用配置变量
- 内置变量:由nginx模块引入,可直接调用
- 自定义变量: 由用户使用set命令定义
- set 变量名 值;
- 引用: $变量名
总配置段:
注意: 只用某一功能时,其他配置段不是必须的,但全局必须有
全局配置...
event {
事件驱动相关
}
http {
http/https相关
upstream name {
...
}
}
mail {
邮件相关
}
stream {
4层负载均衡代理相关
}
nginx配置段简要使用说明
由于nginx的模块太多,配置指令太多,博主就不过多介绍了,选一些重要的说明
后续的文章,直接使用配置案例介绍指令
全局配置:
指令分类:
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试及定位问题相关的配置
- 事件驱动相关的配置
配置说明:
正常运行相关:
user nginx的启动用户
支持: user user [group];
默认: user nobody
pid 文件路径 指定存储nginx主进程号的文件路径
include 文件 | 掩码(通配符) 包含其他配置文件
load_module 文件 指明要装载的动态模块
性能优化相关:
worker_processes number|auto worker进程数量,通常为cpu物理核心数
worker_cpu_affinity cpumask auto|cpu号.; 默认没开启,推荐专用于nginx主机使用,直接把nginx绑定在一个或多个cpu上
cpu mask就是cpu编号,有几个cpu就有几个0排序,4个为4个零,8个8个零
例: 8核的cpu
00000001 0号cpu
00000010 1号cpu
00000100 2号
...
worker_priority num; worker进程的nice值:-20~19
worker_rlimit_nofile 65535; 一个worker打开文件的数量上限
一个worker接收一个请求,就要打开一个socket文件。此值要大于进程数和进程连接数乘数总和:worker_processes * worker_connections
另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n或者limits.conf 的值保持一致
例:修改系统pam限制(可使用博主的系统初始化脚本设置)
vim /etc/security/limits.conf
* soft nofile 1000000
* hard nofile 1000000
调试及定位问题相关:
daemon on|off; 是否以后台运行
master_process on|off; nginx的工作模型,默认on,开启1个master进程管理worker进程,worker处理请求;off为不启动master进程,直接由worker进程处理请求
error_log 文件 [level]; 错误日志记录和级别,用于main, http, mail, stream, server, location,可实现不同记录的日志
级别:debug、info、notice、warn、error、crit、alert、emerg
log_not_found on|off #未找到文件时错误日志是否记录,用于http、server、location
事件驱动相关: events配置段使用
worker_connections 65536; 单个worker最大并发连接数
use epoll; 使用epoll事件驱动类型
支持的事件驱动:select、poll、epoll
accept_mutex on|off; worker处理新请求的方法
on为轮流处理,一个一个来
off为争夺处理,谁先拿到谁处理,默认off
multi_accept on|off; worker的子线程并发连接设置
on为每个worker的子线程可以同时接收n个新的网络连接
off为一个线程只能接受一个新网络连接
http段配置:
总体结构:
http {
... #各server的公共配置(虚拟主机配置)
server {
... #每个server用于定义一个虚拟主机
}
server {
...
listen
server_name
root #家目录,相当于documentroot
alias #路径别名,与httpd一样
location [operator] url { #nginx只能基于url访问定义
...
if CONDITION { #资源访问条件式匹配
...
}
}
}
}
配置说明:
mime相关:
include mime.types; 导入支持的文件类型
例: 导入其他配置文件
include /opt/nginx/conf.d/*;
default_type application/octet-stream; 除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件,此处默认定义成二进制流下载
types_hash_max_size 2048; nginx启动时,默认会把mime类型都加载到内存中,把支持的那些模块名,经过hash运算后,把hash码存入内存,加速访问,此为设置hash码存放的内存大小
响应报文首部相关:
charset 字符|off; 指定字符集,默认off
字符:utf-8、gbk等等
server_tokens on|off|build|string; 响应报文首部显示nginx版本,建议off
显示版本需要修改nginx源码文件,重新源码编译
如果server_tokens on,修改 src/core/nginx.h修改第13-14行
#define NGINX_VERSION "1.68.9"
#define NGINX_VER "hjnginx/" NGINX_VERSION
如果server_tokens off,修改 src/http/ngx_http_header_filter_module.c第49行
static char ngx_http_server_string[] = "Server: hjnginx" CRLF;
把其中的nginx改为自己想要的文字即可,如:hjnginx
server相关:
listen [ip:]80 [参数]; 监听端口
参数:
http2 支持http2协议,需要编译时启用http_v2
spdy SDPY协议支持,与HTTP/2协议不能同时存在
default_server 设置为默认的虚拟主机
ssl 开启ssl访问
backlog=int 消息队列长度。当请求阻塞时,设置挂起连接队列的最大长度,在FreeBSD,DragonFly BSD 和MacOS 操作系统上,默认值为-1,其他平台上值为511
rcvbuf=size socket接收缓冲的大小,默认8k,在接收数据比较大的场景中可以适当调整
sndbuf=size socket发送缓冲的大小,默认8k,在发送数据较大的场景中可以适当调整,这两个修改时也要调整内核参数,否则无效操作
udp 使用udp协议,默认的tcp协议
keepcnt 启用长连接
keepidie 长连接多久关闭
keepintv 长连接开启多久
deferred 在TCP三次握手的过程中,检测到客户端有数据时才将TCP状态置为ESTABLISHED状态,没有数据则直接丢弃(拒绝空数据连接)
proxy_protocol 必须配合haproxy的tcp代理使用(因为走的不再是http协议,而是proxy_protocol协议)。开启后,将无法直接通过ip访问本地web,只能通过4层代理访问。而客户端源地址被单独变量记录:proxy_protocol_addr、proxy_protocol_port
server_name 主机名; 域名访问
主机名支持:
通配符 *.hj.*
表达式 “~”符号为开启表达式模式,~^www.*\.com$
server_names_hash_bucket_size size; 设置服务器名称哈希表的存储桶大小。默认值取决于处理器缓存行的大小
server_names_hash_max_size 512; 设置服务器名称哈希表的最大 size
access_log off | 日志 [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; 访问日志记录
格式 在http字段的log_format中定义,默认使用预定义的格式combined,或者main
buffer 写入日志将被缓冲
gzip 数据被压缩(压缩等级1~9,1最快),默认情况下,缓冲区大小等于64K字节,压缩级别设置为1。压缩后看日志需要 zcat解压或读取日志文件
flush 间隔多少秒刷新缓存到日志文件
open_log_file_cache off| max=N [inactive=time] [min_uses=N] [valid=time]; 缓存经常打开的日志文件描述符,方便写入日志文件时可快速打开
max 设置缓存中描述符的最大数量;如果缓存已满,最近最少使用 (LRU) 描述符将被关闭
inactive 在此期间没有访问,则关闭缓存的描述符;默认10秒
min_use 设置 inactive 参数定义的时间内文件使用的最小次数,以使描述符在缓存中保持打开状态;默认1次
vaild 检查同名文件是否仍然存在的时间;默认60s
主机名匹配优先级:
- 首先是字符串精确匹配
- 左侧“*”号通配符
- 右侧“*”通配符
- 正则表达式
路径相关配置:
root 网页存放路径; 指定web家目录,配置location时,绝对路径为root+location
location [=|~|~*|^~] uri { .. } 根据url定义,用于server和location
说明:[符号] hj/info.html
= 对url做精确匹配,就是绝对路径,可提高匹配效率
~ 开启正则表达式模式匹配,区分大小写
~* 正则表达式匹配,不区分大小写
^~ 对url左半部分做匹配,不区分大小写
不带符号 匹配基于hj的所有url资源,如:hj/web/ngx/xxx.html
\ 转义符
alias 访问路径别名; 仅用于location中,用于定义location的url的访问路径,把整个url本地资源路径定义到新地方
url匹配优先级:
- =
- ^~
- ~、~*
- 不带符号
例1: 文件映射资源重定向
server {
root /data/web; #资源文件放在/data/web
location /img { #访问:域名/img/x.png
#原本访问/data/web/img/x.png,实际资源路径转到访问/opt/pic/img/x.png
root /opt/pic; #此时/opt/pic/img/x.png并没有此文件,会报404
}
}
例2: 文件映射别名
root和alias的区别:
- root定义: /data/web;
- 访问资源: url=/data/web/url/资源
- alias定义: /opt/web;
- 访问资源:url=/opt/web/资源
server {
root /data/web;
location /a {
#hj/a/原为/data/web/a/变成访问:/opt/web/
alias /opt/web;
}
}
例3: 实现动静分离
server {
location ~* \.(gif|png|jpg|jpeg|bmp|tiff|tif|ico|wmf|js)$ {
root /data/web/frontend;
}
location ~* \.(php|jsp)$ {
root /data/web/backend;
}
}
访问控制相关:
基于ngx_http_access_module模块,对客户端ip进行限制
注意:能在防火墙控制最好,nginx做这种事影响性能
allow ip|网段|all; 白名单
deny ip|网段|all; 黑名单,注意顺序和范围
例:
server {
location / {
root /opt/web;
allow 2.2.2.25; #只允许本机访问
deny all; #拒绝所有人访问
}
}
nginx账户认证功能:
由ngx_http_auth_basic_module 模块提供
auth_basic string; 登录页面的提示信息
auth_basic_user_file 账号密码文件;
例:
vim /etc/nginx/conf.d/auth.conf
server {
listen 80;
location /login {
alias /opt/web;
auth_basic 'test login';
auth_basic_user_file /opt/web/.htpasswd;
}
}
#使用apache工具,生成账号和加密的密码,需安装:httpd-tools
yum install -y httpd-tools
htpasswd -cb /opt/web/.htpasswd user1 123456
htpasswd -b /opt/web/.htpasswd user2 123456
自定义错误页面:
以指定的响应状态码进行响应, 可用位置:http, server, location, if in location
error_page 响应码 ... [=响应码] 页面; 使用“=”时,把响应码页面重定向到指定页面
例1: 自定义错误页面
server {
error_page 404 /40x.html
location = /40x.html {
root /opt/web/err;
}
}
例2: 防止错误页面被劫持,页面重定向
server {
#这个能实现京东商城的错误重定向,每次在京东输入错误的页面,都能跳转到:www.jd.com
error_page 404 =302 /index.html;
}
检测文件是否存在:
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误
try_files 文件 ... uri; 用于server,location
例1: 被访问页面都不在,则转到首页
server {
listen 81;
root /data/web;
location / {
try_files $uri $uri.html $uri/index.html /index.html;
}
}
例2: 访问页面都找不到,返回指定响应码
vim t1.conf
server {
listen 81;
root /data/web;
location / {
try_files $uri $uri.html =489;
}
}
#测试访问,查看状态码是否一致
curl -I 127.0.0.1:81
网络连接相关设置:
当web并发较大时,可优化此
keepalive_timeout 秒 [header_timeout]; 保持时间默认75s,header_timeout为首部返回的伪装时间,真实时间以前者为准
keepalive_request int; 一个长连接所能允许请求的最大资源数
keepalive_disable [mise6|safari|none|chrome|firefox17]; 指定类型的的user-agint(客户端)禁用长连接
tcp_nodeley on|off; 持久连接时使用,TCP/IP协议中默认是采用了Nagle算法,数据包较小时,不会立即发送,而是将后面的几个数据包一起组合成一个数据报文发送,但这个算法虽然提高了网络吞吐量,但是实时性却降低了。在高延时、数据量大的通信场景中关闭应该会有不错的效果,需要及时交互应该开启。off为积攒,on为立即响应
tcp_nopush on|off; 在sendfile开启时有效。也是积攒数据小包后发送,内核会尽量把小数据包拼接成一个大的数据包(一个MTU)再发送出去,将nginx的响应头和响应体攒起来同时发送,可理解为上一个配置的增强,但具体实现不一样。多用于www、ftp站点。默认on开启
client_header_timeout num; http请求报文首部的超时时长
client_body_timeout num; 读取http请求报文body部分超时时长
send_timeout num; 发送响应报文超时时长,仅在两个连续的写入操作之间设置超时,而不是为整个响应的传输设置超时。如果客户端在这段时间内没有收到任何内容,则连接将关闭
说明:tcp_nodelay、tcp_nopush两个参数是“互斥”的,如果追求响应速度的应用推荐开启tcp_nodelay参数,如IM、金融等类型的项目。如果追求吞吐量的应用则建议开启tcp_nopush参数,如调度系统、报表系统等。新版本中允许2个同时开启
例: 长连接配置
server {
keepalive_request 3;
keepalive_timeout 65 60;
keepalive_disable mise10;
}
请求限流:
由ngx_http_limi_req_module模块实现
限流分三种:
- 正常限制访问频率(正常流量)
- 突发限制访问频率(突发限流)
- 限制并发连接数
限流算法:
- 漏桶算法
- 请求当做水流,木桶本身是nginx处理能力,水流进去木桶,溢出的水流就是拒绝的请求,限制流入的速率以此限流
- 令牌桶算法
- 系统以恒定的速率生产令牌放入木桶中,一个请求达到时必须从木桶获取一个令牌,木桶中没有令牌时拒绝请求。所以控制木桶容量,发放令牌速率就可实现限流
limit_req_zone [限制地址] zone=name rate=rate 仅用于http
限制地址 对匹配的地址限制,支持变量,如:$binary_remote_addr,就是对客户端ip进行限制(二进制格式客户端ip)
常用变量:
$binary_remote_addr 有cdn时,取到的是cdn的ip,不能真正获取ip
$remote_addr 客户端ip访问速率限制
$erver_name 虚拟主机访问速率限制
zone=名称:10m 共享内存区域,也就是木桶的容量
rate=1r/m 请求接收速率,1r/m表示1分钟处理一个请求,也就达到普通限流
速率单位有: 1r/s(一秒一次)、1r/m(一分钟一次)...
limit_req zone=name [burst=number] [rate=速率] [nodelay | delay=number] 可用于http、server、location
zone=name 调用在http段定义的共享内存空间,也就是木桶
burst=int 缓冲队列,超出速率规定的请求,进行排队,如果rate规定1分钟只能收1个请求,但来了2个,一个被处理,一个进入队列。这也就达到了突发限流
nodelay 配合burst使用,立即处理队列中的请求,如果请求还是超出木桶容量就只能拒绝了,如果没有配置nodelay则严格执行rate规定的速率
limit_conn_zone [限制区域] zone=name 对并发连接限制,参数的作用与上面请求速率限制一样,仅用于http段
limit_conn zone number;
number 并发连接限制数量,只能允许多少连接
limit_req_log_level 日志级别; 超出限流的访问记录会以错误记录下来,可自行修改,默认记录503状态码
日志记录格式:
limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, <br>request: "GET / HTTP/1.0", host: "nginx.com"
解读:
limiting requests 表明日志条目记录的是被“流量限制”请求
excess 每毫秒超过对应“流量限制”配置的请求数量
zone 定义实施“流量限制”的区域
client 发起请求的客户端IP地址
server 服务器IP地址或主机名
request 客户端发起的实际HTTP请求
host HTTP报头中host的值
limit_req_status 状态码; 超出限流后,默认返回503,可指定状态码
例: 对客户端ip限流,并做突发限流
http {
limit_req_zone $binary_remote_addr zone=cip:10m rate=1r/s;
server {
limit_req zone=cip burst=10 rate=10r/s nodelay;
}
}
例: 对客户端ip、虚拟主机进行并发连接限制
http {
limit_conn_zone $binary_remote_addr zone=con_ip:125m;
limit_conn_zone $server_name zone=sname:125m;
server {
limit_conn con_ip 10;
limit_conn sname 10;
location /static {
limit_conn con_ip 100;
limit_conn sname 100;
}
}
}
例:白名单限流
http {
geo $limit { #仅对127.0.0.1和10.0.0.0/8不做限流
default 1;
127.0.0.1/32 0;
10.0.0.0/8 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_conn_zone $limit_key zone=aaa:10m;
limit_req_zone $limit_key zone=bbb:10m rate=20r/s;
server {
location / {
limit_conn aaa 50;
limit_req zone=bbb burst=5 nodelay;
}
}
}
下载速率限制:
由ngx_http_core_module提供
#限制客户端传输速率(除GET和HEAD外),单位bytes/second,默认0为无限制
limit_rate 速率;
文件索引设置: 可作下载服务器
由ngx_http_autoindex_module模块提供,处理以“/”结尾的请求,生成目录列表,作为下载服务器时使用此配置
autoindex on|off; 自动开启文件索引,默认off,作用与httpd的一样,但httpd默认开启
autoindex_exact_size on|off; on为计算精确大小(字节),默认on;off为模糊大小(k、m)
autoindex_locatime on|off; 显示系统时间,默认off
autoindex_format html|xml|json|jsonp; 索引页面的显示风格,默认html
例: 做下载站点,结合下载速率限制
server {
location /download {
autoindex on;
autoindex_exact_size on;
autoindex_locatime on;
limit_rate 1024k; 每秒只能1M下载速度
}
}
做上传服务器配置:
client_max_body_size 50m; 客户端上传文件单个最大大小,默认1m,超过报413错误
注意:一般配合php-fpm时,有3处限制,取3者最小的为标准
client_body_buffer_size int; 上传的文件超过定义的大小,被缓存到磁盘中,此为磁盘缓存区大小,路径由client_body_temp_path定义
client_body_temp_path 路径 [level1 level2] level3]; 缓存目录是由16进制数hash计算生成的,level为指定几个16进制数,1位一个也就是0-f之间随机,2位就是几个16进制,3位是..,也可在编译安装时直接指定路径--http-client-body-temp-path=路径
例: 配合php、nginx修改上传文件的最大值
最后生效的最大只能上传20M文件,也就是取三者最小值作为标准
#改php允许上传的文件大小
vim /etc/php.ini
post_max_size = 20M
upload_max_filesize = 30M
#改nginx允许上传的文件大小
vim /etc/nginx/nginx.conf
server {
client_max_body_size 40m;
}
例: 配置上传服务器的文件缓存目录
server {
client_max_body_size 50m;
client_body_buffer_size 4m;
#在/opt/web/tmp/目录下自动生成上传的临时文件存放目录,1级目录是1个16进制hash后的值,2级目录是2个16进制数hash值,3级目录是2个16进制数hash值
client_body_temp_path /opt/web/tmp/ 1 2 2;
}
限制客户端请求方法
limit_except 方法 [...] {...} 限制客户端请求方法
方法:GET、HEAD、POST、PUT、DELETE、MKCOL、COPY、OPTIONS、PROPFIND、PROPPATCH、LOCK、UNLOCK、PATH
例:
server {
location /upload {
limit_except GET {
allow 2.2.0.0/16 #只允许该网段使用GET方法
deny all; 其他人使用GET时拒绝
}
}
}
状态页显示:
模块ngx_http_stub_status_module实现,编译安装时需添加编译参数开启:--with-http_stub_status_module
注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
stub_status; 显示nginx的状态页,建议配合basci验证
例1: 开启status页面,内部查看统计
server {
location /ngx_status {
stub_status;
auth_basic 'status info login';
auth_basic_user_file /data/web/.http_user;
allow 2.2.0.0/16;
deny all;
}
}
例2: 分析当前网站流量
curl -u hj:123456 http://2.2.2.12:81/ngx_status 2> /dev/null|awk '/Reading/{print $2,$4,$6}'
web状态信息显示:
解读:
- Active connections为总的活动状态客户端连接数,包括空闲、等待的
计算:reading+writing+waiting
- accepts为nginx启动后已接收过的请求总数
- handled为nginx启动后已处理完的请求总数
通常:=accepts,除非有work_connections限制等原因导致请求被拒绝了
- requests为nginx启动后客户端发来的请求总数
- reading为正在读取客户端请求报文首部的连接数,数值越大越说明排队现象严重,性能不足
- writing为正在向客户端发送响应报文的连接数,数值越大越说明访问量越大
- waiting为正在等待客户端发请求的空闲连接数,开启持久连接时
这个值:=active-(reading+writing)
文件I/O相关:
aio on|off|threads[=pool]; 是否启用文件读取异步io(读操作),需要在编译时开启:--with-file-aio。开启后必须启用 directio ,否则读取将被阻塞。threads模式时读取和发送文件操作被指定到指定池的线程,而不会阻塞工作进程。如果省略池名称,则使用名称为“ default ”的池。池名称也可以使用变量设置
aio_write on|off; 仅在使用 aio threads 时有效,并且仅限于使用从代理服务器接收的数据写入临时文件。启用或禁用异步IO写入操作。异步IO写入允许在写入操作发起后立即返回,而不需要等待写入操作的完成,可以在写入操作期间同时处理其他任务,提高并发性和性能。需要操作系统支持异步IO的功能。启用异步IO写入可能会导致内存使用增加
directio size|off; 可以控制文件的直接IO方式,绕过内核缓存,直接在用户空间和存储设备之间进行数据传输,可提高io性能,尤其对于大型文件的操作。设置适当的字节数来控制每次IO操作的最大字节数,默认off关闭,size默认k为单位,配合sendfile和aio
directio_alignment size; 设置directio读取字节的对齐方式,在最开始和最后一读取到文件末时不满足字节大小会阻塞。大多数情况下,512 字节对齐就足够了。但在Linux下使用XFS时,需要增加到4K
sendfile on; 开启零拷贝,内核中数据流程:硬件-->内核-->程序内核空间-->网络套接字。aio 可用于为sendfile预加载数据
sendfile_max_chunk size; 限制单个sendfile调用中可以传输的数据量。如果没有限制,一个快速连接可能会完全占用工作进程,1.21.4版前默认无限制
2.6以上内核提供的aio系统调用:
- sys_io_setup 建立aio的context
- sys_io_submit 提交I/O操作请求
- sys_io_getevents 获取已完成的I/O事件
- sys_io_cancel 取消I/O操作请求
- sys_io_destory 销毁aio的上下文
例1: 配置视频传输
location /video/ {
sendfile on;
tcp_nopush on;
aio on;
}
文件读缓存相关:
可用于静态资源文件
open_file_cache off| max=n [inactive=时间]; 是否缓存打开过的文件信息,off为不缓存
缓存的信息有:
文件元数据:描述符、文件大小、最近一次修改时间
打开的目录结构
没有找到的或没有权限访问的文件的相关信息
max为最大缓存数量,超过后自动进行LRU算法(最近最少使用的被清理掉)
inactive为设置非活动缓存的清除时间,此处指定的时间内没被命中或命中次数少于open_file_cache_min_uses定义的,自动删除
open_file_cache_min_uses int; 指定1一分钟内缓存命中多少次为活动(达标),默认1/m次
open_file_cache_valid 秒; 缓存有效性的检测频率,默认60s
open_file_cache_errors on|off; 在查找缓存时,没有找到该缓存,返回的是错误信息,这些错误信息是否当做缓存被记录,默认off关闭
output_buffers number size; 从磁盘读取响应的缓冲区的数量和大小,默认1个32k
例:
server {
open_file_cache max=10000 inactive=60s; #最大缓存1w个文件,60s内不达标缓存自动清除
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors on;
}
nginx压缩功能相关:
Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源
依赖于ngx_http_gzip_module模块
gzip on|off; 启用或关闭gzip压缩,默认关闭
gzip_comp_level 比率; 压缩比率1-9,默认1,比率越大越消耗cpu周期
gzip_disable "MISE [1-6]\."; 禁用ie浏览器的压缩功能
gzip_min_length 1k; 最小压缩文件大小,小于此值,传输时不会进行压缩
gzip_http_version 1.0|1.1; 压缩时支持的最小协议版本,默认1.1
gzip_buffer int size; 压缩时的缓存区的个数和大小,平台不同默认值也不同,默认32 4K或16 8K。总共由32个缓冲区,每个4K大小
gzip_types mime-type ...; 支持对哪些资源进行压缩,默认text/html(不用指定,避免报错)
gzip_vary on|off; 启用压缩时,在响应头部显示一个字段“Vary:Accept-Encoding”,一般建议打开
例:
vim nginx.conf
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 1k;
gzip_types application/javascript application/x-javascript application/x-httpd-php application/xml text/javascript text/css text/plain image/gif image/png;
gzip_vary on;
}
#测试压缩功能是否正常
cat /var/log/messages > m.txt
curl --compressed -I 2.2.2.12/m.txt
https相关:
基于模块ngx_http_ssl_module,编译安装要指定:--with_http_ssl_module
官方文档:https://nginx.org/en/docs/http/ngx_http_ssl_module.html
lisetn 443 ssl http2;
ssl on|off; 1.15以后已弃用此配置参数,改为上面的
ssl_certificate crt文件; 虚拟主机和ca两个的crt文件,需要将ca和hj.com的crt文件合并,pem和crt是同一个
ssl_certificate_key key文件 当前虚拟主机的私钥文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]; ssl协议版本,早期是ssl,现在是tls,默认后3个
ssl_session_cache off | none | [builtin[:size]] [shared:缓存空间名称:大小]; 配置ssl缓存,使用openssl自己内置的缓存,放在内存中
解读:
off 关闭缓存
none 通知客户端支持ssl会话缓存,但实际没开启
builtin[:size] 每个worker的单独缓存自己的ssl请求
shared:name:size 每个worker进程使用共享缓存,需要定义缓存名称、缓存空间大小。1M可以存4000个会话信息,多个虚拟主机可使用相同的缓存名称
ssl_session_timeout time; ssl会话缓存的有效时间,默认5m,在时间段内,可复用连接(不用重新建立连接)
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; TLS握手时,服务器采用的密码套件
ssl_prefer_server_ciphers on; 开启由服务器决定采用的密码套件
ssl_buffer_size 1400; 设置SSL缓冲区的大小。SSL/TLS握手过程中涉及的数据交换可以存储在缓冲区中
ssl_stapling on; 启用OCSP(在线证书状态协议) stapling,它是一种用于检查SSL证书的验证状态的机制。当启用OCSP stapling时,Nginx将从证书颁发机构获取证书的验证状态,并将其缓存在服务器上。这样,客户端请求时,服务器可以直接提供证书的验证状态,减少了客户端与证书颁发机构之间的交互,提高了性能和安全性
ssl_stapling_verify on; 启用对OCSP响应的验证。当启用OCSP stapling时,服务器会从证书颁发机构获取OCSP响应,然后将其缓存在服务器上。启用`ssl_stapling_verify`将验证OCSP响应的签名是否有效和完整。这可以帮助确保OCSP响应的真实性和可靠性
add_header Strict-Transport-Security max-age=15768000; 添加Strict Transport Security(HSTS)头信息到服务器的响应中。HSTS是一种安全机制,它告诉浏览器在未来一段时间内只通过HTTPS与服务器通信,而不是尝试使用不安全的HTTP连接
例1:自签证书
#!/bin/bash
CA_SUBJECT='/O=hj/CN=ca.hj.com'
SUBJECT='/C=CN/ST=hubei/L=wuhan/O=hj/CN=www.hj.com'
SERIAL=34
EXPIRE=202111
FILE=hj.com
openssl req -x509 -newkey rsa:2048 -subj $CA_SUBJECT -keyout ca.key -nodes -days 202111 -out ca.crt
openssl req -newkey rsa:2048 -nodes -keyout ${FILE}.key -subj $SUBJECT -out ${FILE}.csr
openssl x509 -req -in $FILE.csr -CA ca.crt -CAkey ca.key -set_serial $SERIAL -days $EXPIRE -out ${FILE}.crt
chmod 600 ${FILE}.key ca.key
chmod 600 ca.key hj.crt
#合并时需要注意,必须主机证书在前,ca证书在后
cat hj.com.crt ca.crt > hj.crt
例2: 配置ssl
vim nginx.conf
server {
lisetn 443 ssl;
ssl_certificate /opt/nginx/certs/hj.crt;
ssl_certificate_key /opt/nginx/certs/hj.key;
ssl_session_cache shared:sslcache:128m;
ssl_session_timeout 10m;
ssl_protocols sslv2 sslv3 tlsv1.1 tlsv1.2;
}
把ca.crt证书导入到浏览器,然后在本地hosts文件手动解析主机,再访问:www.hj.com
例3: 实现多域名https
Nginx支持基于单个IP实现多域名的功能,并且还支持单IP多域名的基础之上实现HTTPS,其实是基于Nginx的SNI(Server Name Indication)功能实现
SNI是为了解决一个Nginx服务器内使用一个IP绑定多个域名和证书的功能,其具体功能是客户端在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务器再根据这个域名返回给客户端一个合适的证书(nginx根据请求报文中的host字段,判断访问的是哪个ip或域名,nginx再根据域名返回一个合适的证书给客户端)
#再生成一个证书,和上一个一起就是2个域名了
openssl req -newkey rsa:2048 -nodes -keyout m.hj.com.key -subj '/C=CN/ST=hubei/L=wuhan/O=hj/CN=m.hj.com' -out m.hj.com.csr
openssl x509 -req -in m.hj.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out m.hj.com.crt
vim nginx.conf
server {
listen 80;
server_name m.hj.com;
ssl_certificate /opt/nginx/certs/hj.crt;
ssl_certificate_key /opt/nginx/certs/hj.key;
ssl_session_cache shared:sslcache:128m;
root /opt/web;
}
server {
listen 443 ssl;
server_name m.hj.com;
ssl_certificate /opt/nginx/certs/hj.crt;
ssl_certificate_key /opt/nginx/certs/hj.key;
ssl_session_cache shared:sslcache:128m;
root /opt/web;
}
获取真实ip:
用--with-http_realip_module模块获取,需编译时指定安装
附加变量 | 含义 |
---|---|
$realip_remote_addr | 真实ip |
$realip_remote_port | 真实端口 |
set_real_ip_from ip|cidr|unix #指定可信地址,从该地址建立的连接,获取的真实ip才是可信的,用于http、server、location
real_ip_header X-Real-IP|X-Forwarded-For|proxy_protocol #指定从哪个头部获取真实ip,默认X-Real-IP;若设置X-Forwarded-For获取,会从最后一个ip获取,用于http、server、location
real_ip_recursive on|off #换回地址,默认关闭,开启时若X-Forwarded-For的最后一个地址与remote_addr相同,则过滤,显示其他的(用X-Forwarded-For时开启此)
修改请求头location域名
server_name_in_redirect on|off #关闭后显示请求的域名,若有Host请求头,则用它。用于http、server、location
port_in_redirect on|off #location请求头显示端口。用于http、server、location
absolute_redirect on|off #请求头location是否加上域名,默认打开;关闭则只返回路径
第三方模块使用:
对nginx的功能扩展,第三方模块需要在编译安装Nginx的时候使用参数--add-module=PATH指定路径添加,有的模块是由公司的开发人员针对业务需求定制开发的,有的模块是开源爱好者开发好之后上传到github进行开源的模块,nginx支持第三方模块需要从源码重新编译支持,比如:开源的echo模块 https://github.com/openresty/echo-nginx-module
也就是必须先准备第三方模块,再编译nginx(不过也可以做到动态更换nginx程序)
echo模块:
可用于学习nginx变量时测试使用
可以把字符串、变量输出显示
nginx变量:https://nginx.org/en/docs/varindex.html
echo 字符串|变量;
echo_reset_timer; 计时器时间重置
echo_location 调用location的uri;
echo_sleep 秒; 使用sleep程序
例1: 安装第三方的echo模块
准备echo-nginx-module源码、nginx源码
cd /opt/nginx-xxx
./configure --prefix=/opt/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_realip_module --with-stream_ssl_module --with-http_perl_module --add-module=/opt/echo-nginx-module
make && make install
例2: 使用echo模块的相关指令
访问时,直接访问url,即可显示效果,如:curl 2.2.2.12/main
location /main {
echo $remote_addr;
echo '123456';
echo_location /ts1; 调用/ts1
echo "total $echo_timer_elapsed";
}
location /ts1 {
echo_sleep 1;
echo 'is ts1--'
}
nginx其他补充
关于favicon.ico报404错误:
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错
解决办法:
方法1: 服务器不记录访问日志
location = /favicon.ico {
log_not_found off;
access_log off;
}
方法2: 将图标保存在指定目录访问
cp 图片 /opt/web/image/favicon.ico
vim nginx.conf
server {
location = /favicon.ico {
root /opt/web/images;
expires 365d;
}
}
关于openssl漏洞修复:
心血漏洞,是一个出现在加密程序库OpenSSL的安全漏洞,该程序库广泛用于实现互联网的传输层安全(TLS)协议。此漏洞于2012年被引入了软件中,2014年4月首次向公众披露。只要使用的是存在缺陷的OpenSSL实例,无论是服务器还是客户端,都可能因此而受到攻击。此问题的原因是在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检查),因此漏洞的名称来源于“心跳”(heartbeat)。该程序错误属于缓冲区过读,即可以读取的数据比应该允许读取的还多
修复方法:
1、准备openssl源码包
wget https://www.openssl.org/source/openssl-1.1.1h.tar.gz
tar xf openssl-1.1.1h.tar.gz
2、重新编译nginx
编译时,使用刚刚下载的的openssl,而不是系统的版本(系统版本的openssl大于1.0即可)
./configure --prefix=/opt/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 --add-module=/opt/src/echo-nginx-module --with-openssl=/opt/src/openssl-1.1.1h --with-file-aio --with-http_image_filter_module=dynamic --with-http_image_filter_module