1.常见的恶意行为

所谓的恶意行为就是不触犯法律的红线,也不是正常的访问,但是带有恶意的目的。爬虫会不断进行网站内容的抓取,有写爬虫是我们要禁止的,有些爬虫要允许的 如(百度,google)搜索引擎。在之前介绍过防盗链,目的就是不让恶意用户能轻易的爬取网站对外的数据。 secure_link_module模块对数据安全性提高加密验证和失效性,适合重要数据 感兴趣的小伙伴可以去看看。

2.常见的攻击手段

常见的攻击手段已经触犯了法律的红线,小伙伴们千万不要尝试。

后台密码撞库

后台密码撞库是非常常见的攻击手段-通过猜测密码自典不断对后台系统登录性尝试,获取后台登录密码。可以通过下面一些方法预防

文件上传

文件上传漏洞是利用这些上传的接口将恶意代码植入到服务器中,在通过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代码。

我们来模拟一个用户登录场景,假设前后端都是不负责任的,对提交的内容不做任何校验。事实上,小菜在写项目时,也发现后台有时候不会对前端输入的内容做任何校验, 这时候前端懒一点也不做校验,就会在某些情况写发生严重的后果。

ssl

在正常登陆下,一般都是这样的用户名密码,用户名: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注入场景

ssl

####搭建安装环境

安装数据库

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','[email protected]'); #向表中插入数据

####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输出信息就好了

ssl

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防火墙

ssl

为了简单方便,网上有现成的。

复制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

重启完成后,在输入域名到测试页面去。

ssl

ssl

然后我们修改lua配置

cd /etc/nginx/waf/wafconf/
vim post 

在第一行加入

\sor\s+

保存后重启nginx,在输入之前的用户名会发现被拦截了

ssl

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。

nginx教程

nginx环境搭建(1) nginx基础知识(2) nginx的安装 卸载(3) nginx的基本参数使用(4) nginx分析默认配置(5) nginx 虚拟主机配置(6) nginx 日志(7) nginx 模块(8) nginx 访问控制(9) nginx 静态资源web服务(10) nginx 缓存(11) nginx 跨域访问(12) nginx 防盗链(13) nginx 正向,反向代理配置(14) nginx 代理缓存配置(15) nginx websocket(16) nginx fastcgi(17) nginx 搭建wordPress博客(18) nginx Fastcgi缓存配置(19) nginx uwsgi反向代理(20) nginx 负载均衡(21) [深] nginx 动静分离(22) [深] nginx rewrite规则(23) [深] nginx 平滑升级 添加模块 调试(24) [深] nginx secure_link_module模块(25) [深] nginx geoip_module模块(26) [深] nginx https(27) [深] nginx与lua的开发(28) [架] nginx常见问题(29) [架] nginx性能优化(30) [架] nginx 安全(31) [架] nginx 反向代理gRpc(32)