访问控制
用户访问控制
ngx_http_auth_basic_module
有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。我们在服务课程中学习过apache的访问控制,对于Nginx来说同样可以实现,并且整个过程和Apache 非常的相似。
#1.建立口令文件
htpasswd -c /etc/nginx/passwd.db user1
New password:
Re-type new password:
Adding password for user user1
#2.实现认证
vim default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
auth_basic "hello"; # 这一行是你登录窗口写的提示文字
auth_basic_user_file /etc/nginx/passwd.db; # 密码存放的目录
}
# htpasswd -c选项只有第一次没有密码文件的时候需要添加,第二再添加账户的时候,不需要跟-c
systemctl reload nginx
# 用户认证局限性
# 1. 用户信息依赖文件方式
# 2. 用户管理文件过多,无法联动
# 3. 操作管理机械,效率低下
# 解决办法
# 1. Nginx结合LUA实现高效验证
# 2. Nginx结合LDAP利用nginx-auth-ldap模块
访问测试
重新加载配置文件后如果用elinks,curl访问会报错401,需要授权,需要用浏览器访问.
主机访问控制
ngx_http_access_module
location / {
root /usr/share/nginx/html;
index index.html index.htm;
# auth_basic "hello";
# auth_basic_user_file /etc/nginx/passwd.db;
allow 39.108.140.0; #只允许此IP访问
deny all; #拒绝所有
}
elinks --dump 49.233.69.195
403 Forbidden
状态访问
ngx_http_stub_status_module
使用第三方的软件监控nginx时,需要保证其本身能显示状态信息,然后利用这些数据显示一些监控数据和生成图表,使用该模块需要在编译nginx时启用该模块.
# 在server中加入以下几行
location ~ /status {
stub_status on;
access_log off; # 状态模块的访问不记录日志
allow 39.108.140.0; # 只允许管理员访问
deny all;
}
curl 49.233.69.195/status
Active connections: 1 # Nginx当前活跃连接数
server accepts handled requests
14 14 14
Reading: 0 Writing: 1 Waiting: 0
#第一个14: 为一共处理的多少个连接请求
#第二个14: 为创建多少次握手
#第三个14: 为总处理了多少请求
# Active connections 对后端发起的当前活动连接数
# server accepts handled requests:
# server: Nginx总共处理了14个连接, 表示Nginx处理接收握手总次数
# 成功创建了14次握手,也就是成功的连接数connection 失败连接=(总连接数-成功连接数) (相等表示中间没有失败的)
# 总共处理了14个请求数requests (server和client建立一条连接之后开始请求数据,每有一个请求此数字会+1)
# request: http请求,GET/POST/DELETE/UPLOAD(指的是请求资源),默认情况下下一个请求需要一个连接,但是如果开启了长连接,那么一个连接可以对应多个请求.
# Reading: nginx读取到客户端的Header信息数,请求头,Nginx读取数据
# Waiting:
# nginx返回给客户端的Header信息数,响应头,如果这个值飙升,说明后面的节点挂掉了,例如数据库等. Nginx写的情况
# Waiting: 开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接.
# 处理完等待下次请求的数量, 通俗点就是即没有读也没有写,建立连接情况.
# 一般监控都是通过此模块监控状态比如蓝鲸,zabbix;如果需要监控进程和端口需要
网站过滤
替换网站响应内容: ngx_http_sub_module
server里面加入下面两行代码.
location / {
root /usr/share/nginx/html;
index index.html index.htm;
sub_filter nginx 'flying'; # 默认只替换第一个nginx为flying,如果有多的nginx是不会替换的.
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
sub_filter nginx 'flying';
sub_filter_once off; # 替换全部nginx为flying
}
实用用法
如果我们用模板生成网站的时候,因为疏漏或者别的原因造成代码不如意,但是此时因为文件数量巨大,不方便全部重新生成,那么这个时候我们就可以用此模块来暂时实现纠错,另一方面,我们也可以利用这个实现服务器端文字过滤的效果.
Nginx流量控制(连接和请求)
http协议的连接与请求
HTTP是建立在TCP, 在完成HTTP请求需要先建立TCP三次握手(称为TCP连接),在连接的基础上再HTTP请求
HTTP请求建立在一次TCP连接基础上,一次TCP请求至少产生一次HTTP请求
连接频率限制限制模块
ngx_http_limit_conn_module
(nginx的连接频率限制模块可以根据定义的key来限制每个键值的连接数.)
# Syntax: limit_req_zone key zone=name:size rate=rate;(设置速率每秒多少个请求)
# Default: —
# Context: http
# Syntax: limit_req zone=name [burst=number] [nodelay];(burst可以设置前多少个请求不限制,也可以设置是否延迟访问)
# Default: —
# Context: http, server, location
# Example:
yum -y install httpd-tools
vim /etc/nginx/nginx.conf
http {
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
vim /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
limit_req zone=req_zone;
#limit_req zone=req_zone burst=5; #5个请求时不限制的,但有延迟
#limit_req zone=req_zone burst=5 nodelay; #无延迟,只要拿到令牌就可以处理
}
ab -n 100 -c 10 http://39.108.140.0/
Time taken for tests: 0.940 seconds # 请求花费的总时间
Complete requests: 100
Failed requests: 99 # 请求了100,失败了99
(Connect: 0, Receive: 0, Length: 99, Exceptions: 0)
Write errors: 0
Non-2xx responses: 99 # 非200请求99个
连接限制没有请求限制有效?
我们前面说过, 多个请求可以建立在一次的TCP连接之上, 那么我们对请求的精度限制,当然比对一个连接的限制会更加的有效。
因为同一时刻只允许一个连接请求进入。
但是同一时刻多个请求可以通过一个连接进入。
所以请求限制才是比较优的解决方案。
防盗链
图片防盗链
防止网站资源被盗用 ngx_http_referer_module
# 盗链是本网站的url显示其他网站图片,而直接用它的URL是转发,宣传的也是人家的URL.
# 主机proxy准备一张图片放到根目录
mv 1.png /usr/share/nginx/html/
# 主机rearend修改index.html
cat /usr/share/nginx/html/index.html
<html>
<head>
<meta charset="utf-8">
<title>hello everyone</title>
</head>
<body style="background-color:red;">
<img src="http://39.108.140.0/1.png"/>
</body>
</html>
此时用windows10谷歌浏览器访问rearend主机,但是日志在proxy主机上,消耗资源也是proxy主机
tail -1 /var/log/nginx/access.log
114.242.249.222 - - [03/Nov/2019:17:00:31 +0800] "GET /1.png HTTP/1.1" 304 0 "http://49.233.69.195/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" "-"
修改proxy主机配置文件
vim /etc/nginx/conf.d/default.conf
location ~ .(img|png|gif)$ {
root /usr/share/nginx/html/images;
index index.html;
valid_referers none blocked *.youmen.cn server_names ~youmen ~.google
. ~baidu;
if ($invalid_referer) {
return 403;
}
}
systemctl reload nginx
此时再用浏览器访问rearend主机就会显示一张破碎的图片标志,图片资源也加载不出来
如何区分哪些是不正常的用户?
http referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上referer,告诉服务器我是从那个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等,因此Http Referer头信息是可以通过程序伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是他能限制大部分盗链情况。
Nginx下载站点
Nginx默认不允许整个目录浏览下载
如果需要开启,修改一下配置文件即可
autoindex常用参数
autoindex_exact_size off;
# 默认为on, 显示出文件的确切大小,单位是bytes。
# 修改为off,显示出文件的大概大小,单位是kB或者MB或者GB。
autoindex_localtime on;
# 默认为off,显示的文件时间为GMT时间。
# 修改为on, 显示的文件时间为文件的服务器时间。
charset utf-8,gbk;
# 默认中文目录乱码,添加上解决乱码。
开启全站目录浏览器功能(http下面添加如下内容)
autoindex on; # 开启目录文件列表
autoindex_exact_size on; # 显示出文件的确切大小,单位是bytes
autoindex_localtime on; # 显示的文件时间为文件的服务器时间
charset utf-8,gbk,gb2312; # 避免中文乱码
add_header Content-Disposition attachment; # 文件下载(可以不开启该功能)
开启网站部分目录浏览器功能
# 编辑nginx.conf,在Server{}模块或者localtion模块加入以下内容:
autoindex on; # 开启目录文件列表
autoindex_exact_size on; # 显示出文件的确切大小,单位是bytes
autoindex_localtime on; # 显示的文件时间为文件的服务器时间
charset utf-8,gbk,gb2312; # 避免中文乱码