首页 安全基础 网络安全 安全协议 病毒分析 防火墙 OS安全 无线安全 Web安全 PKI与PMI 入侵检测 经典案例
安全审计 设备安全 安全管理 安全标准 法律法规 隔离网闸 DB安全 XML安全 开源项目 资源下载 安全论坛 备份恢复
 当前位置:首页>>防火墙>>iptables>>正文
透明防火墙架设的完全攻略(bridge+iptables+squid)
文章出处:www.linuxts.com   发布时间:2005-06-12   点击:0
 

 ---- 架设透明代理和防火墙是linux平台上很热的话题,在水木上也有相关文章,但完全的攻略在公网上也很少,最近架了一台,前后花去一个多星期(我这人手脚慢,别笑,中间笑话也颇多)觉得还是把过程写下来的好,可以让人依葫芦画瓢。

 ---- 先把网络环境说一下,一个200人左右的局域网,一个C class,一台路由器做NAT(一个公网ip)。网络环境还是很简单的,目的就是在路由器和局域网间加一台透明防火墙进去,同时完成cache server的功能。我不想让防火墙做nat,一是因为已经有了一台路由器,要物尽其用。二是 nat其实也是很耗资源的事(尤其当下面的clients特别多时,对router cpu的要求还是很高的,我就碰到过一台cisco 75XX 路由器拖1000个用户5分钟死一次机的事,后来不得已架了一台PIX做NAT)还是分分开的好。三是万一cache server 趴下了,只要把链路重新旁接一下,网络照样用(顶多性能不好),不会影响用户。

 ---- 防火墙的平台为一P4 2.4G server, 512M内存,2×80GHD,两块NIC。安装的是RH8.0 kernel 2.4.20(原来想装gentoo的,但要命的1.4到现在才刚到RC3,等不及了,偷了一把懒~_~)

 ---- 先下载bridge做桥接,bridge的作用就是让两块网卡变成一个桥设备,让两端的网络端口完全透明地转发packets,而让 iptables起到blocking的作用。下载地址为http://bridge.sourceforge.net(什么?sourceforge?不知道上不去啊!没办法,因为众所周知的原因,大伙找https proxy绕上去吧!)需下载bridge-utils-0.9.6.tar.gz和 bridge-nf-0.0.7-against-2.4.19.diff。(这个很重要,否则iptables无法拦截转发过来的packets)

 ---- 再到http://netfilter.samba.org下载iptables,并到www.linuxhq.xom下载最新的kernel及patch。

 ---- 在/usr/src下释放kernel,进入/usr/src/linux,并把bridge的patch打上,patch –p1 < bridge-nf-0.0.7-against-2.4.19.diff.

 ---- 最后还有个问题,此时用ifconfig看到的流量,在过了4G之后就会被置0,然后从头开始,很不爽。这是因为 'RX bytes' and 'TX bytes'等变量的数据类型为 unsigned long,即2^32,到了4G就重置,其实把它们改成 unsigned long long(2^64)就可以了。更改
/usr/src/linux/include/linux/netdevice.h 和../linux/net/core/dev.c,以下是打patch时的记录,找到文件改掉相应代码即可。

   diff -urN linux-orig/include/linux/netdevice.h linux/include/linux/netdevice.h 
   --- linux-orig/include/linux/netdevice.h 
   +++ linux/include/linux/netdevice.h 
   @@ -96,10 +96,10 @@ 


struct net_device_stats 
   { 
   - unsigned long rx_packets; /* total packets received */ 
   - unsigned long tx_packets; /* total packets transmitted */ 
   - unsigned long rx_bytes; /* total bytes received */ 
   - unsigned long tx_bytes; /* total bytes transmitted */ 
   + unsigned long long rx_packets; /* total packets received */ 
   + unsigned long long tx_packets; /* total packets transmitted */ 
   + unsigned long long rx_bytes; /* total bytes received */ 
   + unsigned long long tx_bytes; /* total bytes transmitted */ 
   unsigned long rx_errors; /* bad packets received */ 
   unsigned long tx_errors; /* packet transmit problems */ 
   unsigned long rx_dropped; /* no space in linux buffers */ 

   diff -urN linux-orig/net/core/dev.c linux/net/core/dev.c 
   --- linux-orig/net/core/dev.c 
   +++ linux/net/core/dev.c 
   @@ -1689,7 +1689,7 @@ 
   int size; 


if (stats) 
   - size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu %8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu ", 
   + size = sprintf(buffer, "%6s:%8llu %7llu %4lu %4lu %4lu %5lu %10lu %9lu %8llu %7llu %4lu %4lu %4lu %5lu %7lu %10lu ", 
   dev->name, 
   stats->rx_bytes, 
   stats->rx_packets, stats->rx_errors, 

 ---- 这样编译后,ifconfig的4G重置问题就被消除了。

 ---- 下面就是重新编译kernel了,make menuconfig.....
注意,除了要把该编译进去的驱动编进去(象NIC什么的,我第一次编时就漏了一块网卡,汗ing)还要把最重要的iptables给enable 起来,进入Network Options,选中Network Packet filtering (replaces ipchains),这样就会打开IP: Netfilter Configuration --> 子菜单,进入,选中里面所有的选项,然后回到 Network Options菜单,选中“802.1d Ethernet Bridging” 和 “netfilter (firewalling) support”两个选项(一看就知道很重要。)
退出,开编。
   make dep
   make modules
   make modules_install
   make bzImage
 ---- 完成后cp /usr/src/linux/arch/i386/bzImage /boot/bzImage.bridge
 ---- 然后把System.map拷至/boot下再在lilo或grub中更改相应配置即可(这就不细说了,重编kernel的文章到处都有。)

 ---- 重起,如果正常,开始下一步,tar –xzvf bridge-utils-0.9.6.tar.gz. 
    cd ./bridge-utils-0.9.3
    make 
    make install(编译bridge并安装,具体的安装目录可在make文件生成时指定。)
 ---- 完毕后可以先试试bridge的基本命令。如brctl addbr mybridge (创建bridge mybridge,然后用ifconfig查看会发现多了一个mybridge端口)
  brctl addif mybridge eth0 
  brctl addif mybridge eth1 (把eth0和eth1包含到mybridge中)
 ---- 然后需要对各端口做以下动作
   ifconfig eth0 0.0.0.0 promisc 
   ifconfig eth1 0.0.0.0 promisc(打开混杂模式)
 ---- 这时桥接即已成功,从router和局域网转发过来的消息开始通过机器,这时你会发觉满屏的tcp/ip转发消息让你无法下手,硬盘也狂转,这是 syslogd和klogd做的怪,log的priviledge设得太低,改掉它。telnet 进入机器(这时你只能telnet,console上已经泛滥成灾。)kill 掉syslogd和klogd,在/etc/syslog.conf中屏蔽掉*.info至 /var/log/messages的rules(一开始我不知道这个,结果第一天下午连到网络上去,第二天上午一看,/var/log下的 messages居然有2.7G,My God),并修改/etc/init.d/syslog,在daemon klogd 一项后加上-2 -c 4 (提高klogd的消息转发级别),重起syslogd,哈哈,整个世界清净了!!!

 ---- 其实我们也可以写个启动脚本放在/etc/init.d中,如下:
   #!/bin/bash

.  /etc/init.d/functions


   return=$rc_done


start() {
   echo "Starting service bridge tranfw"
   brctl addbr tranfw || return=$rc_failed
   brctl addif tranfw eth0 || return=$rc_failed
   brctl addif tranfw eth1 || return=$rc_failed
   ifconfig eth0 0.0.0.0 promisc || return=$rc_failed
   ifconfig eth1 0.0.0.0 promisc || return=$rc_failed
   brctl sethello tranfw 1 || return=$rc_failed
   brctl setmaxage tranfw 4 || return=$rc_failed
   brctl setfd tranfw 4 || return=$rc_failed
   ifconfig tranfw 192.168.9.11 broadcast 192.168.9.255 promisc up || return=$rc_failed
   /sbin/route add default gw 192.168.9.1 netmask 0.0.0.0 metric 1 
   echo -e "$return"
   }

stop() {
   echo "Shutting down service bridge tranfw"
   brctl delif tranfw eth0 || return=$rc_failed
   brctl delif tranfw eth1 || return=$rc_failed
   brctl delbr tranfw || return=$rc_failed
   echo -e "$return"
   }

status(){
   ifconfig tranfw
   brctl show tranfw
   }

restart(){
   $0 stop && $0 start || return=$rc_failed
   }

   case "$1" in
   start)
   start
   ;;
   stop)
   stop
   ;;
   restart)
   restart
   ;;
   status)
   status tranfw
   RETVAL=$?
   ;;
   *)
   echo $"Usage: $0 {start|stop|status|restart}"
   RETVAL=1

   esac

   exit $RETVAL

 ---- 这样启动时就自己起来了。

 ---- 下一步,我们可以开始配iptables了
   tar –xjvf iptables-1.2.7.tar.bz2
   cd ./iptables-1.2.7
   make
   make install
 ---- 安装很简单。关键是如何用,我懒,抄了个脚本就开用了,如下:
   #!/bin/bash
   #Flush all rules from the chains
   iptables -F
   #Delete all user created chains (mainly KEEP_STATE chain)
   iptables -X

#############################################################
   ##Create special chain KEEP_STATE
   iptables -N KEEP_STATE
   iptables -F KEEP_STATE
   ##Drop bad states
   iptables -A KEEP_STATE -m state --state INVALID -j DROP
   iptables -A KEEP_STATE -m state --state RELATED,ESTABLISHED -j ACCEPT
#############################################################

   #Drop RST/ACKs to limit OS detection through pinging
   iptables -A FORWARD -p tcp --tcp-flags RST RST,ACK -m limit --limit 5/minute -j LOG --log-level notice --log-prefix    "RST/ACK: "
   iptables -A FORWARD -p tcp --tcp-flags RST RST,ACK -j DROP

   #Deny pings from outside
   iptables -A FORWARD -p icmp --icmp-type 0/0 -d 192.168.9.0/24 -j ACCEPT
   iptables -A FORWARD -p icmp --icmp-type 0/0 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Drop Echo Reply: "
   iptables -A FORWARD -p icmp --icmp-type 0/0 -j DROP

   #Drop potential SQL Worm
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 1433 -j ACCEPT
   iptables -A FORWARD -p tcp --dport 1433 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Possible SQL Worm: "
   iptables -A FORWARD -p tcp --dport 1433 -j DROP

   #Pass all boxes to the keep_state chain
   iptables -A FORWARD -j KEEP_STATE

######################################################################
   ##Set up UDP
   #Outgoing Traceroute
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --sport 32769:65535 --dport 33434:33523 -j ACCEPT

   #Incoming Traceroute
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --dport 32769:65535 --sport 33434:33523 -j ACCEPT

   #Time exceeded
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --dport 11 -j ACCEPT

   #Port not found
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --dport 3 -j ACCEPT

   #DNS
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --dport 53 -j ACCEPT

   #SNMP
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --dport 161 -j ACCEPT

   #DHCP
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --sport 68 --dport 67 -j ACCEPT

   #Time Server
   iptables -A FORWARD -p udp -s 192.168.9.0/24 --sport 1024:65535 --dport 123 -j ACCEPT

######################################################################
   ##Allow outward browsing
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 80 -j ACCEPT

   ##Allow outward ssh
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 22 -j ACCEPT

   ##Allow outward ftp
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 21 -j ACCEPT

   ##Allow outward telnet
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 23 -j ACCEPT

   ##Allow outward smtp
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 25 -j ACCEPT

   ##Allow outward pop
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 110 -j ACCEPT

   ###Block HTTP Request from outside that are not authorized
   iptables -A FORWARD -p tcp --dport 80 -j DROP
   iptables -A FORWARD -p tcp --dport 80 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Dropped HTTP: "

   #Allow Telnet out
   iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 23 -j ACCEPT

   #Deny ports
   ##telnet
   iptables -A FORWARD -p tcp --dport 23 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Denied Telnet: "

   #Deny ports
   ##telnet
   iptables -A FORWARD -p tcp --dport 23 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Denied Telnet: "
   iptables -A FORWARD -p tcp --dport 23 -j DROP

   ##Deny BO
  iptables -A FORWARD -p udp --dport 31337 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Denied BO: "
   iptables -A FORWARD -p udp --dport 31337 -j DROP

   #Deny and log ftp on all others
   #iptables -A FORWARD -p tcp -s 192.168.9.0/24 --dport 21 -j DROP
   #iptables -A FORWARD -p tcp --dport 21 -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "Denied FTP: "

   #Deny suspicious traffic 
   iptables -A FORWARD -p tcp --destination-port 1080 -j DROP
   iptables -A FORWARD -p tcp --destination-port 8080 -j DROP
   iptables -A FORWARD -p tcp --destination-port 8000 -j DROP
   iptables -A FORWARD -p tcp --destination-port 8081 -j DROP

   ##Allow all outgoing traffic
   iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 3128 (转发至squid)
   iptables -A FORWARD -s 192.168.9.0/24 -j ACCEPT

   #Set to drop all packets not accepted by rules above
   iptables -A FORWARD -j DROP

 ---- 也把它放到/etc/init.d中,这样就可以随着xinet.d一起启动了。iptables的语法这里就不详细说了,网上很多。

 ---- 最后就是squid的配置,这需要仔细说一下,随RH发布的squid的配置有问题,性能受限。建议先卸除,到www.squid-cache.org下载最新的2.5stable1。然后重新编译,编译前需做以下准备工作:
   1。编辑/usr/include/bits/types.h中__FD_SETSIZE值至32768
   2。ulimit -HSn 32768
 ---- 然后到squid src包目录编译squid ,./configure, make all, make install.....
 ---- squid会安装在缺省的/usr/local/squid下,squid的可执行文件在安装目录的bin子目录下,配置文件在etc子目录下

 ---- Squid配置文件为:/usr/local/squid/etc/squid.conf,以下为我的配置:
   http_port 8080
   cache_mem 32 MB
   cache_swap_low 90
   cache_swap_high 95
   maximum_object_size 4096 KB
   cache_dir ufs /usr/local/squid/cache 10000 16 256
   cache_access_log /usr/local/squid/logs/access.log
   cache_log /usr/local/squid/logs/cache.log
   dns_nameservers 202.96.209.5
   unlinkd_program /usr/local/squid/bin/unlinkd
   acl acllist src 192.168.9.0/255.255.255.0
   acl regular_days time MTWHF 8:00-19:00
   acl movie urlpath_regex "/etc/squid/banned.list"(把过滤关键字写到文件中去)
   acl banned url_regex iij4u.or.jp(做些控制)
   acl cache_prevent1 url_regex cgi-bin /?
   acl cache_prevent2 url_regex Servlet
   acl all src 0.0.0.0/0.0.0.0
   acl manager proto cache_object
   acl localhost src 127.0.0.1/255.255.255.255
   acl SSL_ports port 443 563
   acl Safe_ports port 80 # http
   acl Safe_ports port 21 # ftp
   acl Safe_ports port 443 563 # https, snews
   acl Safe_ports port 70 # gopher
   acl Safe_ports port 210 # wais
   acl Safe_ports port 1025-65535 # unregistered ports
   acl Safe_ports port 280 # http-mgmt
   acl Safe_ports port 488 # gss-http
   acl Safe_ports port 591 # filemaker
   acl Safe_ports port 777 # multiling http
   http_access deny movie regular_days
   no_cache deny cache_prevent1
   no_cache deny cache_prevent2
   http_access deny banned
   http_access allow all
   http_access deny !Safe_ports
   http_access deny CONNECT !SSL_ports
   icp_access allow all
   http_access allow manager localhost
   http_access deny manager
   http_access allow localhost
   http_access deny all
   client_lifetime 2 hours
   half_closed_clients off
   cache_effective_user squid
   cache_effective_group squid(请注意squid对cache及log目录有读写权)
   httpd_accel_host virtual
   httpd_accel_port 80
   httpd_accel_with_proxy on
   httpd_accel_uses_host_header on 

 ---- 同时在/etc/init.d中的启动脚本里加上这句ulimit -HSn 32768
 ---- 这样squid启动时在cache.log中就可以看到如此语句:
    2003/03/05 09:30:53| Starting Squid Cache version 2.5.STABLE1-20030303 for i686-pc-linux-gnu...
    2003/03/05 09:30:53| Process ID 12939
    2003/03/05 09:30:53| With 32768 file descriptors available

 ---- 此时的squid拥有32768个file descriptors(缺省为1024),如果用户很多,缺省值会成为瓶颈,极度影响squid的速度(它会报错说running out of file descriptors),我曾经在板上发问,结果没人理我(,还是自力更生,丰衣足食。

 ---- 启动squid:/usr/local/squid/bin/squid -D

大功告成!整个出internet的http流量就全朝squid走了,用户不知道,同时又可完成封锁的功能。(linux知识宝库)

 

作者:
[返回顶部↑]  [推荐好友] [查看评论]  
用户名: 新注册) 密码: 匿名评论 [查看评论]  发表评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 
↑文章搜索
  关键字:  
  范  围:  
  开始搜索  
※相关文章※
 

◎Linux 2.4中netfilter框架

 
※热点文章※
  ·Linux 2.4中netfilter框架
·建立一个带宽、线程可控的
·用iptables实现NAT
·防火墙之基础篇(iptable)
·iptables应用之动态DNS
·怎样用ipchains构建防火墙
·高性能LINUX双效防火墙HOW
 

关于我们 | 征搞启示 | 版权信息 | 联系我们 | 友情链接

版权所有:中国信息安全组织 © 2003-2005 Power by DedeCms