前言
nginx模块是nginx相比于apache一个很大的优点,模块可以为nginx提供更多的功能来满足运维日常需求。当有一些需求,我们只需要编译新的模块重启nginx即可完成。
一、常见的nginx web模块
1.随机主页 random_index_module
(1)mkdir /usr/share/nginx/html/random_index
touch /usr/share/nginx/html/random_index/{blue.html,green.html,red.html,yellow.html}
<html>
<head>
<title>color</title>
</head>
<body style="background-color:blue">
<h1>color!</h1>
</body>
</html>
(2)vim /etc/nginx/conf.d/liang.conf
server{
listen 192.168.93.136:8080;
server_name web.liang.com;
location /{
#root /usr/share/nginx/html;
#index liang.html;
root /usr/share/nginx/random_index;
random_index on;
}
}
(3)访问 192.168.93.136:8080 并刷新 查看网页变化
2.替换模块 sub_module
Syntax: sub_filter A B; # 网页中的A替换成B Default: — Context: http, server, location
Syntax: sub_filter_once on | off; Default: sub_filter_once on; Context: http, server, location
server{
listen 192.168.93.177:8080;
server_name web.kong.com;
location /{
root /usr/share/nginx/html;
index kong.html index.html;
sub_filter kong ''; # 把kong替换为空
#sub_filter_once on; # 只替换匹配到的第一个kong
sub_filter_once off; # 全部替换
}
}
3.文件读取模块 ngx_http_core_module
Syntax: sendfile on | off; # 加快网络传输速率 Default: sendfile off; Context: http, server, location, if in location 未使用sendfile网络传输 过程: 硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈 使用sendfile网络传输 过程: 硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈
Syntax: tcp_nopush on | off; Default: tcp_nopush off; Context: http, server, location 未使用tcp_nopush网络资源: tcp传输数据会带一个40字节长的包头,应用程序每次操作都会发送一个包,每个包都会加包头 于是产生4000%的过载,很轻易地就能令网络发生拥塞 使用tcp_nopush网络资源: 不会每次操作都会发送一个包,会等待多个包一起发送,只用一个包头
Syntax: tcp_nodelay on | off; Default: tcp_nodelay on; Context: http, server, location 数据包立即发送出去,由于Nagle和DelayedACK的原因,数据包的确认信息需要积攒到两个时才发送,长连接情况下,奇数包会造成延时40ms,所以tcp_nodelay会将ack立刻发出去
4.文件压缩 ngx_http_gzip_module
启动该模块,使文件传输前进行压缩,提升传输效率
Syntax: gzip on | off; # 开启或关闭压缩模块 Default: gzip off; Context: http, server, location, if in location
Syntax: gzip_comp_level level; # 设置压缩级别 Default: gzip_comp_level 1; Context: http, server, location
在nginx.conf的http模块添加
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_static on;
压缩包和图片类对象本身已经自带压缩功能。所以压缩比例较小低。文本类对象在压缩试验中,压缩比例体现优越。
5.状态访问统计 ngx_http_stub_status_module
server{
location ~ /status { # 启动该模块
stub_status on;
access_log off;
}
}
status页面: 102为连接总数 102为成功连接的数量 289为共处理的请求数 Reading: 0 读取客户端Header的信息数 请求头 Writing: 1 返回给客户端的header的信息数 响应头 Waiting: 1 等待的请求数,开启了keepalive 这个值等于active - (reading + writing)
keepalive_timeout httpd守护进程,因为网页每次访问都需要tcp三次握手建立连接,然后http建立请求页面,最后tcp四次挥手断开连接 keepalive_timeout 设置的时间是当tcp建立连接的时候不立刻断开连接 而是等待一段时间 防止客户端和服务端频繁的建立和端来连接而造成的资源浪费
vim /etc/nginx/nginx.conf
keepalive_timeout 65; # 默认参数 等待65s
改为:keepalive_timeout 0;
更改完配置后再次访问status页面,会发现Reading、Writing、Waiting次数一样,说明nginx每处理完一次请求都会断开。
6.防盗链 ngx_http_referer_module
Syntax: valid_referers none | blocked | server_names | string …; Default: — Context: server, location
(1)盗链模拟 创建两个虚拟主机 kong.conf liang.conf
server{
listen 80;
server_name web.kong.com;
location /{
access_log /var/log/nginx/kong.access.log main; # 访问该界面会生成日志
root /usr/share/nginx/html;
index kong.html index.html;
}
}
server{
listen 80;
server_name web.liang.com;
location /{
access_log /var/log/nginx/liang.access.log main;
root /;
index liang.html;
}
}
vim kong.html
<img src='timg.jpg' />
vim liang.html
<img src='http://web.kong.com/timg.jpg' /> # 用连接来盗取kong站点的timg.jpg,liang站点没有图片但是可以看到图片
分别访问两个站点查看两个日志
当访问web.kong.com kong.access.log 日志显示正常
当访问web.liang.com liang.access.log 日志显示正常 但是kong.access.log 也会看到刷新
并且可以从$http_referer看出是从哪个连接跳过来 说明网站被盗链了
192.168.93.136 - - [17/Nov/2018:16:39:14 +0800] “GET /timg.jpg HTTP/1.1” 200 27361 “http://web.liang.com/” “Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0” “-”
(2)开启防盗链
方法1
在location添加
valid_referers none blocked *.kong.com; # web.kong.com开启防盗链 此时web.liang.com不能看到图片
if ($invalid_referer) {
return 403;
}
方法2
location ~* \.(gif|jpg|png|bmp)$ {
root /usr/share/nginx/html; # 一定要重新定义网站根目录 否则图片显示不出来
valid_referers none blocked *.kong.com server_names ~\.liangfaqi\.;
if ($invalid_referer) {
return 403;
#rewrite .* http://web.kong.com/1.jpg;
}
}
7.用户访问限制
1.连接频率限制 ngx_http_limit_conn_module
对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,往往考虑对同一个ip的连接数,并发数进行限制。
Syntax: limit_conn_zone key zone=name:size; Default: — Context: http
开启连接频率限制,示例: 设置一个缓存区保存不同key的状态,大小10m。使用远程ip来作为key,以此限制每个源IP的链接数
http {
limit_conn_zone $binary_remote_addr zone=one:10m; # 定义在http内 server外
}
server {
location / {
...
limit_conn one 2; # 定义每个IP的并发连接数量,特别注意这里最高只能限制到2,高了无效
}
}
# 测试
yum install -y httpd-tools # 压力测试工具
ab -n 100 -c 10 http://web.kong.com/ # 访问100次 分10次访问
Time taken for tests: 0.026 seconds
Complete requests: 100
Failed requests: 0
2.请求频率限制 ngx_http_limit_req_module
Syntax: limit_req_zone key zone=name:size rate=rate; Default: — Context: http
启动请求频率限制,示例:
设置一个缓存区reqps保存不同key的状态,大小10m。这里的状态是指当前的过量请求数。
http { # 定义在http里面,server的外面
...
limit_req_zone $binary_remote_addr zone=reqps:10m rate=5r/s; # 定义每个IP的每秒请求数量,限制每秒5个连接请求,不延迟
}
server {
location / {
...
limit_req zone=reqps; # 引用
# burst=5 表示最大延迟请求数量不大于5。 如果太过多的请求被限制延迟是不需要的 ,这时需要使用nodelay参数,服务器会立刻返回503状态码。
limit_req zone=reqps burst=5; # 引用限制,但是令牌桶有5个。有延迟。速度慢
limit_req zone=reqps burst=5 nodelay; # 引用限制,但是令牌桶有5个。无延迟。速度快
}
}
yum install -y httpd-tools # 压力测试工具
ab -n 100 -c 10 http://web.kong.com # 访问100次 分10次访问
Time taken for tests: 0.041 seconds
Complete requests: 100
Failed requests: 99
查看错误日志:
2018/11/17 17:55:48 [error] 10697#10697: *100 limiting requests, excess: 0.800 by zone “reqps”, client: 192.168.93.136, server: web.kong.com, request: “GET / HTTP/1.0”, host: “web.kong.com”
8.用户访问控制
1.基于主机 ngx_http_access_module
Syntax: allow address | CIDR | unix: | all; Context: http, server, location, limit_except
server {
allow 10.18.47.64; # 允许访问的主机
deny all;
}
2.基于用户 ngx_http_auth_basic_module
htpasswd -cm /etc/nginx/conf.d/passwd user1 # 创建user1 并且创建passwd文件 -c只需要第一次没有文件时使用
htpasswd -m /etc/nginx/conf.d/passwd user2 # 创建user2
location /{
access_log /var/log/nginx/kong.access.log main;
root /usr/share/nginx/html;
index kong.html index.html;
auth_basic "nginx access test!";
auth_basic_user_file /etc/nginx/conf.d/passwd;
}
访问web.kong.com 查看结果
二、nginx 新增模块
- 查看nginx已安装的模块
./sbin/nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
- 下载需要安装的模块 以nginx-module-vts模块为例
git clone git://github.com/vozlt/nginx-module-vts.git
pwd
/root/nginx-1.20.1/nginx-module-vts
ls
Changes config LICENSE README.md share src t util
- 备份旧的nginx二进制文件
pwd
/usr/local/nginx/sbin
mv nginx nginx.bak
- 重新编译添加新增模块 —add-module
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/root/nginx-1.20.1/nginx-module-vts
5. 编译完成之后,将新生成的二进制文件拷贝到nginx目录下
make
*注:这里不要执行make install,我们只需要通过make将新增模块编译进来,生成新的二进制文件,在objs目录下。千万不要执行make instlall ,make install 会重新安装nginx,覆盖原有nginx
pwd
/root/nginx-1.20.1/objs
ls
addon Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
cp nginx /usr/local/nginx/sbin/
- 检查模块,并重启nginx
/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/root/nginx-1.20.1/nginx-module-vts
- 测试新安装的模块
新增nginx配置:
http {
vhost_traffic_status_zone;
...
server {
location /status {
listen 81;
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}
}
重启nginx
/usr/local/nginx/sbin/nginx -s reload
|