查看单个帖子
旧 04-10-2005, 14:20   #3
chyangwa
蝌蚪-小毛驴
 
chyangwa的头像
 
注册日期: Nov 2000
来自: 上海
帖子: 8,285
精华: 6
回复: IPtable 1.0.7指南

IPtable 1.0.7指南(三)

TCP 链
现在我们讲TCP连接。它指定了从Internet的防火墙上什么端口可以被使用。当然这还要做更多的检查,所以我们发送每一个TCP包,其中总有一个会到达我们前面提到的允许的链中。一个tcp_packets 告诉iptables 在哪个链中添加新规则,规则被添在链尾。-p TCP 告诉它匹配TCP包,-s 0/0 匹配所有的源地址,从0.0.0.0 ,掩码为0.0.0.0,换句话说就是所有的源地址,实际上这是省缺的行为,但我在这忽略用它。--dport 21表示目标端口21,换句话说,如果包去向端口21他们也匹配。如果所有的标准都匹配了,包就去向允许的链。如果它有任何一条规则没匹配,它将被传回到发送它到tcp_packets 链的链。
象现在,我允许TCP port 21,或FTP 控制端口,它用来控制FTP 连接,稍后我还允许所有的相关连接,而且那样我还允许PASSIVE 和 PORT 连接,因为ip_conntrack_ftp 模块被加载。如果我们完全不允许FTP ,我们可以卸载ip_conntrack_ftp 模块,从rc.firewall 文件中删除那条链。
端口22是SSH,比允许端口23上的telnet 好,如果你想允许外面的人使用你网络设备上的 shell。
端口80是HTTP,换句话说就是你的网络服务器,如果你不想在你的站点上运行一个网络服务器就删掉它。
最后,我们允许端口113,它是IDENTD ,对于使用象IRC的协议工作好有用处。
如果你想增加更多的开放端口,那怎样做则就是你自己的事情了。

UDP 链
现在,如果我们在INPUT 链上获得一个UDP 包,我们则将它继续传送到udpincoming_packets。
现在,如果我们确实在INPUT 链上获得一个UDP 包,我们则将它继续传送到udpincoming_packets,在那用-p UDP 再为UDP协议做一个匹配,匹配了所有的源地址为0.0.0.0 掩码为0.0.0.0 的东西,换句话说所有的东西又匹配了。如果他们还有源端口53,我们直接接收它们。
现在,我从端口53 接收来的UDP 包,用来做DNS 查找,没有这个我们做不了域名查找而且我们只能使用IP's。我们不希望这种行为,所以我们当然允许DNS。
我个人还允许端口123,是NTP 或网络时间协议(network time protocol)。这个协议用来将你的计算机的时间设置为与具有非常准确的时钟的服务器相同的时间。虽然你们大多数人可能不用这个协议,我允许它是因为我知道有些人用。
我们现在还允许端口2074,用于象speak freely 一类的实时多媒体应用。使用speak freely你可以通过喇叭、麦克风或耳机与其他人实时交谈。
端口4000,现在众所周知是ICQ协议。我觉得没有必要进一步解释它是干什么的。

nat table的PREROUTING 链
PREROUTING 链与它的字面意思一样,在它们真正遇到将它们送到过滤表上不同的INPUT/FORWARD/OUTPUT 链的路由表之前过滤包。这是检查包是否具欺骗性的好地方。
首先我们检查显然欺骗的IP 地址,就象万一我们从Internet 接口处获得一个包,声明有一个源IP 192.168.x.x, 10.x.x.x 或 172.16.x.x, 我们马上把它们扔掉,因为这些地址是为本地内部网保留的,显然不能在Internet上使用。这也可以反过来使用,比如我们从$LAN_IFACE 处获得一个包,声明不是从$LAN_IP_RANGE的IP地址处来的,我们也把它扔掉 。

INPUT 链
象我写的INPUT 链大多使用其他链来工作。在这种方法下,我们并没有从iptables处获得太多的负载,因此它在那些高负载下可能丢失包的慢机器上也能工作的很好。
在这我们对坏包做特别检查。如果你想完全了解这一点,你要看附录的regarding state NEW and non-SYN packets getting through other rules。在特殊条件下这些包被允许,但99%的情况下我们不希望这些包通过。所以我们将它们记录到日志并丢弃。首先我们匹配引入接口$INET_IFACE的INPUT 链的所有ICMP包,引入接口是eth0,把包传到前面讲过的icmp_packets。然后我们对$INET_IFACE 上的TCP 包做同样的匹配,并将它们送到tcp_packets 链,之后所有的UDP 包送到udpincoming_packets 链。最后我们检查来自$LOCALHOST_IP的所有东西,一般是127.0.0.1 ,接收从那来的所有负载,对来自$LAN_IP_RANGE的做同样的事,一般是192.168.0.0/24,这之后要考虑一下安全问题了,我们允许来自我们自己Internet IP 的任何东西,它们或者已建立连接或者与某些连接相关联。我们还允许我们局域网的广播负载,一些应用依赖于它,象Samba , 没有它这些应用无法很好地工作。
在我们遇到INPUT 链的默认规则前,我们把它记入日志以便发现可能的问题或bugs。它或者是一个我们不允许的包,或者是对我们做坏事的人,或者是我们防火墙中的一个问题,不允许那些被允许的包。无论是那种情况我们都想知道然后做出处理。虽然每分钟我们记录不超过3个包,这是为了使日志文件不被垃圾充斥,我们还为日志记录加了前缀,使我们知道它是哪来的。
不被匹配的东西就会被INPUT 链的默认规则扔掉。默认规则是很早以前设置的,你应该记得。

OUTPUT 链
因为我知道除了我之外没人使用这个部分用做防火墙和工作站的网络设备,我允许来自它拥有源地址$LOCALHOST_IP, $LAN_IP 或 $STATIC_IP的任何东西。其他的所有东西都以某种方式欺骗,尽管这样我还是怀疑某个我知道的人会在我的网络设备上这么做。最后,我们将扔掉的所有东西记录下来。如果它确实被扔掉了,我们确定会因为这个或那个而想知道它。不管它是一个令人厌恶的错误或是一个奇怪的包,都是欺骗。最后我们扔掉默认规则中的包。

FORWARD 链
我虽然没在rc.firewall 例子文件中建立一个特别的块,但是我将对其中的几行加以评论。象现在这样,我用下面这行接收来自我们局域网的所有包:
/usr/local/sbin/iptables -A FORWARD -i $LAN_IFACE -j ACCEPT
所以不管情况怎样来自我们本地网接口的任何东西都被接收。之后我们接收来自任何地方具有ESTABLISHED 或RELATED状态的任何东西,换句话说,如果我们打开一个从我们局域网到Internet上某个东西的连接,我们允许从那个站点回来的具有ESTABLISHED 或RELATED状态的包。之后我们记录所有的东西并丢弃它。我们每分钟最多记录3个日志记录以防止日志文件溢出,加一个短前缀, 可做文件内的字符串查找。同样我们也可以做调试级的记录。我们最后会碰到FORWARD链的默认规则,丢弃所有东西。

其他例子
rc.DMZ.firewall.txt

你将在下书URL处找到这一脚本:rc.DMZ.firewall.txt
。这一脚本是为那些拥有一个可信赖的网络、一个De-Militarized Zone 、一个Internet 连接的人。De-Militarized Zone 是1-to-1 NAT'ed ,需要你在防火墙上做一些IP别名,就是你必须使网络设备认识来自多于一个IP的包。在这个指南的后面你将看到如何做IP别名(IP aliasing )的例子,现在 你还看不到什么实际的例子。从图中你可以看出你需要2个内部网络。一个使用的ip范围是192.168.0.0/24 ,包括De-Militarized Zone。如果internet 上的某个人向我们的DNS_IP发送一个包,我们使用DNAT(Destination Network Adress Translation)将包发送到DMZ上的DNS 。当DNS 看到我们的包时,包将去向真正的DNS 内部网IP,而不是外部的DNS IP。如果包不被翻译,DNS不应答包。DNAT 代码如下面的例子:
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP –dport 53 -j DNAT --to-destination $DMZ_DNS_IP
首先DNAT 只能在nat table的PREROUTING 链中执行。然后我们来看看拥有匹配$DNS_IP的目的IP的$INET_IFACE 上的TCP协议,被指向端口53,是DNS's中地域传送的TCP 端口。如果我们真得到了一个目的为DNAT的包,即Destination NAT。之后我们用--to-destination 选项规定想让包去的地方,将它赋值$DMZ_DNS_IP,即我们DMZ上DNS 的IP。这就是DNAT 工作的基本原理。当对DNAT包的应答穿过防火墙,它自动被un-DNAT'ed。
现在你该知道一切是怎么工作的,能够在较简单的情况下地了解这个脚本了吧? 如果有什么你不了解,而且我的指南也没讲,那么请发邮件给我,因为那也许是我的错误。

没有DCC的被动FTP , 感兴趣的额外阅读
这是关于2.4.x 内核的新iptables 支持的真正美好的部分之一,比如你可以允许被动的FTP 连接,但不允许DCC 发送带有新状态匹配代码的函数。你可能会问自己如何做到,只要你想就很简单。只要编译内核中的ip_conntrack_irc 和ip_conntrack_ftp 模块。这些模块做的就是增加对conntrack 模块的支持,使它可以识别一个被动的FTP 连接或一个DCC发送连接。比如你想允许一个被动的FTP连接而不允许DCC发送,你将加载ip_conntrack_ftp 模块,而不是ip_conntrack_irc 模块,然后做:
/usr/local/sbin/iptables -A INPUT -p TCP -m state --state RELATED –j ACCEPT
允许被动的FTP 而不允许DCC。如果你想做相反的,你就加载ip_conntrack_irc 模块而不是ip_conntrack_ftp 模块。

规定 NEW 信息包 但没有 SYN 置位
iptables 有一个特点没被很好的说明, 因而可能被许多人忽视。如果你使用状态NEW,SYN 位没置的包将穿过你的防火墙。有这个特点是因为特定情况下我们不认为一个包是另一个防火墙上已建立连接的一部分。这个特点使得有两个或更多的防火墙成为可能。这个子网的防火墙将被我们的第二防火墙取代,状态NEW 因此允许相当多的任何种类的TCP连接,不管这是否是三方握手(3-way handshake) 。为解决这个问题,我们向防火墙的INPUT, OUTPUT 和 FORWARD 链添加如下规则:
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP"
上述规则将解决这个问题。这是netfilter/iptables 计划中文档的严重问题,应该被提出。换句话说在你的防火墙上对此种行为应该发出严重警告。
__________________
生活就象是强奸,如果无力反抗那就闭上眼睛好好享受.
工作就象是轮奸,你不行就赶紧让别人换上来.
社会就象是自慰,我们总要用自己的双手来解决自己的问题~!
chyangwa离线中   回复时引用此帖