`
wangminshe89
  • 浏览: 669176 次
文章分类
社区版块
存档分类
最新评论

实现一个网桥式防火墙

 
阅读更多

实现一个网桥式防火墙


原作者: David Whitmarsh
编译:ideal <ideal@linuxaid.com.cn>

传统防火墙和网桥式防火墙有什么区别呢?通常一个防火墙象一个路由器一样工作:内部系统被设置为将防火墙看做是通向外部网络的网关,并且外部的路由器被设置为将防火墙看做是连往内部被保护的网络的网关。一个网桥则是一个联结一个或多个网段的设备,在各个网段之间转发数据,而网络中其他设备并不会感觉到存在一个网桥。换句话说,一个路由器将两个网络连接在一起,在两者之间传输数据;一个网桥则更象一段网线,将一个网络的两个部分连接在一起。一个网桥防火墙则象网桥一样工作,而不被两端设备发现,但是同样具有过滤通过它的数据包的功能。

为什么会需要实现网桥式防火墙呢?一般有以下几个原因:

  • 你可以在网络中添加一个防火墙而不需要修改网络中任何设备的参数。
  • 你可能希望保护网络的某一个部分而却没有权利控制外部路由的参数信息。

我遇到的问题

我的办公室是一个ADSL连接到Demon互联网,同时有16个IP地址的子网可供使用。因为英国ISP的特殊原因,线路和路由器是由英国电信公司安装和拥有,因此我们有权利配置外部路由器来指定谁是内部网络的网关,这样我只有两种选择:
  • 直接将每台主机和ADSL路由器相连接,并且独立地为每台主机使用iptables来设置防火墙规则。
  • 另外一种选择是使用NAT功能的防火墙来带动内部网络访问互联网。
第一种方法是不可接受的,因为这样将大大增加出错和系统管理开销。第二种方法也优缺点,虽然大多数应用都能被NAT方式支持,但是也有例外,例如视频流和VPN等等。一个网桥防火墙则能解决这些问题,防火墙能架设在ADSL路由器和内部网络之间来保护网络,但同时不需要修改配置。最后一个障碍是在标准的Linux内核中完全旁路了iptables,因此你能使用网桥或者是iptables防火墙,但是不能同时使用该功能。

解决方案

幸运的是,有一个项目专门实现支持iptables的网桥,因此任何穿过网桥的数据包可以被递交给iptables规则进行过滤处理。结果是防火墙可以是完全透明于网络的,不需要特殊的路由功能。就互联网而言,防火墙并不存在,除了特定的连接被阻塞。网桥软件是一个内核补丁来支持已有的网桥代码可以连同iptables一起工作。方便的是开发者已经制作了RPM形式的支持网桥防火墙的内核。但不方便的是相关文档太少,因此该文章就是帮助那些希望实现网桥式防火墙的人们。

桥接和路由 - 是如何工作的

简单的说,Linux网桥实现一般是在具有一个或多个网络接口的设备上实现的,通过检测多个网段的活动性,桥接代码学习到哪个MAC地址从哪个接口可以到达,并且使用该信息来判断是否要中继一个数据包到另外一个网段。网桥接口本身是没有分配IP地址的,但是整个网桥被配置作为防火墙的单个接口。

从上图可以看到,在桥接情况下目的地址为桥设备本身的数据需要经过filter表的INPUT规则链和mangle表的PREROUTING规则链;从桥设备自身发出的数据需要经过filter表的OUTPUT规则链和mangle表的PREROUTING规则链;而流经桥设备的数据则要分别经过mangle表的PREROUTING规则链和filter表的FORWARD规则链和mangle表的POSTROUTING规则链。

网络拓朴

我分配得到的静态IP地址范围为xxx.xxx.xxx.48-63,也就是子网掩码为255.255.255.240。我决定将整个IP分割为两个网段:xx.xxx.xxx.48-56用于防火墙以外,这包括ADSL路由器自身的IP地址 (xxx.xxx.xxx.49);xxx.xxx.xxx.57-62用在防火墙之后部分。需要注意的是这并不是真正的子网划分,因为它们是有网桥而不是路由器连接的。

防火墙规则

防火墙规则定义如下:

#!/bin/sh
#
# rc.firewall - Initial SIMPLE IP Firewall test script for 2.4.x
#
# Author: David Whitmarsh
# (c) 2001, 2002 Sparkle Computer Co ltd.
# based on rc.firewall by Oskar Andreasson <blueflux@koffein.net>
# parts (c) of BoingWorld.com, use at your own risk,
# do whatever you please with
# it as long as you don't distribute this without due credits to
# BoingWorld.com and Sparkle Computer Co Ltd
#

###########
# Configuration options, these will speed you up getting this script to
# work with your own setup.

#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP adress. the same as netmask 255.255.255.0
#
# BR_IP is used to access the firewall accross the network
# For maxium security don't set one up - but then you must do
# everything directly on the firewall.

BR_IP="xxx.xxx.xxx.57"
BR_IFACE=br0

LAN_BCAST_ADDRESS="xxx.xxx.xxx.63"
INTERNAL_ADDRESS_RANGE="xxx.xxx.xxx.56/29"

INET_IFACE="eth1"
LAN_IFACE="eth0"

LO_IFACE="lo"
LO_IP="127.0.0.1"

IPTABLES="/sbin/iptables"

#########
# Load all required IPTables modules
#

#
# Needed to initially load modules
#
/sbin/depmod -a

#
# Adds some iptables targets like LOG, REJECT
#
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_REJECT

#
# Support for connection tracking of FTP and IRC.
#
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc

#
# Take down the interfaces before setting up the bridge
#

ifdown $INET_IFACE
ifdown $LAN_IFACE
ifconfig $INET_IFACE 0.0.0.0
ifconfig $LAN_IFACE 0.0.0.0

# Clean up for a restart

$IPTABLES -F
$IPTABLES -X
#
# Set default policies for the INPUT, FORWARD and OUTPUT chains
#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD DROP

# Our interfaces don't have IP addresses so we have to start with the mangle
# PREROUTING table

$IPTABLES -t mangle -P PREROUTING DROP

# Now we are pretty secure, let's start the bridge
# This will create a new interface

brctl addbr $BR_IFACE

# and add the interfaces to it
brctl addif $BR_IFACE $INET_IFACE
brctl addif $BR_IFACE $LAN_IFACE

# make us visible to the network again (optional)
if [ "$BR_IP" != "" ] ; then
ifconfig $BR_IFACE $BR_IP
else
# otherwise we must at least bring the interface up for the bridge to work.
ifconfig $BR_IFACE up
fi

# Block obvious spoofs

$IPTABLES -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
$IPTABLES -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
$IPTABLES -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP

# Accept internal packets on the internal i/f
$IPTABLES -t mangle -A PREROUTING -i $LAN_IFACE -s $INTERNAL_ADDRESS_RANGE -j ACCEPT

# Accept external packets on the external i/f

$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE ! -s $INTERNAL_ADDRESS_RANGE -j ACCEPT

#
# Accept the packets we actually want to forward
#

$IPTABLES -A FORWARD -p ALL -s $INTERNAL_ADDRESS_RANGE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level 7 --log-prefix "IPT FORWARD packet died: "

#
# Create separate chains for ICMP, TCP and UDP to traverse
#

$IPTABLES -N icmp_packets
#
# ICMP rules
#

$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 0 -j ACCEPT # echo reply
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 3 -j ACCEPT # dest unreachable
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 5 -j ACCEPT # redirect
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT # time exceeded
$IPTABLES -A FORWARD -p ICMP -j icmp_packets

#
# UDP ports
#
$IPTABLES -N udpincoming_packets

$IPTABLES -A udpincoming_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT # DNS
$IPTABLES -A udpincoming_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT # ntp
#$IPTABLES -A udpincoming_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT # speakfreely
#$IPTABLES -A udpincoming_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT #icq

$IPTABLES -A FORWARD -p UDP -j udpincoming_packets

#

$IPTABLES -N tcp_packets

#
# The allowed chain for TCP connections
#

$IPTABLES -N allowed
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP

# TCP rules
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A tcp_packets -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:"
$IPTABLES -A tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

$IPTABLES -A tcp_packets -p TCP -s 0/0 -d springfield.sparkle-cc.co.uk --dport 80 -j allowed # smtp
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d lisa.sparkle-cc.co.uk --dport 6346 -j allowed # gnutella
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d springfield.sparkle-cc.co.uk --dport 25 -j allowed # smtp

$IPTABLES -A FORWARD -p TCP -j tcp_packets

#
# Input to the firewall itself. Leave these out if you don't want the firewall
# to be visible on the network at all.
# Note that the PREROUTING restrictions above mean that only packets form inside
# the firewall can fulfill the source condition. So the firewall machine should not be
# visible to the internet.
#

$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $LAN_BCAST_ADDRESS -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $BR_IP -j ACCEPT

# But you *will* need this

$IPTABLES -A INPUT -p ALL -i $LO_IFACE -d $LO_IP -j ACCEPT

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level 7 --log-prefix "IPT INPUT packet died: "

#
# OUTPUT chain
#

$IPTABLES -A OUTPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:"
$IPTABLES -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $BR_IP -j ACCEPT
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level 7 --log-prefix "IPT OUTPUT packet died: "

这里的样本防火墙脚本类似于传统的防火墙设置,摘抄于Oskar Andreasson's iptables tutorial

基本的防火墙策略为:

  1. 阻止不可能的IP地址的数据包。
  2. 允许所有防火墙内部到外连的连接。
  3. 允许属于内部到外部的连接的反向数据进入内部网络。
  4. 允许外部连接到特定的主机的特定端口。

变量定义

为了保证清晰性和可维护性,定义一些接口名和IP地址作为变量是很不错的想法。例子中使用了下面这些数据:
BR_IP="xxx.xxx.xxx.57"
BR_IFACE=br0

LAN_BCAST_ADDRESS="xxx.xxx.xxx.63"
INTERNAL_ADDRESS_RANGE="xxx.xxx.xxx.56/29"

INET_IFACE="eth1"
LAN_IFACE="eth0"

LO_IFACE="lo"
LO_IP="127.0.0.1"
"xxx.xxx.xxx"表示网络IP的前三个字段。$INTERNAL_ADDRESS_RANGE表示内部网络的IP范围。

设置一个桥接设备

为了设置一个网桥,我们需要做以下一些工作。首先我们需要关闭网络接口并将其IP设置去除:
ifdown $INET_IFACE
ifdown $LAN_IFACE
ifconfig $INET_IFACE 0.0.0.0
ifconfig $LAN_IFACE 0.0.0.0
如果你仅仅是通过telnet或ssh会话执行了这些命令,那是不行的而应该到主机的控制台来进行操作。下一步我们创建一个桥设备,并为其指定以太接口:
brctl addbr $BR_IFACE

brctl addif $BR_IFACE $INET_IFACE
brctl addif $BR_IFACE $LAN_IFACE
现在我们就可以启动桥接设备作为一个内部接口:
ifconfig $BR_IFACE $BR_IP

阻止伪装

我们可以在mangel PREROUTING规则链中阻塞伪造的数据包。通过在这里阻塞,我们同时可以抓获流入和被转发的数据包。我们使用mangle PREROUTING,而不是nat PREROUTING是因为在NAT表中只有第一个数据包被检查。

下面的内容确保只有具有河岸得分内部地址的数据包被内部接口所接受:

$IPTABLES -t mangle -A PREROUTING -i $LAN_IFACE -s $INTERNAL_ADDRESS_RANGE -j ACCEPT
下面命令阻止网桥外部接口接收具有内部地址的数据包:
$IPTABLES -t mangle -A PREROUTING -i $INET_IFACE ! -s $INTERNAL_ADDRESS_RANGE -j ACCEPT

从内部网络中访问防火墙

也许你希望你的防火墙对于网络是完全透明的,或者你也可能为了方便允许从内部网络直接连接网桥防火墙,下面的命令将只允许内部网络到防火墙的连接。当然根据自己的实际情况对是否允许访问网桥防火墙的要求是不一样的:
$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $LAN_BCAST_ADDRESS -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $BR_IFACE -s $INTERNAL_ADDRESS_RANGE -d $BR_IP -j ACCEPT
前面我们已经阻止了具有和接收接口不匹配的IP地址的数据包了。

更多信息

内核补丁,没有它iptables将不能和桥设备一起使用。

Oskar Andreasson的iptables入门教程是推荐读物。

Rusty's Remarkably Unreliable Guides讨论了包过滤和联网的一些背景信息。

Sparkle Home Page (作者的公司)

<!-- *** END navbar *** --> <!--endcut ============================================================-->

分享到:
评论

相关推荐

    网路岗7.03.35官方原版破解

     VLAN,是英文Virtual Local Area Network的缩写,中文名为"虚拟局域网", VLAN是一种将局域网(LAN)设备从逻辑上划分(注意,不是从物理上划分)成一个个网段(或者说是更小的局域网LAN),从而实现虚拟工作组...

    什么是VLAN

     局域网(LAN)通常是一个单独的广播域,主要由Hub、网桥或交换机等网络设备连接同一网段内的所有节点形成。处于同一个局域网之内的网络节点之间可以直接通信,而处于不同局域网段的设备之间的通信则必须经过路由器...

    计算机网络技术20秋在线作业1-0001.docx

    () A:计算机及相关外部设备通过通信媒体互连在一起,组成一个群体。 B:网络中任意两台计算机都是独立的,它们之间不存在主从关系。 C:不同计算机之间的通信应有双方必须遵守的协议。 D:网络中的软件和数据可以共享...

    东北财经大学《计算机网络技术基础》在线作业二-0002.docx

    A:8 B:16 C:32 D:64 参考选项:B 10Base-T通常使用(),两端各用一个RJ-45连接器 A:屏蔽双绞线 B:非屏蔽双绞线 C:同轴电缆 D:光纤 参考选项:B 用户通过客户机上的()来浏览WEB服务器上的信息 A:浏览器程序 B:编程语言...

    计算机网络常见问题解答

    问题3-25:一个单个的以太网上所使用的网桥数目有没有上限? 问题3-26:当我们在PC机插上以太网的适配器(网卡)后,是否还必须编制以太网所需的MAC协议的程序? 问题3-27:使用网络分析软件可以分析出所捕获到的每...

    TCP/IP技术大全(中文PDF非扫描版)

    6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 52 6.7.2 叠代查询 52 6.8 高速缓存 52 6.9 反向解析(Pointer)查询 52 6.10 DNS安全 52 6.11 资源记录 53 6.12 小结 54 第7章 WINS 55 7.1 ...

    TCP-IP技术大全

    6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 52 6.7.2 叠代查询 52 6.8 高速缓存 52 6.9 反向解析(Pointer)查询 52 6.10 DNS安全 52 6.11 资源记录 53 6.12 小结 54 第7章 WINS 55 7.1 ...

    计算机网络设计试题及答案.doc

    以太网交换机的每一个端口相当于一个( )。 A.网卡 B.Hub C . 中继器 D.网桥 14. 在中低端路由器中,( )负责交换路由信息、路由表查找以及转发数据包。 A.数据库 B.路由算法 C . CPU D.NVROM 15. 路由器在轻载...

    计算机网络&计算机网络

    第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止频率与带宽 2.2.3 信道的最大数据...

    计算机网络(汲及内容全面)

    第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止频率与带宽 2.2.3 信道的最大数据...

    计算机网络基础知识

    第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止频率与带宽 2.2.3 信道的最大...

    经典全面系统的网络工程师资料

    第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止频率与带宽 2.2.3 信道的最大数据...

    计算机网络技术基础

    第1章 计算机网络基础知识  ...14.5 实验5 组建一个小型对等网  14.6 实验6 WWW服务  14.7 实验7 使用电子邮件  14.8 实验8 DHCP服务器的安装与配置  14.9 实验9 DNS服务器的安装与配置 

    TCP/IP教程TCP/IP基础

    6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 52 6.7.2 叠代查询 52 6.8 高速缓存 52 6.9 反向解析(Pointer)查询 52 6.10 DNS安全 52 6.11 资源记录 53 6.12 小结 54 第7章 WINS 55 7.1 ...

    TCP/IP技术大全

    6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 52 6.7.2 叠代查询 52 6.8 高速缓存 52 6.9 反向解析(Pointer)查询 52 6.10 DNS安全 52 6.11 资源记录 53 6.12 小结 54 第7章 WINS 55 7.1 ...

    TCP/IP详解

    6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 52 6.7.2 叠代查询 52 6.8 高速缓存 52 6.9 反向解析(Pointer)查询 52 6.10 DNS安全 52 6.11 资源记录 53 6.12 小结 54 第7章 WINS 55 7.1 ...

    清华大学的计算机网络课件

    问题4-19:一个单个的以太网上所使用的网桥数目有没有上限? 问题4-20:当我们在PC机插上以太网的网卡后,是否还必须编制以太网所需的MAC协议的程序? 问题4-21:使用网络分析软件可以分析出所捕获到的每一个帧的...

    TCPIP协议详解(4-1)

    DNS:名字服务器 48 6.1 域名系统概述 48 6.2 授权局 50 6.3 DNS分布数据库 50 6.4 域和区 50 6.5 Internet顶级域 51 6.6 选择一个域名服务器 52 6.7 名字服务解析过程 52 6.7.1 递归查询 ...

Global site tag (gtag.js) - Google Analytics