[LinuxFocus-icon]
<--  | 首页  | 站点地图  | 索引  | 搜索

新闻 | 过往期刊 | 链接 | 关于LF
This document is available in: English  Castellano  ChineseGB  Deutsch  Francais  Nederlands  Russian  Turkce  

Vincent Renardias
by Vincent Renardias
<vincent(at)renardias.com>

关于作者:

Vincent Renardias于1993使用GNU/Linux,1996年开始涉及于它的发展: Debian开发者,GIMP和GNOME 桌面的法语译者, Linux组织Marseille(PLUG) 的创始人...现在是EFB2公司的R&D经理,他始终为GNU/Linux做着贡献。


目录:

 

Packet filtering with Linux

[Illustration]

摘要:

这篇文章首次发表是在Linux期刊法国特刊中的安全焦点上。编辑,作者和翻译者 总是和善的允许LinuxFocus发表这个特刊里的每一篇文章。因此,LinuxFocus将立 刻将他们翻译成英文带给你。感谢所有为此工作的人们。这个摘要将会被复制在每篇文 章的开头。


防止入侵的一个好的方法是尝试着虑过网络中没有用的东西。这个任务通常属于一台作 为防火墙的设备。
在这篇文章里,我们将介绍执行和配置这样一个系统所必须要的基础。


_________________ _________________ _________________

 

Gateway, Proxy-Arp 和 Ethernet Bridge ?

过滤机构可以被考虑成一张能够过滤有害的数据包的网。最重要要的是找到合适大 小的网孔和安装他的正确位置。

防火墙在网络中的位置
Firewall location

为了能够完全的过滤数据包,这个过滤机构必须无缝的插入他所要保护的网络和“其 余的世界”之间。在实践上,这个可以用一台带有两块网络接口(通常是以太网卡)的 设备来完成 ,一个连接内部的网络,另一块连接外部作为路由转发。这种方式,通信 将不得不通过防火墙,这样防火墙可以阻止他们或不依照他们的内容进行发送。
设备运行过滤机构可以被配置成3种不同的方式:

- "simple" Gateway: 这是最普通的配置。设备被用作两个网络或子网之间的网关。在本地网络内的电脑将使 用防火墙代替他们的默认路由。

- "Proxy-ARP" Gateway: 前面那个配置暗示着把一个网络划分成两个子网,这个 会造成一半可利用的 ip 地址失效了。这是有点恼人的。举个例子,一个16个地址的子 网(28位子网掩码),除去网络地址和广播地址只有14个是有效的,子网添加一位,有 效地址将从14减少到6(8个ip减去网络地址和广播地址)。当你不能够接受失去一半有 效ip地址的情况,你可以使用这种技术,我们将会在稍后的文章里解释他。此外,这种 技术不需要对网络中存在的路由器和被保护的电脑做的任何改变。

- Ethernet bridge: 作为一个以太网网关安装 (不是ip网关),使过滤机构对于 其他设备来说是透明的。因此不分配ip地址给以太网接口是妥当的。于是,设备将不会 被ping,traceroute等工具发现。让我们注意一个数据包过滤执行,在2.4.x内核还 还没完成前提下,基于这个端口的特性需要2.2.x的内核。

 

过滤基本规则

既然我们知道什么地方安装过滤器,那么我们必须定义什么应该阻止什么应该接受。
这里有两种方式去配置一个过滤器:

- 好的方法:没有数据被允许通过,除了规则允许的。
- 坏的方法:(不幸的是经常被使用)明确地阻止被禁止数据包,所有的数据包被接受。

这有一个简单的解释:在第一种情况,遗忘规则导致服务不完全工作或根本不工作。通 常,这会被很快的注意到,然后添加适当的规则使服务再运行起来。
在第二中情况,遗忘一个规则会造成一个潜在的弱点,如果我们去找,很难去发现...

 

Netfilter

在linux 2.4内核上使用的最多的包过滤软件是Netfilter:它很好的取代了使 用在2.2内核的‘ipchains’。Netfilter由两部分组成:内核支持这需要编译你的 内核和在你系统中可用到的‘iptables’命令

 

安装实例

一个实例的注释比一段长时间的演讲要好的多,下面我们将描述怎样去安装和配置 一个过滤器设备。首先,设备要先配置成一个网关,使用Proxy-ARP来限定ip地址的 数量,我们将配置过滤系统。

著者偏好选择了Debian发布版来构建一个这样的系统,任何linux发行版都可以。

首先,检查你的内核已经支持Netfilter。如果是的,引导信息将包含:

ip_conntrack (4095 buckets, 32760 max)
ip_tables: (c)2000 Netfilter core team

另外,当Netfilter支持被激活后你不得不反编译内核。相应的选项将会在 "Networking Options"菜单里的"Network Packet Filtering" 子菜单里找到。从"Netfilter Configuration"选项,选择你需要的。 如果不能确定,你可以全部选择。此外,最好把Netfilter包含至内核,而不是作为加 载模块。如果因为一些原因或者Netfilter一个模块出错或不能加载,过滤器将不能工 作,我们不更多的谈论关于这么做所冒的风险了。

你也应该安装‘iproute2’包(这在最后是不必要做的,但是我们的实例将使 用从它允许我们建立配置脚本文件开始。)对于Debian,‘apt-get install iproute’ 命令足够了。
其他的发行版,获得相应的软件包。用通常的方法,或从源程序安装。你可以在下面的 地址下载到相应的软件包:
ftp://ftp.inr.ac.ru/ip-routing/

现在对两块以太网卡配置。我们必须注意Liunx的内核,自动检测硬件程序到检测 网络卡的这一步时就会发现它。可是,仅仅第一块被探测到。
一个简单的解决方案是在lilo.conf文件里添加一句话:
append="ether=0,0,eth1"

现在,我们配置以太网接口。我们选择对两块网卡使用同一个ip地址的方法,因而 可以节约一个地址。
我们假定有一个10.1.2.96/28的子网。它的地址从10.1.2.96到10.1.2.111 路由器的地址是10.1.2.97,我们的过滤器设备的地址的10.1.2.98。eth0 接口之间如果没有通过hub或switch相连,那么将通过RJ45双绞线直接连接路由器; eth1接口将连接hub或switch, 通过他它到达本地网络设备。

因此,两个接口将会被配置成下列参数:

address  : 10.1.2.98
netmask  : 255.255.255.240
network  : 10.1.2.96
broadcast: 10.1.2.111
gateway  : 10.1.2.97

接下来,我们使用下面的脚本,它必须在网卡初始化配置以后运行。

net.vars: configuration variables

PREFIX=10.1.2
DMZ_ADDR=$PREFIX.96/28
# Interface definitions
BAD_IFACE=eth0
DMZ_IFACE=eth1
ROUTER=$PREFIX.97


net-config.sh: network configuration script

#!/bin/sh
# Comment out the next line to display the commands at execution time
# set -x
# We read the variables defined in the previous file
source /etc/init.d/net.vars
# We remove the present routes from the local network
ip route del $PREFIX.96/28 dev $BAD_IFACE
ip route del $PREFIX.96/28 dev $DMZ_IFACE
# We define that the local network can be reached through eth1
# and the router through eth0.
ip route add $ROUTER dev $BAD_IFACE
ip route add $PREFIX.96/28 dev $DMZ_IFACE
# We activate Proxy-ARP for both interfaces
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
# We activate the IP forwarding to allow the packets coming to one card
# to be routed to the other one.
echo 1 > /proc/sys/net/ipv4/ip_forward

让我们返回Proxy-ARP机制对我们的配置所必需的。
当一个设备在同一个网段里同另一台设备会话时,他需要知道以太网地址(或者MAC地 址或者硬件地址)相应的ip地址。当源设备广播请求”ip地址位1.2.3.4的MAC地址是 什么?”目标设备必须回答。

这里有一个“会话”的实例,是通过tcpdump检测到的:
- the request: the machine 172.16.6.72 asks the MAC address corresponding to the IP address IP 172.16.6.10.
19:46:15.702516 arp who-has 172.16.6.10 tell 172.16.6.72
- the answer: the machine 172.16.6.10 provides its card number.
19:46:15.702747 arp reply 172.16.6.10 is-at 0:a0:4b:7:43:71

通过这个简略的解释将引导我们到达目的地:ARP请求通过广播传播,因此它被限 定在同一个物理网段里。因此,受保护的设备想要去查找路由器MAC地址的请求将会被 过滤器设备阻止。激活着的Proxy-ARP的特色就是解决这个问题,它将传 输ARP请求。

这下一阶段里,你将有一个运行着的网络,它是由一台设备管理整个本地网络和外 网的通信。

现在,我们必须使用Netfilter建立过滤。
Netfilter允许直接对经过的数据包有所行动。在基本配置里,数据包被3条规则链管理:
- INPUT:数据包通过一个接口进来。
- FORWARD:把所有的数据包从一个接口转发到另一个接口。
- OUTPUT:数据包通过一个接口出去。

‘iptables’命令允许对这些链添加,改变或者移除规则从而修改过滤器的动作。
此外,每一个链有一个默认的策略,换句话说,它知道当一个数据包没有规则匹配时该 怎么处理。
当前有四个选项:
- ACCEPT:允许通过数据包。
- REJECT:拒绝数据包通过,关联的错误信息被传送(ICMP端口不能到达,TCP重置 关于这些的),
- LOG:把数据包记录写在syslog。
- DROP:忽略数据包,不发送回答。

数据流通过标准链

Packet flow

这里有一些操作整个链常用到的iptables选项。我们将在稍后解释他们:

-N:创建一条新链。
-X:移除一条空链。
-P:改变一条链的默认策略。
-L:列出一条链的规则。
-F:清空一条链里所的规则。
-Z:清除已经通过这条链的字节和数据包包的计算器。

修改一条链,下面的命令将会有用的:
-A:添加一条规则在链的最后。
-I:插入一条新规则在链的给定位置。
-R:取代一条给定规则。
-D:删除链里的规则,可以使用规则的编号或它的具体描述。

让我们看一个简单的实例:我们将阻止对给定设备PING回应(这是一个'echo-reply' 类型的ICMP数据包)。
首先,让我们检测能"ping"通所给定的设备:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms
现在,我们对INPUT链添加一条规则,这将截取来自172.16.6.74('-s 172.16.6.74') 的ICMP-Reply数据包('-p icmp --icmp-type echo-reply')这些数据包将会被 忽略('-j DROP')。
# iptables -A INPUT -s 172.16.6.74 -p icmp --icmp-type echo-reply -j DROP

让我们再PING那个设备:

# ping -c 3 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes

--- 172.16.6.74 ping statistics ---

3 packets transmitted, 0 packets received, 100% packet loss

这和我们所期望的一样,回应没有通过。我们检查已经被阻止的3个回 应。(3个数据包共252字节)

# iptables -L INPUT -v
Chain INPUT (policy ACCEPT 604K packets, 482M bytes)
 pkts bytes target     prot opt in    out     source       destination
  3   252   DROP       icmp --  any   any     172.16.6.74    anywhere

如果想返回到初始状态,我们要做的仅仅是移除INPUT链里的第一条规则:

# iptables -D INPUT 1

我们再PING一次:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms
#

运行了!

你可以对3条存在链添加其他的链(这3条链你无论如何不能移除),使通信通过他 们。这是有用,举个例子,可以避免在不同的链里重复规则。

让我们设置一个最小化的防火墙所必需的规则。他将允许ssh,域(DNS),http, smtp服务和其他一些无关紧要的。
为了简单化,将设置命令写在shell脚本比配置更容易一点。当这个脚本设立一个新的 规则前应当清空当前配置。这里有一个小诀窍去运行脚本,就是在配置没有副本规则下 被激活。

rc.firewall

#!/bin/sh

# Flushing out the rules
iptables -F
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD


# The chain is built according to the direction.
# bad = eth0 (outside)
# dmz = eth1 (inside)
iptables -X bad-dmz
iptables -N bad-dmz
iptables -X dmz-bad
iptables -N dmz-bad
iptables -X icmp-acc
iptables -N icmp-acc
iptables -X log-and-drop
iptables -N log-and-drop

# Specific chain used for logging packets before blocking them
iptables -A log-and-drop -j LOG --log-prefix "drop "
iptables -A log-and-drop -j DROP

# The packets having the TCP flags activated are dropped
# and so for the ones with no flag at all (often used with Nmap scans)
iptables -A FORWARD -p tcp --tcp-flags ALL ALL -j log-and-drop
iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j log-and-drop

# The packets coming from reserved addresses classes are dropped
# and so for multicast
iptables -A FORWARD -i eth+ -s 224.0.0.0/4 -j log-and-drop
iptables -A FORWARD -i eth+ -s 192.168.0.0/16 -j log-and-drop
iptables -A FORWARD -i eth+ -s 172.16.0.0/12 -j log-and-drop
iptables -A FORWARD -i eth+ -s 10.0.0.0/8 -j log-and-drop

# The packets belonging to an already established connexion are accepted
iptables -A FORWARD -m state --state INVALID -j log-and-drop
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# The corresponding chain is sent according to the packet origin
iptables -A FORWARD -s $DMZ_ADDR -i $DMZ_IFACE -o $BAD_IFACE -j dmz-bad
iptables -A FORWARD -o $DMZ_IFACE -j bad-dmz
# All the rest is ignored
iptables -A FORWARD -j log-and-drop

# Accepted ICMPs
iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-request -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A icmp-acc -j log-and-drop

# Outside -> Inside chain
# mail, DNS, http(s) and SSH are accepted
iptables -A bad-dmz -p tcp --dport smtp -j ACCEPT
iptables -A bad-dmz -p udp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport www -j ACCEPT
iptables -A bad-dmz -p tcp --dport https -j ACCEPT
iptables -A bad-dmz -p tcp --dport ssh -j ACCEPT
iptables -A bad-dmz -p icmp -j icmp-acc
iptables -A bad-dmz -j log-and-drop

# Inside -> Outside chain
# mail, DNS, http(s) and telnet are accepted
iptables -A dmz-bad -p tcp --dport smtp -j ACCEPT
iptables -A dmz-bad -p tcp --sport smtp -j ACCEPT
iptables -A dmz-bad -p udp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport www -j ACCEPT
iptables -A dmz-bad -p tcp --dport https -j ACCEPT
iptables -A dmz-bad -p tcp --dport telnet -j ACCEPT
iptables -A dmz-bad -p icmp -j icmp-acc
iptables -A dmz-bad -j log-and-drop

# Chains for the machine itself
iptables -N bad-if
iptables -N dmz-if
iptables -A INPUT -i $BAD_IFACE -j bad-if
iptables -A INPUT -i $DMZ_IFACE -j dmz-if

# External interface
# SSH only accepted on this machine
iptables -A bad-if -p icmp -j icmp-acc
iptables -A bad-if -p tcp --dport ssh -j ACCEPT
iptables -A bad-if -p tcp --sport ssh -j ACCEPT
ipchains -A bad-if -j log-and-drop

# Internal interface
iptables -A dmz-if -p icmp -j icmp-acc
iptables -A dmz-if -j ACCEPT

关于服务质量的几点说明。Linux能够修改ToS("Type of Service")字段,对 一个数据包赋予不同的优先权。举例:下面的命令改善流出的SSH数据包的连接响应。

iptables -A OUTPUT -t mangle -p tcp --dport ssh -j TOS --set-tos Minimize-Delay

用同样的方法,对于FTP连接你可以使用'--set-tos Maximize-Throughput' 选项来改善传输速度。

这就是Netfilter。现在你知道设置一个有效的数据包过滤系统的基础知识。但是, 紧记当涉及安全时防火墙并不是万能药。他仅仅是一种预防。你还需使用强壮的密码, 最新的安全补丁,入侵检测系统等等。

 

涉及资料

 

对这篇文章发表评论

每篇文章都有各自的反馈页面。在这个页面里,您可以提交评论,也可以查看其他读者的评论:
 反馈页面 

<--, back to the index of this issue

主页由LinuxFocus编辑组维护
© Vincent Renardias, FDL
LinuxFocus.org
翻译信息:
fr --> -- : Vincent Renardias <vincent(at)renardias.com>
fr --> en: Georges Tarbouriech <gt(at)linuxfocus.org>
en --> zh: hwhuwww <hudihui(at)zj165.com>

2004-03-15, generated by lfparser version 2.46