网站被攻击了,运维给了我自动封禁ip的脚本
我的网站被攻击了,发现友圈最近出现这种情况的还不少,真是神奇了,这事也能扎堆发生。
分享出来给大家,万一以后用得着呢~
故事背景
我的一个小网站最近总是收到云监控报警,一个部署在4核8G单机上的小网站。
查了log发现,我是被流量攻击了。
我招谁惹谁了呀,烦死了。昨天半夜11点收到报警短信,搞到了半夜12点,太耽误我睡觉了。
调研了一下云平台的安全服务,还挺贵,弃疗了。
我还是自己写吧,不是为了提升技术水平,单纯的为了省钱!
实现思路
首先,我的小网站访问量不高,如果某位大哥一天访问超过10次我就觉得有鬼了。
综上分析,我的实现思路如下:
监测log日志,分析访问ip。 每天ip的访问次数超过100就果断封掉。(为了避免误伤,我暂时把这个阈值设置成100,后面看情况动态调整。)
功能拆解
编写脚本,按日期拆分access.log(之前犯懒没做日志拆分,只是定时删除了访问日志) 编写定时任务,每天0点拆分访问日志 编写脚本,分析access.log访问日志,封禁当天访问次数超过100的ip 编写定时任务,每10分钟执行一次封禁ip脚本
思路是如此的清晰,奈何我并不擅长编写shell脚本,于是请教了群里的大佬,最终的实现如下:
具体实现
1. 日志拆分脚本
已经清楚的写了注释
其中LOG_PATH
和PID
换成你自己的路径
# 每天0点执行日志按日期分隔脚本 0 0 * * * cd /www/Home/ && ./log_cut.sh #!/bin/bash #此脚本⽤于⾃动分割Nginx的⽇志,包括access.log #每天00:00执⾏此脚本将前⼀天的access.log重命名为access-xxxx-xx-xx.log格式,并重新打开⽇志⽂件 #Nginx⽇志⽂件所在⽬录 todo 换成你自己的 LOG_PATH=/data/logs/nginx/ #获取昨天的⽇期 YESTERDAY=$(date -d "yesterday" +%Y-%m-%d) #获取pid⽂件路径 todo 换成你自己的 PID=/var/run/nginx.pid #分割⽇志 mv ${LOG_PATH}access.log ${LOG_PATH}access-${YESTERDAY}.log #向Nginx主进程发送USR1信号,重新打开⽇志⽂件 kill -USR1 `cat ${PID}`
2. 编写定时任务
# 每天0点执行日志按日期分隔脚本 0 0 * * * cd /www/Home/ && ./log_cut.sh
#
代表注释&& 表示将两个命令连接在一起,前面的先执行,后面的再执行 如果你不知道crontab的定时任务怎么编写,强烈建议你使用这个工具:「Crontab在线工具」:
简直不要太好用!
3. 编写封禁ip脚本
注释写得很清楚了:
logdir
替换成你自己的地址/tmp/nginx_deny.log
也可以设置成你自己的地址,或者用这个地址也可以。
# 每十分钟执行一次封禁ip脚本 */10 * * * * cd /www/Home/ && ./blackip.sh#!/bin/bashlogdir=/data/logs/nginx/access.log #nginx访问日志文件路径port=443#循环遍历日志文件取出访问量大于100的ip(忽略自己本地ip)for drop_ip in $(cat $logdir | grep -v '127.0.0.1' | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if ($1>100) print $2}'); do # 避免重复添加 num=$(grep ${drop_ip} /tmp/nginx_deny.log | wc -l) if [ $num -ge 1 ]; then continue fi # shellcheck disable=SC2154 iptables -I INPUT -p tcp --dport ${port} -s ${drop_ip} -j DROP echo ">>>>> $(date '+%Y-%m-%d %H%M%S') - 发现攻击源地址 -> ${drop_ip} " >>/tmp/nginx_deny.log #记录logdone
4. 编写封禁ip定时任务
# 每十分钟执行一次封禁ip脚本 */10 * * * * cd /www/Home/ && ./blackip.sh
思考
如果自己人的ip不小心被封了怎么办呢?
别担心,可以用下面的命令:
#清空屏蔽IPiptables -t filter -D INPUT -s 1.2.3.4 -j DROP #一键清空所有规则iptables -F
附上大佬给的iptablse常用命令,先收藏,慢慢学。
iptablse常用命令
1.清除iptables(常用)
iptables -F
2. 备份iptables(常用)
iptables-save > iptables.txt
3. 导入iptables(常用)
iptables-restore < iptables.txt
4. 机器重启自动生效(常用)
service iptables save
5. 清空某条规则:
iptables -t filter -D INPUT -s 1.2.3.4 -j DROP
6. 禁止某个ip(下面用$ip表示)访问本机:
iptables -I INPUT -s $ip -j DROP
7. 禁止某个ip段(下面用 mask表示,其中$mask是掩码)访问本机:
iptables -I INPUT -s $ip/$mask -j DROP
8. 禁止本机访问某个ip(下面用$ip表示):
iptables -A OUTPUT -d $ip -j DROP
9. 禁止某个ip(下面用$ip表示)访问本机的80端口的tcp服务:
iptables -I INPUT -p tcp –dport 80 -s $ip -j DROP
10. 禁止所有ip访问本机的80端口的tcp服务:
iptables -A INPUT -p tcp --dport 80 -j DROP
11. 禁止所有ip访问本机的所有端口:
iptables -A INPUT -j DROP
12. 禁止除了某个ip(下面用$ip表示)之外其他ip都无法访问本机的3306端口(常用):
(1)首先 禁止所有
iptables -I INPUT -p tcp --dport 3306 -j DROP
(2)然后 开放个别
iptables -I INPUT -s $ip -p tcp --dport 3306 -j ACCEPT
总结
我之前的思路是配置nginx的黑名单,每次添加新的黑名单之后,还要重启Nginx。
大佬告诉我,不用这么麻烦:直接用Linux的iptables防火墙,既高效又简单。连403都不要那些坏人看到!
如果你也碰到类似的问题,欢迎复刻我的经验。
相关文章
- 在昨天的《Javascript权威指南》学习笔记之十:ECMAScript 5 增强的对象模型一文中,对于一段代码的调试出现了一个奇怪现象,现将源代码贴在下面: 复制代码 代码如下: <script type="text/javascript"> function Person(){}...2014-05-31
- 复制代码 代码如下: //element:需要添加新样式的元素,value:新的样式 function addClass(element, value ){ if (!element.className){ element.className = value; }else { newClassName = element.className; newClas...2014-05-31
- 在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代。 它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下...2015-03-15
- 有一道js面试题,题目是这样的:下列代码的执行结果是什么,为什么? 复制代码 代码如下: var i, j, k; for (i=0, j=0; i<10, j<6; i++, j++) { k = i+j; } document.write(k); 答案是显示10,这道题主要考察JavaScript的逗...2015-03-15
- 事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQue...2014-06-07
- 1、ActiveX向Javascript传参 复制代码 代码如下: <script language="javascript" for="objectname" event="fun1(arg)"> fun2(arg); </script> objectname为ActiveX控件名,通过<object>标签里的id属性设定,如下; 复制...2014-06-07
- 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素。 HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。 HTML DOM 模型被构造为对象的树: 通过可编程的对象模型,Java...2015-10-23
- Window有navigator对象让我们得知浏览器的全部信息.我们可以利用一系列的API函数得知浏览器的信息.JavaScript代码如下:function message(){ txt = "<p>浏览器代码名: " + navigator.appCodeName + "</p>";txt+= "<p>...2015-11-24
- 虽然ES6都还没真正发布,但已经有用ES6重写的程序了,各种关于ES789的提议已经开始了,这你敢信。潮流不是我等大众所能追赶的。潮流虽然太快,但我们不停下学习的步伐,就不会被潮流丢下的,下面来领略下ES6中新特性,一堵新生代JS...2015-11-24
- ---恢复内容开始---1.location.href.....(1)self.loction.href="http://www.cnblogs.com/url" window.location.href="http://www.cnblogs.com/url" 以上两个用法相同均为在当前页面打开URL页面 (2)this.locati...2015-10-30
- tab切换在网页中很常见,故最近总结了4种实现方法。 首先,写出tab的框架,加上最简单的样式,代码如下: <!DOCTYPE html> <html> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style> *{ pa...2015-11-08
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
前言在面向对象的编程范式中,封装都是必不可少的一个概念,而在诸如 Java,C++等传统的面向对象的语言中, 私有成员是实现封装的一个重要途径。但在 JavaScript 中,确没有在语法特性上对私有成员提供支持, 这也使得开发人员使...2015-10-30- 生生把写过的java版改成javascript版,第一次写,很不专业,见谅。唉,我是有多闲。复制代码 代码如下: var Sudoku = { init: function (str) { this.blank = []; this.fixed = []; this.cell =...2015-03-15
javascript中slice(),splice(),split(),substring(),substr()使用方法
1.slice();Array和String对象都有在Array中 slice(i,[j])i为开始截取的索引值,负数代表从末尾算起的索引值,-1为倒数第一个元素 j为结束的索引值,缺省时则获取从i到末尾的所有元素参数返回: 返回索引值从i到j的数组,原数组...2015-03-15javascript中的document.open()方法使用介绍
document.open()方法打开一个新的文档,并用document.write()方法编写文档的内容,然后用document.close()方法关闭文档操作,使其内容显示出来。 例如: 复制代码 代码如下: <script type="text/javascript"> window.onloa...2013-10-13- 本文实例讲述了JS实现的自定义网页拖动类。分享给大家供大家参考,具体如下: Javascript本身没有暂停功能(sleep不能使用)同时 vbscript也不能使用doEvents,故编写此函数实现此功能。 javascript作为弱对象语言,一个函数也...2015-11-08
- 经常在写代码的时候碰到这样的场景:页面初始化时显示loading页,同时启动多个ajax并发请求获取数据,当每个ajax请求返回时结束loading。 举个例子,一个下订单的页面,要查询常用地址信息、商品信息、地市信息…而这些请求都...2015-10-30
- 小编也是刚开始学JavaScript,觉得淘宝评星效果很棒,于是产生了自己写一个的想法,先给大家分享一下实现效果:现附上自己写的源代码 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <script language="Java...2015-11-24
开启Javascript中apply、call、bind的用法之旅模式
我希望能够通过这篇文章,能够清晰的提升对apply、call、bind的认识,并且列出一些它们的妙用加深记忆。 apply、call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为...2015-10-30浅析javascript中function 的 length 属性
[1,2,3].length 可以得到 3, "123".length 也可以得到 3,这个略懂js的都知道。但是 eval.length,RegExp.length,"".toString.length,1..toString.length 会得到什么呢?分别得到 1,2,0,1,这些数字代表什么呢?这个是群里很多新...2014-05-31