发现有个IP不断的猜测路径、试图往服务器上传文件(木马)。于是查看了之前的日志,无奈鄙站被攻击者盯上了,不断的有不同的IP试图上传木马。看来坏人还是有的。由于不想让鄙站沦为肉鸡,所以就想写个简单的脚本,来阻止攻击者的IP访问。
攻击者:
1
2
3
4
5
6
7
8
|
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
40
+
0800
]
"POST /wp-content/themes/twentyten/404.php HTTP/1.1"
404
27
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
40
+
0800
]
"POST /wp-content/themes/twentythirteen/404.php HTTP/1.1"
404
27
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
40
+
0800
]
"POST /wp-content/themes/twentytwelve/404.php HTTP/1.1"
404
27
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
40
+
0800
]
"POST /wp-content/uploads/phptest.php HTTP/1.1"
404
27
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
41
+
0800
]
"POST /xyr/confings.asp HTTP/1.1"
404
1569
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
41
+
0800
]
"POST /xz.asp;.jpg HTTP/1.1"
404
564
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
41
+
0800
]
"POST /yanyu/?q={${eval%28$_POST[u]%29}} HTTP/1.1"
404
1569
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
195.154.216.165
-
-
[
28
/
Nov
/
2015
:
23
:
10
:
42
+
0800
]
"POST /ztxxw/Images/images.asp HTTP/1.1"
404
1569
"http://www.z-dig.com/11m.php"
"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
"-"
|
1
2
3
|
[
root
@
z
-
dig
www
]
# grep '195.154.216.165' 2015-11-28.access.log|wc -l
289
[
root
@
z
-
dig
www
]
#
|
1
2
3
4
5
6
7
8
9
10
11
|
[
root
@
z
-
dig
www
]
# curl ipinfo.io/195.154.216.165;echo''
{
"ip"
:
"195.154.216.165"
,
"hostname"
:
"fr.07.gs"
,
"city"
:
""
,
"region"
:
""
,
"country"
:
"FR"
,
"loc"
:
"48.8600,2.3500"
,
"org"
:
"AS12876 ONLINE S.A.S."
}
[
root
@
z
-
dig
www
]
#
|
法国的哥们竟然试了180多次!辛苦了。
用 shell 和定时任务来实现吧。>_<
网站跑在 Nginx 上,所以可以使用 Nginx 的 Deny 来拒绝攻击者的IP访问。
那么思路就出来了,定期(五分钟或十分钟)获取攻击者的IP,将IP放入到黑名单(Nginx 配置文件),并 reload 使其生效。
由于前期规划的比较好,网站的访问日志放在了一个指定的目录,Nginx 的错误日志也放在了一个指定的目录。网站的访问日志每日进行切割。Nginx 的错误日志没有进行切割。
下面就是我的思路和操作步骤:
通过 Nginx 的错误日志(为什么不使用访问日志)来获取攻击者的IP。之前没有对 Nginx 的错误日志进行定时切割,为了方便统计攻击者的IP所以,编写脚本并加入定时任务,使错误日志每小时切割一次,并且每小时对黑名单文件进行清空。
错误日志切割、清空黑名单脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[
root
@
z
-
dig
scripts
]
# cat rotate-nginx-error-logs.sh
#!/bin/bash
# Rotate nginx error logs and clean block ip 's configure file
# Nginx pid file : /application/nginx/logs/nginx.pid
# Nginx error logs directory : /data/logs/nginx
# Block Ip 's configure file : /application/nginx/conf/website/blockip.conf
# Default log name : error.log
# Author : Mr.Zhou
# E-mail : zhou@z-dig.com
NGX_PID
=
/
application
/
nginx
/
logs
/
nginx
.
pid
NGINX_CMD
=
/
application
/
nginx
/
sbin
/
nginx
LOGS_DIR
=
/
data
/
logs
/
nginx
LOG_NAME
=
error
.
log
BLOCK_IP_FILE
=
/
application
/
nginx
/
conf
/
website
/
blockip
.
conf
cd
$
LOGS_DIR
&&
/
usr
/
bin
/
rename
$
LOG
_NAME
$
(
/
bin
/
date
+
%
F
-
%
H
-
d
"last hour"
)
.
$
LOG
_NAME
$
LOG_NAME
&&
/
bin
/
kill
-
USR1
$
(
cat
$
NGX_PID
)
>
$
BLOCK_IP_FILE
&&
$
(
$
NGINX_CMD
-
s
reload
)
[
root
@
z
-
dig
scripts
]
#
|
获取攻击者IP脚本:
该脚本从 Nginx 的错误日志中统计出超过20次试图猜测路径或上传文件的IP,并将这些IP加入到 Nginx 的配置文件。若有新增加的IP则 reload Nginx 使配置文件生效,若没有新增IP则不进行reload。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[
root
@
z
-
dig
scripts
]
# cat block-ip.sh
#!/bin/bash
# Author : Mr.Zhou
# Email : zhou@z-dig.com
# Website : http://www.z-dig.com
# block ip
ERR_LOG
=
/
data
/
logs
/
nginx
/
error
.
log
BLOCK_IP_FILE
=
/
application
/
nginx
/
conf
/
website
/
blockip
.
conf
BLOCKED_IP
=
/
dev
/
shm
/
blocked
-
ip
.
txt
BLOCK_IP
=
/
dev
/
shm
/
block
-
ip
.
txt
NGINX_CMD
=
/
application
/
nginx
/
sbin
/
nginx
/
bin
/
cp
$
BLOCK_IP
_FILE
$
BLOCKED_IP
&&
/
bin
/
sed
-
nr
's#.*[^0-9](([0-9]+\.){3}[0-9]+).*#\1#p'
$
ERR_LOG
|
/
bin
/
awk
'{IP[$1]++}END{for (i in IP) print IP[i],i}'
|
/
bin
/
awk
'{if($1>20)print "deny "$2";"}'
>
$
BLOCK_IP
&&
/
bin
/
grep
-
v
-
f
$
BLOCK_IP
_FILE
$
BLOCK_IP
>>
$
BLOCK_IP_FILE
&&
$
(
$
NGINX_CMD
-
s
reload
)
[
root
@
z
-
dig
scripts
]
#
|
将拒绝指定IP访问的配置文件(黑名单)单独存放,并在 nginx 主配置文件中 include 进去。
1
2
3
|
[
root
@
z
-
dig
conf
]
# grep blockip.conf nginx.conf
include
website
/
blockip
.
conf
;
[
root
@
z
-
dig
conf
]
#
|
blockip.conf 文件格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[
root
@
z
-
dig
website
]
# cat blockip.conf
deny
195.154.211.220
;
deny
195.154.188.28
;
deny
195.154.188.186
;
deny
180.97.106.161
;
deny
180.97.106.162
;
deny
180.97.106.36
;
deny
195.154.180.69
;
deny
195.154.211.26
;
deny
221.229.166.247
;
deny
180.97.106.37
;
deny
195.154.216.164
;
deny
195.154.216.165
;
[
root
@
z
-
dig
website
]
#
|
将脚本放入定时任务执行:
每小时对 Nginx 的错误日志进行切割并且清空一次被拒绝访问IP的配置文件,若不清空的话,此IP将终生不能访问,若它再次攻击则会再次进入黑名单,>_<。 清空命令放在了切割脚本的尾部。
可以自己决定统计频率,根据指定的频率执行脚本,获取攻击者的IP,若此IP已经在黑名单中,则会忽略掉(由于错误日志一小时切割一次,所以在一小时内会出现重复的IP)。然后把剩下的新攻击者的IP追加到黑名单。并 reload Nginx 。若没有新增的攻击者IP则什么都不做。
1
2
3
4
5
6
7
8
|
[
root
@
z
-
dig
~
]
# crontab -l
# rotate nginx log everyday
00
00
*
*
*
/
bin
/
bash
/
application
/
scripts
/
rotate
-
nginx
-
logs
.
sh
&
>
/
dev
/
null
# rotate nginx error log every hour and clean the block ip file
00
*
/
1
*
*
*
/
bin
/
bash
/
application
/
scripts
/
rotate
-
nginx
-
error
-
logs
.
sh
&
>
/
dev
/
null
# check hacker's ip every ten minutes
*
/
10
*
*
*
*
/
bin
/
bash
/
application
/
scripts
/
block
-
ip
.
sh
&
>
/
dev
/
null
[
root
@
z
-
dig
~
]
#
|
以下是脚本运行一段时间的攻击者IP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[
root
@
z
-
dig
~
]
# cat /application/nginx/conf/website/blockip.conf
deny
195.154.211.220
;
deny
195.154.188.28
;
deny
195.154.188.186
;
deny
180.97.106.161
;
deny
180.97.106.162
;
deny
180.97.106.36
;
deny
195.154.180.69
;
deny
195.154.211.26
;
deny
221.229.166.247
;
deny
180.97.106.37
;
deny
195.154.216.164
;
deny
195.154.216.165
;
[
root
@
z
-
dig
~
]
#
|
过段时间,再列出一份黑名单IP,看是否有变化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[
root
@
z
-
dig
~
]
# cat /application/nginx/conf/website/blockip.conf
deny
195.154.188.224
;
[
root
@
z
-
dig
~
]
# curl ipinfo.io/195.154.188.224;echo ''
{
"ip"
:
"195.154.188.224"
,
"hostname"
:
"195-154-188-224.rev.poneytelecom.eu"
,
"city"
:
""
,
"region"
:
""
,
"country"
:
"FR"
,
"loc"
:
"48.8600,2.3500"
,
"org"
:
"AS12876 ONLINE S.A.S."
}
[
root
@
z
-
dig
~
]
# grep '195.154.188.224' /data/logs/nginx/error.log |wc -l
102
[
root
@
z
-
dig
~
]
# grep '195.154.188.224' /data/logs/nginx/error.log |grep -v 'access forbidden' |wc -l
24
[
root
@
z
-
dig
~
]
#
[
root
@
z
-
dig
~
]
# tail -n 1 /data/logs/nginx/error.log
2015
/
11
/
30
10
:
47
:
53
[
error
]
30754
#0: *37828 access forbidden by rule, client: 195.154.188.224, server: www.z-dig.com, request: "GET / HTTP/1.1", host: "www.z-dig.com", referrer: "http://www.z-dig.com"
[
root
@
z
-
dig
~
]
#
|
看来多少还是管点用的。一共 access forbidden by rule 了 102-24=78 次。
适当的改改脚本,保存黑名单的历史数据,定期将大于1000的IP直接放入iptables!