共享一个Internet连接
网络地址翻译和IP伪装都可以实现多台主机共享一个Internet连接,而这个局域网可以是Linux和Windows系统组成的多系统局域网。假设现在我们有一台机器有两个网卡,其中eth0为“公共”网卡,eth1为“私有”网卡。
换句话说,eth0被分配了一个静态的,可路由的IP地址,而eth1则被分配给了一个私有的、不能路由的IP,也就是说该IP是属于该局域网子网的。要实现上述功能,我们需要向nat和filter表中添加一些链:
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -t filter -A FORWARD -i eth0 -o eth1 -m state --state
RELATED,ESTABLISHED -j ACCEPT
# iptables -t filter -A FORWARD -i eth1 -o eth0 -j ACCEPT |
这显示了有状态的数据包检测的价值。请注意,我们这里是如何实现流入数据包只有在属于一个已经存在的连接时才被允许的,而所有来自局域网内流向外的数据包则都允许通过 (注意:这里的filter是缺省的表,但它并不是必须的)。第一条规则让所有流出的信息看起来都是来自防火墙机器的,而并不会显示出防火墙后面还有一个局域网。
下面的例子是为FORWARD和POSTROUTING链设置了缺省的策略,在使用伪装时,有一个缺省的POSTROUTING DROP策略是非常重要的,否则,就有可能有心怀恶意的用户突破网关后伪装它自己的身份。
# iptables -t filter -P FORWARD DROP
# iptables -t nat -P POSTROUTING DROP |
下面的例子是为了拨号连接设置的,它可以动态地分配IP地址:
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE |
规则的保存
使用脚本更改规则的问题是:改动每个规则都要调用命令iptables,而每一次调用iptables,它首先要把netfilter内核空间中的整个规则集都提取出来,然后再插入或附加,或做其他的改动,最后,再把新的规则集从它的内存空间插入到内核空间中,这显然会花费很多时间。
为了解决这个问题,可以使用命令iptables-save和restore 。iptables-save用来把规则集保存到一个特殊格式的文本文件里,而iptables-restore则用来把这个文件重新装入到内核空间中。
这两个命令最好的地方在于一次调用就可以装载和保存规则集,而不像脚本中每个规则都要调用一次iptables。
iptables-save运行一次就可以把整个规则集从内核里提取出来,并保存到文件里,而iptables-restore每次装入一个规则表。换句话说,对于一个很大的规则集,如果用脚本来设置,那这些规则就会反复地被卸载、安装很多次,而我们现在可以把整个规则集一次就保存下来,安装时则是一次一个表,这可是节省了大量的时间。所以,一旦测试结果令你满意,你就可以将它们保存为脚本:
# iptables-save > iptables-script |
现在,信息包过滤表中的所有规则都被保存在文件iptables-script中。无论何时再次引导系统,都可以使用 iptables-restore 命令将规则集从该脚本文件恢复到信息包过滤表,恢复指令如下所示:
# iptables-restore iptables-script |
如果您愿意在每次引导系统时自动恢复该规则集,则可以将上面指定的这条命令放到任何一个初始化shell脚本中。
事实上,大部分发行版都为用户提供了一个可以自动加载的文件,让用户在其中编辑规则集,并且大部分发行版都会有一个已经预先配置好的防火墙。不同的发行版的配置文件位置不尽相同,我们可以使用命令locate iptables来找到配置文件。对于Red Hat或者 Fedora Core而言,这个配置文件位于/etc/sysconfig/iptables。该文件初始的内容如下:
1 # Firewall configuration
2 *filter
3 :INPUT <target> [0:0]
4 :FORWARD <target> [0:0]
5 :OUTPUT <target> [0:0]
6
7 # your rules here
8
9 COMMIT |
建议将其基本框架改成以下内容:
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT ACCEPT [0:0]
5
6 # allow local loopback connections
7 -A INPUT -i lo -j ACCEPT
8
9 # drop INVALID connections
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # allow all established and related
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16
17 # add anymore rules here
18
19 COMMIT |
具体例子:
作为例子,我们来为一个普通家庭用户创建一个防火墙。假设该家庭用户一般将自己的计算机用于Internet浏览、电子邮件等。我们所要做的就是允许所有必须的连接通过,而禁止所有不相关的连接。以下是防火墙配置文件的内容:
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT DROP [0:0]
5
6 # 允许本地loopback连接
7 -A INPUT -i lo -j ACCEPT
8
9 # drop非法连接
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # 允许所有已经建立的和相关的连接
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16 -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
17
18 # 允许连接的ISP的DNS服务器
19 -A OUTPUT -d 2.3.4.10 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
20 -A OUTPUT -d 2.3.4.11 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
21
22 # 允许向外连接到Web服务器
23 -A OUTPUT -d 0/0 -m state --state NEW -p tcp --dport http -o eth0 -j ACCEPT
24 -A OUTPUT -m state --state NEW -p tcp --dport https -o eth0 -j ACCEPT
25
26 # 允许向外连接到ISP的SMTP和POP3服务器
27 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport smtp -o eth0 -j ACCEPT
28 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport pop3 -o eth0 -j ACCEPT
29
30 # 记录其它试图向外进行的连接
31 -A OUTPUT -o eth0 -j LOG
32 # 缺省情况下是DROP向外的连接
33
34 COMMIT |
有关具体命令行的意义参照上文很容易就可以理解,这里就不在赘述。事实上,只要熟悉了某一特定环境下防火墙的设置,我们就可以比较容易地为其它的应用环境创建相应的防火墙。