1.常见的恶意行为
- 爬虫行为
- 恶意抓取
- 资源盗用
所谓的恶意行为就是不触犯法律的红线,也不是正常的访问,但是带有恶意的目的。爬虫会不断进行网站内容的抓取,有写爬虫是我们要禁止的,有些爬虫要允许的
如(百度,google)搜索引擎。在之前介绍过防盗链{:target="_blank"},目的就是不让恶意用户能轻易的爬取网站对外的数据。
secure_link_module模块{:target="_blank"}对数据安全性提高加密验证和失效性,适合重要数据
感兴趣的小伙伴可以去看看。
2.常见的攻击手段
常见的攻击手段已经触犯了法律的红线,小伙伴们千万不要尝试。
- 后台密码撞库
- 文件上传
- sql注入
后台密码撞库
后台密码撞库是非常常见的攻击手段-通过猜测密码自典不断对后台系统登录性尝试,获取后台登录密码。可以通过下面一些方法预防
- 提高后台登录密码的复杂度
- access_module对后台提供ip的访问控制
- 设立预警机制,当一个ip在短时间内尝试多次请求,就启动预警
文件上传
文件上传漏洞是利用这些上传的接口将恶意代码植入到服务器中,在通过url去访问执行代码。在nginx早期版本存在一个漏洞,例如http://www.waliblog.com/upload/1.jpg/1.php
,
当黑客上传一张1.jpg图片放在文件upload目录下,图片内容实际上是php代码(假设恶意的),只是修改了文件名称,于是就可以通过http://www.waliblog.com/upload/1.jpg来访问到1.jpg文件。nginx此时是将1.jpg文件作为静态资源来处理。
当我们通过http://www.waliblog.com/upload/1.jpg/1.php访问时,后面加上1.php
。nginx就会将1.jpg交给php解析器,作为php代码执行。在服务器端就可以做想做的事情了,这个漏洞被修复掉了。
location ^~ /upload{
root /opt/app/images;
if($request_filename ~* (.*)\.php){
return 403;
}
}
SQL注入
SQL注入-利用未过滤/未审核用户输入的攻击方法,让应用运行本不应该运行SQL代码。
我们来模拟一个用户登录场景,假设前后端都是不负责任的,对提交的内容不做任何校验。事实上,小菜在写项目时,也发现后台有时候不会对前端输入的内容做任何校验,
这时候前端懒一点也不做校验,就会在某些情况写发生严重的后果。
在正常登陆下,一般都是这样的用户名密码,用户名:wali122 密码:123456。如果在用户名中输入' or 1=1'#
,密码随便输入一个。在后台查询的sql语句如下
$sql = "select * from users where username='$name' and password='$pwd'";
那么在数据库中sql语句
select * from users where username =' or 1=1'# and password='233423'";
解读sql,就会发现是一个ture的语句。并且密码后半段校验就会被注释掉,这样随便一个账号就能够登录。
虽然上面为举这个例子有大量的假设,而且我相信这样的错误几乎是不会在出现。但作为程序员还是要有自己的责任。
3.模拟SQL注入场景
####搭建安装环境
安装数据库
yum install mariadb-server mariadb
安装php
yum install php php-fpm php-mysql
启动mql
systemctl start mariadb
mysql -uroot -p
默认数据库的密码是回车
show databases; #查看数据库
create database info; #创建info数据库
use info; #使用info数据库
show tables; #查看表
create table users(id int(11),username varchar(64),password varchar(64),email varchar(64)); #创建表结构
desc users; #查看表结构
insert into users (id,username,password,email) values(1,'wali','1234','walidream@163.com'); #向表中插入数据
####PHP环境
ps -aux|grep php #查看php-fpm起来没
php-fpm -D #守护进程
配置目录
/etc/nginx/cond.f
|-php.conf
/opt/app/code
|-index.php
|-validate.php
|-login.html
php.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
access_log /var/log/nginx/yagm.log main;
root /opt/app/code;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /opt/app/code/$fastcgi_script_name;
include fastcgi_params;
}
}
index.php
<?php
phpinfo();
?>
重启nginx,在页面上输入域名,出现php输出信息就好了
login.html
<html>
<head>
<title>sql注入演示</title>
<meta http-equiv="content-type"content="text/html;charset=utf-8">
</head>
<body>
<form action="validate.php" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"/></td>
</tr>
<tr> <td> <input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</body>
</html>
validate.php
<?php
$conn = mysql_connect("localhost",'root','') or die("数据库连接失败!");
mysql_select_db("info",$conn) or die("您要选择的数据库不存在");
$name=$_POST['username'];
$pwd=$_POST['password'];
$sql="select * from users where username=’$name' and password='$pwd'";
echo $sql."<br/><br/>";
$query=mysql_query($sql);
$arr=mysql_fetch_array($query);
if($arr){
echo "login success!\n";
echo $arr[1];
echo $arr[3]."<br/>";
}else{
echo "login failed";
}
?>
访问http://yagm.xin/login.html就会出现登录页面
正常情况:
用户名:eve 密码:1234
sql注入:
用户名:’ or 1=1# 密码:1adfa
输出sql语句
select * from users where username=’ ’ or 1=1# and password=‘1234’
虽然上面的例子实在有些勉强,但是小菜想说在前后端逻辑不严谨的情况下是很容易给黑客留下漏洞的。
4.搭建Nginx+lua防火墙
为了简单方便,网上有现成的。
- https://github.com/loveshell/ngx_lua_waf{:target="_blank"}
复制https://github.com/loveshell/ngx_lua_waf.git
命令
cd /opt/download
git clone https://github.com/loveshell/ngx_lua_waf.git
cd /etc/nginx/
mv /opt/download/ngx_lua_waf ./waf/
cd waf
修改config.lua文件配置路径
原文件
RulePath = "/usr/local/nginx/conf/waf/wafconf/"
attacklog = "on"
logdir = "/usr/local/nginx/logs/hack/"
UrlDeny="on"
Redirect="on"
CookieMatch="on"
postMatch="on"
whiteModule="on"
black_fileExt={"php","jsp"}
ipWhitelist={"127.0.0.1"}
ipBlocklist={"1.0.0.1"}
CCDeny="off"
CCrate="100/60"
html=[[ ...
修改后的文件
RulePath = "/etc/nginx/waf/wafconf/" #匹配的规则
attacklog = "on" #如果有攻击,会记录日志
logdir = "/var/log/nginx/log/hack" #日志的保存路径
UrlDeny="on"
Redirect="on"
CookieMatch="on"
postMatch="on"
whiteModule="on"
black_fileExt={"php","jsp"}
ipWhitelist={"127.0.0.1"} #白名单
ipBlocklist={"1.0.0.1"} #黑名单
CCDeny="off"
CCrate="100/60"
html=[[ ...
将lua加入nginx.conf配置文件
vim /etc/nginx/nginx.conf
原nginx.conf文件
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
修改后nginx.conf文件
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
lua_package_path "/etc/nginx/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file /etc/nginx/waf/init.lua;
access_by_lua_file /etc/nginx/waf/waf.lua;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
检测nginx语法并重启
nginx -tc /etc/nginx/nginx.conf
nginx -s reload -c /etc/nginx/nginx.conf
重启完成后,在输入域名到测试页面去。
然后我们修改lua配置
cd /etc/nginx/waf/wafconf/
vim post
在第一行加入
\sor\s+
保存后重启nginx,在输入之前的用户名会发现被拦截了
5.nginx对cc攻击限制
接上面lua配置继续配置对cc攻击的限制
vim /etc/nginx/waf/config.lua
将config.lua文件中
CCDeny="off"
CCrate="100/60"
修改为
CCDeny="on"
CCrate="10/60" #每60秒访问1次
修改完成检查nginx语法并重启
nginx -tc /etc/nginx/nginx.conf
nginx -s reload -c /etc/nginx/nginx.conf
然后在测试页面输入域名http://yagm.xin/login.html,不停的按F5键,就会出现503。