服务器 频道

用ipfilter在动态ip环境下做重定向

    【IT168 服务器学院】用ipfilter在动态ip环境下做重定向

    欢迎斧正,转载必须保留版权信息

    在ipfilter的nat规则中,如果出口ip地址是动态ip,比如PPPoE拨号或DHCP,那么可以使用类似
map tun0 192.168.0.0/24 -> 0.0.0.0/32 的语法进行地址(端口)映射;可是类似
rdr tun0 0/32 port rtsp -> 192.168.2.100 port rtsp tcp/udp这样的语法却是不对的,因为rdr
    规则要求第三个域是ip包的目的地址,通常是该出口网卡的地址,显然,当别人访问你的机器的时候tcp/udp包的目的地址是你的当前地址,而不是0/32,所以,rdr tun0 0/32 ...这样的规则是不会生效的,你必须以该网卡的当前ip地址来做这个规则;ipfilter本身没有提供这样的定义使得我们可以方便的做这样的规则,下面是我做的脚本,用来动态的获得当前出口网卡地址,并一次刷新ipfilter规则。

    1。内核中编译ipfilter的支持,不能让ipfilter以模块的形式载入;
    因为我没有在/etc/rc.conf中指定ipfilter_enable="yes";
    2。编制如下shell script;

    #!/bin/sh
    #vi /usr/local/sbin/ipf.sh
    #此脚本用来刷新ipf规则;
    #注意/etc/ipf.rules是根据/etc/ipf.rules.template这个模板自动生成的;
    #所以,如果你要改规则,应该改/etc/ipf.rules.template这个模板;
    #For dynamic ip ipf rules
    #$EXT_NIC is the internet connected NIC
    #$EXT_ADDR is the internet connected NIC ADDRESS.

    #get dynamic nic.
    #获得默认路由经过的网卡,即所谓的外网网卡;
    EXT_NIC=`netstat -arn | grep "default\>" | awk ''{print $6 }''`
    if [ -z $EXT_NIC ];
    then
    echo "ERROR default gateway NO found !!!"
    exit 1
    else
    export EXT_NIC
    #get dynamic nic and ip.
    #获得外网卡地址;
    EXT_ADDR=`ifconfig $EXT_NIC | grep "inet\>" | awk ''{print $2}''`
    if [ -z $EXT_ADDR ];
    then
    echo "ERROR:EXT_ADDR NO found !!!"
    exit 1
    else
    export EXT_ADDR
    #根据上述信息参照模板生成规则;
    echo "#NOTE:" >/etc/ipf.rules
    echo "#DON''T modify /etc/ipf.rules for your ipf rules ,Just    modify /etc/ipf.rules.template instance !!!" >>/etc/ipf.rules
    echo "#Read /usr/local/sbin/ipf.sh for detail." >>/etc/ipf.rules
    echo "#." >>/etc/ipf.rules
    echo "#Reflashed date:`date`." >>/etc/ipf.rules
    sed s/\$EXT_NIC/$EXT_NIC/g /etc/ipf.rules.template >/etc/ipf.rules.nic
    sed s/\$EXT_ADDR/$EXT_ADDR/g /etc/ipf.rules.nic >>/etc/ipf.rules
    #刷新规则;
    /sbin/ipf -Fa
    /sbin/ipf -y -f /etc/ipf.rules
    fi
    fi
    #end /usr/local/sbin/ipf.sh

    #!/bin/sh
    #vi /usr/local/sbin/ipnat.sh
    #此脚本用来刷新ipnat规则;
    #注意/etc/ipnat.rules是根据/etc/ipnat.rules.template这个模板自动生成的;
    #所以,如果你要改规则,应该改/etc/ipnat.rules.template这个模板;
    #For dynamic ip ipnat rules
    #$EXT_NIC is the internet connected NIC
    #$EXT_ADDR is the internet connected NIC ADDRESS.

    #get dynamic nic.
    #获得默认路由经过的网卡,即所谓的外网网卡;
    EXT_NIC=`netstat -arn | grep "default\>" | awk ''{print $6 }''`
    if [ -z $EXT_NIC ];
    then
    echo "ERROR default gateway NO found !!!"
    exit 1
    else
    export EXT_NIC
    #get dynamic nic and ip.
    #获得外网卡地址;
    EXT_ADDR=`ifconfig $EXT_NIC | grep "inet\>" | awk ''{print $2}''`
    if [ -z $EXT_ADDR ];
    then
    echo "ERROR:EXT_ADDR NO found !!!"
    exit 1
    else
    export EXT_ADDR
    #根据上述信息参照模板生成规则;
    echo "#NOTE:" >/etc/ipnat.rules
    echo "#DON''T modify /etc/ipnat.rules for your nat rules ,Just modify /etc/ipnat.rules.template instance !!!" >>/etc/ipnat.rules
    echo "#Read /usr/local/sbin/ipnat.sh for detail." >>/etc/ipnat.rules
    echo "#." >>/etc/ipnat.rules
    echo "#Reflashed date:`date`." >>/etc/ipnat.rules
    sed s/\$EXT_NIC/$EXT_NIC/g /etc/ipnat.rules.template >/etc/ipnat.rules.nic
    sed s/\$EXT_ADDR/$EXT_ADDR/g /etc/ipnat.rules.nic >>/etc/ipnat.rules
    #刷新规则;
    /sbin/ipnat -C
    /sbin/ipnat -v -f /etc/ipnat.rules
    fi
    fi
    #end /usr/local/sbin/ipnat.sh

    #!/bin/sh
    #vi /usr/local/sbin/ipfrenew
    #调用预先编制的脚本刷新ipf以及ipnat规则;
    /usr/local/sbin/ipf.sh
    /usr/local/sbin/ipnat.sh
    #显示当前状况;
    /sbin/ipnat -l |grep -v ''<- -> ''
    echo List of active sessions have been cutted.
    /sbin/ipfstat -if
    /sbin/ipfstat -of
    #end of /usr/local/sbin/ipfrenew

    #设置可执行;
    chmod 700 /usr/local/sbin/*

    3。在会更换ip的程序中调用/usr/local/sbin/ipfrenew
    PPPoE:

    #vi /etc/ppp/ppp.linkup
    default:
    pppoe:
    shell "/usr/local/sbin/ipfrenew"
    #end of /etc/ppp/ppp.linkup

    #假设你的PPPoE配置名称叫pppoe;

    DHCP(Cable modem):

    #!/bin/sh
    #vi /etc/dhclient-exit-hooks
    /usr/local/sbin/ipfrenew
    #end of /etc/dhclient-exit-hooks

    #至于说调用的语法,自己查man,都说的很清楚了;

    #罗嗦一句,如果你不怕麻烦,这个方法用在固定ip的环境也是可以的,就是要在/etc/rc.local中调用/usr/local/sbin/ipfrenew,不能依赖
    #/etc/rc.conf中的ipfilter_enable设置;因为当系统处理ipfilter_enable设置时,还没有设置default gateway;

    #begin of /etc/ipnat.rules.template
    rdr $EXT_NIC $EXT_ADDR/32 port 5022 -> 192.168.1.82 port 22
    rdr $EXT_NIC $EXT_ADDR/32 port 5023 -> 192.168.1.82 port 23
    rdr $EXT_NIC $EXT_ADDR/32 port 9900 -> 192.168.1.82 port 9900

    # For 192.168.0.0/24
    # ------------------------------------------------------------
    # Use ipfilter FTP proxy for hosts behind NAT doing transfer
    # mode active.
    # ------------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32 proxy port ftp ftp/tcp

    # -----------------------------------------------------------
    # Use ipfilter IKE proxy for ESP packets for hosts behind NAT
    # IP Filter 3.4.21 and beyond only.
    # -----------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32 proxy port 500 ipsec/udp

    # -----------------------------------------------------------
    # Use ipfilter RealAudio proxy for hosts behind NAT
    # -----------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32 proxy port 7070 raudio/tcp

    # -----------------------------------------------------------
    # Use ipfilter H323 proxy for hosts behind NAT
    # -----------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32 proxy port 1720 h323/tcp

    # -----------------------------------------------------------
    # Map all internal UDP and TCP traffic to the external IP address
    # -----------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32 portmap tcp/udp 40000:60000

    # -----------------------------------------------------------
    # Map all other traffic e.g. ICMP to the external IP address
    # -----------------------------------------------------------
    map $EXT_NIC 192.168.0.0/24 -> $EXT_ADDR/32
    #end of /etc/ipnat.rules.template

    #begin of /etc/ipf.rules.template
    #ipfilter default to pass;
    block in log quick all with ipopts
    block in log quick all with short
    block in log quick all with frag

    block in log on $EXT_NIC all
    block out log on $EXT_NIC all

    block in quick on $EXT_NIC from 10.0.0.0/8 to any
    block in log quick on $EXT_NIC from 192.168.0.0/16 to any
    block in log quick on $EXT_NIC from 172.16.0.0/12 to any
    block in log quick on $EXT_NIC from 127.0.0.0/8 to any
    block in log quick on $EXT_NIC from 169.254.0.0/16 to any

    pass in on $EXT_NIC proto icmp from any to any icmp-type echo
    pass in on $EXT_NIC proto icmp from any to any icmp-type echorep

    #for http and https
    pass in quick on $EXT_NIC proto tcp from any to any port = 80 keep state
    pass in quick on $EXT_NIC proto tcp from any to any port = 443 keep state

    #for mail
    pass in quick on $EXT_NIC proto tcp from any to any port = 25 keep state
    pass in quick on $EXT_NIC proto tcp from any to any port = 110 keep state

    pass out quick on $EXT_NIC proto tcp/udp from any to any keep state
    pass out quick on $EXT_NIC proto icmp from any to any keep state

    block return-rst in log on $EXT_NIC proto tcp from any to any
    block return-icmp-as-dest(port-unr) in log on $EXT_NIC proto udp from any to any
    #end of /etc/ipf.rules.template  

0
相关文章