<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>温室小花.技术.博客 --纯粹的unix技术博客 &#187; ipfw</title>
	<atom:link href="http://www.evanjiang.net.cn/archives/category/network_security/ipfw/feed" rel="self" type="application/rss+xml" />
	<link>http://www.evanjiang.net.cn</link>
	<description>红颜弹指老，刹那芳华，与其天涯思君，恋恋不舍，莫若相忘于江湖！</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>FreeBSD7.0 IPFW内核级NAT安装设置笔记</title>
		<link>http://www.evanjiang.net.cn/archives/571.html</link>
		<comments>http://www.evanjiang.net.cn/archives/571.html#comments</comments>
		<pubDate>Wed, 25 Feb 2009 03:59:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[freebsd unix]]></category>
		<category><![CDATA[ipfw]]></category>
		<category><![CDATA[Freebsd ipfw  NAT 安装 试用]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=571</guid>
		<description><![CDATA[<p>


 <p>一、内核加入以下内容并编译内核：
options IPFIREWALL
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=100
options IPFIREWALL_DEFAULT_TO_ACCEPT
options DUMMYNET
options IPFIREWALL_NAT
options LIBALIAS
</p>
<p>二、在/etc/rc.conf中加入以下内容：
firewall_enable=&#8221;YES&#8221;
firewall_nat_enable=&#8221;YES&#8221;
firewall_nat_interface=&#8221;bge1&#8243;
firewall_type=&#8221;/etc/ipfw.conf&#8221; </p>
<p>说明：bge1是接外网的网卡







</p>
<p>三、ipfw.conf（试验用）：
add 00100 allow all from any to any via lo0
add 00110 deny all from any to 127.0.0.0/8
add 00120 deny all from 127.0.0.0/8 to any
add 00200 deny all from any to any ipoptions rr
add 00210 deny all from any to any ipoptions ts
add 00220 deny all [...]]]></description>
			<content:encoded><![CDATA[<p style="float: left;margin: 4px;"><script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 160x600, 创建于 10-2-7 */
google_ad_slot = "8970910006";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p> <p>一、内核加入以下内容并编译内核：<br />
options IPFIREWALL<br />
options IPFIREWALL_FORWARD<br />
options IPFIREWALL_VERBOSE<br />
options IPFIREWALL_VERBOSE_LIMIT=100<br />
options IPFIREWALL_DEFAULT_TO_ACCEPT<br />
options DUMMYNET<br />
options IPFIREWALL_NAT<br />
options LIBALIAS<br />
<span id="more-571"></span></p>
<p>二、在/etc/rc.conf中加入以下内容：<br />
firewall_enable=&#8221;YES&#8221;<br />
firewall_nat_enable=&#8221;YES&#8221;<br />
firewall_nat_interface=&#8221;bge1&#8243;<br />
firewall_type=&#8221;/etc/ipfw.conf&#8221; </p>
<p>说明：bge1是接外网的网卡<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>三、ipfw.conf（试验用）：<br />
add 00100 allow all from any to any via lo0<br />
add 00110 deny all from any to 127.0.0.0/8<br />
add 00120 deny all from 127.0.0.0/8 to any<br />
add 00200 deny all from any to any ipoptions rr<br />
add 00210 deny all from any to any ipoptions ts<br />
add 00220 deny all from any to any ipoptions ssrr<br />
add 00230 deny all from any to any ipoptions lsrr<br />
add 00240 deny tcp from any to any in tcpflags syn,fin </p>
<p>add 00300 nat 10 all from any to any via bge1<br />
nat 10 config if bge1 </p>
<p>nat 50 config redirect_port tcp 192.168.1.1:80 80<br />
nat 60 config redirect_port tcp 192.168.1.1:21 21 </p>
<p>add 01030 allow all from 192.168.0.0/16 to any<br />
add 01040 allow all from any to 192.168.0.0/16 </p>
<p>add 04000 deny all from any to any<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
四、试用感言<br />
在FreeBSD上作NAT，小流量(100兆以下)，用户数少情况下(2000左右)，IPFW、IPFILTER和PF区别不大，但是大流量，用户数多(3000以上)的情况下，IPFW和IPFILTER占用CPU较多（50%以上），流量也被打下来不少，启用POLLING后会有所改善。在三款防火墙中，表现最好的当属PF，占用CPU较少（30%左右），但流量到150兆左右就上不去，用户再多一些(5000左右)，开始迟滞，出现掉线，吞吐量下降。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/571.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IPFW中文手册</title>
		<link>http://www.evanjiang.net.cn/archives/433.html</link>
		<comments>http://www.evanjiang.net.cn/archives/433.html#comments</comments>
		<pubDate>Thu, 19 Feb 2009 12:08:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[freebsd unix]]></category>
		<category><![CDATA[ipfw]]></category>
		<category><![CDATA[IPFW 防火墙 中文 手册]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=433</guid>
		<description><![CDATA[<p style="float: right;margin: 4px;">


</p> <p>
ipfw 是 FreeBSD 内建的防火墙指令，我们可以用它来管理进出的网络交通。如果防火墙服务器是扮演着路由器 (gateway 例如上一篇中的 NAT 服务器) 的角色，则进出的封包会被 ipfw 处理二次，而如果防火墙扮演的是桥接器 (bridge) 的角色，则封包只会被处理一次。这个观念关系着我们以下所要介绍的语法，有的语法并不适用于桥接器。 </p>
<p>另外，我们在设定防火墙时有二种模式，一种模式是预设拒绝所有联机，再一条一条加入允许的联机；另一种是预设接受所有联机，加入几条拒绝的规则。如果是非常强调安全性，应该是使用预设拒绝所有联机，再一条一条加入我们允许的规则。 </p>
<p>我们会将 firewall 的设定写在 /etc/rc.firewall 中，每一条设定都是以先入为主 (first match wins) 的方式来呈现，也就是先符合的规则 (rules) 为优先。所有进出的封包都会被这些规则过滤，因此我们会尽量减少规则的数量，以加速处理的速度。 </p>
<p>在 kernel 中，关于防火墙的设定有下列几条：
</p>
<p># 防火墙
options IPFIREWALL </p>
<p># 支援 NAT
options IPDIVERT </p>
<p># 下面这一行是预设允许所有封包通过，如果没有这一行，
# 就必须在 /etc/rc.firewall 中设定封包的规则。
# 这条规则内定编号是 65535，也就是所有规则的最后一条
# 如果没有加这一条规则，内定就是拒绝所有封包，
# 只允许规则中允许的封包通过。
options IPFIREWALL_DEFAULT_TO_ACCEPT </p>
<p># 这一行是让你可以在 ipfw 中设定要记录哪些封包，
# 如果没有这一行，就算设定了要留下记录也不会有作用。
options IPFIREWALL_VERBOSE </p>
<p># [...]]]></description>
			<content:encoded><![CDATA[<p>
ipfw 是 FreeBSD 内建的防火墙指令，我们可以用它来管理进出的网络交通。如果防火墙服务器是扮演着路由器 (gateway 例如上一篇中的 NAT 服务器) 的角色，则进出的封包会被 ipfw 处理二次，而如果防火墙扮演的是桥接器 (bridge) 的角色，则封包只会被处理一次。这个观念关系着我们以下所要介绍的语法，有的语法并不适用于桥接器。 </p>
<p>另外，我们在设定防火墙时有二种模式，一种模式是预设拒绝所有联机，再一条一条加入允许的联机；另一种是预设接受所有联机，加入几条拒绝的规则。如果是非常强调安全性，应该是使用预设拒绝所有联机，再一条一条加入我们允许的规则。 </p>
<p>我们会将 firewall 的设定写在 /etc/rc.firewall 中，每一条设定都是以先入为主 (first match wins) 的方式来呈现，也就是先符合的规则 (rules) 为优先。所有进出的封包都会被这些规则过滤，因此我们会尽量减少规则的数量，以加速处理的速度。 </p>
<p>在 kernel 中，关于防火墙的设定有下列几条：<br />
<span id="more-433"></span></p>
<p># 防火墙<br />
options IPFIREWALL </p>
<p># 支援 NAT<br />
options IPDIVERT </p>
<p># 下面这一行是预设允许所有封包通过，如果没有这一行，<br />
# 就必须在 /etc/rc.firewall 中设定封包的规则。<br />
# 这条规则内定编号是 65535，也就是所有规则的最后一条<br />
# 如果没有加这一条规则，内定就是拒绝所有封包，<br />
# 只允许规则中允许的封包通过。<br />
options IPFIREWALL_DEFAULT_TO_ACCEPT </p>
<p># 这一行是让你可以在 ipfw 中设定要记录哪些封包，<br />
# 如果没有这一行，就算设定了要留下记录也不会有作用。<br />
options IPFIREWALL_VERBOSE </p>
<p># 这一行是限制每一条规则所要记录的封包数量，<br />
# 因为同样的规则可能有许多记录，加上这一条可以使<br />
# 同样的记录重复数减少，以避免记录文件爆增。<br />
options IPFIREWALL_VERBOSE_LIMIT=10 </p>
<p># 下面这一行是用来支援封包转向，<br />
# 当你要使用 fwd 动作时必须要有这一项设定。<br />
options IPFIREWALL_FORWARD </p>
<p># 如果要使用 pipe 来限制频宽，必须加入下列选项以支持 dummynet。<br />
options DUMMYNET </p>
<p>ipfw 也支持状态维持 (keep-state) 的功能，就是可以让符合设定的规则以动态的方式来分配增加规则 (地址或连接端口) 来让封包通过。也就是说防火墙可以记住一个外流的封包所使用的地址及连接端口，并在接下来的几分钟内允许外界响应。这种动态分配的规则有时间的限制，一段时间内会检查联机状态，并清除记录。 </p>
<p>所有的规则都有计数器记录封包的数量、位数、记录的数量及时间等。而这些记录可以用 ipfw 指令来显示或清除。 </p>
<p>在说明 ipfw 规则的语法之前，我们先来看这个指令的用法。ipfw 可以使用参数： </p>
<p>指令 说明<br />
ipfw add [rule] 新增一条规则。规则 (rule) 的语法请参考下一节的说明。<br />
ipfw delete [number] 删除一条编号为 number 的规则。<br />
ipfw -f flush 清除所有的规则。<br />
ipfw zero 将计数统计归零。<br />
ipfw list 列出现在所有规则，可以配合下列参数使用。<br />
-a 使用 list 时，可以列出封包统计的数目。<br />
-f 不要提出确认的询问。<br />
-q 当新增 (add)、归零(zero)、或清除 (flush) 时，不要列出任何回应。当使用远程登入，以 script (如 sh /etc/rc.firewall) 来修改防火墙规则时，内定会列出你修改的规则。但是当下了 flush 之后，会立即关掉所有联机，这时候响应的讯息无法传达终端机，而规则也将不被继续执行。此时唯一的方法就是回到该计算机前重新执行了。在修改防火墙规则时，最好在计算机前修改，以免因为一个小错误而使网络联机中断。<br />
-t 当使用 list 时，列出最后一个符合的时间。<br />
-N 在输出时尝试解析 IP 地址及服务的名称。<br />
-s [field] 当列出规则时，依哪一个计数器 (封包的数量、位数、记录的数量及时间) 来排序。 </p>
<p>12.3.1 ipfw 规则 </p>
<p>我们在过滤封包时，可以依据下列的几个封包所包含的信息来处理该封包： </p>
<p>接收或传送的接口，可以使用接口名称或地址。<br />
方向，流入或流出。<br />
来源或目的地的 IP 地址，也可以加上子网掩码。<br />
通讯协议，TCP,UDP,ICMP 等。<br />
TCP flags。<br />
IP fragment flag。<br />
IP options。<br />
ICMP 的类型。<br />
和封包相关的 socket User/group ID。<br />
使用 IP 地址或 TCP/UDP 的端口号来做为规则可能蛮危险的，因为这二种都有可能被以假的信息所蒙骗 (spoof)。但是这二种却也是最常被使用的方法。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
下列为 ipfw rules 的语法： </p>
<p>[number] action [log] proto from src to dist [interface_spec] [option]<br />
使用 [ ] 包起来的表示可有可无，我们一一为大家说明它们的意义： </p>
<p>number： </p>
<p>number 是一个数字，用来定义规则的顺序，因为规则是以先入为主的方式处理，如果你将规则设定放在一个档案中 ( 如 /etc/rc.firewall )，规则会依每一行排列的顺序自动分配编号。你也可以在规则中加上编号，这样就不需要按顺序排列了。如果是在命令列中下 ipfw 指令来新增规则的话，也要指定编号，这样才能让规则依我们的喜好排列，否则就会以指令的先后顺序来排。这个编号不要重复，否则结果可能不是你想要的样子。 </p>
<p>action： </p>
<p>action 表示我们这条规则所要做的事，可以用的 action 有下列几个： </p>
<p>命令 意义<br />
allow 允许的规则，符合则通过。也可以使用 pass,permit, accept 等别名。<br />
deny 拒绝通过的规则。<br />
reject 拒绝通过的规则，符合规则的封包将被丢弃并传回一个 host unreachable 的 ICMP。<br />
count 更新所有符合规则的计数器。<br />
check-state 检查封包是否符合动态规则，如果符合则停止比对。若没有 check-state 这条规则，动态规则将被第一个 keep-state 的规则所检查。<br />
divert port 将符合 divert sock 的封包转向到指定的 port。<br />
fwd ipaddr[,port] 将符合规则封包的去向转向到 ipaddr，ipaddr 可以是 IP 地址或是 hostname。如果设定的 ipaddr 不是直接可以到达的地址，则会依本机即有的 routing table 来将封包送出。如果该地址是本地地址 (local address)，则保留本地地址并将封包送原本指定的 IP 地址。这项设定通常用来和 transparent proxy 搭配使用。例如：<br />
# ipfw add 50000 fwd 127.0.0.1,3128 tcp from \<br />
  192.168.1.0/24 to any 80<br />
如果没有设定 port ，则会依来源封包的 port 将封包送到指定的 IP。使用这项规则时，必须在 kernel 中设定选项 IPFIREWALL_FORWARD。 </p>
<p>pipe pipe_nr 传递封包给 dummynet(4) &#8220;pipe&#8221;，用以限制频宽。使用本语法必须先在核心中加入 option DUMMYNET。请 man ipfw 及 man dummynet。<br />
基本语法是先将要设定频宽的规则加入：<br />
ipfw add pipe pipe_nr &#8230;.<br />
再设定该规则的频宽： </p>
<p>ipfw pipe pipe_nr config bw B delay D queue Q plr P<br />
这里的 pipe_nr 指的是 pipe 规则编号，从 1~65535；B 是指频宽，可以表示为 bit/s、Kbit/s、Mbit/s、Bytes/s、KBytes/s、或 MBytes/s。D 是延迟多少 milliseconds (1/1000)。Q 是 queue size 的大小 (单位为 packages 或 Bytes)。P 是要随机丢弃的封包数量。 </p>
<p>例如我们要限制内部网域的计算机对外上传的最大频宽是 20 KBytes： </p>
<p>ipfw add pipe 1 ip from 192.168.0.1/24 to any in<br />
ipfw pipe 1 config bw 20KBytes/s </p>
<p>log： </p>
<p>如果该规则有加上 log 这个关键词，则会将符合规则的封包记录在 /var/log/security 中。前提是在核心中有设定 IPFIREWALL_VERBOSE 的选项。有时因为同样的封包太多，会使记录文件保有大量相同的记录，因此我们会在核心中再设定 IPFIREWALL_VERBOSE_LIMIT 这个选项，来限制要记录多少相同的封包。 </p>
<p>proto： </p>
<p>proto 表示 protocol，即网络协议的名称，如果使用 ip 或 all 表示所有协议。可以使用的选项有 ip,all,tcp,udp,icmp 等。 </p>
<p>src 及 dist： </p>
<p>src 是封包来源；dist 是封包目的地。在这二个项目可以用的关键词有 any, me, 或是以<br />
<address/mask>[ports] 的方式明确指定地址及端口号。 </p>
<p>若使用关键词 any 表示使这条规则符合所有 ip 地址。若使用关键词 me 则代表所有在本系统接口的 IP 地址。而使用明确指定地址的方式有下列三种： </p>
<p>IP 地址，指定一个 IP，如 168.20.33.45。<br />
IP/bits，如 1.2.3.4/24，表示所有从 1.2.3.0 到 1.2.3.255 的 IP 都符合规则。<br />
IP:mask，由 IP 加上子网掩码，如 1.2.3.4:255.255.240.0 表示从 1.2.0.0 到 1.2.15.255 都符合。<br />
而在 me, any 及 指定的 ip 之后还可以再加上连接埠编号 (ports)，指定 port 的方法可以是直接写出 port ，如 23；或给定一个范围，如 23-80；或是指定数个 ports，如 23,21,80 以逗点隔开。或者是写出在 /etc/services 中所定义的名称，如 ftp，在 services 中定义是 21，因此写 ftp 则代表 port 21。 </p>
<p>interface-spec： </p>
<p>interface-spec 表示我们所要指定的网络接口及流入或流出的网络封包。我们可以使用下列几个关键词的结合： </p>
<p>关键词 意义<br />
in 只符合流入的封包。<br />
out 只符合流出的封包。<br />
via ifX 封包一定要经过接口 ifX，if 为接口的代号，X 为编号，如 vr0。<br />
via if* 表示封包一定要经过接口 ifX，if 为接口的代号，而 * 则是任何编号，如 vr* 代表 vr0,vr1,&#8230;。<br />
via any 表示经过任何界面的封包。<br />
via ipno 表示经过 IP 为 ipno 界面的封包。 </p>
<p>via 会使接口永远都会被检查，如果用另一个关键词 recv ，则表示只检查接收的封包，而 xmit 则是送出的封包。这二个选项有时也很有用，例如要限制进出的接口不同时： </p>
<p>ipfw add 100 deny ip from any to any out recv vr0 xmit ed1<br />
recv 接口可以检查流入或流出的封包，而 xmit 接口只能检查流出的封包。所以在上面这里一定要用 out 而不能用 in，只要有使用 xmit 就一定要使用 out。另外，如果 via 和 recv 或 xmit 一起使用是没有效的。 </p>
<p>有的封包可能没有接收或传送的接口：例如原本就由本机所送出的封包没有接收接口，而目的是本机的封包也没有传送界面。 </p>
<p>options： </p>
<p>我们再列出一些常用的 option 选项 ，更多选项请 man ipfw： </p>
<p>选项名称 意义<br />
keep-state 当符合规则时，ipfw 会建立一个动态规则，内定是让符合规则的来源及目的地使用相同的协议时就让封包通过。这个规则有一定的生存期限 (lift time，由 sysctl 中的变量所控制)，每当有新的封包符合规则时，便用重设生存期限。<br />
bridged 只符合 bridged 的封包。<br />
established 只适用于 TCP 封包，当封包中有 RST 或 ACK bits 时就符合。<br />
uid xxx 当使用者 uid 为 xxx 则符合该规则。例如，我们如果要限制 Anonymous FTP 的下载速度最大为 64KB/s，则可以使用： </p>
<p>ipfw pipe 1 config bw 512Kbit/s<br />
ipfw add pipe 1 tcp from me to any uid 21<br />
上列规则第一行是先建一个编号为 1 的 pipe，限制频宽为 512 Kbit/s (也就是 64 KByte/s)，接着第二条是当使用者 uid 为 21 时，从本机 (me) 下载的 tcp 封包都使用编号 1 的 pipe。因为 Anonymous FTP 的使用者是 ftp，它的预设 uid 为 21，所以这条规则会被套用在 Anonymous FTP user 上。 </p>
<p>setup 只适用于 TCP 封包，当封包中有 SYN bits 时就符合。 </p>
<p>以上的说明只是 man ipfw 中的一小部份。如果你想要对 ipfw 更了解，例如如何使用 ipfw 来限制频宽等，建议你 man ipfw。 </p>
<p>不知道您看了这么多的规则是否觉得眼花撩乱，如果不了解 TCP/IP 的原理，彻底了解 ipfw 的设定还真不容易。没关系，我们下面将举几个简单、常用的设定，这些范例应该够平常使用了。 </p>
<p>12.3.2 范例 </p>
<p>我将原本的 /etc/rc.firewall 备份成 rc.firewal.old，并将它改成下列内容，请注意，这里只是范例，只供参考： </p>
<p># 设定我的 IP<br />
myip=&#8221;1.2.3.4&#8243;<br />
# 设定对外的网络卡代号<br />
outif=&#8221;vr0&#8243;<br />
# 设定对内的网络上代号<br />
inif=&#8221;vr1&#8243;<br />
#清除所有的规则<br />
/sbin/ipfw -f flush<br />
# Throw away RFC 1918 networks<br />
${ipfw} add deny ip from 10.0.0.0/8 to any in via ${oif}<br />
${ipfw} add deny ip from 172.16.0.0/12 to any in via ${oif}<br />
${ipfw} add deny ip from 192.168.0.0/16 to any in via ${oif}<br />
# 只允许内部网络对 192.168.0.1 使用 telnet 服务<br />
/sbin/ipfw add 200 allow tcp from 192.168.0.1/24 to 192.168.0.1 telnet<br />
# 拒绝其它人连到 port 23，并记录尝试联机的机器<br />
/sbin/ipfw add 300 deny log tcp from any to me 23<br />
# 拒绝任何 ICMP 封包<br />
/sbin/ipfw add 400 deny icmp from any to any </p>
<p># 下面这台机器是坏人，不让它进来，并记录下来<br />
/sbin/ipfw add 1100 deny log all from 211.21.104.102 to any<br />
# NAT 的设定<br />
/sbin/ipfw add divert natd all from any to any via vr0<br />
# 限制内部网域对外下载最大频宽为 20KBytes/s，上传最大频宽为 5KBytes/s<br />
ipfw pipe 20 config bw 20KBytes/s<br />
ipfw add pipe 20 ip from any to 192.168.0.1/24 out<br />
ipfw pipe 30 config bw 5KBytes/s<br />
ipfw add pipe 30 ip from 192.168.0.1/24 to any in<br />
# 允许本机对任何地方联机<br />
/sbin/ipfw add check-state<br />
/sbin/ipfw add 2000 allow udp from ${myip} to any keep-state<br />
/sbin/ipfw add 2100 pass ip from ${myip} to any </p>
<p># 允许外界使用邮件服务<br />
/sbin/ipfw add 3000 pass tcp from any to ${myip} 25 in via ${outif} </p>
<p># 不允许内部的 IP 从外部连进来<br />
/sbin/ipfw add 1200 add deny ip from ${myip}/24 to any in via ${oif} </p>
<p># 其它都拒绝，如果没有在 kernel 中设定<br />
# IPFIREWALL_DEFAULT_TO_ACCEPT 则内定就有下列这一条<br />
/sbin/ipfw 65535 add deny all from any to any </p>
<p>存盘后就可以使用 sh rc.firewall 来执行新的规则了。如果您将规则放在 /etc/rc.firewall 中，则开机时会自动执行。 </p>
<p>12.3.3 一些小建议 </p>
<p>在建立一个封包过滤的防火墙时，应该尽可能阻挡一些不必要的服务。避免开放 port 1024 以下的 TCP 服务，例如只通过 SMTP 封包 (port 25) 给邮件服务器；拒绝所有 UDP 联机 (只有少部份服务如 NFS 会用到)；一些只有内部才会使用的服务，如数据库等也不必对外开放。 </p>
<p>另外，同样的防火墙限制可以使用不同的语法来展现，应该要试着让规则数量越少越好，以加快处理速度。 </p>
<p>在更新 firewall 规则时，如果规则没有写好，而你又是以远程登入的方式修改规则，很可能会因此无法继续登入。因此建议更新规则时最好在 console 前执行，若迫不得已一定要使用远程登入，建议您执行 /usr/share/examples/ipfw/change_rules.sh 这支程序来编辑规则： </p>
<p># cd /usr/share/examples/ipfw<br />
# sh change_rules.sh<br />
接着会出现文书编辑软件并最动加载 /etc/rc.firewall 让你编辑，结束离开后，会询问是否要执行更新。如果执行新的规则后造成断线，它会自动加载旧的规则，让我们可以再次联机。 </p>
<p>12.4 封包过滤桥接器 </p>
<p>如果您有三台机器全部都有 public IP，而您想使用其中一台做为防火墙，在不改变另外二台机器的设定下，我们可以使具封包过滤的桥接器来架设防火墙。只要将这台桥接器放在另外二台和对外网络之间即可。 </p>
<p>另外，当我们的内部网络有不同 class 的主机时，例如内部有 140.115.2.3 及 140.115.5.6 这二台计算机时，就无法使用传统的防火墙。如果要在这二台机器连到因特网中途中使用防火墙，我们必须使用新的方式，也可以使用这里介绍的桥接器。 </p>
<p>我们可以使用 FreeBSD 为桥接器，利用它来做封包过滤的动作，而丝毫不影响内部的主机原本的设定。为了达到这个功能，我们必需要有二张支持 promiscuous mode 的网络卡，现在的网络卡大部份都有支持。二张网络卡当中，一张需要设定 IP，另一张不需要。至于您要将 IP 设定在哪一张卡都可以，建议是设在对外的网络卡上。 </p>
<p>首先，我们必须在核心中加入关于桥接器的设定： </p>
<p># 支援桥接器<br />
options BRIDGE<br />
# 防火墙设定<br />
options IPFIREWALL<br />
options IPFIREWALL_VERBOSE<br />
# 我们这里不将防火墙预设为接收所有封包<br />
#options IPFIREWALL_DEFAULT_TO_ACCEPT </p>
<p>如果您要让桥接器具有流量控制的功能，则可以加上之前提到的选项「options DUMMYNET」。重新编译核心后，在重开机前，我们先设定一下 /etc/rc.conf： </p>
<p>firewall_enable=&#8221;YES&#8221;<br />
firewall_type=&#8221;open&#8221; </p>
<p>还有一件事要做，当在以太网络上跑 IP 协议时，事实上使用二种以太网络协议，一个是 IP，另一个是 ARP。ARP 协定是当机器要找出给定 IP 地址所对应的以太网络地址时使用的。ARP 并不是 IP 层的一部份，只是给 IP 应用在以太网络上运作。标准的防火墙规则中并未加入对于 ARP 的支持，幸运的是，高手们的在 ipfirewall 程序代码中加入了对封包过滤桥接器的支持。如果我们在 IP 地址 0.0.0.0 上建立一个特别的 UDP 规则，UDP 端口的号码将被使用来搭配被桥接封包的以太网络协议号码，如此一来，我们的桥接器就可以被设定成传递或拒绝非 IP 的协议。请在 /etc/rc.firewall 中接近文件顶端处理 lo0 的那三行之下(就是有写 Only in rare cases do you want to change these rules 的地方)加入下面一行： </p>
<p>${fwcmd} add allow udp from 0.0.0.0 2054 to 0.0.0.0 </p>
<p>现在我们就可以重新开机了。重开机之后，先执行下列指令来启动桥接器： </p>
<p>如果您使用的是 FreeBSD 4.x： </p>
<p># sysctl -w net.link.ether.bridge_ipfw=1<br />
# sysctl -w net.link.ether.bridge=1<br />
如果您使用的是 FreeBSD 5.x： </p>
<p># sysctl -w net.link.ether.bridge.ipfw=1<br />
# sysctl -w net.link.ether.bridge.enable=1<br />
现在我们可以将机器放在内外二个网域之间了。因为我们之前在 /etc/rc.conf 中，设定防火墙完全打开，不阻挡任何封包，所以放在二个网域之间时，运作应该没有问题。我们之前只设了一张网络上的 IP，而在执行了上述的指令之后，第二张网络卡便开始运作。 </p>
<p>下一步就是将我们启动桥接器的指令放在 /etc/rc.local 中，让系统在开机时自动执行。或者，我们可以在 /etc/sysctl.conf 中加入下面二行： </p>
<p># 如果您使用的是 FreeBSD 4.x<br />
net.link.ether.bridge_ipfw=1<br />
net.link.ether.bridge=1<br />
# 如果您使用的是 FreeBSD 5.2 以后的版本<br />
net.link.ether.bridge.enable=1<br />
net.link.ether.bridge.ipfw=1 </p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
接下来我们就可以依自己的需求在 /etc/rc.firewall 文件的最后面加上我们自己想要的防火墙规则了。以下是一个简单的设定规则，假设桥接器的 IP 是 140.115.75.137，内部有二台主机，一台提供网页服务，一台是 BBS： </p>
<p>us_ip=140.115.75.137<br />
basrv_ip=140.115.3.4<br />
bbs_ip=140.115.5.6<br />
oif=fxp0<br />
iif=fxp1<br />
ipfw=&#8221;/sbin/ipfw&#8221;<br />
# Things that we&#8217;ve kept state on before get to go through in a hurry.<br />
${ipfw} 1000 add check-state </p>
<p># Throw away RFC 1918 networks<br />
${ipfw} 1100 add deny ip from 10.0.0.0/8 to any in via ${oif}<br />
${ipfw} 1200 add deny log ip from 172.16.0.0/12 to any in via ${oif}<br />
${ipfw} 1300 add deny log ip from 192.68.0.0/16 to any in via ${oif}<br />
# 允许桥接器本身所有想做的联机 (keep state if UDP)<br />
${ipfw} 1400 add pass udp from ${us_ip} to any keep-state<br />
${ipfw} 1500 add pass ip from ${us_ip} to any </p>
<p># 允许内部网络任何想做的联机 (keep state if UDP)<br />
${ipfw} 1600 add pass udp from any to any in via ${iif} keep-state<br />
${ipfw} 1700 add pass ip from any to any in via ${iif} </p>
<p># 允许任何的 ICMP 联机<br />
${ipfw} 1800 add pass icmp from any to any </p>
<p># 不允许使用 port 888 联机<br />
${ipfw} 2000 add deny log tcp from any to ${bbs_ip} 888 </p>
<p># TCP section<br />
# 任何地方都可以建立 TCP 联机<br />
${ipfw} 3000 add pass tcp from any to any via ${oif} </p>
<p># Pass the &#8220;quarantine&#8221; range.<br />
${ipfw} 3100 add pass tcp from any to any 49152-65535 in via ${oif}<br />
# Pass ident probes. It&#8217;s better than waiting for them to timeout<br />
${ipfw} 3200 add pass tcp from any to any 113 in via ${oif}<br />
# Pass SSH.<br />
${ipfw} 3300 add pass tcp from any to any 22 in via ${oif}<br />
# Pass DNS. 当内部网络有名称服务器时才需要<br />
#${ipfw} add pass tcp from any to any 53 in via ${oif}<br />
# 只传递 SMTP 给邮件服务器<br />
${ipfw} 3400 add pass tcp from any to ${bbs_ip} 25 in via ${oif}<br />
${ipfw} 3500 add pass tcp from any to ${basrv_ip} 25 in via ${oif}<br />
# UDP section<br />
# Pass the &#8220;quarantine&#8221; range.<br />
${ipfw} 4000 add pass udp from any to any 49152-65535 in via ${oif}<br />
# Pass DNS. 当内部网络有名称服务器时才需要<br />
#${ipfw} 4100 add pass udp from any to any 53 in via ${oif} </p>
<p># 其它的都拒绝<br />
${ipfw} 60000 add deny ip from any to any</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/433.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
