一 : Shell脚本防攻击的方法与实例
不知道得罪了哪路神仙,收到nagios报警,发现有个网站有CC攻击。看样子,量还不小,把服务器的负载都弄到40+了,虽然网站还能打开,但打开也是非常的缓慢。如果不是配置高点,估计服务器早就挂掉了。看来又是不一个不眠之夜了。
迅速查看一下nginx的访问日志:
#tail -f access.log
貌似全是像这样的状态。
我先紧急手动封了几个访问量比较大的Ip。
#iptables -A INPUT -s 83.187.133.58 -j DROP
#iptables -A INPUT -s 80.171.24.172 -j DROP
......
紧急封 了几个ip后,负载降了一些了,网站访问速度有所提升了,但是不一会,又来了一批新的Ip, 受不了了,看来要出绝招了。写了shell脚本,让他逮着了,就封。发现他攻击的状态都相同,每一个攻击ip后面都有HTTP/1.1" 499 0 "-" "Opera/9.02 (Windows NT 5.1; U; ru) 的字段,那我们就来搜这个字段。
#vim fengip.sh
#! /bin/bash
for i in `seq 1 32400`
do
sleep 1
x=`tail -500 access.log |grep 'HTTP/1.1" 499 0 "-" "Opera/9.02'|awk '{print $1}'|sort -n|uniq`
if [ -z "$x" ];then
echo "kong" >>/dev/null
else
for ip in `echo $x`
do
real=`grep -l ^$ip$ all`
if [ $? -eq 1 ];then
echo iptables -A INPUT -s $ip -p tcp --dport 80 -j DROP
iptables -A INPUT -s $ip -p tcp --dport 80 -j DROP
echo $ip >>all
fi
done
fi
done
脚本写好了。
如图
我们来运行一下,运行几分钟后,如下图所示
经过半个小时的观察,服务器负载也降到0.几了,脚本也不断在封一些CC攻击的ip。 一直让他运行着,晚上应该能睡个好觉了。
下来我们来对脚本进行解释一下。
#vim fengip.sh
#! /bin/bash
Touch all #建立all文件,后面有用到
for i in `seq 1 32400` #循环32400次,预计到早上9点的时间
do
sleep 1
x=`tail -500 access.log |grep 'HTTP/1.1" 499 0 "-" "Opera/9.02'|awk '{print $1}'|sort -n|uniq` #查看最后500行的访问日志,取出包含'HTTP/1.1" 499 0 "-" "Opera/9.02' 的行的ip并排序,去重复
if [ -z "$x" ];then
echo "kong" >>/dev/null #如果$x是空值的话,就不执行操作,说明500行内,没有带'HTTP/1.1" 499 0 "-" "Opera/9.02' 的行 www.61k.com
else
for ip in `echo $x` #如果有的话,我们就遍历这些ip
do
real=`grep -l ^$ip$ all` #查看all文件里有没有这个ip,因为每封一次,后面都会把这个ip写入all文件,如果all文件里面有这个ip的话,说明防火墙已经封过了。
if [ $? -eq 1 ];then #如果上面执行不成功的话,也就是在all文件里没找到,就用下面的防火墙语句把ip封掉,并把ip写入all文件
echo iptables -A INPUT -s $ip -p tcp --dport 80 -j DROP
iptables -A INPUT -s $ip -p tcp --dport 80 -j DROP
echo $ip >>all
fi
done
fi
done
脚本很简单,大牛略过啊。。。
二 : 几个shell脚本例子
几个脚本例子本章内容包括:pingall:一个按照/etc/hosts文件中的条目逐一ping所有主机得脚本
backup_gen:一个通用的备份脚本,能够加载缺省设置
del.lines:一个引用sed命令得脚本,能从文件中删除若干行
access_deny:一个能够组织某些特定用户登陆得工具
logroll:一个能够清除超过某一长度得日志得工具
nfsdown:一个快速unmount所有nfs文件系统得工具27.1 pingall该脚本列出/etc/hosts文件并查找其中的非注释行(不已#开头的行),然后使用一个while循环读入所有的行,接下来使用awk分析出每行的第一个域,并把她赋给变量ADDR.最后使用for循环逐一ping相应的地址.$ vi pingall.sh
#!/bin/bash
# pingall
# grab /etc/hosts and ping each address
cat /etc/hosts |grep -v '^#'
|while read LINE
do
ADDR=`awk '{print $1}'`
for MACHINE in $ADDR
do
ping -s -c1 $MACHINE
done
done$ cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1localhost.localdomainlocalhost
192.168.0.1testtest
$ sh pingall.sh
PING 192.168.0.1 (192.168.0.1) 0(28) bytes of data.
8 bytes from 192.168.0.1: icmp_seq=0 ttl=128
8 bytes from 192.168.0.1: icmp_seq=1 ttl=128
PS.为什么不是127.0.0.1 ?
27.2 backup_genbackup_gen是一个用于备份的脚本,它从一个缺省得配置文件中读入设置,然后根据这些参数对系统进行备份.用户可以根据自己得需要改变这些缺省设置.这是一个不同脚本如何使用相同设置或仅在自己运行期间改变相应设置得极好例子.当该脚本执行时,它首先确定源文件backup.defaults是否存在,如果不存在,则退出.脚本省略...
27.3 del.lines这个脚本只是包装了一下sed命令,但它能够使用户很方便地使用,他们非常喜欢用.
这个脚本可以处理一个或多个文件.每个文件在用sed删除空行之前要先核实是否存在.sed的输出被导入一个文件名中含有$$得临时文件,最后这个临时文件又被移回到原来得文件中.
该脚本使用shift命令取得所有得文件名,用while循环逐个处理所有得文件,直至处理完为止.$ vi del.lines.sh
#!/bin/bash
# del.lines
# script takes filename(s) and deletes all blank lines
TEMP_F=/tmp/del.lins.$$
usage()
{# usage
echo "Usage: `basename $0` file [file..]"
echo "try `basename $0` -help for more info"
exit 1
}if [ $# -eq 0 ]; then
usage
fiFILES=$1
while [ $# -gt 0 ]
do
echo "..$1"
case $1 in
-help) cat <<MAYDAY
Use this script to delete all blank lines from atext file(s)
MAYDAY
exit 0
;;
*) FILE_NAME=$1
if [ -f $1 ]; then
sed '/^$/d' $FILE_NAME>$TEMP_F
mv $TEMP_F $FILE_NAME
else
echo "`basename $0` cannot find this file:$1"
fi
shift
;;
esac
done27.4 access.deny在对系统进行某些更新时,你可能不希望用户登陆,这时可以使用/etc/nologin文件,大多数系统都提供这个文件.一旦在/etc目录中使用touch命令创建了一个名为nologin的文件,除root以外得任何用户都将无法登陆.如果系统不支持这种方法,你一样还可以做到这点--可以自己创建这个文件.可以在/etc/profile文件中加入下面代码:
if [ -f /etc/nologin ]
; then
if [ $LOGNAME != "root" ]; then
echo "Sorry $LOGNAME the system is unavailable atthe moment"
exit 1
fi
fi
现在,可以通过在/etc目录下创建nologin文件来组织除根用户以外得其他用户登陆,且该文件对所有用户可读.当决定恢复用户登陆时,只要删除该文件即可.上述方法可以很方便地组织除根用户以外得所有用户登陆.如果希望临时禁止某个用户登陆,可以修改/etc/passwd文件,把该用户得口令域得第一个字符变成*.这里有个上述工具得简化版本deny.access.该脚本从/etc/profile文件中运行,它读入一个名为lockout.users的文件.该文件包含有禁止登陆得用户名,如果文件中出现了all词,那么除root外得所有用户都将被禁止登陆.$ vi lockout.users
# lockout.users
# put the user names in this file,that you want
# locked out of the system
# remove the user names from this file,to let the users backin.
# peter is on long holiday back next month
peter
# lulu is off two weeks back at the end of the month
lulu
需要在/etc/profile中加入一航:
. /apps/bin/deny.access
/apps/bin目录要确保所有用户对该脚本及存放它得目录具有执行权限.完整脚本略...
27.5 logroll我得系统中有些日志文件增长十分迅速,每天手工检查这些日志文件得长度并倒换这些日志文件(通常是给文件名加各时间戳)是非常乏味得.于是我决定编写一个脚本来自动完成这项工作.该脚本将提交给cron进程来运行,如果某个日志文件超过了特定得长度,那么它得内容将被倒换到另一个文件中,并清除原有文件中得内容.该脚本中日志文件得长度限制是由变量BLOCK_LIMIT设定得,这一数字代表了块数目,在本例中是8块(每块大小为4k字节).可以按照自己得需求把这一数字设得更高.检查得日志文件名都保存在变量LOGS中.这里使用了一个for循环来依次检查每一个日志文件,使用du命令来获取日志文件长度.如果相应得文件长度大于BLOCK_LIMIT变量所规定得值,那么该文件将被拷贝到一个文件名含有时间戳得文件中,并改变这个文件所属得组,原先得文件长度被截断为0.脚本略...
27.6 nfsdown如果系统中包含nfs文件系统,你将发现下面得脚本非常实用.我管理着好多台主机,经常需要在工作时间重启其中得某台机器.由于在机器上挂接了远程目录,我不想依靠系统得重启过程来卸载这些nfs文件系统,宁愿自己来完成这个工作,这样还可以更快一些.只要运行这个脚本就可以迅速卸载所有得nfs文件系统,这样就能更快得重新启动这些机器.该脚本得LIST变量中含有提供nfs目录得主机名,使用for循环逐一卸载相应得目录,用grep命令在df命令得结果中查找nfs文件系统.nfs目录得mount形式为:machine: remote_directory这一字符串被保存在变量NFS_MACHINE中,在umount命令中使用了该变量.
$ vi nfsdown.sh
#!/bin/bash
# nfsdown
LIST="methalpha accounts warehouse dwaggs"for LOOP in $LIST
do
NFS_MACHINE=`df -k |grep $LOOP |awk '{print$1}'`if [ "$NFS_MACHINE" != "" ]; then
umount $LOOP
fi
done
三 : Linux系统下Shell多线程编程的实例
#!/bin/bash
#———————————————————————————–
# 此例子说明了一种用wait、read命令模拟多线程的一种技巧
# 此技巧往往用于多主机检查,比如ssh登录、ping等等这种单进程比较慢而不耗费cpu的情况
# 还说明了多线程的控制
#———————————————————————————–
function a_sub
{
# 此处定义一个函数,作为一个线程(子进程)
sleep 3 # 线程的作用是sleep 3s
}
tmp_fifofile="/tmp/$.fifo" mkfifo $tmp_fifofile # 新建一个fifo类型的文件
exec 6<>$tmp_fifofile # 将fd6指向fifo类型
rm $tmp_fifofile thread=15 # 此处定义线程数
for
((i=0;i<$thread;i++));do echo
done >&6 # 事实上就是在fd6中放置了$thread个回车符
for
((i=0;i<50;i++));do # 50次循环,可以理解为50个主机,或其他
read -u6 # 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
# fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制
{ # 此处子进程开始执行,被放到后台
a_sub &&
{ # 此处可以用来判断子进程的逻辑
echo "a_sub is finished"
}
||
{ echo "sub error"
}
echo >&6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
}
& done wait # 等待所有的后台子进程结束
exec 6>&- # 关闭df6 exit 0
说明:
此程序中的命令
mkfifo tmpfile
和linux中的命令
mknod tmpfile p
效?果相同。区别是mkfifo为POSIX标准,因此推荐使用它。该命令创建了一个先入先出的管道文件,并为其分配文件标志符6。管道文件是进程之间通信的一种方式,注意这一句很重要
exec 6<>$tmp_fifofile # 将fd6指向fifo类型
如果没有这句,在向文件$tmp_fifofile或者&6写入数据时,程序会被阻塞,直到有read读出了管道文件中的数据为止。而执行了上面这一句后就可以在程序运行期间不断向fifo类型的文件写入数据而不会阻塞,并且数据会被保存下来以供read程序读出。
通过运行命令:
time ./multithread.sh >/dev/null
最终运算时间: 50/15 = 3组(每组15)+1组(5个<15 组成一个组)= 4组,每组花费时间:3秒,
则 3 * 4 = 12 秒。
传统非多线程的代码 运算时间: 50 * 3 = 150 秒。
四 : shell脚本编程实现9*9乘法表
这篇文章主要介绍了shell脚本编程实现9*9乘法表,本文直接给出实现代码,并同时总结了实现代码中的知识点,需要的朋友可以参考下
脚本内容
代码如下:
#!/bin/bash
for i in "1" "2" "3" "4" "5" "6" "7" "8" "9"
do
for j in "1" "2" "3" "4" "5" "6" "7" "8" "9"
do
if [ ${j} -lt ${i} ]
then
k=$((i * j))
echo -n ${i}*${j}=${k}$'t'
fi
if [ ${j} -eq ${i} ]
then
k=$((i * j))
echo ${i}*${j}=${k}
fi
done
done
输出结果
代码如下:
[iufo@iufo test]$ bash ./test.sh
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
[iufo@iufo test]$
总结下知识点
1、for 循环
代码如下:
for v_1 in [list]
do
done
list 如果是“1 2 3”,那么v_1值就是一个数组1 2 3
如果要每次只给v_1赋一个值,那么需要分开写,即”1“ ”2“ ”3“
2、bash中的算术运算
代码如下:
k=$((i * j))
等号左右不能有空格,没有空格为赋值。
此外算术运算需要使用$(())括起来,表示先进行运算,将结果算出来。运算符加减乘除两边要带着空格。
3、echo命令的使用
echo,输出echo后面的字符。
默认输出后面带有一个换行符。
-n参数取消末尾带的换行符。
-e参数可使转义字符生效。转义符为“”,常用的转义符有 t n
例如:
代码如下:
echo -e 1t2
echo -ne 1n2
本文标题:
shell脚本编程实例-Shell脚本防攻击的方法与实例 本文地址:
http://www.61k.com/1167249.html