茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671954 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_0056.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

小企鵝開談 : [分享]一張網卡 bind 兩個不同網段的 IP

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]簡易 NAT 伺服器
什麼是 NAT 呀:
    我想,大家對於 NAT 一定是有所耳聞才對,不過,到底什麼是 NAT 呢?NAT
    其實是 Network Address Translation 的簡寫,字面上的意思是『網路位址的傳送』,他主要的功能就是在提供內部私有網路的電腦之頻寬分享了。簡單的說,NAT
    的功能就是『 IP 分享器』咯!(註:NAT 主機的功能相當的多,不過,這裡我們僅說明頻寬分享的部分!)。
     

    NAT 的功能
     
    我們由 網路基礎 當中知道,要能夠連接上
    Internet 必須要具有『公共 IP (Public IP)』才行,內部私有
    IP (Private IP) 是不能直接與 Internet 進行資料溝通的。好了,今天假設您是一家公司的主管,或者是一間學校的資訊主任,而且您所負責的單位內有
    20 部電腦好了,這 20 部電腦都需要能夠連上 Internet ,並可以進行任何 Internet
    的服務要求,請問您是否需要具備有 20 個公共 IP 呢?如果真的要提供 20 個公共
    IP 的話,以最經濟的價格來說,我們可以申請 Seednet 的 512/64 (下載/上傳)
    撥接制 ADSL ,每個專線都可以具有五個 IP ,因為我們有 20 部主機,所以就需要四條電話線~呵呵!怕了吧!光是接線與申請
    ADSL 的流程就會讓人崩潰,更不用說申請到之後還需要在每一部電腦上面設定撥接、管制電腦使用性、進行防毒等等的工作,光是用想的,就已經很頭大了,更不用說實際去作.....
     
    那麼應該要怎麼辦呢?比較聰明的朋友已經想到要去買 IP 分享器來分享網路頻寬了!那麼
    Linux 是否能夠達到 IP 分享器的功能!?當然可以啦!那就是 NAT 主機的能力之一囉!我們在之前的Router
    設定
    當中,提過路由的概念了,封包的傳送主要是透過路由的資訊,但是,私有路由是不能直接與
    Internet 溝通的啊!因此用 Linux 作為 Router 時,如果 Linux 主機本身就是僅有私有
    IP ,自然也就無法直接連接到 Internet 上面去了。
     
    到底該如何是好?呵呵!這個時候就得要回頭談一談 TCP 封包的概念咯。由
    網路基礎 章節裡面提到的TCP
    封包的架構圖
    ,我們可以發現 TCP 封包裡頭有來源與目的地的 IP 及 port
    的資訊在 Header 裡面,那麼如果透過某些技術,來改變 TCP 封包的 header 呢?如果能夠將
    TCP 封包的來源 IP 由本來的 Private IP 變成 Public IP 的話,不就可以連接到
    Internet 了嗎?!呵呵!沒錯沒錯!談到重點了!就是這樣啦!NAT
    主機的重要功能之一就是將來自內部 Client 端電腦封包的 Header 的 IP 『偽裝』成公共
    IP ,而提供 Client 端連上 Internet 的一個方法
    !(註:當然啦,
    IP 分享器也是使用同樣的道理!
    )。那麼 Linux 是用什麼機制達到這樣的功能?還記得簡易防火牆設定當中提到的
    iptables 吧?!iptables 可以進行封包的分析,當然,他還可以進行封包資訊的修改呢!那麼整個流程是如何呢?如下圖所示,當我的區域內的具有
    192.168.1.100 的 client 要對外連線的時候:
     

     
    1. 這個 client 的 gateway 設定為 NAT 主機,所以當要連上
      Internet 的時候,該封包就會被送到 NAT 主機啦,這個時候的封包 Header 之
      source IP 為 192.168.1.100 喔;
    2. 而透過這個 NAT 主機,她會將 client 的對外連線封包的
      source IP ( 192.168.1.100 ) 偽裝成 ppp0 ( 假設為撥接情況 )這個介面所具有的公共
      IP 囉,因為是公共 IP 了,所以這個封包就可以連上 Internet 了!同時 NAT 主機並且會記憶這個連線的封包是由哪一個
      ( 192.168.1.100 ) client 端傳送來的;
    3. 由 Internet 傳送回來的封包,當然由 NAT 主機來接收了,這個時候,
      NAT 主機會去查詢原本記錄的路由資訊,並將目標 IP 由 ppp0 上面的公共 IP 改回原來的
      192.168.1.100 ;
    4. 最後則由 NAT 主機將該封包傳送給原先發送封包的 Client
      囉!

     
    如果是在 iptables 的內建 table 當中,與 NAT 有關的就是 nat table 的
    POSTROUTING 那個鏈了!就是簡易防火牆當中的圖九的示意圖喔!也就是說,整個封包其實只有經過
    NAT 主機的 iptables 機制在偽裝 IP 與修改路由資訊而已,並沒有進入 NAT 主機內部啦!
    ^_^!由上面的資訊我們可以知道一件事,那就是:『您的
    NAT 主機至少需要有一個私有 IP 與一個公共 IP 才行
    』喔!而且,『NAT
    主機,一般來說,也是一部 Router 喔!
    』如果 Router
    兩邊都是私有 IP 或都是公共 IP 時,Linux 主機只要有 Router 的功能即可,若是兩邊分別為公共與私有
    IP 時,才需要以 iptables 來啟動 NAT 的功能

     
    其實 NAT 的功能也可以簡單的這樣想:『當您在私人賽車場上比賽的時侯,不必管您是否有註冊過的車牌﹔但開到馬路上卻非得要一個監理站核發的車牌不可。如果您要將跑車開到街道上,必須要改掛一個合法的車牌。這時候,賽車場老闆(NAT)自有辦法幫您弄一個就是了。』!這樣可以瞭解了嗎?
     

    連線示意圖:
     
    由上面的說明您應該可以瞭解了吧?!沒錯,您的 NAT 主機上面,至少需要『兩塊網路介面』請注意,鳥哥說的是『網路介面』而不是『網路實體介面卡』呦!以撥接為例,由於撥接之後會產生
    ppp0 這個撥接後產生的網路介面,加上原本的實體網路介面,那麼自然就有兩個以上的網路介面囉!這麼說應該很容易瞭解了嗎?底下我以兩塊實體網路介面卡的佈線情況作為連線的示意圖,至於一塊網路卡進行
    NAT 的圖示,將在待會說明囉。

圖一、兩塊網路卡的 NAT 主機配置
    在上面的圖示當中,很清楚吧!我們的 Linux 共有兩塊實體介面卡,一塊接在
    數據機 上面,一塊接在 Hub/Switch 上面,並且以此 Hub/Switch 連接所有的區域網路內的電腦,以組成內部的私有網域!鳥哥個人是比較喜歡這樣的接線方式啦!不過,人人各有其所好,而且這樣的情況也不見得適合所有的人,所以還是得瞭解一下其他種類的連接方法!好吧,等一下再告訴您~
    ^_^""
     

    核心版本:
     
    我們在簡易防火牆設定當中就提過了,核心與防火牆機制是有關係的,也就是:
     
    • Kernel 2.2.xx :使用 ipchains
      做封包偽裝的技術;
    • Kernel 2.4.xx :使用 iptables
      做封包偽裝的技術!

     
    所以,還是請仔細的檢查一下您的核心版本吧!(用 uname
    -r 來察看)。簡單的判別方法,如果是 Red Hat 7.0 ( 含 7.0 )以前的版本,使用的是
    2.2.xx 的核心,自然只有 ipchains 而已,而如果是 Red Hat 7.1 ( 含 7.1 )
    以後的版本,則使用的是 Kernel 2.4.xx ,因此最好使用 iptables 的技術!因為
    2.4.xx 的 IP 處理模組當中,大部分都是針對 iptables 來作為處理的軟體, ipchains
    的模組已經不含在 2.4.xx 裡頭了!由於我是以 Red Hat 7.2, 7.3 與 9 作為範例的,所以自然以
    iptables 為準囉!如果還想要以 ipchains 來進行架設 NAT 的朋友,不妨參考一下底下這篇:
     
     

    誰需要 NAT
    架設:

     
    由前面 NAT( Network Address Translation ) 的功能介紹,我們知道他可以作為頻寬分享的主機,當然也可以管理一群在
    NAT 主機後面的 Client 電腦!呵呵!所以 NAT 的功能至少有這兩項:

     
    • 頻寬分享:我想,架設
      NAT 的朋友大部分都是希望可以達到頻寬分享的目的的!這畢竟是 NAT 主機的最大功能囉!
    • 安全防護:咦!關安全防護什麼事呀!?別忘了,
      NAT 之內的 PC 連線到 Internet 上面時,他所顯示的 IP 是 NAT 主機的公共 IP
      ,所以 Client 端的 PC 當然就具有一定程度的安全了!最起碼人家在進行 port
      scan 的時候,就偵測不到您的 Client 端的 PC 啦!安全多了!

NAT
的設定:
    NAT 的設定可以使用一塊網路卡,當然也可以使用兩塊網路卡啦!鳥哥個人還是比較建議使用兩塊網路卡來完整的隔開私有網域的內外部分,畢竟還是比較安全一些!不怕內部私有網域的高手作怪啊!
    ^_^
     

    一塊網路卡的
    NAT 架設:

     
    剛剛上面我們已經提過了,要架設 NAT 的話,只要『兩塊網路介面』就夠了,倒不一定需要兩塊『實體網路卡(
    NIC )』,是的!所以鳥哥先以較為便宜的方式(因為少了一塊網路卡呀!)來介紹
    NAT 的架設!底下是我們介紹的安裝步驟:
     
    1. 關閉一些系統服務的
      port

    2. 為了安全起見,還是檢查一下吧!首先,我們需要先來瞭解一下我的 Linux
      主機的功用為何?!如果只是單純的要作為 NAT 的話,那麼
      Linux 主機所開放的 port 是越少越好
      !鳥哥可不希望您開機了大約一個星期,就開始苦苦哀嚎說自己的主機無法以
      root 登入了......。關閉 port 的方法與選擇『系統一定需要的服務』的介紹在限制連線的埠口
      裡面已經說的很清楚了!我以 Red Hat 9 來說明:
      1. 使用 ntsysv
      設定開機時啟動的服務項目:

      [root@test
      root]#
      ntsysv

      只要選擇底下幾個服務即可:
      atd, cron,
      iptables, keytables, network, random, syslog, xinetd

      2. 重新開機讓設定生效:
      [root@test
      root]#
      reboot

      3. 觀察目前的
      port 開啟多少個?

      [root@test
      root]#
      netstat -an | more

      Active Internet
      connections (servers and established)

      Proto Recv-Q
      Send-Q Local Address
      Foreign Address State

      Active UNIX
      domain sockets (servers and established)

      Proto RefCnt
      Flags Type
      State I-Node Path

      unix
      7 [ ]
      DGRAM
      944 /dev/log

      unix
      2 [ ]
      DGRAM
      3162963

      unix
      2 [ ]
      DGRAM
      739227

      unix
      2 [ ]
      DGRAM
      739189

      unix
      2 [ ]
      DGRAM
      1070

      unix
      2 [ ]
      DGRAM
      953

      unix
      2 [ ]
      STREAM CONNECTED 690

      # 注意:盡量不要看到有
      LISTEN 的咚咚!最多就是有 ssh 就好了!除非您有其他的服務!

       
    3. 實體線路配置圖

    4. 怎麼安裝連線呢?趕快買線材來架設吧!由於 Linux 主機只有一張網路卡,所以所有的裝置(包括
      Linux 主機, client 端電腦, 數據機等等)都需要接在 Hub/Switch 上面,有點像底下的樣子:
       

      圖二、一塊網路卡的 NAT 主機配置

       
      這個時候請特別留意啦!如果是使用 ADSL 撥接制的話,那麼在 Linux 主機上應該會有安裝
      rp-pppoe 這個東西,並且在撥接之後會產生 ppp0 這個網路介面,同時不要忘了,啟動網路卡的時候不是就已經有
      eth0 這個實體網路界面的設定嗎?,嘿嘿!那麼我們不是就有兩個網路介面了嗎?!沒錯!就是這樣!但是,如果是
      Cable 或者是其他的固定制的方法的話,那麼跟這個也差不多啦!不過由於 Cable
      的方式沒有自動產生兩個以上的網路界面,所以就需要設定 IP Alias 囉,也就是
      eth0:0 啦!亦即就是以 eth0 跟 eth0:0 這兩個介面來連線囉!反正,只有一張網路卡,也可以進行
      NAT 的啦! ^_^""
       
    5. 設定網路介面

    6. 我們分別以撥接、 Cable 及固定 IP 為例啦!
       
        ADSL撥接制 :
        在進入 Linux 並啟動網路卡之後,我們會得到 eth0
        這個界面,再加上撥接之後的 ppp0 界面,所以我們就已經會有個兩網路介面,分別是
        ppp0,
        eth0
        !此外,我預計的私有網域的 IP 選用 192.168.1.0/24
        這個 C Class 的網域,其中, Linux NAT 主機的私有 IP 選擇為 192.168.1.2
        這一個!

         
        • 第一個網路介面 -- ppp0 -- 的設定:這個東西應該不難吧!就是我們在連上
          Internet
          一文裡頭提到的關於rp-pppoe
          的撥接上網方式。

        •  
        • 實體網路卡 -- eth0 -- 的設定:請注意,如果您要同時使用
          ppp0 及 eth0 ,那麼請在撥接之前啟動 eth0 吧!以取得內部的 eth0 這個網路界面的設定!(
          註:如果您不知道如何設定的話,那麼就請照我的方式來填寫即可 ):
        • [root@test
          root]#
          vi /etc/sysconfig/network-scripts/ifcfg-eth0

          DEVICE=eth0
          BOOTPROTO=static
          BROADCAST=192.168.1.255
          IPADDR=192.168.1.2
          NETMASK=255.255.255.0
          NETWORK=192.168.1.0
          ONBOOT=yes
          <==重要的地方在這裡!請設定為 yes 呦!

          # 如果您不曉得應該如何設定的話,就照上面的打就好了!
           
        Cable 浮動式:
        在 Cable 的情況又不太相同了!這個時候只有兩塊網路介面,分別是
        eth0, eth0:0
        囉!設定為:
         
        • 實體網路卡 -- eth0 -- 的設定:請注意,由於
          cable 使用的是 DHCP 主機,所以這個時候請特別留意您底下的設定呦!( 註:如果您不知道如何設定的話,那麼就請照我的方式來填寫即可
          ):
        • [root@test
          root]#
          vi /etc/sysconfig/network-scripts/ifcfg-eth0

          DEVICE=eth0
          BOOTPROTO=dhcp
          <==這裡最重要!

          BROADCAST=192.168.100.255
          IPADDR=192.168.100.1
          NETMASK=255.255.255.0
          NETWORK=192.168.100.0
          ONBOOT=yes
          # 如果您不曉得應該如何設定的話,就照上面的打就好了!
           
        • 虛擬網路介面 --eth0:0 的設定:在 IP
          Alias 的設定當中,我們已經在 Router 當中說明過多次了!請務必回到該章節再閱讀一次,如果您不記得如何設定的原理的話!
        • [root@test
          root]#
          vi /etc/sysconfig/network-scripts/ifcfg-eth0:0

          DEVICE=eth0:0
          BOOTPROTO=static
          BROADCAST=192.168.1.255
          IPADDR=192.168.1.2
          NETMASK=255.255.255.0
          NETWORK=192.168.1.0
          ONBOOT=yes
          # 如果您不曉得應該如何設定的話,就照上面的打就好了!

           
        固定 IP 的情況:
        跟 cable 的設定幾乎一模一樣,只有兩個介面,分別是
        eth0, eth0:0
        ,需要特別注意的是 eth0 這個東西,您必須要『填寫正確的
        IP, netmask, network, broadcast 而且 ONBOOT=yes 才可以!』,而 eth0:0 則與上面相同!
         
        啟動私有網域的 IP 網路介面:
        啟動之後順便觀察一下路由的資訊!
        [root@test
        root]#
        ifdown eth0

        [root@test
        root]#
        ifup eth0

        [root@test
        root]#
        route

        Kernel IP routing
        table

        Destination
        Gateway Genmask
        Flags Metric Ref Use Iface

        swks81-1.adsl.s
        *
        255.255.255.255 UH 0 0
        0 ppp0

        192.168.1.0
        *
        255.255.255.0 U 0
        0 0 eth0

        127.0.0.0
        *
        255.0.0.0 U
        0 0
        0 lo

        default
        swks81-1.adsl.s 0.0.0.0
        UG 0 0
        0 ppp0

        # 嘿嘿!這樣就是成功啦!注意,上面這個路由是以
        adsl 撥接為例的!

         
    7. 設定其他檔案

    8. 還有一些網路的相關檔案要設定呦!/etc/hosts, /etc/resolv.conf, /etc/sysconfig/network,
      別忘了我們還有其他的檔案要設定呦!很重要的:
      1. 將私有 IP
      加入到 /etc/hosts 裡面去吧!

      [root@test
      root]#
      vi /etc/hosts

      127.0.0.1
      localhost

      192.168.1.1
      linux001

      192.168.1.2
      linux002

      .......(略)......
      192.168.1.100
      linux100

      .......(略)......
      192.168.1.254
      linux254

      2. 將 DNS 的
      IP 寫到 /etc/resolv.conf 裡面去,這裡以中華電信跟 Seednet 為例

      [root@test
      root]#
      vi /etc/resolv.conf

      nameserver
      168.95.1.1

      nameserver
      139.175.10.20

      3. 設定主機名稱跟
      gateway 與否:

      [root@test
      root]#
      vi /etc/sysconfig/network

      NETWORKING=yes
      HOSTNAME=your.domain.name<==寫您的主機名稱
      GATEWAY=
      <==除非您是固定制的,不然這個不要填入任何東西!


       
    9. 設計 NAT 的 shell
      scripts

    10. 直接將一些指令寫在 scripts 裡頭執行較快啦!正確的情況之下,目前您的
      Linux 主機上面應該是已經可以正常的對外連線的才對!而且內部也已經可以正確的連線成功了才對!如果還沒有成功的話,請趕快再到區域網路設定
      裡頭去查一查資料去!好了,接著下來只要執行一個程式,嘿嘿!就可以將 NAT
      啟動喔!這個就好玩了!因為基本上,我們使用的是 iptables 這個東西,自然就需要這個
      ip_tables 的模組了!而查看模組與載入模組的指令分別為 lsmod,modprobe
      哩!好了,您可以直接在命令提示字元底下進行工作:
      echo "1" >
      /proc/sys/net/ipv4/ip_forward

      modprobe ip_tables
      modprobe ip_nat_ftp
      modprobe ip_nat_irc
      modprobe ip_conntrack
      modprobe ip_conntrack_ftp
      modprobe ip_conntrack_irc
      /sbin/iptables
      -F

      /sbin/iptables
      -X

      /sbin/iptables
      -Z

      /sbin/iptables
      -F -t nat

      /sbin/iptables
      -X -t nat

      /sbin/iptables
      -Z -t nat

      /sbin/iptables
      -P INPUT DROP

      /sbin/iptables
      -P OUTPUT ACCEPT

      /sbin/iptables
      -P FORWARD ACCEPT

      /sbin/iptables
      -t nat -P PREROUTING ACCEPT

      /sbin/iptables
      -t nat -P POSTROUTING ACCEPT

      /sbin/iptables
      -t nat -P OUTPUT ACCEPT

      /sbin/iptables
      -t nat -A POSTROUTING -o ppp0 -s 192.168.1.0/24 -j MASQUERADE

      還記得我們在簡易防火牆設定裡面有提供一支script
      吧?那支 script 名為 iptables.rule
      ,該 script 同時可以提供 NAT 的功能喔!完整的 script 請前往該章節觀看,這裡鳥哥僅以
      ADSL 撥接的 NAT 主機為例來介紹需要更改的地方:
      [root@test
      root]#
      cd /usr/local/virus/iptables

      [root@test
      iptables]#
      vi iptables.rule

      #!/bin/bash
      #...(略)...
      # 設定對外的網路介面
      EXTIF="ppp0"
      # 設定對內的網路介面與內部私有網域的設定
      INIF="eth0"
      INNET="192.168.1.0/24"
      # This is for NAT's network

      #....(略)....

      if [ "$INIF" != "" ]; then


      /sbin/iptables -A INPUT -i $INIF -j ACCEPT


      echo "1" > /proc/sys/net/ipv4/ip_forward


      /sbin/iptables -t nat -A POSTROUTING -s $INNET -o $EXTIF -j MASQUERADE

      fi
      #...(略)...

      這支程式當中,只要修改 EXTIF 及 INIF 與內部網域表示方法 (INNET) ,再藉由最後面那一行設定偽裝(MASQUERADE)的功能,呵呵!整個
      NAT 以及基本的主機防護就已經 OK 囉!相當的簡單吧!詳細的 iptables.rule
      的安裝方法,請往前翻到簡易防火牆設定當中去搞定喔!^_^!如果執行無誤,就可以將這支
      script 寫在您的 /etc/rc.d/rc.local 裡面囉!
       
    11. Client 端的設定參數:包含的是網路的設定參數而已!這個等一下我們在用戶端設定當中再講!

     

    兩塊網路卡的
    NAT 架設

     
    真是的,這個部分的連線架設在 區域網路連線
    當中已經提過很多遍了!這裡不再重複的說明!僅列出幾個重要的地方,基本上,跟剛剛一張網路卡的設定方式幾乎完全相同,只是那個
    eth0:0 變成了 eth1 而已啦!鳥哥的設定為:
     
    • eth0 為對內的實體網路卡,具有私有
      IP ,其 IP 為 192.168.1.2 。
    • eth1 為對外的實體網路卡,被用來進行
      ADSL 的撥接,所以開機的時候不要設定 on !

     
    同樣的,我們的設定方式為:
     
    1. 關閉一些系統服務的 port :與前一節相同!

    2.  
    3. 實體線路配置圖:與圖一的配置相同。

    4.  
    5. 設定網路介面

    6. 重要的地方在安裝第二塊網路卡!安裝網路卡的相關技巧請前往 連上
      Internet
      參考!不過,對於第二塊網路卡的安裝,在這裡有些建議:基本上,第二張網路卡最好不用使用與第一張相同晶片的卡,例如您第一張卡使用
      RTL 8139,那第二張卡最好使用別的卡。因為鳥哥曾經發現,在鳥哥的 RedHat 6.1
      英文版中,安裝兩塊相同的 ( 同公司出的 ) RTL8139 ,結果竟然兩張卡的輸出輸入都是經由第一張!也就是說,第二張卡根本就沒有用處!並且,也很容易發生
      eth1 與 eth0 捉錯的情況!所以,請記得,『第二張網路卡盡量不要使用與第一張網路卡相同晶片的卡!』當然,您要使用同一個晶片的網路卡也是可以啦!目前我的機器上面就是使用兩塊
      RTL8139 的網路卡。不過,在安裝的時候請特別留意,不要同時安插兩塊,最好是一塊安裝完畢之後,再安裝另一塊!會比較好一點啦!安裝的步驟可以是(請注意,我以
      ADSL 撥接為例的,其中, eth0 為對內, eth1 為對外,請依照您的設定來修正呢!
      ):
       
      • 關機、硬體安裝:這個不用再提了吧!,先關機,然後拆開外殼,插入PCI網路卡即可;
      • 開機、硬體掃瞄:然後再開機,而於開機的過程中,您的
        Linux 會主動去找到這一張網路卡(如果這張卡是有被 Linux 支援的!);
      • 安裝網路卡驅動程式:如果在上一步驟中,您的網路卡並不能被捉到,哪就比較傷腦筋!請到連上
        Internet
        參考網路卡的驅動程式安裝方法
      • 檢視設定 /etc/sysconfig/network-scripts/ifcfg-eth1:在安裝完了網路卡的驅動程式之後,在
        /etc/sysconfig/network-scripts/ 中,應該會有 ifcfg-eth1 這一個檔案。請設定他吧!因為是對外卡,我這裡假設他是利用
        ADSL 撥接的,所以可以是這樣:
      • [root@test
        root]#
        vi /etc/sysconfig/network-scripts/ifcfg-eth1

        DEVICE=eth1
        BOOTPROTO=static
        BROADCAST=192.168.0.255
        IPADDR=192.168.0.2
        NETMASK=255.255.255.0
        NETWORK=192.168.0.0
        ONBOOT=no
        <==這裡很重要!對外用來撥接的卡不要在開機的時候啟動啦!

         
      這樣就成功囉!很簡單吧! ^_^""
       
    7. 設定其他檔案

    8. 其他一些網路的相關檔案也要設定!亦即/etc/hosts, /etc/resolv.conf, /etc/sysconfig/network,設定的方式跟前一小節相同!
       
    9. 設計 NAT 的 shell scripts

    10. 基本上,設定的方式跟上面也是一模一樣的啦!您依舊可以僅使用前一小節的script
      來進行 NAT 的設定,只是要注意那個粗體字部分的設定,如果您跟我的情況不同,那麼就需要修改一下啦!趕快下載
      script
      吧!
       

    觀察路由資訊:
     
    在整個 NAT 的設定當中,最經典的錯誤連線訊息來自於 路由資訊
    的錯誤啦!這個在我們的 連上 Internet
    網路偵測 文章當中已經說明過了,不過,我們這裡再次提醒一下!免得您又犯了同樣的錯誤了!由於網路在進行連接的時候,都會指定所謂的
    router 或者是 gateway 的設定,除非是來自於廣播的網域之連線。而我們在設定網路時,常常會犯了一個錯誤,那就是指定錯了
    Gateway 了!請您參考一下連上 Internet
    一文
    的設定方式,在 ADSL 撥接及 Cable 連線時,請『務必』不要設定 gateway
    才好!
     
    再來,請常下達 route 的指令來觀察一下您的
    linux 主機的路由設定是否正確呦!

客戶端的設定
在 Client 端的設定真是簡單的可以了!由於我們上面的網域設定的是
192.168.1.0/24 這個 C Class 的私有網域,所以您只要記得幾件事情:
  1. network 設定需要為: 192.168.1.0
  2. broadcast 設定需要為: 192.168.1.255
  3. netmask 設定需要為 255.255.255.0
  4. IP 設定需要為 192.168.1.1 ~ 192.168.1.254 之一,且『不能重複』
  5. Gateway 或者說是 通訊閘 需要設定為您的 Linux 的對內
    IP ,以我的例子來說,就是 192.168.1.2 !
  6. DNS 的設定:這個最容易出錯了,您的 DNS 設定需要是您的
    ISP 給您的 DNS IP,如果您不知道的話,可以填入 168.95.1.1 這一個中華電信的
    DNS 或者是 139.175.10.20 這一個 SeedNet 的 DNS 即可!千萬不要設定為 192.168.1.2
    呦!會連不出去!

大致上就是這樣啦!至於 Client 端通常是 Windows ,相關的設定可以前往參考一下區域網路設定一文說!至於
Linux 端則需要查看一下 連上 Internet
裡面的固定 IP 的設定啦!
安全性:
請注意,在這個例子當中,我們並沒有使用到封包分析的動作,有的只有
IP 偽裝而已,所以:

  • 對於 Client 端來說,由於已經經過了 IP 偽裝的功能,所以基本上,您通過 NAT
    主機連出去的封包的 IP 都會是『 NAT 主機對外的公共
    IP
    』,因此對於內部 Client 端而言,由於網路 Cracker 幾乎都是根據
    IP 來進行破壞,而因為您連出去的封包 IP 是 NAT 主機的公共 IP ,自然您的
    Client 端就比較安全多了!基本上, Client 端在 NAT 之內,沒有安裝防火牆軟體也還好,但是『防毒軟體一定要安裝!』因為您畢竟會接收電子郵件呀等等的,所以還是可能會中毒啦!!

  • 對於 Server 端來說,我們僅僅設定一些簡單的防火牆規則,而且在原本的
    iptables.rule
    當中還預設開啟了許多的埠口,所以其實這樣的一個主機並不是十分的安全的,因此,您最好還是自行將
    iptables.rule 內的最後面的幾個開放的埠口給他註解掉才好吶!(如果您的 NAT
    主機僅想要負責頻寬分享的功能的話!)


文章來源 - 鳥哥的LINUX私房菜
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]PROXY.IP Masquerading.Transparent Proxy.工作原理
這裡還有一篇比較複雜的作法!
作者是鼎鼎大名的網中人!
其中提到了PROXY.IP Masquerading.Transparent Proxy.工作原理.iptables.FTP.搭配核心模組.netmeeting.ICMP 的問題.封包過濾.架設 NAT.安全考量等等議題!
非常值得一看!
但因為文章比較長,所以無法轉載於此!
請大家自己過去看看ㄌㄡ~~~

STUDY AREA - 架設NAT
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]iptables/chains + squid transparent proxy
作者: kenduest (小州) 站內: LinuxNetwork
標題: [文件]iptables/chains + squid transparent proxy
時間: Sun Jul 1 08:32:08 2001

transparent proxy,簡單說,就是透通性 proxy,clint 存取 web port時,gateway 能夠把這個 request 導向給 proxy server,由 proxyserver 代為 proxy 抓資料,然後會應給 client 。(註: 一般用在 web的 proxy)

transparent proxy 好處就是,client 不用特定設定 proxy,可以暗自由 gateway 達成這個目的。整體就是能夠因為 proxy 的機制,對於web 瀏覽部份能夠避免重複抓取相同的資料,省下大量的頻寬。

transparent proxy,當然需要一台 proxy 主機幫忙。這裡的環境就是:

-- 一台 Linux 主機,提供 nat 功能,上面同時跑 squid proxy 服務
於 3128 port 。 eth0 對外,eth1 對內。

squid.conf 需要先設定好,以便於可能使用 transparent proxy 機制。

httpd_accel_host proxy.xxx.com.tw
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

(see: http://www.squid-cache.org/Doc/FAQ/FAQ-15.html#ss15.4 )

上面的 proxy.xxx.com.tw 請改成該 proxy 主機名稱。

接著是 nat、transparent proxy 機制設定。以 kernel 2.2 來說,是這般設定:

ipchains -A input -i eth1 -p tcp -s xxx.xxx.xxx.xxx/netmask -d 0/0
--dport 80 -j REDIRECT 3128

ipchains -A forward -i eth0 -s xxx.xxx.xxx.xxx/netmask -d 0/0 -j MASQ

設定好後,只要是 xxx.xxx.xxx.xxx 這些 private ip 對外發出port 80 的 request 後,就會導向給該 nat 主機上的 port 3128,由 squid cache server 代為 proxy 資料。

使用 kernel 2.4 的話:

iptables -t nat -A PREROUTING -i eth1 -p tcp -s xxx.xxx.xxx.xxx/netmask --dport 80 -j REDIRECT --to-ports 3128

iptables -t nat -A POSTROUTING -o eth0 -s xxx.xxx.xxx.xxx/netmask -j MASQUERADE
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]使用 iptables 設定使用 NAT 分享網路頻寬
作者: kenduest (小州) 站內: LinuxNetwork
標題: [文件]使用 iptables 設定使用 NAT 分享網路頻寬
時間: Tue May 15 19:09:03 2001

Linux 上使用 IP-Masquerade 所謂的 IP 儰裝以便於達成該功能。

Linux 上的 IPMASQ 因為 kernel 一些核心功能有調整過,所以相關的設定工具因為不同的核心版本所以不同.

kernel 2.0.x 時代,是使用 ipfwadm 程式。(這個說法不算是完全正確)

kernel 2.1.x/2.2.x 時代,則是使用 ipchains 程式

kernel 2.3.x/2.4.x 時代,使用 netfilter 過濾機制, 是使用
iptables 程式。

演進來看,目前 kernel 2.4 配合使用 netfilter 核心過濾機制,可以達到的功能相當棒.... 那 netfilter 提供那些機制呢?
比方:

1. 傳統 ipchains 的任何功能(基本來源與目的封包過濾、導向、偽裝)
2. 提供 Source NAT 與 Destination NAT 的功能
3. 可以針對特定使用者、群組、PID 等限制網路連結的過濾存取
4. 可以設定封包在 Routing Table 進出前時先預先處理
5. 提供可以讓 UserSpace 的程式處理 filter 部分。
6. 可以針對外面自動建立、與現有連線有關這類連線過濾處理...
7. 可以針對 Mac 卡號處理。

ipmasq 的文件,那邊可以閱讀呢? linux 本身提供的 howto 很足夠了...

使用 ipfwadm/ipchains 等程式的 kernel 環境,可以參考:

http://www.linux.org.tw/CLDP/IP-Masquerade-HOWTO.html

不過該版文件中文翻譯已經太久沒有更新了,建議找原文的IP-Masquerade-HOWTO 文件。那邊找呢?可以上這裡找找:

http://www.linuxdoc.org

裡面提到了包含 port forward 等相關重要的資訊。比方ipmasqadm 等程式的使用。

若是您目前使用 kernel 2.3/2.4,可以參考這給篇中譯文:

http://www.linux.org.tw/CLDP/NAT-HOWTO.html

http://www.linux.org.tw/CLDP/Packet-Filtering-HOWTO.html

相同的,原文部份,上 http://www.linuxdoc.org 也有喔..

當然,若是您的 linux dist 版本是最近的,那系統安裝好的HOWTO 文件應該也可以找到..

ok.. 若是您目前要使用 nat 功能的話,首先就是確定您的核心是支援linux firewall 與 ip masquerade 功能... 不過目前許多 LinuxDistribution 都已經把 IP Masquerade 支援編入到 kernel 內了,所以重編 kernel 的部份可以略過....

當然啦,目前 kernel 2.4.0 正式 release 出沒有多久,所以若是您打算使用 netfilter 提供的一些先進的機制,那您需要先更新核心到 2.4,編譯核心時要選擇把 netfilter 提供的一些功能打開..(可以選擇編入核心 或者是編譯成為 module)

這裡環境,假設:

對外 internet 連結的 ip 是: 210.1.1.1
對內的部份,使用 192.168.1.1

當然,您需要兩張網路卡,一張就是設定 210.1.1.1,另外一張
就是設定 192.168.1.1 (netmask: 255.255.255.0)

另外提到,有人會說到也許可以使用 ip aliases 達到一張網路卡就可以有兩個 ip .. 當然,這是可行的.. 不過弟不建議使用在nat 的環境下.. 一者是因為一般 nat 多半充當 firewall,而若是使用 ip aliases 後對外與對內的封包都跑在同一個 interface上,那就失去封包過濾功能了... 而不同區段的封包跑在一起,網路效能也是會變差的...

OK.. 目前要啟動 nat/ipmasq 功能的話,首先就是只要 Linux 主機把IP Forwarding 打開 (ip 轉送),並使用 ipchains/iptables 等這類程式設定好後,Client 端就可以透過 Linux 這台 gateway 主機的協助而上網了。

kernel 2.2.x :

echo "1" /proc/sys/net/ipv4/ip_forward
ipchains -P forward DENY
ipchains -A forward -i eth0 -j MASQ -s 192.168.1.0/24
ipchains -M -S 86400 86400 360 <-- 這是讓 timeout 拉長一點
modprobe ip_masq_ftp <-- 掛入 ftp 等 module 處理 ftp 相關連結問題

當然,我想另外的一些 ipmasq module 一起掛入也許比較完整一點...

ip_masq_cuseeme、ip_masq_irc、ip_masq_mfw、ip_masq_pptp、
ip_masq_quake、ip_masq_raudio、ip_masq_user、ip_masq_vdolive ..

kernel 2.3.x/2.4.x :

echo "1" /proc/sys/net/ipv4/ip_forward
modprobe ip_tables # 這是編譯核心是選擇 module 才需要
modprobe ip_nat_ftp # 同上,處理 ftp 等連結問題
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobn ip_conntrack_irc
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE

上面等使用上,請先注意各位系統目前預設每個 INPUT、OUTPUT、FORWARD CHAIN
是不是為 ACCEPT ,而不是 DROP/DENY 或者是 REJECT。

for kernel 2.2 :

ipchains -P input ACCEPT
ipchains -P output ACCEPT
ipchains -P forward ACCEPT

若是要把就有規則清除,可以補上:

ipchains -F
ipchains -X

for kernel 2.4 :

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

若是要把就有規則清除,可以補上:

iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat

上面很單純的提供 nat/ipmasq 服務,沒有針對一些安全性考量,比方聲稱來自內部網路的 ip 範圍,是由 eth0 這個對外 interface 進入的話那就應該拒絕.... 比方像是位於 eth1 上 192.168.1.x 這段虛擬 ip 區段就是一個例子。所以這裡要說的是,若是要嚴謹一點的話,額外的設定是很需要的...

另外補充的,就是 port forward 部份,kernel 2.2.x 內是使用ipmasqadm 達成:

ipmasqadm portfw -a -P tcp -L 210.1.1.1 25 -R 192.168.1.100 25

該 ipmasqadm 敘述,提供讓 nat 對外主機,可以讓他人使用210.1.1.1 port 25 進行 tcp 服務連結,而該連結請求會轉給內部主機192.168.1.100 port 25 .. 簡單說,這行敘述是給有一台 mail server是放在 nat 架構內使用虛擬 ip,然後透過 nat 主機設定 port 重導到內部的真實主機。

若是使用 kernel 2.4 的話,iptables 指令則是:

iptables -A PREROUTING -t nat -p tcp -d 210.1.1.1
--dport 25 -j DNAT --to 192.168.1.100:25

當然,以前有人提到,外面使用 telnet 210.1.1.1 25 的確是可以 work,不過內部 192.168.1.x 的電腦若是 telnet 210.1.1.1 25 就不行..
那補上下面的敘述:

iptables -A OUTPUT -t nat -p tcp -d 210.1.1.1
--dport 25 -j DNAT --to 192.168.1.100:25

上面說的是單一 port 重導.. 若是需要的功能是全部 port 都重導的話,比方就是使用:

iptables -A PREROUTING -t nat -p all -d 210.1.1.1
-j DNAT --to 192.168.1.1

ok.. 此外幾點要說明的是:

1. 目前許多人都使用 adsl 寬頻,若是使用計時制的話要注意的是,因為透過 pppoe 這類程式撥接後,會產生一個 ppp0 的 interface,然後再透過一個網路卡介面作封包的傳輸,所以先前的指令有指定eth0 的敘述要改成 ppp0 才正確....

2. 使用 nat 後,使用虛擬 ip 連上網路的電腦,一般使用上應該是不大會有問題的... 不過若是想與 internet 上的電腦玩網路遊戲對戰的話,可能會發生一些問題.... 因為許多 game 的網路連線的運作方式在 nat 架構下多半無法工作.... 一般解決方式,找看看是否有專人寫出了 ipmasq 的 module,掛入後就可以解決了...或者是找出相關的 game 是有那些 port 的連結,然後設定好 portforwarding 的動作即可。

關於 port forwarding 部份,這裡有個連結提供很好的資訊:

http://www.tsmservices.com/masq

許多 ap 程式、game 等等都有提供相關解決設定,不過都是針對kernel 2.2.x 內配合使用 ipmasqadm 程式.. 若是是使用 kernel 2.4的話,研究一下 iptables 指令的用法後,同樣也是可以完成的。

3. 有人無法使用 icq 傳檔案,甚至無法正確傳訊息?我建議更新icq 到 2000 等版本,然後把連結設定改成在 firewall 後面使用,那就沒有問題了...

4. 要觀察目前設定規則,請使用 iptables -L 。若是當初有使用 -t xxxx的話,請使用 iptables -L -t xxx 。ex: iptables -L -t nat

5. 先前 netfilter 核心機制有一些 bug (Connection State,Related statebug) 會導致一些安全性的問題,see:

http://www.tempest.com.br/advisories/01-2001.html

http://netfilter.samba.org/security-fix/

(Mandrake 8.0 , the kernel is ok )

6. 若是遇到先前使用 kernel 2.2 都可以正常連線到一些站台,但是用了kernel 2.4 後卻不行得情況... 實際例子可能就是,可以 ping 到對方,不過卻連不上對方主機。

echo 0 /proc/sys/net/ipv4/tcp_ecn

see: http://www.tux.org/lkml for more information

7. 該篇文章省略設定網路卡的步驟...

大概就是這樣子了,有問題請告知,也歡迎大家討論。
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]使用 iptables 設定一些安全防護功能 (1)
發信人: kenduest.bbs@bbs.cynix.com.tw (小州), 看板: Linux
標 題: [文件]使用 iptables 設定一些安全防護功能 (1)
發信站: CynixBBS. (Tue May 15 19:08:40 2001) at.cynix.com.tw
轉信站: Maxwell!bbs.ee.ntu!freebsd.ntu!news.cis.nctu!db1.bbs99.com!netnews.hin


常看到有人亂使用 port scan 軟體,(ex:nmap) 來亂掃他人的 port,實在很討厭 @_@

這裡提供幾個方式,透過 linux kernel 2.4 的新核心機制 + iptables來進行一些設限:

# NMAP FIN/URG/PSH
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

# Xmas Tree
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL ALL -j DROP

# Another Xmas Tree
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

# Null Scan(possibly)
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL NONE -j DROP

# SYN/RST
iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

# SYN/FIN -- Scan(possibly)
iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

這是針對一些像是使用 scan 軟體,配合所謂的 Stealth 等機制去亂掃他人主機時,可以把這些封包丟棄不處理。那對方一掃就卡死了,或者是要等連線 timeout 才能夠繼續工作,拉長 scan 所需的時間。
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]使用 iptables 設定一些安全防護功能 (2)
發信人: kenduest.bbs@bbs.cynix.com.tw (小州), 看板: Linux
標 題: [文件]使用 iptables 設定一些安全防護功能 (2)
發信站: CynixBBS. (Tue May 15 19:15:01 2001) at.cynix.com.tw
轉信站: Maxwell!bbs.ee.ntu!freebsd.ntu!news.cis.nctu!db1.bbs99.com!netnews.hin


下面是我設定 iptables 的一些簡單規則,可以參考一下。(與 NAT 無關喔)

# 掛入相關 module
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc

# 重設
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t mangle

# 把 FORWARD 關閉
iptables -P FORWARD DROP

# 這是打開讓自己網域可以方便連結,也就是該網域不設防

iptables -A INPUT -p all -s ip_net/netmask -j ACCEPT

# 允許相關連結服務

iptables -A INPUT -i eth0 -p tcp --dport 20 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 23 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 113 -j ACCEPT

iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,INVALID -j DROP

上面是打開允許 port 20、21、22、23、25、53、110、113 等服務才能夠
被外面所連線。

port 20、21 : ftp 使用的。
port 22 : ssh 連線
port 23 : telnet 連線。方便使用,其實不開放比較安全。
port 25 : sendmail 使用。讓信件可以寄進來。
port 53 : dns 使用。dns 需要打開 udp 使用。
port 110 : pop3 使用
port 113 : auth 身份確認。我打開是讓一些使用該 113 確認身份的主機
不至於反查時會卡住很久。

最後一行是對於主動連線或者是不合法連線,一律通通拒絕掉。

這個 script 內容,很適用只允許外面連結特定的 port 服務,剩下的其餘port 就拒絕外面主動建立的連線。比方使用 Modem 撥接,只希望裡面可以正常連線出去,外面都無法連線進來這個需求。(ps: modem 是使用 ppp0等這些介面,上面的 eth0 要改成 ppp0 )
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]使用 iptables 設定一些安全防護功能 (3)
發信人: kenduest.bbs@bbs.cynix.com.tw (小州), 看板: Linux
標 題: [文件]使用 iptables 設定一些安全防護功能 (3)
發信站: CynixBBS. (Tue May 15 19:39:44 2001) at.cynix.com.tw
轉信站: Maxwell!bbs.ee.ntu!freebsd.ntu!news.cis.nctu!db1.bbs99.com!netnews.hin

防止 sync flood 攻擊的設定:

iptables -N synfoold
iptables -A synfoold -p tcp --syn -m limit --limit 1/s -j RETURN
iptables -A synfoold -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state NEW -j synfoold

這個方式對於一個很忙碌的站台來說,這個設定方式會不會有不良影響呢?測試過一個很忙碌的站台用這個設定,老實說並不好....所以也許可以調整時間與次數的觸發值。

防止 Ping of Death :

iptables -N ping
iptables -A ping -p icmp --icmp-type echo-request -m limit --limit
1/second -j RETURN
iptables -A ping -p icmp -j REJECT
iptables -I INPUT -p icmp --icmp-type echo-request -m state --state NEW
-j ping

這裡只有把 icmp 的 echo request 部份拒絕掉,可以視情況再調整。

或者是直接設定主機不回應 echo request 。

/proc/sys/net/ipv4/icmp_echo_ignore_all
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]IPtables與防火牆
iptables 跟 ipchains 是無法同時使用,如果您已經使用 ipchains ,要改用 iptables 時,要先將 ipchains 的 modules 移除,在載入 iptables 的 module , 才可以使用 iptables !!
1.先檢查是否載入 ipchains module
lsmod | grep ipchains
2.如果有的話,要移除 ipchains
/etc/rc.d/init.d/ipchains stop ( or ipchains -F )
rmmod ipchains
3.再檢查是否有成功移除
lsmod | grep ipchains
4.載入 iptable module
modprobe ip_tables
--------------------------------------------------------------------------------
防止別人用ACK、SYN、FIN等等的封包來掃瞄 Linux
iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
--------------------------------------------------------------------------------
NAT
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
不過此時 ftp 會無法正常運作,必須另外再加上
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
另外可以配合 proxy server,強制每台 client 端均透過 proxy 連線
iptables -t nat -I PREROUTING -i eth0 -p tcp -s 192.168.0.0/255.255.255.0 -d 192.168.0.113 --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.0.0/24 --dport 80 -j REDIRECT --to-port 3128
--------------------------------------------------------------------------------
限制連線條件
iptables -A FORWARD -p TCP -s 11.22.33.44 -d 44.33.22.11 -j DROP
從 11.22.33.44 的 port 1024-65535 連線到 44.33.22.11 的 port 80 ,一律檔掉!!
iptables -A FORWARD -p TCP -s 11.22.33.44 --sport 1024:65535 -d 44.33.22.11 --dport www -j DROP
--------------------------------------------------------------------------------
防止 port scan
# NMAP FIN/URG/PSH
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
# Xmas Tree
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL ALL -j DROP
# Another Xmas Tree
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# Null Scan(possibly)
iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL NONE -j DROP
# SYN/RST
iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# SYN/FIN -- Scan(possibly)
iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
--------------------------------------------------------------------------------
防止 sync flood 攻擊的設定:
iptables -N synfoold
iptables -A synfoold -p tcp --syn -m limit --limit 1/s -j RETURN
iptables -A synfoold -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp -m state --state NEW -j synfoold
不過流量一大就不太好了!!
所以可以調整時間與次數的觸發值
iptables -N ping
iptables -A ping -p icmp --icmp-type echo-request -m limit --limit 1/second -j RETURN
iptables -A ping -p icmp -j REJECT
iptables -I INPUT -p icmp --icmp-type echo-request -m state --state NEW -j ping
關閉主機的 icmp echo request
或者是直接設定主機不回應 echo request
/proc/sys/net/ipv4/icmp_echo_ignore_all
--------------------------------------------------------------------------------
其他 iptables 的 sample
# 掛入相關 module
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
# 先清成空白
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t mangle
# 把 FORWARD 關閉
iptables -P FORWARD DROP
# 這是打開讓自己網域可以方便連結,也就是該網域不設防
iptables -A INPUT -p all -s 192.168.0.0/255.255.255.0 -j ACCEPT
# 允許相關連結服務
iptables -A INPUT -i eth0 -p tcp --dport 20 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 23 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 113 -j ACCEPT
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,INVALID -j DROP
上面是打開允許 port 20、21、22、23、25、53、110、113 等服務才能夠
被外面所連線。
port 20、21 : ftp 使用的。
port 22 : ssh 連線
port 23 : telnet 連線。方便使用,其實不開放比較安全。
port 25 : sendmail 使用。讓信件可以寄進來。
port 53 : dns 使用。dns 需要打開 udp 使用。
port 110 : pop3 使用
port 113 : auth 身份確認。打開是讓一些使用該 113 確認身份的主機
不至於反查時會卡住很久。
最後一行是對於主動連線或者是不合法連線,一律通通拒絕掉。
這個 script 內容,很適用只允許外面連結特定的 port 服務,剩下的其餘
port 就拒絕外面主動建立的連線。
(以上部分轉載自網路上的 news ,來自小州兄的大作,可惜小編一直抽不出時間完整的整理 iptables ...殘廿...)
以下是小編針對單一防護型的 server , 所撰寫的 iptables ,其目的只有防護自己,如果您的情形也是如此,可以直接採用,只需要修改哪些 port 要開放就可以了!!
#!/bin/sh
# Sep,30,2002 Mon Anderson add for testing
# load modules if necessary
modprobe ip_tables
# modprobe ip_conntrack
# modprobe ip_conntrack_ftp
# modprobe ip_conntrack_irc
# disable all chains
iptables -F
iptables -t nat -F
iptables -t mangle -F
# define default policy
iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# allow all localhost
iptables -A INPUT -i lo -j ACCEPT
# allow ssh
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -i eth0 -p tcp --dport 23 -j ACCEPT
# iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
# iptables -A INPUT -p tcp -d 192.168.0.229 -j ACCEPT
# log
# iptables -A INPUT -p tcp -d 0.0.0.0/24 -j LOG --log-prefix "DROP_AAA__ " --log-level info
# iptables -A INPUT -p tcp --dport 1:65535 -j LOG --log-prefix "DROP_BBB__ " --log-level info
# allow old connection and deny new connection
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,INVALID -j DROP
如果用 iptables -L ,會得到以下結果
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
DROP all -- anywhere anywhere state INVALID,NEW
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain RH-Lokkit-0-50-INPUT (0 references)
target prot opt source destination
另外,使用 iptables -t nat -L ,會得到以下結果
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
以上的 script , 用來保護單機型的 server ,應該是足夠了!!
--------------------------------------------------------------------------------
將 Server 藏在 LAN 中--DNAT 的實作
看完單機型的 firewall , 接著就來看看如何利用 iptables 實作 firewall , 將需要保護的 server 藏到 LAN , 透過 firewall 實作 DNAT 的方式來保護!!
架構圖如下 :
將 WWW Server 藏到 192.168.0.1 , 但是希望 Internet 的其他 user ,輸入 http://11.22.33.44/ 能夠看到 192.168.0.1 的網頁內容
#!/bin/sh
# Dec,11,2002 Wed Anderson add for testing
# load modules if necessary
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
# disable all chains
iptables -F
iptables -t nat -F
iptables -t mangle -F
# disable forward chain
# iptables -P FORWARD DROPecho "1" > /proc/sys/net/ipv4/ip_forward
iptables -P FORWARD ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# alloe all localhost
iptables -A INPUT -i lo -j ACCEPT
# allow specical IP
# iptables -A INPUT -p tcp -d 192.168.0.1 -j ACCEPT
# allow ssh
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth1 -p tcp --dport 22 -j ACCEPT
# allow http
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT
# allow old connection and deny new connection
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -m state --state NEW,INVALID -j DROP
iptables -A INPUT -i eth1 -m state --state NEW,INVALID -j DROP
# setup DMZ -- DNAT
iptables -A PREROUTING -t nat -i eth0 -p tcp -d 11.22.33.44 --dport 80 -j DNAT --to-destination 192.168.0.1:80
# open DMZ goto Internet
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
至於 WWW Server , 只要將 Default Gateway 指向 192.168.0.254 即可以,此時就可以從 Internet 上,輸入 http://11.22.33.44 連結到 LAN 上的 WWW Server 了!!
其他如果需要 FTP Server, Mail Server,則依照需要的 port 開放就可以了!!
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]How to bind 2 WAN 1 LAN
這裡有一篇當年冷日發MAIL到IPTABLES的MAIL LIST的回覆!
裡面也有提到一些建議與方向,可參考一下!

<H1>How to bind 2 WAN 1 LAN ?</H1>
George Vieira
GeorgeV@citadelcomputer.com.au

Wed, 4 Dec 2002 08:04:11 +1100




You need a combination of iptables and iproute2 to do what you want because
routing is based on it's DESTINATION address and you need to route on your
SOURCE address so it uses a different route depending on which source IP is
in the packet..
Refer to this page which is sort of what you want BUT not exact. It'll give
you some ideas...
http://www.samag.com/documents/s=3D1824/sam0201h/
Thanks,
____________________________________________
George Vieira
Systems Manager
georgev@citadelcomputer.com.au=20
Citadel Computer Systems Pty Ltd
Phone : +61 2 9955 2644
HelpDesk: +61 2 9955 2698 =20
http://www.citadelcomputer.com.au
-----Original Message-----
From: raykey@dinyi.com.tw [mailto:raykey@dinyi.com.tw]
Sent: Thursday, 24 October 2002 3:25 PM
To: netfilter-announce@lists.netfilter.org
Cc: netfilter@lists.samba.org
Subject: How to bind 2 WAN 1 LAN ?
Dear all...
I'm a Chinese and I don't think that my English is well .
But I have a big problem in use IPTABLES .
I've looked all the documents and FAQs , but I can't find a solution to
solve my problem .
At last I decide to ask you in my poor English ...^^||
I have a Linux server (Turbo Linux7.0 in kernel 2.4.9-3) to be my NAT server
.
I have make it running iptables-1.2.2-6 .
It have 3 NIC(Network interface Card) eth0.eth1.eth2 .
I have 1 LAN and 2 WAN interface they are 192.168.1.0/255.255.255.0 and 2
ADSL (one of my ADSL is pppoe another one is static IP) .
Now I want to bind thy all in my NAT server .
I rty to cut my LAN to 4 part are 192.168.1.0/255.255.255.192 &amp;
192.168.1.64/255.255.255.192 &amp; 192.168.1.128/255.255.255.192 &amp;
192.168.1.192/255.255.255.192 .
That I wish the preceding 3 part go out and in with the pppoe ADSL (ppp0)
and the final part go through with static IP(because they are my servers) .
My biggest problem is in Linux I can't set the default gateway otherwise the
ppp0 will not work .
But if ppp0 is working I can't find who to make my final part
(192.168.1.192/26) go through the eth0 out or aome in...-.-&quot;
I have do my best to explain my problem .
If you can't understand my question maybe can find somebody who know my
English or can talk in Chinese will better .
Sincerely yours
thanks a lot...^^
------------------------------
=B9=A9=A9=F6=A6L=A8=EA=B8=EA=B0T=AB=C7
Dinyi Printing CO. LTD
RaykeySu
raykey@dinyi.com.tw
------------------------------
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Linux 上多條對外連線(Multi-Path)實作
Linux 上多條對外連線(Multi-Path)實作
--------------------------------------------------------------------------------
作者﹕網中人 <mailto:netman<netman@study-area.org>?subject=zope_study>
version 0.04
date 2004-09-27
一、前言
由於 ADSL 及 Cable Modem 的普及,越來越多企業或個人所擁有的對外連線早已超過一條了,
不管是固接還是撥接,相信不少人都在思考如何用最有效的方式將多條連線作整合,
將所有連線的使用發揮至最大極限及最佳的使用率。
除了起到負載的分攤之外,還能達到斷線備援目的,以提供更靈活的連線整合方案。
本文將以實作的方式試圖在 Linux 上做到上述要求。
二、環境
我先說明一下我的測試環境:
2.1 系統方面:
我目前測試的系統是 RedHat 9.0 Linux ,採用"伺服器"類型安裝,並沒提供 X 界面。
透過 APT 更新至最新修補,並沒安裝 distro 之外的套件。
事實上,只要實作所需的套件滿足的話,並不需要安裝任何伺服器套件。
甚至,核心版本也不需作任何修改,只是某些連線特徵會有些差異(後文[7.1]再詳述)。
2.2 網路方面:
原本的 seednet adsl 是五個 IP 撥接的, 除了之前透過 ip share 來使用外,我再起了另外一個 ppp0 界面。
此外另外再牽了一條 hinet 固一 adsl 。
如此環境,基本上能夠分別測試到如下這幾種連線方式:
* 固接(固定 IP)
* 撥接(非固定 IP)
* ip share(非固定 IP)
見圖:
[code:1:e156f909e5]/\__/\__/
,--| internet |--.
/ /--/--/
| |
| |
+--[seednet ADSL] [hinet ADSL]
| (非固定) (固一)
| | 220.130.96.254
| [ ip share ] |
| 192.168.100.1 |
| | |
| 192.168.100.2 220.130.96.21
| +----------------------------------+
+---| (eth1) (eth0) |
ppp0| kernel 2.4.23 |
+----------------------------------+
(my linux box RH9.0)[/code:1:e156f909e5]
2.3 測試方式
雖然,撥接adsl 都是同一設備,或許還不十分理想,目前也只能如此了...
我採用的是拔線的方式來測斷線的,暫還沒想到其他方式,或許大家可以幫忙想想的...
我的測試基本上是用 ping 來做:
* 若是 ppp 或不指定測試目標,我會用 next hop 來測。
* 否則,我會用 traceroute 找出 ISP 端機房的 router ip ,
而不用 next hop ,是因為怕不準,比方說斷線是外部線路之類的。
若大家有更好提議,也歡迎提供....
三、設計目標
實作方案基本上要做到如下這些要求:
3.1 出向負載分流
所有連線在正常情況下,將共同分攤由內對外產生的連線流量。
對於固定連線,可指定權重(weight),否則使用相同權重( weight 1)。
3.2 斷線偵測
若有連線斷掉,需自動從路由中移除。
當連線恢復時,則自動增加路由。
3.3 進向負載分流(額外需求)
外部連線進來,儘可能的將流量分攤在每一條連線上。
四、設計構思
4.1 出向負載分流
利用 Linux iproute 程式,將每一條連線的 gateway 及其權重增加至路由表的 default route 中。
其中的固接 adsl 及 ip share 連線,需靜態指定其 gateway 位址及權重。
其餘撥接或非固接連線,則用 iproute 程式抓出當時的 gateway ,權重分配為 1 。
4.2 斷線偵測
不管是固接還是非固接連線,用手工方式(如 traceroute)抓出 ISP 端的機房 router 位址,
並確定用 ping 可以獲得回應。
然後用靜態路由指定通向 router 的 nexthop gateway ,定期使用 ping 來偵察連線。
每次偵測後都重跑 iproute 程式,並重新設定路由表。
若 ping 不成功,則抓出連線界面,且在重設路由表時忽略該界面連線。
4.3 進向負載分流(額外需求)
使用動態 dns(ddns) 將為每一界面位址分配一個 A 記錄,以達到輪詢回應結果,
從而讓不同的外部連線請求輪流使用每一條連線進入。
本實作方案中,ddns server 建議部署於外部的穩定連線的主機上。
關於動態 dns 的 server 設定,不含在本次實作方案之內。可請參考:
http://www.study-area.org/tips/ddns.htm
設計難點在於 ipshare :
其中 ipshare 部份需另行設定 nat 轉線。
否則需從清單中移除。
若 nat 設定正確,接下來的難點是獲得 ipshare 的 IP (因為也是非固接的),
這需要在外部的 web server 另行開發 php 程式來獲取(可置於 ddns server)。
關於這部份設計,請參考:
http://phorum.study-area.org/viewtopic.php?p=108638
或使用如下代碼:
[code:1:e156f909e5]
<?php
//Get the real client IP ("bullet-proof"???)
function GetProxyIP()
{
if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else
$ip = "unknown";
return($ip);
}/*-------GetIP()-------*/
function GetClientIP()
{
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
printf("proxy IP: ");
print_r(GetProxyIP());
printf("<br>
");
printf("client IP: ");
print_r(GetClientIP());
?>
[/code:1:e156f909e5]
五、實作指令
5.1 獲取當前各界面之 ip :
# ip address show
1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:02:44:84:26:4f brd ff:ff:ff:ff:ff:ff
inet 220.130.96.21/24 brd 220.130.96.255 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:20:ed:36:f9:74 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global eth1
4: eth2: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:02:b3:4b:69:49 brd ff:ff:ff:ff:ff:ff
inet 10.1.2.3/24 brd 10.1.2.255 scope global eth2
15: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP> mtu 1492 qdisc pfifo_fast qlen 3
link/ppp
inet 210.64.33.27 peer 210.64.33.1/32 scope global ppp0
5.2 設定 ip rule :
# ip rule add pref 10 from 220.130.96.21 table 10
# ip rule add pref 20 from 192.168.100.2 table 20
# ip rule add pref 30 from 210.64.33.27 table 30
5.3 設定 ip route 各 table :
# ip route replace default via 220.130.96.254 dev eth0 table 10
# ip route replace default via 192.168.100.1 dev eth1 table 20
# ip route replace default via 210.64.33.1 dev ppp0 table 30
5.4 設定 ip route main table:
# ip route replace default
nexthop via 220.130.96.254 dev eth0 weight 4
nexthop via 192.168.100.1 dev eth1 weight 1
nexthop via 210.64.33.1 dev ppp0 weight 1
5.5 檢視 main table 規則:
# ip route show
210.64.33.1 dev ppp0 proto kernel scope link src 210.64.33.27
192.168.100.0/24 dev eth1 scope link
220.130.96.0/24 dev eth0 scope link
10.1.2.0/24 dev eth2 scope link
169.254.0.0/16 dev eth2 scope link
127.0.0.0/8 dev lo scope link
default
nexthop via 220.130.96.254 dev eth0 weight 4
nexthop via 192.168.100.1 dev eth1 weight 1
nexthop via 210.64.33.1 dev ppp0 weight 1
5.6 刷新 route cache:
# ip route flush cache
5.7 測試及確認連線生效:
基本上,若在輸入上述命令中沒遇到 error ,那設定就已完成。
接下來可起用多個對外連線(或用 ping),
然後使用 tcpdump -i any 來查看封包是否能分攤在每一條連線上。
六、撰寫 script :
若前述設定經測試成功後,接下來就是撰寫 script 以讓工作自動進行。
6.1 configs
* 說明:
提供給其它 scripts 所需的共同變數值。
* 代碼:
[code:1:e156f909e5]
BASH=/bin/bash
MAIL=root
SH=/bin/bash
LS=/bin/ls
GREP=/bin/grep
AWK=/bin/awk
SED=/bin/sed
HEAD=/usr/bin/head
TAIL=/usr/bin/tail
CUT=/bin/cut
CAT=/bin/cat
WC=/usr/bin/wc
TR=/usr/bin/tr
SEQ=/usr/bin/seq
SORT=/bin/sort
LSMOD=/sbin/lsmod
IP=/sbin/ip
PING=/bin/ping
IPTABLES=/sbin/iptables
ROUTE=/sbin/route
DATE=/bin/date
DHCP_DIR=/var/lib/dhcp
STATIC=./statics
INTERVAL=60 # check time interval in seconds
RUN_SCRIPT=./run_ip.sh # script to run ip route
DDNS_SCRIPT=./ddns/ddns.sh # script to run ddns update
DDNS=yes # enable/disable ddns update
#-- define public destination for ping --#
fixed_dest="168.95.1.1"
#-- define fixed interface & gateway --#
#-- format: "if:gw:weight [if:gw:weight]..." --#
fixed_gw="eth0:220.130.96.254:4 eth1:192.168.100.1:1"
fixed_if="$(echo -e "${fixed_gw// /
}" | cut -d: -f1)"
#-- define internal interface, or comment out for none --#
int_if="eth0"
#-- statict routing dest & order --#
#-- format: "static_xxx=value; static_xxxx_order=value"
static_seed_net="139.175.0.0/16"
static_seed_net_order="eth1 eth0"
static_studyarea=140.113.27.184
static_studyarea_order="eth0 eth1"
[/code:1:e156f909e5]
* 變數設定說明:
fixed_dest=
用來作 ping 測試的外部 IP。
fixed_gw=
固定界面之閘道及權重,格式為 "界面名稱:閘道位址:權重"。
int_if=
內部界面名稱,可設定多個。該界面將不會用來設定 default route 。
INTERVAL=
偵測動作之時間間隔,以秒數作單位。
RUN_SCRIPT=
執行路由設定 script 之路逕。執行時可使用 -d 選項排除不必要之界面。
DDNS_SCRIPT=
執行動態 DNS 更新 script 之路逕。執行時可使用 -e 選項排除不必要之界面。
DDNS=
啟用或關閉 ddns 更新(yes|no)。
static_xxxxxx=
靜態路由之目的地,可為單一 IP 或 net_ID/mask 。xxxxxx 為任意名稱。
static_xxxxxx_order=
靜態路由選取的界面次序。左邊為最優,若該界面失效,則選下一個。
6.2 run_ip.sh
* 說明:
此 script 用來抓出系統全部界面及 nexthop gateway ,
並完成路由規則及路由表設定。
* 代碼:
[code:1:e156f909e5]
#!/bin/bash
#
# script name: run_ip.sh
# purpose: changing route table.
# author: netman(netman@study-area.org)
# license: GPL(http://www.gnu.org/licenses/gpl.html)
#
# date: 2004-09-23
# version: v0.05
#
# caveate:
# 1) tested on redhat 9.0 linux only
# 2) iproute program is required
#
#------------------------------------------------------------
# change log:
# 1) 2004-03-23 v0.01
# * first beta release
# 2) 2004-03-24 v0.02
# * BUGFIXED:
# - Add IPIF and GWIP checking before change route.
# 3) 2004-04-15 v0.03
# * Add function:
# - Restart network if dead device detected.
# 4) 2004-07-07 v0.04
# * IMPROVEMENT
# - Create central config file
# * Add function:
# - Enable static routing
# 5) 2004-09-23 v0.05
# * IMPROVEMENT
# - More accurate on deleting old rules
# - More accurate on deleting dead interface
# - Add gw determining for dhcp interface
# - Add deletion for dead route
# * BugFix
# - Use central conf file
# - Filter out IPv6 address
#
#------------------------------------------------------------
WD=${0%/*}
CONFIG=$WD/configs
[ -f $CONFIG ] && . $CONFIG || {
echo "${0#*/}: ERROR: can not load $CONFIG."
exit 1
}
#-- route command prefix --#
DEFGW='/sbin/ip route replace default'
#-- define dead interface --#
while getopts "d:" opt; do
case $opt in
d) dead_dev=$OPTARG ;;
esac
done
#-- determine active interfaces --#
interfaces=$($IP address | $GREP -E 'ppp|eth' |
$AWK -F': ' '/^[0-9][0-9]*:/{print $2}' | $SORT -u
| grep -Ev "${int_if// /|}")
#-- remove old rule table --#
for i in $interfaces; do
$IP address | $GREP -A2 $i | $AWK '/inet[^6]/{print $2}' | $CUT -d'/' -f1
done | xargs -n1 echo from | while read line; do
$IP rule | grep "$line"
done | $SED -e "s/^/ip rule del pref /;s/://;s/lookup/table/" | $BASH
unset i
#-- remove dead interfaces --#
if [ -n "$dead_dev" ]; then
interfaces=$(echo "$interfaces" | grep -Ev "${dead_dev// /|}")
for dev in $dead_dev; do
DEF_ROUTE=$($IP route list | grep '^default' | grep "dev $dev")
echo "$DEF_ROUTE" | while read line; do
$IP route del $line
done
done
fi
#-- exit while all dead --#
[ "$interfaces" ] || {
$IP route del default
exit 2
}
#-- define table_id --#
init_num=10
offset=`echo -e "${interfaces// /
}" | $WC -l`
last_num=$(($init_num + $((offset * 10)) ))
tb_num=`$SEQ -s ' ' $init_num 10 $last_num`
#-- FUNCTION: determine DHCP assigning gw --#
dhgw() {
get_lastest () {
OIFS="$IFS"
IFS='
'
for line in $RnT1 $RNT2; do
l="$(echo $line | grep -o 'lease-time[^;]*' | cut -d' ' -f2)"
r="$(echo $line | grep -o 'routers[^;]*' | cut -d' ' -f2)"
e="$(echo $line | grep -o 'expire[^;]*' | cut -d' ' -f3-)"
EX_TIME=$($DATE -d "$e" +%s)
if [ "$((EX_TIME - l))" -gt "${P_TIME-0}" ]; then
P_TIME=$((EX_TIME-l))
D_TIME=$EX_TIME
ROUTER=$r
fi
done
IFS="$OIFS"
echo $D_TIME $ROUTER
}
DH_IF=$1
shift 1
RnT1=$($CAT $1 2>/dev/null | xargs echo | tr '}{' '
' | $GREP $DH_IF | $TAIL -n 2)
RnT2=$($CAT $1 2>/dev/null | xargs echo | tr '}{' '
' | $GREP $DH_IF | $TAIL -n 2)
[ "$RnT1" -o "$RnT2" ] || return
GnT=$(get_lastest)
C_TIME=$($DATE +%s)
[ "${GnT% *}" -gt $C_TIME ] && GWIP=${GnT#* }
}
#-- FUNCTION: determine gw --#
dgw() {
unset GWIP
#-- for fixed if --#
if echo $fixed_if | $GREP -wq $1 ; then
GWIP=`echo -e "${fixed_gw// /
}" | $GREP "^$1:" |
$CUT -d: -f2`
WEIGHT=`echo -e "${fixed_gw// /
}" | $GREP "^$1:" |
$CUT -d: -f3`
#-- for ppp if --#
elif echo $1 | $GREP -q ppp ; then
GWIP="`$IP address show dev $1 | $AWK '/inet[^6]/{print $4}' |
$CUT -d'/' -f1 | $HEAD -n 1`"
else
#-- try current gw --#
GWIP=$($ROUTE -n | $GREP $1'$' | $AWK '/^0.0.0.0/{print $2}' | $HEAD -n 1)
fi
#-- for dhcp if --#
[ "$GWIP" ] || dhgw $1 $DHCP_DIR/dhclient.leases $DHCP_DIR/dhclient-$i.leases
}
#-- config rule & routing --#
for i in $interfaces ; do
unset IFIP GWIP WEIGHT
IFIP="`$IP address show dev $i | $AWK '/inet[^6]/{print $2}' |
$CUT -d'/' -f1`"
dgw $i
[ "$tb_num" ] && tb_id=${tb_num%% *}
[ "$IFIP" -a "$GWIP" ] || continue
# check gw
$IP route replace $fixed_dest via $GWIP dev $i &/dev/null &&
sleep 2; $PING -c1 -w2 $fixed_dest &/dev/null && GWOK=true
$IP route del $fixed_dest via $GWIP dev $i &/dev/null
if [ "$GWOK" = true ]; then
unset GWOK
else
continue
fi
# set rule
$IP rule add pref $tb_id from $IFIP table $tb_id
# set route to gw
$IP route replace default via $GWIP dev $i table $tb_id
DEFGW=$DEFGW" nexthop via $GWIP dev $i weight ${WEIGHT:=1}"
SETGW=true
tb_num=${tb_num#* }
done
#-- apply routing --#
[ "$SETGW" = true ] && {
#-- remove old default route --#
DEF_NU=$($IP route | $GREP -c '^default')
for ((i=1;i<=$DEF_NU;i++)); do
$IP route del default
done
#-- set new default route --#
$DEFGW
}
#-- apply static routes --#
[ -f $STATIC ] && . $STATIC
#-- flush cache --#
$IP route flush cache
#-- show routing
$IP route list
#-- FINISH --#
exit 0
[/code:1:e156f909e5]
* 參數說明:
-d "<interface...>"
指定失效界面,可設定多個。
6.3 statics
* 說明:
此 script 用來設定靜態路由,封包將只會從單一連線送出,而不會分攤至其他連線。
* 代碼:
[code:1:e156f909e5]
#!/bin/bash
#
# script name: statics
# purpose: set static routes.
# author: netman(netman@study-area.org)
# license: GPL(http://www.gnu.org/licenses/gpl.html)
#
# date: 2004-09-23
# version: v0.02
#
# caveate:
# 1) tested on redhat 9.0 linux only
# 2) iproute program is required
#
#------------------------------------------------------------
# change log:
# 2004-07-08 v0.01
# * first beta release2
# 2004-09-23 v0.02
# * Improvment:
# - using flexible static_xxxx variable
WD=${0%/*}
CONFIG=$WD/configs
[ -f $CONFIG ] && . $CONFIG || {
echo "${0#*/}: ERROR: can not load $CONFIG."
exit 1
}
set_static () {
while [ "$2" ]; do
eval s_dest=$$1
eval s_order=$$2
all_gw="$($IP route show | $SED -n '/^default/,$p')"
for if in $s_order; do
if echo "$all_gw" | $GREP -q "$if" ; then
sn_gw=$(echo "$all_gw" | $GREP $if | awk '{print $3}')
sn_gw=${sn_gw%/*}
break
fi
done
[ "$sn_gw" ] && {
$IP route replace "$s_dest" via $sn_gw
}
shift 2
done
}
set_static ${!static_*}
[/code:1:e156f909e5]
* 注意要點:
此 script 可由 run_ip.sh 來呼叫,也可以獨立使用。
6.4 chk_line.sh
* 說明:
此 script 用來偵測連線是否正常,並定期執行 run_ip.sh 及 ddns.sh(選用)。
若抓出失效界面,再用 -d 參數傳給 run_ip.sh ,該界面將被忽略。
* 代碼:
[code:1:e156f909e5]
#!/bin/bash
#
# script name: chk_ip.sh
# purpose: checking outbound link and change route and dns.
# author: netman(netman@study-area.org)
# license: GPL(http://www.gnu.org/licenses/gpl.html)
#
# date: 2004-09-23
# version: v0.04
#
# caveate:
# 1) tested on redhat 9.0 linux only
# 2) using PING for link detection
# 3) iproute program is required
# 4) scripts run_ip.sh & ddns.sh are required too
#
#------------------------------------------------------------
# change log:
# 1) 2004-03-23 v0.01
# * first beta release
# 2) 2004-03-24 v0.02
# * add script path detection
# 4) 2004-07-07 v0.03
# * IMPROVEMENT
# - Create central config file
# * Add function:
# - Add email notification
# 5) 2004-09-23 v0.04
# * IMPROVEMENT
# - Rewrite the method of getting dead interface
#
#------------------------------------------------------------
WD=${0%/*}
CONFIG=$WD/configs
[ -f $CONFIG ] && . $CONFIG || {
echo "${0#*/}: ERROR: can not load $CONFIG."
exit 1
}
# change working directory
cd $WD
#-- determine gateways --#
get_gw () {
defaults=$($IP route show | $SED -n '/default/,$p' | $GREP via)
if_n_gw=$(echo -en "$defaults" | $AWK '{print $5":"$3":'$fixed_dest'"}')
if [ -n "$fixed_gw" ]; then
fixed_pair=$(echo -e "${fixed_gw// /
}" | awk -F: '{print $1":"$2":'$fixed_dest'"}')
dyn_pair=$(echo "$if_n_gw" | $GREP -Ev "$(echo $fixed_if | $TR ' ' '|')")
all_pair=$(echo $fixed_pair $dyn_pair)
else
all_pair=$(echo "$if_n_gw")
fi
}
#-- configure static route --#
get_dev () {
for i in "$@"; do
if=${i%%:*}
gw=$(echo $i | $CUT -d: -f2)
dest=${i##*:}
$IP route replace $dest via $gw dev $if &&
sleep 1; $PING -c1 -w2 $dest &>/dev/null || echo $if
$IP route del $dest via $gw dev $if
done
unset i
}
#-- run loop --#
while : ; do
get_gw # have gw
d_dev=$(echo $(get_dev $all_pair)) # have dead link
[ "$d_dev" ] && { # send mail if dead link found
echo "dead link found: $d_dev" |
mail -s "$(hostname): dead link" $MAIL
}
$SH $RUN_SCRIPT -d "$d_dev" # to run ip script
[ -f "$DDNS_SCRIPT" -a "$DDNS" = yes ] && $SH $DDNS_SCRIPT
unset all_pair
sleep $INTERVAL
done
[/code:1:e156f909e5]
6.3 ddns/ddns.sh (選用項目)
* 說明:
此 script 用來動態偵測連線位址,並動態更新 dns 位址記錄。
* 代碼:
[code:1:e156f909e5]
#!/bin/bash
#
# script name: ddns.sh
# purpose: updating dns record
# author: netman(netman@study-area.org)
# license: GPL(http://www.gnu.org/licenses/gpl.html)
#
# date: 2004-09-25
# version: v0.04
#
# caveate:
# 1) tested on redhat 9.0 linux only.
# 2) iproute program is required.
# 3) a php webpage to show ip, and the lynx program are required.
# 4) ddns server and ddns key are required.
#
#------------------------------------------------------------
# change log:
# 1) 2004-03-23 v0.01
# * first beta release
# 2) 2004-03-23 v0.02
# * add EXCL_IF list for exception
# 3) 2004-03-23 v0.03
# * add -e option for appending EXCL_IF
# 4) 2004-09-25 v0.04
# * BugFix: detect gw interface list
#
#------------------------------------------------------------
# set commands
HOST=/usr/bin/host
GREP=/bin/grep
CAT=/bin/cat
IP=/sbin/ip
SED=/bin/sed
AWK=/bin/awk
LYNX=/usr/bin/lynx
TOUCH=/bin/touch
DIFF=/usr/bin/diff
NSUPDATE=/usr/bin/nsupdate
MV=/bin/mv
# set variables
if echo $0 | $GREP '^/' ; then
w_dir=${0%/*}
else
w_dir=$PWD/${0%/*}
fi
KEY_FILE=$w_dir/Ktestddns.+157+14615.key
UPDATE_DATA=$w_dir/nsupdate.data
UPDATE_OLD=$UPDATE_DATA.old
HOST_NAME=testddns.study-area.org
NS_SERVER=dns.study-area.org # don't use IP address
IP_SERVER=dns.study-area.org # server running ip.php program
IP_SERVER_IP=$(echo $($HOST $IP_SERVER) | tail -n 1 | $AWK '{print $NF}')
IP_URL="http://$IP_SERVER/ip.php"
CLIENT_TYPE="client" # no proxy or using ISP's proxy
#CLIENT_TYPE="proxy" # use local proxy
MASQ_IF="eth1" # which masqueraded behine NAT
#EXCL_IF="eth1" # note: also use -e options to append list
# have exception
while getopts "e:" opt; do
case $opt in
e) EXCL_IF=$(echo $EXCL_IF $OPTARG) ;;
esac
done
# ensure key files
for file in $KEY_FILE ${KEY_FILE%key}private
do
if [ ! -r $file ]; then
echo "$(basename $0): ERROR: $file is not readable."
exit 1
fi
done
# ensure the server is connectable
$HOST $NS_SERVER $NS_SERVER | $GREP -q "^$NS_SERVER has address" || {
echo "$(basename $0): ERROR: could not contact nameserver $NS_SERVER."
exit 2
}
# prepare initial script
$CAT >| $UPDATE_DATA <> $UPDATE_DATA
echo "send" >> $UPDATE_DATA
# do a test then update
$TOUCH $UPDATE_OLD
if ! $DIFF $UPDATE_OLD $UPDATE_DATA; then
$NSUPDATE -k $KEY_FILE -v $UPDATE_DATA && {
$MV $UPDATE_DATA $UPDATE_OLD
}
fi
#-- end of script --#
[/code:1:e156f909e5]
* 變數設定說明:
KEY_FILE=
用以更新 dns 記錄的 key 。
UPDATE_DATA=
儲存 nsupdate 所需的命令稿。
UPDATE_OLD=
上一次 nsupdate 所需的命令稿。
script 會比對前一份命令稿內容,若相同,則不做 update ,否則才做。
HOST_NAME=
主機名稱。需與 ddns 所設定的記錄一致。
NS_SERVER=
ddns server 之主機名稱,不能使用 IP 位址。
IP_SERVER=
偵測 IP 用的主機名稱。
IP_SERVER_IP=
偵測 IP 用的主機位址。
IP_URL=
偵測 IP 用的網頁 URL 。
CLIENT_TYPE=
主機連線類型。其值為 "client" 或 "proxy" 二者之一。
若主機沒有使用 proxy 或使用 ISP 提供的 proxy,請設為 "client"。
若主機使用 local LAN 的 proxy ,則請設為 "proxy"。
MASQ_IF=
連線將會經過 NAT 的界面,但其偽裝位址需作 ddns 更新。
(注意:NAT 必須要有相應的 port mapping 設定。)
EXCL_IF=
排除在 ddns 更新之外的界面。
通常是連線將會經過 NAT 的界面,但其偽裝位址不作 ddns 更新。
* 參數說明:
-e "<interface...>"
排除在 ddns 更新之外的界面,可設定多個。
若為多個界面,其值必須至於雙引號(" ")或單引號(' ')之中,如:
-e "eth0 eth1"
參數值將會擴充至 $ESCL_IF 變數裡面。
* 注意要點:
1) 關於動態 ddns 的 server 及 client 端設定,請另行參考:
http://www.study-area.org/tips/ddns.htm
2) 請定期檢測及確認 ddns server 能夠連線及正常運作。
3) 當前實作範例,是將 ddns.sh 與相關的 keys 置於 ddns 子目錄中。
6.4 軟件包
我將本實作所用到的 script 及其它相關檔案包裝為 tarball ,其內容如下:
multipath/
工作目錄
multipath/run_ip.sh
路由更新 script
multipath/chk_line.sh
連線檢測 script
multipath/ddns/
ddns 子目錄
multipath/ddns/ddns.sh
ddns 更新 script
multipath/ddns/Ktestddns.+157+14615.key
ddns key
multipath/ddns/Ktestddns.+157+14615.private
ddns private key
multipath/configs
共用變數
multipath/kernel-patch/
kernel-patch 子目錄
multipath/kernel-patch/2.4.25-mp01
kernel 2.4.25 config 檔
multipath/kernel-patch/patch-2.4.25-ja2.diff
kernel 2.4.25 修補檔
multipath/statics
靜態路由 script
大家可以從如下位址下載整個軟件包:
http://www.study-area.org/linux/src/multipath.tgz
七、關於 kernel patch
7.1 關於 patch-2.4.25-ja2.diff
本實作方案不一定需要進行 kernel path ,經測試是可用的。
只是因為 routing cache 的關係,通往同一個 destination 的 routing 可能在某一段時間內是不變的。
參考 http://www.lartc.org/howto/lartc.rpdb.multiple-links.html 最後一段有提到:
Note that balancing will not be perfect, as it is route based, and routes are cached.
This means that routes to often-used sites will always be over the same provider.
這對於某些需要作 session 記憶的連線來說(如連接 phpBB 討論版),是不錯的。
但倘若多條 session 在某一特定時間內均為同一目標位址,其流量並不會分攤到其它線路上。
如果要做到將不同的 session 分攤開來,而不論其目標位址是否相同,則須要下載 patch 修補。
我在 RedHat 9.0 上另行下載 kernel 2.4.25 源始碼及 patch-2.4.25-ja2.diff 這支 patch 。
大家可從前面 6.4 章節提供的 tarball 獲取這次實作所用的 config 及 patch 。
或至官方網站下載:
http://www.ssi.bg/~ja/patch-2.4.25-ja2.diff
7.2 關於 equailze
雖然前述 patch 能夠將不同的 session 分攤至不同連線,但這仍然是 by session 的分攤,
並非做到 by packet 層級的分攤,也就是所謂的"均衡負載"(equailze)。
要做到這點,似乎還要下載另一支 patch:
http://www.teatime.com.tw/~tommy/linux/equalize.patch
不過,遺憾的是,這部份我並沒有測試成功。
且後來也沒在 kernel 2.4.25 上與另一支 patch 混合使用。
關於 equailze 的探討及設定,大家可參考 study-area 的討論:
http://phorum.study-area.org/viewtopic.php?t=10085
若有人成功測試起來,歡迎回報分享。謝謝﹗
八、展望
當前實作並沒提及頻寬控管。若日後有時間,再來探討 QOS 及 cbq 相關的題目。
在這之前,大家不妨先參考:
http://peterkim.cgucccc.org/document/MPath.html
九、參考資料
http://phorum.study-area.org/viewtopic.php?t=10085
http://phorum.study-area.org/viewtopic.php?t=9057
http://www.teatime.com.tw/~tommy/doc/multipath.txt
http://www.study-area.org/tips/m_routing.htm
http://www.lartc.org/howto/lartc.rpdb.multiple-links.html
http://peterkim.cgucccc.org/document/MPath.html
------- 本文結束 ------

原文出處 - STUDY AREA
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|