1. 最大化安全設置
鎖定一臺用作NAT防火牆的電腦的第一步是停止所有安裝時不需要的服務。編輯/etc/rc.conf並確認inetd、portmap、sendmail這些守護者都被禁止了。除了設置
inetd_enable="NO"
portmap_enable="NO"
sendmail_enable="NO"
之外,爲了以防萬一,最好將/etc/inetd.conf中關於這些服務的設置註釋掉。如果確實需要遠程登陸,那麼應該安裝ssh並且家上
sshd_enable="YES"
到/etc/rc.conf。一旦你禁用了所有不需要的服務,你就可以到http://www.unixcircle.com/memberonly/portscan.php3去進行一次遠程掃描,以便確認設置正確。注意別在防火牆裏面進行這樣的掃描,否則你得到的結果將是你的防火牆是否安全!如果沒有條件出國的話,也可以用NetScanTools這樣的工具,不過一定要確認你掃描的時候用的是當前子網外面的電腦。用CVSup獲得一份最新的穩定版(-STABLE)FreeBSD源碼也非常重要,因爲和Windows一樣,FreeBSD也需要經常打補丁。
2. 設置網卡
爲了便於說明,我們假定你的計算機是用兩塊3com 509B網卡,並且它們對應的FreeBSD驅動的名字分別是ep0和ep1。當然,如果你不太喜歡3com,或者無論如何總之和我們用的不太一樣的話,就把下面的對應ep0、ep1換成你需要的名字。第一塊網卡將根據rfc1918使用不可路由的私有地址,而第二塊則可以制定一個靜態或動態的DHCP地址。
爲了方便你的設置,這裏引用一下那些不可路由的私有地址:
10.0.0.1 - 10.255.255.254 掩碼(netmask) 255.0.0.0
172.16.0.1 - 172.31.255.254 掩碼 255.240.0.0
192.168.0.1 - 192.168.255.254 掩碼 255.255.0.0
在這裏我們選用192.168.0.1(很多人都這麼做),在/etc/rc.conf中設置
ifconfig_ep0="inet 192.168.1.1 netmask 255.255.255.0"
這樣第一塊網卡就能用了。如果第二塊網卡打算是用靜態IP,則在/etc/rc.conf中這樣配置:
ifconfig_ep1="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"
這裏的IP和掩碼(xxx部分)根據你的實際情況設置就可以了。相反,使用動態IP(DHCP):
ifconfig_ep1="DHCP"
並且要根據需要設置/etc/dhclient.conf
一定要確認你在兩塊網卡上都使用了正確的IP和掩碼,而一旦確認了內部網的IP範圍就不要改變。第一塊網卡的IP地址將是內部網的默認網關地址。
3. 設置kernel
想編譯新的kernel,首先需要的是源代碼(通常這是你拿到的發行版本的一部分)。如果你沒有安裝它,那麼就運行/stand/sysinstall來裝上。然後執行下面的命令
# cd /sys/i386/conf
# cp GENERIC firewall
當然,我這麼命名是因爲那臺機器叫firewall,這樣便於記憶,當然你也可以使用其它的名字。編輯kernel配置文件:# vi firewall 在options小節中加入以下幾行:
# 添加IPFilter、記錄支持
options IPFILTER
options IPFILTER_LOG
# 默認禁止所有的包傳遞
options IPFILTER_DEFAULT_BLOCK
# 使用RANDOM_IP_ID阻止外界瞭解網關生成包的情況
options RANDOM_IP_ID
去掉所有和你的硬件無關的硬件相關options。一個比較有效的確定方法是觀察dmesg輸出。查看和kernel文件處於同一目錄的LINT可以幫助你瞭解全部可用設置。修改完配置文件,重新制作、安裝kernel:
# cd /usr/src
# make buildkernel KERNCONF=firewall
(kernel編譯的輸出結果)
# make installkernel KERNCONF=firewall
# reboot
這種編譯方法將保留原來的kernel爲kernel.old,這樣如果你做錯了什麼,就有機會通過boot:出現時輸入kernel.old來恢復。
4. 打開包轉發、dhcp、防火牆和NAT功能
打開包轉發功能:在/etc/sysctl.conf中加入
net.inet.ip.forwarding=1
加強轉發安全性:
在/etc/sysctl.conf中作相應修改可以實現:
防禦基於rfc1948的序號攻擊,方法是使用隨機的初始序號
net.inet.tcp.strict_rfc1948=1
驗證進入的包的目的地址正確性
net.inet.ip.check_interface=1
增強性能:
net.inet.tcp.recvspace=65535
net.inet.tcp.sendspace=65535
過濾規則:
如果不知道應該禁止什麼包的通過,則需要打開它們。在/etc/ipf.rules中加入:
pass in all
pass out all
NAT(網絡地址翻譯)規則:
爲了讓NAT後面的NAT和ftp可以正常工作,在/etc/ipnat.rules中加入:
# 在“主動”模式中使用ipfilter ftp proxy
map ep1 192.168.1.0/24 -> 0.0.0.0/32 proxy port ftp ftp/tcp
# 將所有來自192.168.1.0/24的tcp和udp連接映射到外部IP
# 並且將端口號改爲40000到60000的不衝突的數(如果你監聽OICQ端口會發現很多人這樣做)
map ep1 192.168.1.0/24 -> 0.0.0.0/32 portmap tcp/udp 40000:60000
# 把其他IP包映射到外部IP地址
map ep1 192.168.1.0/24 -> 0.0.0.0/32
注意,所有的proxy行應該放到通用portmap行之前,因爲只有首先匹配的行起作用。
透明代理:
如果在內部網有一個地址爲192.168.1.2的郵件服務器,則需要使用rdr來進行透明代理。由於NAT在rdr之前生效,因此需要在/etc/ipf.rules中加入一個pass in規則,這樣才能把翻譯過的包發到郵件服務器上來。
/etc/ipnat.conf:
# 將進入的smtp數據重定向到NAT裏面的郵件服務器上
rdr ep1 0.0.0.0/0 port 25 -> 192.168.1.2 port 25
/etc/ipf.rules:
# 允許包括碎片和SYN標誌的經過翻譯的包進入。
pass in quick on ep1 proto tcp from any to any port = 25 flags S keep state keep frags
均衡負載:
爲了在NAT後面的6臺鏡象web服務器實現均衡負載,使用round-robin語句。IPFilter將把負載均衡分配給這些服務器,甚至在某臺down掉的情況下。
rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.1,192.168.1.2 port 80 tcp round-robin
rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.3,192.168.1.4 port 80 tcp round-robin
rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.5,192.168.1.6 port 80 tcp round-robin
現在,在/etc/rc.conf中打開NAT/防火牆功能:
ipfilter_enable="YES" #打開防火牆
ipfilter_flags="" #IPFilter作爲kernel,而不是作爲模塊
ipnat_enable="YES" #NAT
ipmon_enable="YES" #記錄防火牆的信息
ipmon_flags="-Dsn"
-D: ipmon作爲守護者程序(daemon)加載
-n: 可能的情況下將IP地址和端口號映射成主機名和服務名
-s: 將包的信息送到syslogd而不是保存成文件
5. 配置NAT後面的機器
所有內部網的機器必須進行配置,用剛纔那臺FreeBSD網關的內部IP作爲默認網關。假設我們的網關地址是192.168.1.254,則:
FreeBSD:在 /etc/rc.conf 中加入 defaultrouter="192.168.1.254"
Linux Redhat:在 /etc/sysconfig/network 中加入 GATEWAY=192.168.1.254
NetBSD: echo "192.168.1.254" > /etc/mygate
OpenBSD: echo "192.168.1.254" > /etc/mygate
Solaris: echo "192.168.1.254" > /etc/defaultrouter
Win2k: 開始-設置->控制面板->網絡與撥號連接->局域網->屬性->Internet 協議 (TCP/IP)->默認網關->192.168.1.254
6. 熟悉IPFilter
一旦NAT/防火牆連入了Internet,就應該看看http://www.unixcircle.com/ipf的IPFILTER-HOWTO這篇文章,並且在/etc/ipf.rules加入一些禁止規則。某些比較有用的信息可以在www.ipfilter.org主頁找到。每次修改/etc/ipf.rules或/etc/ipnat.rules之後,需要讓他們生效。重新加載規則將斷開所有已經存在的連接。
# /sbin/ipf -Fa -f /etc/ipf.rules
# /sbin/ipnat -CF -f /etc/ipnat.rules
查看防火牆的統計信息:
# /sbin/ipfstat -t
查看ipfilter的版本:
# /sbin/ipf -V
查看當前的映射/重定向設置:
# /sbin/ipnat -l
其它的課以查看ipftest(1), mkfilters(1), ipf(4), ipl(4), ipf(8), ipfstat(8), ipmon(8), ipnat(8)的說明。
7. QoS
限制帶寬:
FreeBSD包括了dummynet帶寬管理機制。dummynet可以阻止潛在的超速連接阻塞另一個慢速連接。man dummynet(4)可以得到更多的說明。由於dummynet和ipfw -- FreeBSD專用防火牆捆綁在一起,因此你需要在設置dummynet的同時加入3個ipfw設置到kernel中。
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_DEFAULT_TO_ACCEPT
options DUMMYNET
並且重新編譯kernel,重啓。
在/etc/rc.conf中設置dummynet:
firewall_enable="YES"
firewall_script="/etc/rc.dummynet"
firewall_type="open"
firewall_logging="YES"
假設你擁有一條快速以太網出口,並且需要把它限制在普通以太網的速度:建立一個從192.168.1.4到任意目的地址的pipe 1:
# /sbin/ipfw add 100 pipe 1 ip from 192.168.1.4 to any
將管道限制在10Mbits/s:
# /sbin/ipfw pipe 1 config bw 10Mbit/s
可以建立不同的、針對不同速度、協議的管道。需要刪掉所有的管道時,執行:
# /sbin/ipfw flush
需要自動設置管道,把他們加入/etc/rc.dummynet.