我的番茄炒蛋
生活如此精彩,挑战无处不在!

导航

 
FreeBSD+IPFILTER实现整网(N个Vlan)透明代理上网
[ 繁体中文/BIG5 ] [ 简体中文/GB ]

--------------------------------------------------------------------------------
UNIX中文宝库 http://www.douzhe.com

2005年04月04日 作者: 转自: 点击: 331
1:前言
我们学校以前是用的教育网,所有办公机器、机房用的都是公网地址,由于前段时间更换网络出口,换为网通的宽带,所以才作了代理,因为学校领导还没完全确定以后还用不用教育网,所以要求下面机器原来的网络设置不能改变,经过自己摸索,加上CU、freebsdchina上面的各位高手帮忙,现在已经全部搞定,实现了透明代理,下面的机器网络设置跟以前用教育网的一样,可以随时再开通教育网,不敢独享,拿出来给大家看看。
另外一点说明,原来的公网地址因为当作私有地址来用了,我下面贴出来的代码均以10.0.*.*这些私网地址代替,这样可能其他兄弟们用的时候更合适一些,外部网通个的公网地址我以a.b.c.d和a1.b1.c1.d1等代替,如果要参考我的使用可换为你们的公网ip。
2:系统安装
用的是最新的5.3release,用最小化安装,因为后面要自己编译内核,就把内核sys装上了,man也是需要的,其他的都不要,因为只作代理,所以连ports都不要。
3:/etc/rc.conf里面的设置
这里要说明一下:我们的内部地址总共用了12个c的地址,10.0.40.0/21和10.1.44.0/22。为了实现整网的机器都能透明的通过代理服务器上网,需要在路由器上把默认路由指向代理服务器的内网网卡地址,我们这里的核心交换是cisco6509,就是一条语句:ip route 0.0.0.0 0.0.0.0 192.168.0.1,这样做还不够,还需要在代理服务器上添加路由,把数据包经由内网网卡返回。代理的内网卡地址我设置的192.168.0.1,它所在vlan网关是192.168.0.2,掩码是255.255.255.252,这个vlan也就192.168.0.1这个地址可用J
下面是rc.conf的内容,我加入了一些优化的选项:

ifconfig_em0="inet a.b.c.d netmask 255.255.255.240"
ifconfig em0 a1.b1.c1.d1 netmask 255.255.255.255 alias
ifconfig_em1="inet 192.168.0.1 netmask 255.255.255.252"

sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
## 关闭SENDMAIL

portmap_enable="NO"
inetd_enable="NO"
kern_securelevel_enable="YES"
kern_securelevel="2"
syslogd_enable="YES"
syslogd_flags="-ss"

firewall_enable="NO"
gateway_enable="YES"

ipfilter_enable="YES"
ipfilter_program="/sbin/ipf"
ipfilter_rules="/etc/ipf.conf"
ipfilter_flags=""
#IPFilter作为kernel,而不是作为模块

ipnat_enable="YES"
ipnat_program="/sbin/ipnat -CF -f"
ipnat_rules="/etc/ipnat.conf"

ipmon_enable="YES"
ipmon -o N > /tmp/nat.log &

static_routes="static1 static2"
route_static1="-net 10.0.40.0 -netmask 255.255.248.0 -gateway 192.168.0.2"
route_static2="-net 10.1.44.0 -netmask 255.255.252.0 -gateway 192.168.0.2"

4:我的ipf.conf文件:
这里我把冲击波等的一些端口给封了,外网网卡上所有来自于10.0.0.0/8等私网地址和发往这些地址的数据包肯定是非法的,所以也给禁止掉,因为我的代理还把内部的一些机器给nat出去对外提供服务,暂时只用了80端口,就只允许了80端口上的数据包经外网网卡进入,其他的都封掉,如果你还需要其他的,可相应的增加规则。

#############优化ipf.conf#########################

block in quick all with ipopts
block in quick all with frag
block in quick all with short

#################################################################
# Resist the attack of the virus
#################################################################
block in quick proto tcp/udp from any to any port 134 >< 140
block in quick proto tcp/udp from any to any port = 445
block in quick proto tcp/udp from any to any port = 593
block in quick proto tcp/udp from any to any port = 333
block in quick proto tcp/udp from any to any port = 5554
block in quick proto tcp/udp from any to any port = 9995
block in quick proto tcp/udp from any to any port = 9996
block in quick proto tcp/udp from any to any port = tftp
block in quick proto tcp/udp from any to any port = 554
block in quick proto tcp/udp from any to any port = 1434
block in quick proto tcp/udp from any to any port = 4444

#################################################################
# Loopback Interface
#################################################################

#----------------------------------------------------------------
# Allow everything to/from your loopback interface so you
# can ping yourself (e.g. ping localhost)
#----------------------------------------------------------------
pass in quick on lo0 all
pass out quick on lo0 all
################################################################

#################################################################
# Inside Interface
#################################################################
#----------------------------------------------------------------
# Allow out all TCP, UDP, and ICMP traffic & keep state
#----------------------------------------------------------------
pass out quick on em1 all head 1
pass out quick on em1 proto tcp from any to any keep state group 1
pass out quick on em1 proto udp from any to any keep state group 1
pass out quick on em1 proto icmp from any to any keep state group 1
block out quick on em1 all group 1
#----------------------------------------------------------------
# Allow in all TCP, UDP, and ICMP traffic & keep state
#----------------------------------------------------------------
pass in quick on em1 all head 2
pass in quick on em1 proto tcp from 10.0.40.0/24 to any port = 22 flags S keep state group 2
block in quick on em1 proto tcp from any to any port = 22 flags S keep state group 2
pass in quick on em1 proto tcp from any to any keep state group 2
pass in quick on em1 proto udp from any to any keep state group 2
pass in quick on em1 proto icmp from any to any keep state group 2
block in quick on em1 all group 2

#################################################################
# Outside Interface
#################################################################
#----------------------------------------------------------------
#Block out all traffic to the private address
#----------------------------------------------------------------
block out quick on em0 all head 11
block out quick on em0 from any to 192.168.0.0/16 group 11
block out quick on em0 from any to 172.16.0.0/12 group 11
block out quick on em0 from any to 10.0.0.0/8 group 11
block out quick on em0 from any to 127.0.0.0/8 group 11
block out quick on em0 from any to 0.0.0.0/8 group 11
block out quick on em0 from any to 169.254.0.0/16 group 11
block out quick on em0 from any to 192.0.2.0/24 group 11
block out quick on em0 from any to 204.152.64.0/23 group 11
block out quick on em0 from any to 224.0.0.0/3 group 11
block out quick on em0 from any to 20.20.20.0/24 group 11

#----------------------------------------------------------------
# Allow out all TCP, UDP, and ICMP traffic & keep state on it
# so that it's allowed back in.
#----------------------------------------------------------------
pass out quick on em0 proto tcp from any to any keep state group 11
pass out quick on em0 proto udp from any to any keep state group 11
pass out quick on em0 proto icmp from any to any keep state group 11
block out quick on em0 all group 11

#----------------------------------------------------------------
#Block in all traffice from the private address
#----------------------------------------------------------------
block in quick on em0 all head 12
block in quick on em0 from 192.168.0.0/16 to any group 12
block in quick on em0 from 172.16.0.0/12 to any group 12
block in quick on em0 from 10.0.0.0/8 to any group 12
block in quick on em0 from 127.0.0.0/8 to any group 12
block in quick on em0 from 0.0.0.0/8 to any group 12
block in quick on em0 from 169.254.0.0/16 to any group 12
block in quick on em0 from 192.0.2.0/24 to any group 12
block in quick on em0 from 204.152.64.0/23 to any group 12
block in quick on em0 from 224.0.0.0/3 to any group 12
block in quick on em0 from 20.20.20.0/24 to any group 12

#----------------------------------------------------------------
# Block all remaining traffic coming into the firewall
#----------------------------------------------------------------
pass in quick on em0 proto tcp from any to any port = 80 flags S keep state group 12
block in quick on em0 all group 12

#############The END############################################

5:我的ipnat.conf文件:

######################ipnat.conf###########################################
map em0 10.0.40.0/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
map em0 10.0.40.0/24 -> a.b.c.d/32 portmap tcp/udp 1025:65500
map em0 10.0.40.0/24 -> a.b.c.d/32
map em0 10.0.41.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.0.41.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.0.41.0/24 -> a1.b1.c1.d1/32
map em0 10.0.42.0/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
map em0 10.0.42.0/24 -> a.b.c.d/32 portmap tcp/udp 1025:65500
map em0 10.0.42.0/24 -> a.b.c.d/32
map em0 10.0.43.0/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
map em0 10.0.43.0/24 -> a.b.c.d/32 portmap tcp/udp 1025:65500
map em0 10.0.43.0/24 -> a.b.c.d/32
map em0 10.0.44.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.0.44.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.0.44.0/24 -> a1.b1.c1.d1/32
map em0 10.0.45.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.0.45.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.0.45.0/24 -> a1.b1.c1.d1/32
map em0 10.0.46.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.0.46.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.0.46.0/24 -> a1.b1.c1.d1/32
map em0 10.0.47.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.0.47.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.0.47.0/24 -> a1.b1.c1.d1/32
map em0 10.1.44.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.1.44.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.1.44.0/24 -> a1.b1.c1.d1/32
map em0 10.1.45.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.1.45.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.1.45.0/24 -> a1.b1.c1.d1/32
map em0 10.1.46.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.1.46.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.1.46.0/24 -> a1.b1.c1.d1/32
map em0 10.1.47.0/24 -> a1.b1.c1.d1/32 proxy port ftp ftp/tcp
map em0 10.1.47.0/24 -> a1.b1.c1.d1/32 portmap tcp/udp 1025:65500
map em0 10.1.47.0/24 -> a1.b1.c1.d1/32
##说明一下,后面的是为了让内网用户也可以通过外部的地址来访问我用rdr转出去的内网的机器。
map em1 10.0.40.0/24 -> a1.b1.c1.d1/32
map em1 10.0.41.0/24 -> a1.b1.c1.d1/32
map em1 10.0.42.0/24 -> a1.b1.c1.d1/32
map em1 10.0.43.0/24 -> a1.b1.c1.d1/32
map em1 10.0.44.0/24 -> a1.b1.c1.d1/32
map em1 10.0.45.0/24 -> a1.b1.c1.d1/32
map em1 10.0.46.0/24 -> a1.b1.c1.d1/32
map em1 10.0.47.0/24 -> a1.b1.c1.d1/32
map em1 10.0.48.0/24 -> a1.b1.c1.d1/32
map em1 10.1.44.0/24 -> a1.b1.c1.d1/32
map em1 10.1.45.0/24 -> a1.b1.c1.d1/32
map em1 10.1.46.0/24 -> a1.b1.c1.d1/32
map em1 10.1.47.0/24 -> a1.b1.c1.d1/32
rdr em1 a1.b1.c1.d1/32 port 80 -> 10.0.43.70 port 80
rdr em0 a1.b1.c1.d1/32 port 80 -> 10.0.43.70 port 80
map em1 10.0.40.0/24 -> a.b.c.d/32
map em1 10.0.41.0/24 -> a.b.c.d/32
map em1 10.0.42.0/24 -> a.b.c.d/32
map em1 10.0.43.0/24 -> a.b.c.d/32
map em1 10.0.44.0/24 -> a.b.c.d/32
map em1 10.0.45.0/24 -> a.b.c.d/32
map em1 10.0.46.0/24 -> a.b.c.d/32
map em1 10.0.47.0/24 -> a.b.c.d/32
map em1 10.0.48.0/24 -> a.b.c.d/32
map em1 10.1.44.0/24 -> a.b.c.d/32
map em1 10.1.45.0/24 -> a.b.c.d/32
map em1 10.1.46.0/24 -> a.b.c.d/32
map em1 10.1.47.0/24 -> a.b.c.d/32
rdr em1 a.b.c.d/32 port 80 -> 10.0.40.59 port 80
rdr em0 a.b.c.d/32 port 80 -> 10.0.40.59 port 80
#########################The end############################################

6:优化内核
mkdir /usr/kern
cp /usr/src/sys/i386/conf/GENERIC /usr/kern/proxy
ln -s /usr/kern/proxy /usr/src/sys/i386/conf/proxy

cd /sys/i386/conf
ee proxy

options IPFILTER #ipfilter support
options IPFILTER_LOG #ipfilter logging
options IPFILTER_DEFAULT_BLOCK #block all packets by default

options TCP_DROP_SYNFIN

options PQ_LARGECACHE
## 为512k二级缓存的CPU提供支持
options SC_DISABLE_REBOOT
##屏蔽Ctrl+Del+Alt热键重启系统

#To make an SMP kernel,the netx two are needed
options SMP #Symmetric MultiProcess Kernel
device apic # I/O APIC
#如果没有双cpu就不需要了

#####加入对polling的支持##################################
#options DEVICE_POLLING
#options HZ=1193
在/sys/kern/kern_pool.c里面找到#error一行删掉。
在/etc/sysctl.conf里面加入 kern.polling.enable=1
DEVICE_POLLING不能跟SMP同时使用,所以本服务器可省略。
###########################################################
其余的优化选项可参考其他内核优化的文章。

7:系统资源优化

ee /etc/sysctl.conf

#######################/etc/sysctl.conf############################################
net.inet.tcp.rfc1323=1
net.inet.tcp.rfc1644=1
net.inet.tcp.rfc3042=1
net.inet.tcp.rfc3390=1
#### 某些加快网络性能的协议,请参考RFC文章。

net.inet.ip.forwarding=1
##作路由必须打开
net.inet.ip.sourceroute=0
net.inet.ip.accept_sourceroute=0
##安全方面的参数

kern.ipc.maxsockbuf=8388608
##最大的套接字缓冲区
kern.ipc.somaxconn=8192
##最大的等待连接完成的套接字队列大小,高负载服务器和受到分布式服务阻塞攻击的系统也许
会因为这个队列被塞满而不能提供正常服务。默认仅为128,根据机器和实际情况需要改动,太大就浪费了内存
kern.maxfiles=65536
##系统中允许的最多文件数量,缺省的是几千个但如果你在运行数据库或大的很吃描述符的进程可以把它设到1万或2万个
kern.maxfilesperproc=32768
##每个进程能够同时打开的最大文件数量
net.inet.tcp.delayed_ack=0
##当一台计算机发起TCP连接请求时,系统会回应ACK应答数据包。该选项设置是否延迟ACK应答数据包,把它和包含数据的数据包一起发送,在高速网络和低负载的情况下会略微提高性能,但在网络连接较差的时候,对方计算机得不到应答会持续发起连接请求,反而会降低性能。
net.inet.tcp.sendspace=65535
##最大的待发送TCP数据缓冲区空间,应用程序将数据放到这里就认为发送成功了,系统TCP堆栈保证数据的正常发送
net.inet.tcp.recvspace=65535
##最大的接受TCP缓冲区空间,系统从这里将数据分发给不同的套接字,增大该空间可提高系统瞬间接受数据的能力以提高性能。
net.inet.udp.recvspace=65535
##最大的接受UDP缓冲区大小
net.inet.udp.maxdgram=57344
##最大的发送UDP数据缓冲区大小
net.local.stream.recvspace=32768
##本地套接字连接的数据接收空间
net.local.stream.sendspace=65535
##本地套接字连接的数据发送空间
net.inet.icmp.drop_redirect=1
net inet.icmp.log_redirect=1‘
net.inet.ip.redirect=0
#net.inet6.ip6.redirect=0
##屏蔽ICMP重定向功能
net.inet.icmp.bmcastecho=0
net.inet.icmp.maskrepl=0
##防止广播风暴
net.inet.icmp.icmplim=100
##限制系统发送ICMP速率
net.inet.icmp.icmplim_output=0
net.inet.tcp.drop_synfin=1
##安全参数,编译内核的时候加了options TCP_DROP_SYNFIN才可以用
net.inet.tcp.always_keepalive=0
##设置为1会帮助系统清除没有正常断开的TCP连接,这增加了一些网络带宽的使用,但是一些死掉的连接最终能被识别并清除。死的TCP连接是被拨号用户存取的系统的一个特别的问题,因为用户经常断开modem而不正确的关闭活动的连接。
net.inet.ip.intr_queue_maxlen=1000
##若看到net.inet.ip.intr_queue_drops这个在增加,就要调大net.inet.ip.intr_queue_maxlen,为0最好

####以下为防止dos攻击#####
net.inet.tcp.msl=7500
##freebsd默认为30000
net.inet.tcp.blackhole=2
##接收到一个已经关闭的端口发来的所有包,直接drop,如果设置为1则是只针对TCP包
net.inet.udp.blackhole=1
##接收到一个已经关闭的端口发来的所有UDP包直接drop
########end#################

net.inet.ipf.fr_tcpidletimeout=7200
net.inet.ipf.fr_tcpclosewait=60
net.inet.ipf.fr_tcplastack=120
net.inet.ipf.fr_tcptimeout=120
net.inet.ipf.fr_tcpclosed=60
net.inet.ipf.fr_udptimeout=90
net.inet.ipf.fr_icmptimeout=35
net.inet.ipf.fr_tcphalfclosed=300
net.inet.ipf.fr_defnatage=600

net.inet.tcp.inflight.enable=1
## 为网络数据连接时提供缓冲
net.inet.ip.fastforwarding=0
##如果打开的话每个目标地址一次转发成功以后它的数据都将被记录进路由表和arp数据表,节约路由的计算时间,但会需要大量的内核内存空间来保存路由表。

#kern.polling.enable=1
##打开POLLING功能
##SMP不能和polling一起用
#########################The end##################################################

8:设置rc.sysctl, rc.conf 和 sysctl.conf 权限:

chmod 600 /etc/rc.sysctl
chmod 600 /etc/rc.conf
chmod 600 /etc/sysctl.conf


9:优化启动选项
##################编辑/boot/loader.conf优化启动########

autoboot_delay="2"
## 设置启动等待时间为2秒。

kern.ipc.nmbclusters="32768"
##设置系统的mbuf大小,系统的缓冲区

kern.ipc.maxsockets="16384"
## 增大线程间套接数量

net.inet.tcp.tcbhashsize="10240"
## 增大TCP控制块数量

beastie_disable="YES"
## 关闭小恶魔图像启动菜单
#############################################


10:增强ipfilter功能

修改/sys/contrib/ipfilter/netinet/ip_nat.h,把里面的LARGE_NAT前面的注释去掉,改为#define LARGE_NAT

修改/sys/contrib/ipfilter/netinet/ip_state.h

IPSTATE_SIZE 64997
IPSTATE_MAX 45497

IP_STATE_MAX=IPSTATE_SIZE*0.7左右
第一个可以调到10万左右
注意都要是质数
11:
##############打系统补丁以后重新编译内核#############

cd /usr/src
fetch http://people.freebsd.org/~delphij/patch-SMP
patch < patch-SMP
重新编译内核并重新启动。
#这是针对5.3 SMP的delphij大哥做的补丁,

cd /sys/contrib/ipfilter/netinet/
patch < patch-ip_nat.c
#这个是针对ip_nat的一个补丁,也可以自己手动注释,改了ip_nat的参数以后编译内核会提示两个变量没有定义。

cd /usr/src
make buildkernel KERNCONF=proxy
make installkernel KERNCONF=proxy
reboot
这种编译方法将保留原来的kernel为kernel.old,
这样如果你做错了什么,就有机会通过boot:出现时输入kernel.old来恢复。

######如果用config/make编译内核的会在/usr/src产生很多中间文件#########
cd /usr/src/sys/i386/conf
/usr/sbin/config proxy
cd ../compile/proxy
make depend
make
make install
reboot
#########################################################################


12:自动备份日志
目前方法不太成熟,我曾经试过把nat.log清空,但是也许是因为系统正在频繁的写入该文件,所以我只能是先暂停记录,备份完记录以后再重新开始记录,好在我是一个小时备份一个日志文件,拷贝这一小时的记录不用很长时间的,所以基本上不会少记录东西的,看到本文的兄弟们如果有更好的切实可行的方法,望告诉我一声,多谢!

#################/usr/local/beifen.sh
#!/bin/sh
year=$(date +%Y)
month=$(date +%m)
date=$(date +%d)
time=$(date +%Y%m%d%H%M)
mkdir -p /usr/local/logbak/$year/$month/$date
killall ipmon
cp /var/nat.log /usr/local/logbak/$year/$month/$date/$time.log
cat > /var/nat.log<<END
END
/sbin/ipmon -o N > /var/nat.log &
#############################################

chmod +x /usr/local/beifen.sh

crontab -e
编辑一个文件:

0 0 * * * /usr/local/beifen.sh
0 1 * * * /usr/local/beifen.sh
0 2 * * * /usr/local/beifen.sh
0 3 * * * /usr/local/beifen.sh
2 3 * * 1 /sbin/reboot
0 4 * * * /usr/local/beifen.sh
0 5 * * * /usr/local/beifen.sh
0 6 * * * /usr/local/beifen.sh
0 7 * * * /usr/local/beifen.sh
0 8 * * * /usr/local/beifen.sh
0 9 * * * /usr/local/beifen.sh
0 10 * * * /usr/local/beifen.sh
0 11 * * * /usr/local/beifen.sh
0 12 * * * /usr/local/beifen.sh
0 13 * * * /usr/local/beifen.sh
0 14 * * * /usr/local/beifen.sh
0 15 * * * /usr/local/beifen.sh
0 16 * * * /usr/local/beifen.sh
0 17 * * * /usr/local/beifen.sh
0 18 * * * /usr/local/beifen.sh
0 19 * * * /usr/local/beifen.sh
0 20 * * * /usr/local/beifen.sh
0 21 * * * /usr/local/beifen.sh
0 22 * * * /usr/local/beifen.sh
0 23 * * * /usr/local/beifen.sh

13:后记
本文参考了网上太多的资料,已经记不清这里的每一行选项都是参考的哪篇文章了,在此对曾经对我有帮助的文章的作者们标识诚挚的感谢!因为你们的无私,整个世界才能加快进步的步伐,本文大家可随意转载,注不注明作者都无所谓,因为这里面毕竟几乎全部都是参考大家的文章写的,原创的甚少,我只是做了个整理、实验的工作而已。
如果您愿意就我文中的内容进行探讨,可在本贴回复,或者email:wuming122@eyou.com,小弟洗耳恭听,还是我自己的网站http://freebsd.jzu.cn上面的宣言写的那句话:自由是FreeBSD的目的,共享是FreeBSD走向自由的必经之路^_^
文中所提的步骤就是我在调试我们的代理服务器过程中以ssh登录以后作的,您完全可以在安装完基本的系统以后以ssh登录,根据您的实际网络环境对我的文章进行修改以后复制粘贴即可,不需要一行一行的输入,那样太麻烦了J
posted on 2006-12-15 08:43  bluesky  阅读(801)  评论(0编辑  收藏  举报