【Day8】Nginx实战训练营
28-31、nginx访问控制
1、Nginx访问控制 —— deny、allow
Nginx 的 deny 和 allow 指令是由 ngx_http_access_module 模块提供,Nginx 安装默认内置了该模块。
除非在安装时有指定 –without-http_access_module
-
语法: allow/deny address | CIDR | unix: | all
它表示,允许/拒绝某个 ip 或者一个 ip 段访问。
如果指定 unix:,那将允许 socket 的访问。
注意: unix 在是1.5.1中新加入的功能。
在 nginx 中,allow 和 deny 的规则是按顺序执行的。 -
示例1:
location /
{
allow 192.168.0.0/24;
allow 127.0.0.1;
deny all;
}
-
说明: 这段配置值允许 192.168.0.0/24 网段和 127.0.0.1 的请求,其他来源 IP 全部拒绝。
-
访问测试:
[root@alexis-01 ~]# curl -x192.168.194.128:80 www.1.com/123 -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Sun, 03 Nov 2019 12:06:48 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123 -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:06:58 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
- 示例2:
location ~ "admin"
{
allow 192.168.194.0/24;
deny all;
}
-
说明: 访问的 uri 中包含 admin 的请求,只允许192.168.194.0/24 这个 IP 段的请求。
-
访问测试:
[root@alexis-01 ~]# curl -x192.168.194.128:80 www.1.com/123/admin -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:11:13 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123/admin -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:11:25 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
2、基于 location 的访问控制
在生产环境中,我们会对某些特殊的请求进行限制,比如对网站的后台进行限制访问。
这就用到了location配置。
- 示例1:
location /alexis/
{
deny all;
}
-
说明: 针对 /alexis/ 目录,全部禁止访问,这里的 deny all 可以改为 return 403.
-
示例2:
location ~ ".bak|\.htp"
{
return 403;
}
-
说明: 访问的 uri 中包含 .bak 字样的或者包含 .htp 的直接返回 403 状态码
.bak 的 . 表示任意字符,.htp 表示包含 .htp 字符的。(\ 脱义) -
访问测试:
- www.1.com/123.bak
- www.1.com/alexis/123/.htpalskdjf
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123.bak -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 11:56:00 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123.1bak -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 11:56:08 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123.b1ak -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 11:57:44 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123/.htpalsd -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 11:56:39 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123/.htdpalsd -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 11:56:50 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
- 示例3:
location ~ (data|cache|tmp|image|attachment).*\.php$
{
deny all;
}
-
说明: 请求的 uri 中包含 data、cache、tmp、image、attachment 并且以 .php 结尾的,全部禁止访问。
如果网站目可写,那么久不应该支持解析 php。 -
访问测试:
- www.1.com/alexis/cache/1.php
- www.1.com/image/123.phps
- www.1.com/alexis/datas/1.php
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/alexis/cache/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:15:56 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/image/123.phps -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:16:14 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/alexis/datas/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:16:25 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/alexis/dasta/1.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:16:39 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Nginx 安全原则: 网站有些目录可写的话,那么可写目录不应该支持解析 php
3、Nginx 基于 $document_uri 的访问控制
这就用到了变量 $document_uri,根据前面所学内容,该变量等价于 $uri,其实也等价于 location 匹配。
- 示例1:
if ($document_uri ~ "/admin/")
{
return 403;
}
-
说明: 当请求的uri中包含 /admin/ 时,直接返回 403.
-
if 结构中不支持使用 allow 和 deny。
-
访问测试:
1、www.1.com/123/admin/1.php 匹配
2、www.1.com/admin123/1.php 不匹配
3、www.1.com/admin.php 不匹配
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123/admin/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:21:02 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/admin123/1.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:21:14 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/admin.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:21:40 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
- 示例2:
if ($document_uri = /admin.php)
{
return 403;
}
-
说明: 请求的uri为 /admin.php 时返回403状态码。
-
访问测试:
1、www.1.com/admin.php 匹配
2、www.1.com/123/admin.php 不匹配
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/admin.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:23:00 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/123/admin.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:23:08 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/admin.html -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:26:11 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
- 示例3:
if ($document_uri ~ '/data/|/cache/.*\.php$')
{
return 403;
}
-
说明: 请求的 uri 包含 data 或者 cache 目录且以 php 结尾时,返回 403 状态码。
-
访问测试:
1、www.1.com/data/123.php 匹配
2、www.1.com/cache1/123.php 不匹配
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/data/123.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:29:17 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/cache/admin.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:29:26 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/cache1/123.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:29:42 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
4、nginx 基于 $request_uri 访问控制
$request_uri 比 $docuemnt_uri 多了请求的参数。
主要是针对请求的 uri 中的参数进行控制。
- 示例:
if ($request_uri ~ "gid=\d{9,12}")
{
return 403;
}
-
说明: \d{9,12} 是正则表达式,表示只要有连续 9 到 12 位数字,哪怕多出,例如 gid=1234567890 就符和要求。
-
访问测试:
1、 www.1.com/index.php?gid=1234567890 匹配
2、www.1.com/gid=123 不匹配
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/da2ta/1.php?gid=1234567890 -I
HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:41:26 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
[root@alexis-01 ~]# curl -x127.0.0.1:80 www.1.com/da2ta/1.php?gid=123a4567890 -I
HTTP/1.1 404 Not Found
Server: nginx/1.16.1
Date: Thu, 31 Dec 2019 12:41:36 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
- 背景知识:
曾经有一个客户的网站 cc 攻击,对方发起太多类似这样的请求:/read-123405150-1-1.html
实际上,这样的请求并不是正常的请求,网站会抛出一个页面,提示帖子不存在。
所以,可以直接针对这样的请求,return 403 状态码。