iptables防火墙实例

iptables防火墙实例

推荐使用脚本来编写防火墙, 然后通过 /etc/init.d/iptables save 来将结果存储到 /etc/sysconfig/iptables 中去。而且此一特色还可以用在呼叫其他的 scripts ,可以让防火墙规则具有较为灵活的使用方式。

规则草拟

下面介绍的这个防火墙,可以用来作为路由器上的防火墙,也可以用来作为本机的防火墙。 假设硬件连接如同下图所示, Linux 主机本身也是内部 LAN 的路由器,也就是一个简单的 IP 路由器的功能。假设目前网络接口有下面这些:

  • 外部网络使用 eth0(如果是拨号,有可能是 ppp0,请针对具体环境来设置)。
  • 内部网络使用 eth1,且内部使用 192.168.100.0/24 这个 Class。
  • 主机默认开放的服务有 WWW、SSH、HTTPS 等。

centos_6_real_case.png

图:一个局域网络的路由器架构示意图

由于希望将信任网域 (LAN) 与不信任网域 (Internet) 完全分开,所以建议在 Linux 主机上面安装两块以上的实体网卡,将两块网卡接在不同的网络,这样可以避免很多问题。最重要的防火墙策略是:关闭所有的连接,仅开放特定的服务模式。 而且假设内部用户已经受过良好的训练,因此在 filter table 的 3 条链中默认策略是:

  • INPUT 为 DROP
  • OUTPUT 及 FORWARD 为 ACCEPT

整个防火墙流程图:

simple_firewall.png

图:本机的防火墙规则流程示意图

原则上,内部 LAN 主机与主机本身的开放度很高,因为 OUTPUT 与 FORWARD 是完全开放的。对于小家庭的主机是这种设置可以接受的,因为内部的计算机数量不多,而且人员都是熟悉的,所以不需要特别加以控制。但是在大企业的内部,这样的规划是很不合格的,因为不能保证内部所有的人都可以按照我们的规定来使用 Network,也就是说家贼难防。因此,在这种环境下,连 OUTPUT 与 FORWARD 都需要特别加以管理才行。

实际设置

事实上,我们在设置防火墙的时候,不太可能会一个命令一个命令地输入,通常是利用 shell scripts 来帮我们实现这样的功能。下面是利用上面的流程图所规划出来的防火墙脚本,参考一下,但是需要将环境修改成适合自己的环境才行。此外,为了未来修改维护的方便,将整个 script 拆成 3 部分。

  • iptables.rule:设置最基本的规则,包括清除防火墙规则、加载模块、设置服务可接受等。
  • iptables.deny:设置阻挡某些恶意主机的进入。
  • iptables.allow:设置允许某些自定义的后门来源主机进入。

个人习惯是将这个脚本放置到 /data/scripts/iptables 目录下,你也可以自行放置到自己习惯的位置。那下面就来瞧瞧这个脚本是怎么写的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
mkdir -p /data/scripts/iptables
cd /data/scripts/iptables

vim iptables.rule
#!/bin/bash

# 请先输入相关参数,不要输入错误
EXTIF="eth0" # 这个是可以连上 Public IP 的网络接口
INIF="eth1" # 内部 LAN 的连接接口;若无则写成 INIF=""
INNET="192.168.100.0/24" # 若无内部网域接口,请填写成 INNET=""
export EXTIF INIF INNET

########################### 第一部份,针对本机的防火墙设置 ###########################
# 1. 先设置好内核的网络功能
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
for i in /proc/sys/net/ipv4/conf/*/{rp_filter,log_martians}; do
echo "1" > $i
done
for i in /proc/sys/net/ipv4/conf/*/{accept_source_route,accept_redirects,\
send_redirects}; do
echo "0" > $i
done

# 2. 清除规则、设置默认策略及开放 lo 与相关的设置值
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin; export PATH
iptables -F
iptables -X
iptables -Z
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# 3. 启动额外的防火墙 script 模块
if [ -f /data/scripts/iptables/iptables.deny ]; then
sh /data/scripts/iptables/iptables.deny
fi
if [ -f /data/scripts/iptables/iptables.allow ]; then
sh /data/scripts/iptables/iptables.allow
fi
if [ -f /data/scripts/httpd-err/iptables.http ]; then
sh /data/scripts/httpd-err/iptables.http
fi

# 4. 允许某些类型的 ICMP 数据包进入
AICMP="0 3 3/4 4 11 12 14 16 18"
for tyicmp in $AICMP
do
iptables -A INPUT -i $EXTIF -p icmp --icmp-type $tyicmp -j ACCEPT
done

# 5. 允许某些服务的进入,请依照自己的环境开启
# iptables -A INPUT -p TCP -i $EXTIF --dport 21 --sport 1024:65534 -j ACCEPT # FTP
# iptables -A INPUT -p TCP -i $EXTIF --dport 22 --sport 1024:65534 -j ACCEPT # SSH
# iptables -A INPUT -p TCP -i $EXTIF --dport 25 --sport 1024:65534 -j ACCEPT # SMTP
# iptables -A INPUT -p UDP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS
# iptables -A INPUT -p TCP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS
# iptables -A INPUT -p TCP -i $EXTIF --dport 80 --sport 1024:65534 -j ACCEPT # WWW
# iptables -A INPUT -p TCP -i $EXTIF --dport 110 --sport 1024:65534 -j ACCEPT # POP3
# iptables -A INPUT -p TCP -i $EXTIF --dport 443 --sport 1024:65534 -j ACCEPT # HTTPS

########################### 第二部份,针对后端主机的防火墙设置 ###########################
# 1. 先加载一些有用的模块
modules="ip_tables iptable_nat ip_nat_ftp ip_nat_irc ip_conntrack ip_conntrack_ftp ip_conntrack_irc"
for mod in $modules; do
testmod=$(lsmod | grep "^${mod} " | awk '{print $1}')
if [ "$testmod" == "" ]; then
modprobe $mod
fi
done

# 2. 清除 NAT table 的规则
iptables -F -t nat
iptables -X -t nat
iptables -Z -t nat
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

# 3. 若有内部接口的存在 (双网卡) 开放成为路由器,且为 IP 路由器
if [ "$INIF" != "" ]; then
iptables -A INPUT -i $INIF -j ACCEPT
echo "1" > /proc/sys/net/ipv4/ip_forward
if [ "$INNET" != "" ]; then
for innet in $INNET; do
iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
done
fi
fi
# 如果你的 MSN 一直无法连接,或者是某些网站 OK 某些网站不 OK,
# 可能是 MTU 的问题,那你可以将下面这一行取消注释来启动 MTU 限制范围
# iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss \
# --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu

# 4. NAT 服务器后端的 LAN 内对外之服务器设置
# iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80 \
# -j DNAT --to-destination 192.168.1.210:80 # WWW

# 5. 特殊的功能,包括 Windows 远程桌面所产生的规则,假设桌面主机为 1.2.3.4
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4 --dport 6000 \
# -j DNAT --to-destination 192.168.100.10
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4 --sport 3389 \
# -j DNAT --to-destination 192.168.100.20

# 6. 最终将这些功能存储下来
/etc/init.d/iptables save

特别留意上面脚本的特殊字体部分,基本上,只要修改一下最上方的接口部分,就能够运作这个防火墙了。不过因为每个人的环境都不相同,因此在设置完成后,依旧需要测试一下才行。不然,出了问题可就麻烦了。再来看一下关于 iptables.allow 的内容。假如我要让一个 140.116.44.0/24 这个网络的所有主机来源可以进入本机主机的话,那么这个文件的内容可以写成这样:

1
2
3
4
5
6
7
8
9
10
11
12
vim iptables.allow
#!/bin/bash
# 下面是填写允许进入本机的其他网络或主机
iptables -A INPUT -i $EXTIF -s 140.116.44.0/24 -j ACCEPT

# 下面是关于阻挡的文件设置方法
vim iptables.deny
#!/bin/bash
# 下面填写的是你要阻挡的那个 IP
iptables -A INPUT -i $EXTIF -s 140.116.44.254 -j DROP

chmod 700 iptables.*

将这3个文件的权限设置为 700 且只属于 root 的权限后,就能够直接执行 iptables.rule 了。不过要注意的是,在上面的案例当中,默认将所有的服务通道都关闭的。所以你必须要到本机防火墙的第 5 步骤 处将一些注释 (#) 取消才行。同样地,如果有其他更多的 port 想要开启时,同样需要增加额外的规则。

不过,还是如同前面所说的,这个 firewall 仅能提供基本的安全防护,其他的相关问题还需要再测试。此外,如果希望一开机就自动执行这个 script 的话,请将这个文件的完整文件名写入 /etc/rc.d/rc.local 中。

1
2
3
4
vim /etc/rc.d/rc.local
...(其他省略)...
# 1. Firewall
/data/scripts/iptables/iptables.rule

事实上,这个脚本的最下面已经加入写入防火墙默认规则文件的功能,所以只要执行一次,就拥有最正确的规则了。上述的 rc.local 仅是预防万一而已。上述 3 个文件请不要在 Windows 系统上面编辑后才传送到 Linux 上运行,因为 Windows 系统的换行符问题,将可能导致该文件无法执行。建议传送到 Linux 后可以利用 dos2unix 指令去转换换行符等,就不会有问题了

这就是一个最简单的防火墙。同时,这个防火墙还可以具有最简答的 IP 路由器的功能,也就是在 iptables.rule 这个文件中的第二部分。

---------------- The End ----------------
0%