实用防火墙(Iptables)脚本分析

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://chenguang.blog.51cto.com/350944/1338882

实用防火墙(Iptables)脚本分析

——Redhat,CentOS,Ubuntu等常见Linux发行版中都会预装Iptables防火墙,大多数初学者设置起来由于对这款软件比较陌生,设置起来比较困难,下面这段脚本实现了修改变量的值就能轻松移植到自己的网络,同时对各段内容做了介绍。首先在/usr/bin下建立一个脚本名为firewall,设定可执行权限

#chmod +x /usr/bin/firewall

下面我最这个脚本的关键部分做一些说明:

——首先设定假设你想限制某IP(例如10.10.10.20),你只需将他们填入到BADIPS变量中,可以设定多个IP或网端,每个用空格分开.

BADIPS="10.10.10.20 10.1.14.0/24"

——接下来开始设定impossible_ips变量,例如设定三个私有iP的网段,前提是你的主机IP 不能在三个设定的网段范围之内,如果在设定范围内就要删除.

IMPOSSIBLE_IPS="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"

如果你的系统只是家用,单独上网,以下6行代码就无需设置。

1).IN_TCP_PORTALLOWED=""

2).IN_ICMP_ALLOWED=""

3).EGRESS="0"

4).OUT_TCP_PORTALLOWED=""

5).OUT_UDP_PORTALLOWED=""

6).OUT_ICMP_ALLOWED=""

——如果你架设了服务器就需要下面的设定,这里强调一下in_tcp_porallowed,in_udp_portallowed是变量,他的值设定常见网络服务的端口号;如果需要开放连续端口就需要使用“:”号,例如需要开放38000-38090之间的所有端口,只要进行如下设定:
in_tcp_portallowed=”38000:38090”

下面看个复杂的例子,

例1

——假定SSH服务只允许200.100.10.10访问,而FTP服务之开放给192.168.20.0/24网段使用;SMTP则是出了10.10.10.20以外其余都可以访问:

In_tcp_portallowed=”ssh,200.100.10.10ftp,192.168.20.0/24smtp,!10.10.10.20”

例2

——架设需要开放smtp,domain服务给所有IP使用,然后仅允许来自200.100.10.10和192.168.20.0/24的使用者使用ssh登陆服务器:

In_tcp_portallowed=”ssh,200.100.10.10 ssh,192.168.20.0/24 smtp domain”

案3:一个错误的案例

——有人想允许192.168.150.30对内网ssh服务器访问,但是除了192.168.20.10以外其他所有Ip都可以访问22端口,其余都阻断。他是这样写的:

In_tcp_portallowed=”ssh,192.168.150.30ssh,!192.168.20.10”

——我们可以看到虽然规则1限制了只有192.168.150.30可以访问 ssh服务器,但是规则2却反而将其开放给所有人,第一个规则等于摆设。

更多详细的信息您可以在/etc/service文件中找到。

# 允许内网的TCP链接

IN_TCP_PORTALLOWED="ssh,192.14.0.3 smtp domain http https"

# 允许内网的UDP链接

IN_UDP_PORTALLOWED="domain"

如果你想让ping包通过那么需要如下设定

In_icmp_allowed=”8”

当然也可以设定只有某个IP能ping,例如:

In_icmp_allowed=”8,61.63.33.172”

表示只有61.63.33.172可以ping 主机。

# 允许内网ICMP的类型

IN_ICMP_ALLOWED="0 3 8 11"

下面看个例子帮助我们理解这张表,在ping时,如果这个 echo-request 不能到达对方的机器﹐或是对方回应的 echo-reply 不能顺利送回来﹐那 ping 就失败。在许多有防火墙的环境中都会碰到﹐如果防火墙将 request 和 reply 拦下来就会导致 ping 失败。另外﹐就算不是防火墙设置的问题﹐对方也可以将机器设定为不回应任何 echo-request 封包﹐若在 Linux 上,只要用下面命令就可以了﹕

echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all

再举一个例子,在使用traceroute命令式,我们要知道当封包被一个路由节点处理之后﹐它原来的 TTL 值就会被扣掉 1 ﹐这样﹐如果封包的 TTL 降到 0 的时候﹐路由器就会丢弃这个封包﹐并且同时向来源地送出一个 time_exceeded( type 11 ) 的 ICMP 封包﹐以告知其封包的命运。

egress这个设置表示是否限制对外的链接,值为0代表不限制,1代表限制对外链接。

EGRESS="0"

# 允许对外链接的通讯端口

OUT_TCP_PORTALLOWED="ssh smtp,root http https pop3"

 

# 允许对外链接的UDP通讯端口

OUT_UDP_PORTALLOWED=""

 

OUT_ICMP_ALLOWED="0 3 8 11"

 

#如果你希望记录所有被放火墙阻止的数据包,就需要将droplog的值设定为1,不过这样会使/var/log/messages日志容量上升

DROPLOG="0"

 

#

DSHIELD="0"

#装载iptables核心模块

modprobe ip_tables 2>/dev/null

modprobe ip_conntrack 2>/dev/null

modprobe ip_conntrack_ftp 2>/dev/null

modprobe ip_conntrack_irc 2>/dev/null

 

#清除当前iptables所有表的规则

echo -n "Initiating iptables..."

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -t filter -F

iptables -t nat -F

iptables -t filter -X

iptables -t nat -X

echo "ok"

 

if [ "$DSHIELD" = "1" ]; then

echo -n "Getting the DShield Block List..."

BADIPS="$BADIPS

`lynx --dump http://feeds.dshield.org/block.txt | \

awk '/^[1-9]/ {print $1 "/" $3}'`"

echo "ok"

fi

 

block.txt的部分内容如下:

开始IP 结束IP 网络号 攻击数量 Name Country email

222.189.239.0222.189.239.255242054

195.178.109.0195.178.109.255241601PROVIDERRU[no email]

216.145.110.0216.145.110.255241355

193.219.163.0193.219.163.255241264LITNET-3LTdaiva@litnet.lt

221.6.51.0221.6.51.255241075CNll@jsnetcom.com

 

# 若你加上start参数,则将$skiptest变量置1,那么就会跳过测试模式,设定所有规则后不再清除。

[ "$1" = "start" ] && skiptest="1"

 

##设置iptables核心的安全相关参数

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects

echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

echo 1 > /proc/sys/net/ipv4/tcp_syncookies

echo 3 > /proc/sys/net/ipv4/tcp_retries1

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

echo 1400 > /proc/sys/net/ipv4/tcp_keepalive_time

echo 0 > /proc/sys/net/ipv4/tcp_window_scaling

echo 0 > /proc/sys/net/ipv4/tcp_sack

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

 

## 下面开始设定防火墙规则

echo -n "Setting rules..." 

#设定input,output,forward的过滤规则,不符合规则的就会丢弃。

iptables -P INPUT DROP 

iptables -P OUTPUT DROP

iptables -P FORWARD DROP

 

# 允许流经环路地址(loopback)的包通过,lo代表环路接口。

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

iptables -A INPUT -i ! lo -s 127.0.0.0/8 -j DROP

iptables -A OUTPUT -o ! lo -d 127.0.0.0/8 -j DROP

 

# 增加新链badpkt

iptables -N BADPKT

# 若droplog数值为1则记录所有badpkt链的数据包

if [ "$DROPLOG" = "1" ]; then

iptables -A BADPKT -j LOG --log-prefix "** Firewall BADPKT **"

fi

# 丢弃所有进入badpkt链的封包

iptables -A BADPKT -j DROP

 

# 将可疑封包交给badpkt链处理。

iptables -A INPUT -m state --state INVALID -j BADPKT

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j BADPKT

iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADPKT

iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j BADPKT

iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ALL ALL -j BADPKT

iptables -A INPUT -p tcp --tcp-flags ALL FIN -j BADPKT

 

# 允许目的端口为53的UDP包通过,这样才能使用DNS查询。

iptables -A OUTPUT -p udp -m state --state NEW --dport 53 -j ACCEPT

 

# 允许已建立连线和回应的数据包通过

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

 

# 增加一个阻止IP的新链

iptables -N BADIP

# 若droplog变量为1,则记录所有进入badip链的封包

if [ "$DROPLOG" = "1" ]; then

iptables -A BADIP -j LOG --log-prefix "** Firewall BADIP **"

fi

# 丢弃所有进入badip链的封包

iptables -A BADIP -j DROP

 

# 阻止特定IP

for ip in $BADIPS $IMPOSSIBLE_IPS ; do

iptables -A INPUT -s $ip -j BADIP

done

 

# 允许特定TCP号对内新连接

for i in $IN_TCP_PORTALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

 

port="$1"

[ -n "$2" ] && ipt_option="-s `echo $2 | sed 's/^!/! /'`"

 

iptables -A INPUT -p tcp $ipt_option --dport $port \

--syn -m state --state NEW -j ACCEPT

done

 

# 允许特定UDP端口的对内新链接

for i in $IN_UDP_PORTALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

 

port="$1"

[ -n "$2" ] && ipt_option="-s `echo $2 | sed 's/^!/! /'`"

 

iptables -A INPUT -p udp $ipt_option --dport $port \

-m state --state NEW -j ACCEPT

done

 

# 允许特定ICMP类型数据包进入

for i in $IN_ICMP_ALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

 

type="$1"

[ -n "$2" ] && ipt_option="-s `echo $2 | sed 's/^!/! /'`"

iptables -A INPUT -p icmp $ipt_option --icmp-type $type \

-m state --state NEW -j ACCEPT

done

 

# 前面讲过egress数值为1标志管制对外链接

if [ $EGRESS = "1" ]; then

 

# 允许特定TCP对外链接

for i in $OUT_TCP_PORTALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

 

port="$1"

[ -n "$2" ] && ipt_option="-d `echo $2 | sed 's/^!/! /'`"

[ -n "$3" ] && ipt_option="$ipt_option -m owner \

`echo $3 | sed 's/\([^!]\)/ --uid-owner \1/'`"

 

iptables -A OUTPUT -p tcp $ipt_option --dport $port \

--syn -m state --state NEW -j ACCEPT

done

 

for i in $OUT_UDP_PORTALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

port="$1"

[ -n "$2" ] && ipt_option="-d `echo $2 | sed 's/^!/! /'`"

[ -n "$3" ] && ipt_option="$ipt_option -m owner \

`echo $3 | sed 's/\([^!]\)/ --uid-owner \1/'`"

 

iptables -A OUTPUT -p udp $ipt_option --dport $port \

-m state --state NEW -j ACCEPT

done

 

for i in $OUT_ICMP_ALLOWED ; do

IFS=','

set $i

unset IFS ipt_option

 

type="$1"

[ -n "$2" ] && ipt_option="-d `echo $2 | sed 's/^!/! /'`"

[ -n "$3" ] && ipt_option="$ipt_option -m owner \

`echo $3 | sed 's/\([^!]\)/ --uid-owner \1/'`"

 

iptables -A OUTPUT -p icmp $ipt_option --icmp-type $type \

-m state --state NEW -j ACCEPT

done

fi

 

if [ ! "$EGRESS" = "1" ]; then

iptables -A OUTPUT -m state --state NEW -j ACCEPT

fi

 

if [ "$DROPLOG" = "1" ]; then

iptables -A INPUT -j LOG --log-prefix "** Firewall DROP **"

iptables -A OUTPUT -j LOG --log-prefix "** Firewall DROP **"

iptables -A FORWARD -j LOG --log-prefix "** Firewall DROP **"

fi

 

echo "done"

 

# 5秒后自动清除iptables规则,这样可以避免锁住自己。

if [ "$skiptest" = "1" ]; then exit ;fi

echo -e "\nTEST MODE"

echo -n "All chains will be cleaned after 5 sec."

i=1; while [ "$i" -le "5" ]; do

echo -n "."

i=`expr $i + 1`

sleep 1

done

echo -en "\nFlushing ruleset..."

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -t filter -F

iptables -t nat -F

iptables -t filter -X

iptables -t nat -X

echo "ok"

这样一个200多行脚本就能实现基本功能的防火墙,大家可以去上机试试,附件中带完整脚本。

 

 

本文出自 “李晨光原创技术博客” 博客,请务必保留此出处http://chenguang.blog.51cto.com/350944/1338882

时间: 2024-10-08 13:28:16

实用防火墙(Iptables)脚本分析的相关文章

一个经典实用的iptables shell脚本

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://navyaijm.blog.51cto.com/4647068/816634 这个iptables脚本不错,很实用,根据实际应用改一下就可以自己用.分享出来,供大家来参考.原作者佚名.源代码如下: #!/bin/sh # modprobe ipt_MASQUERADE modprobe ip_conntrack_ftp modprobe ip_nat_ftp iptables -

Linux防火墙Iptables新手教程(非常的详细)

首先我们要弄明白,防火墙将怎么对待 这些数据包.这些数据包会经过一些相应的规则链,比如要进入你的计算机的数据包会首先进入INPUT链,从我们的计算机发出的数据包会经过 OUTPUT链,如果一台计算机做一个网络的网关(处于内网和外网两个网络连接的两台计算机,这两台计算机之间相互通讯的数据包会经过这台计算机,这台计 算机即相当于一个路由器),可能 会有很多数据经过这台计算机,那么这些数据包必经FORWARD链,FORWARD链即数据转发链.明白了这些"链"的概念我们才能进一步学习使用 ip

一个对IpCop有用的Iptables脚本

一个对IpCop有用的iptables脚本(朋友写的),不记得是哪一个写的了,麻烦你mail(ayihu@qq.com)下告诉我一声: #!/bin/sh## firewall starting firewall## chkconfig: 2345 98 01# description: setting firewall########################################################################### 设定参数#########

Linux防火墙iptables简明教程

  前几天微魔部落再次遭受到个别别有用心的攻击者的攻击,顺便给自己充个电,复习了一下linux下常见的防火墙iptables的一些内容,但是无奈网上的很多教程都较为繁琐,本着简明化学习的目的,微魔为大家剔除了许多冗余的内容,提取出尽量多的精华部分成文,和大家共同学习,本文涉及的内容包括如下 Linux防火墙iptables简明教程 1.安装iptables 2.查看现有的iptables规则 3.删除某iptables规则 4.清除现有iptables规则 5.创建规则 6.设置开机启动 7.保

linux系统防火墙iptables命令规则及配置

防火墙概述: 在互联网上我们的主机随时都有被攻击的可能,因此我们需要用到防火墙机制来保护我们互联网上的主机,在我们主机上面,防火墙主要是通过一些规则来限制一些不安全因素的网络信息传输,准确的说,防火墙就是制定一些有顺序的规则,来管理所负责的范围内的主机数据封包的一种机制,通过防火墙我们能够分析和过滤进出主机或者网络的封包数据,从而将一些不安全因素的包隔离开. iptables与netfilter: Linux上的防火墙是由iptables/netfilter组成,iptables是基于netfi

Android ROM开发(二)——ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法

Android ROM开发(二)--ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法 怪自己二了,写好的不小心弄没了,现在只好重新写一些了,上篇简单的配置了一下环境,这里呢,就来讲一下相关的只是点 我们先下载一个ROM,随便下,原理都是差不多的,这里我就下载一个红米Note的MIUI稳定版 1.ROM结构 ROM根据厂商的定制可能有所不同,但是大体是不变的 data 内置一些软件 META-INF 脚本文件 update-binary 二进制文件 updater

MLSBS dev分支,iptables脚本增加特性

#MLSBS git的dev分支 MLSBS is the abbreviation of "My linux's bash script"! "MLSBS"是"My linux's bash script"的缩写linux运维技术人员日常需要写一堆脚本来简化工作量."MLSBS"的目的就是把我日常在linux下的工作通过脚本整合到一个项目中,需要的时候几个点击就可以完成任务了.(其实,写这脚本的最初原因是,我有一些搞开发朋友

8个实用的Shell脚本分享

  这篇文章主要介绍了8个实用的Shell脚本分享,本文给出了判断输入为数字.字符或其他.求平均数.自减输出.在文件中添加前缀.批量测试文件是否存在等实用脚本,需要的朋友可以参考下 几个Shell脚本的例子,觉得还不错. [例子:001]判断输入为数字,字符或其他 代码如下: #!/bin/bash read -p "Enter a number or string here:" input case $input in [0-9]) echo -e "Good job, Y

Centos 安装 VPN pptpd 防火墙 iptables 转发设置

 下面我们一起来看一篇关于Centos 安装 VPN pptpd 防火墙 iptables 转发设置,这个问题是因为一朋友设置之有一些网站无法访问时想出的解决办法.   centos 安装vpn 出现一部分网站无法访问的问题!iptables的一些转发规则设置 建立NAT转换规则,否则拨上也无法通过远程网关连上公网. iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source $src_ip Centos 6.4 安装 vpn 遇到有些网站