:::

Linux的iptables防火牆設定記事

2011-07-22_160136 view_iptables

iptables是Linux作業系統中常見的防火牆套件,中文的維基百科也有介紹iptables。它可以用來設計靈活的過濾規則,並以簡單的語法進行設定,是Linux的網管人員必須學習操作的套件。架設伺服器時,為了防止被惡意攻擊、入侵,網管人員都必須要一併設定防火牆。但是高靈活性的iptables設定起來門檻也相當的高,往往讓初學者不知該從何設起。

我最近鑽研iptables的設定,參考了Linux網管人員必讀的鳥哥的Linux私房菜中的iptables實際設定,並根據身邊的網路伺服器環境做了些修改,想辦法讓iptables的設定與使用讓人簡單易懂。

這一篇就是分享我設定iptables的腳本檔,介紹安裝與使用方法,供其他人設定iptables時作為參考。


iptables腳本檔防火牆設定概述

這些腳本檔是參考鳥哥的iptables實際設定修改而成,iptables腳本檔可以從以下網址下載:

在pulipuli.iptables.zip裡面有六個檔案。以sh副檔名的三個檔案是可以執行的腳本檔,其他三個則是設定檔。

以下簡單敘述這些腳本檔的目的,稍後會再詳細介紹腳本檔的內容與用法。

  • iptables.rule.sh:設定iptables的主要規則。以下三個檔案是依附此腳本的設定檔:
    • iptables.deny:設定要阻擋的IP。
    • iptables.allow:設定要允許的IP。
    • iptables.service:設定要允許的連接埠。
  • reset_iptables.sh:清除iptables的設定。
  • view_iptables.sh:觀察iptables的設定。
iptables.rule.sh的功用

其中,主要的設定都集中在iptables.rule.sh中,裡面設定了相當多常見的防火牆規則。以下我簡單地敘述它的綱要:

  • 設定核心的網路功能
  • 重設防火牆設定:包括阻擋所有INPUT封包
  • 開放 lo 本機網路卡
  • 開放由本機發出的回應封包
  • 阻擋指定的IP:使用iptables.deny設定檔
  • 允許指定的IP連入:使用iptables.allow設定檔
  • 允許 0 3 3/4 4 11 12 14 16 18 ICMP封包進入
  • 允許指定的連接埠連入:使用iptables.service設定檔
  • 儲存防火牆設定

以下是iptables.rule.sh的內容:

#!/bin/bash

# 請先輸入您的相關參數,不要輸入錯誤了!
EXTIF="eth0" # 這個是可以連上 Public IP 的網路介面
RULE_PATH="/root/iptables" #iptables的設定路徑,最後不要有「/」
export EXTIF RULE_PATH

# 第一部份,針對本機的防火牆設定!##########################################
# 1. 先設定好核心的網路功能:

# 防止SYN Flloding的DoS攻擊
echo "1" > /proc/sys/net/ipv4/tcp_syncookies

# 防止ping的Dos攻擊
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

#rp_fileter:啟動逆向路徑過濾(Reverse Path Filtering)
#log_martians:記錄不合法的IP來源到/var/log/meesages
for i in /proc/sys/net/ipv4/conf/*/{rp_filter,log_martians}; do
echo "1" > $i
done

# 以下建議關閉
# accept_source_route:來源路由
# accept_redirects:IP相同時採用最短路徑
# send_redirects:與前者類似,發送ICMP redirect封包
for i in /proc/sys/net/ipv4/conf/*/{,accept_source_route,accept_redirects,send_redirects}; do
if [ -f $i ]; then
echo "0" > $i
fi
done

# 2. 清除規則、設定預設政策及開放 lo 與相關的設定值
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin; export PATH
iptables -F
iptables -X
iptables -Z
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

#接受lo本機介面網路卡
iptables -A INPUT -i lo -j ACCEPT

#接受由本機發出的回應封包
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# 3. 啟動額外的防火牆 script 模組
if [ -f $RULE_PATH/iptables.deny ]; then
sh $RULE_PATH/iptables.deny
fi

if [ -f $RULE_PATH/iptables.allow ]; then
sh $RULE_PATH/iptables.allow
fi

# 4. 允許某些類型的 ICMP 封包進入
# 詳細請參考ICMP協定 http://linux.vbird.org/linux_server/0110network_basic.php#tcpip_network_icmp
AICMP="0 3 3/4 4 11 12 14 16 18"
for tyicmp in $AICMP
do
iptables -A INPUT -i $EXTIF -p icmp --icmp-type $tyicmp -j ACCEPT
done

# 5. 允許某些服務的進入,請依照你自己的環境開啟
if [ -f $RULE_PATH/iptables.service ]; then
sh $RULE_PATH/iptables.service
fi

# 6. 最終將這些功能儲存下來吧!
/etc/init.d/iptables save

各個指令的意義請參考鳥哥的Linux私房菜 第九章、防火牆與NAT伺服器介紹,在此不贅述。以下我就直接介紹如何安裝、設定與使用這些腳本檔。


1. iptables腳本檔安裝

iptables的設定必須以 root 管理者 的身分操作,因此這一篇所有的動作都請以 root 進行吧。

另外,為了避免防火牆配置錯誤導致伺服器無法遠端連線,建議請在可以直接控制本機的時候再進行設定。以免設定錯誤導致伺服器無法連線的時候,再遠端也無能為力啊。

1-1. 檔案下載與配置

請下載以下檔案:

將該zip檔案上傳到伺服器的指定目錄「/root/」。並以unzip解壓縮。unzip解壓縮的指令如下:

[root@dspace-dlll ~]# unzip pulipuli.iptables.zip -d /root

iptables的腳本檔就會出現在「/root/iptables」目錄中。

當然,你也可以在其他電腦解壓縮之後再上傳到「/root/iptables」目錄。

1-2. 修改sh權限為700

為了要讓副檔名為sh的腳本檔可以執行,必須將他們的權限設為700,意思是只有擁有者root才能執行。

設定權限的指令如下:

[root@dspace-dlll ~]# chmod 700 /root/iptables/*.sh


2. iptables腳本檔設定

在主要設定中,我們會先讓iptables阻擋所有外來連線。因此我們要在以下三個檔案中設定特別阻擋或允許的IP與連接埠設定。以下主要設定的有三個檔案,他們的優先順序也是由先到後:

  1. iptables.deny:設定要阻擋的IP。
  2. iptables.allow:設定要允許的IP。
  3. iptables.service:設定要允許的連接埠。
2-1. iptables.deny 設定要阻擋的IP

檔案的內容如下,紅字的部份是要阻擋的IP

#!/bin/bash

# 這份設定要搭配iptables.rule.sh運作

# 底下填寫的是『你要抵擋的IP!』

# iptables -A INPUT -i $EXTIF -d members.lycos.co.uk -j DROP #不能使用Domain Name,會被iptables轉換成IP
iptables -A INPUT -i $EXTIF -s 213.131.252.251 -j DROP #阻止後門程式連入
iptables -A INPUT -i $EXTIF -d 213.131.252.251 -j DROP #阻止後門程式連出

在此範例中,我將「213.131.252.251」這個IP列為阻擋的對象。一個IP有兩條設定,一個是加上「-s」參數的阻擋連入,一個是加上「-d」參數的阻擋輸出。如果你要擋下其他的IP的話,可以據此依樣畫葫蘆建立相同的設定,然後更換IP即可。

2-2. iptables.allow 設定要允許的IP

檔案的內容如下,藍字的部份是要允許一定範圍的IP紅字部分是要允許的IP

#!/bin/bash

# 這份設定要搭配iptables.rule.sh運作

# 底下則填寫你允許進入本機的其他網域或主機

#iptables -A INPUT -i $EXTIF -s 140.119.61.0/255.255.255.0 -j ACCEPT #140.119.61.*的電腦,不建議開放
iptables -A INPUT -i $EXTIF -s 140.119.61.254 -j ACCEPT #允許指定IP連線

此例中,我設定「140.119.61.0/255.255.255.0」,也就是「140.119.61.*」這個範圍的IP都可以允許連線,不論是用哪種連接埠。(因為連接埠的設定iptables.service是在iptables.allow之後執行)但是這種大範圍的允許規則比較危險,除非你非常信任這個區域網路,否則不建議開放。因此我將此條規則前面加上「#」註解掉,讓它無法生效。

另外我指定「140.119.61.254」這個IP,允許他連線到伺服器,而不論是用哪種連接埠。如果你通常使用固定IP來管理這台伺服器,那麼我比較建議使用這種用法。

2-3. iptables.service 設定要允許的連接埠

檔案的內容如下,紅字的部份是要允許的連接埠藍字的部份是連接埠預設對應的服務名稱

#!/bin/bash

# 這份設定要搭配iptables.rule.sh運作

# 5. 允許某些服務的進入,請依照你自己的環境開啟
#iptables -A INPUT -p TCP -i $EXTIF --dport 21 --sport 1024:65534 -j ACCEPT # FTP
#iptables -A INPUT -p TCP -i $EXTIF --dport 22 --sport 1024:65534 -j ACCEPT # SSH 不建議直接開放,請允許IP即可
#iptables -A INPUT -p TCP -i $EXTIF --dport 25 --sport 1024:65534 -j ACCEPT # SMTP
#iptables -A INPUT -p UDP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS
#iptables -A INPUT -p TCP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS
iptables -A INPUT -p TCP -i $EXTIF --dport 80 --sport 1024:65534 -j ACCEPT # WWW
#iptables -A INPUT -p TCP -i $EXTIF --dport 110 --sport 1024:65534 -j ACCEPT # POP3
#iptables -A INPUT -p TCP -i $EXTIF --dport 389 --sport 1024:65534 -j ACCEPT # LDAP
#iptables -A INPUT -p TCP -i $EXTIF --dport 443 --sport 1024:65534 -j ACCEPT # HTTPS SSL
#iptables -A INPUT -p TCP -i $EXTIF --dport 8080 --sport 1024:65534 -j ACCEPT # Tomcat
#iptables -A INPUT -p TCP -i $EXTIF --dport 10000 --sport 1024:65534 -j ACCEPT # Webmin

在iptables.rule.sh中,我們先將所有連線都擋掉,而以白名單的方式設定要允許的連接埠。這邊設定的連接埠,可以讓任何電腦藉此連線到伺服器。

然而,我們一般伺服器開放的服務並沒有這麼多,通常只有開放WWW網頁伺服器而已,因此大部分的服務我都用「#」註解掉不使用。請依照你的需求來決定是否要開放。

必須要注意的是,我並不建議在此開放管理用的連接埠,像是ssh用的22、Webmin用的10000。我建議應該要設定 iptables.allow 指定允許的IP連線即可,這些IP不會受到iptables.service的連接埠設定限制。不要將管理用的連接埠開放到網際網路,是比較安全的作法。


3. 執行iptables腳本檔

3-1. 執行iptables.rule.sh:設定生效

設定完上述三個檔案之後,接下來執行 iptables.rule.sh 腳本檔,設定才會生效。

執行的指令與正常運作的訊息如下:

[root@dspace-dlll ~]# /root/iptables/iptables.rule.sh
正在儲存防火牆規則到 /etc/sysconfig/iptables: [ 確定 ]

3-2. 執行view_iptables.sh:檢查設定

為了確認iptables的設定是否有正常寫入,你可以執行 view_iptables.sh 這個腳本檔。其實它的內容只是「iptables –L –n -v」 ,也就是iptables查詢設定的指令。為了簡便記憶,我把它連同參數一起寫成 view_iptables.sh 這個腳本檔。

執行 view_iptables.sh 的指令與正常運作的訊息如下:

[root@dspace-dlll ~]# /root/iptables/view_iptables.sh
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
65 5564 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
55 3344 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 DROP all -- eth0 * 213.131.252.251 0.0.0.0/0
0 0 DROP all -- eth0 * 0.0.0.0/0 213.131.252.251
0 0 ACCEPT all -- eth0 * 140.119.61.254 0.0.0.0/0
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 0
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 3
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 3 code 4
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 4
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 11
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 12
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 14
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 16
0 0 ACCEPT icmp -- eth0 * 0.0.0.0/0 0.0.0.0/0 icmp type 18
0 0 ACCEPT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp spts:1024:65534 dpt:80

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 98 packets, 8728 bytes)
pkts bytes target prot opt in out source destination

看到設定都有順利存入iptables之後,防火牆設定就大功告成囉!

reset_iptables.sh:清除iptables設定

有時候防火牆設定並不如人意,你又不確定是哪裡設定錯誤的時候,你可以用 reset_iptables.sh 來暫時清除所有防火牆的設定。

reset_iptables.sh的檔案內容如下。

#!/bin/bash

# 清除iptables的所有設定,並允許所有連線
iptables -F
iptables -X
iptables -Z
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# 儲存設定
#/etc/init.d/iptables save #先不儲存,重開機之後就會恢復之前的設定

請注意最後一行,我將儲存設定的指令註解掉,因此清除iptables設定的動作並不會永久儲存,下次重新開機或重新啟動iptables的時候,之前的設定就會恢復。如果你有必要永久儲存的話,請取消這一行的註解吧。

reset_iptables.sh 的執行指令如下:

[root@dspace-dlll ~]# /root/iptables/reset_iptables.sh


結語

網路上對iptables規則設定的討論相當多,由於每台伺服器所在的網路環境都有所不同,因此似乎沒有能夠完美應對所有環境的設定。

我也還在鑽研iptables中,這個腳本檔也可能有些問題。在此歡迎大家多多指教。

總共6 則留言, (我要發問)

  1. 很高興可以看到這篇文章
    想問一下
    如果預設是DROP
    那除了大大上所列出的規則外
    是否還要加入底下的規則呢?

    # 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

    謝謝

    回覆刪除
  2. 哎呀呀,我自己也不是很熟呢
    以下請高手解答:

    回覆刪除
  3. 您好,想跟您請教,我使用Ubuntu 12.04 Desktop版,kernel是3.13.0,
    已裝入您這個檔案,
    最後在執行iptables.rule.sh時,
    結果沒有/etc/init.d/iptables沒有此一檔案或目錄,
    我找了一下,也沒有/etc/sysconfig/這個目錄,
    是因為我的iptables不是安裝來的嗎?
    這樣是否有其他方式能儲存這些iptables的規則呢?
    謝謝!

    回覆刪除
  4. ​To 3樓匿名,

    我跟鳥哥的教學是用CentOS,也就是RedHat系列(包含了RedHat/Fedora/CentOS)
    你的Ubuntu是Debian系列
    兩大不同類型的Linux使用的系統路徑不同。

    /etc/sysconfig 是RedHat系列的路徑,Ubuntu不使用這個路徑。
    http://ubuntuforums.org/showthread.php?t=2061511

    關於在Ubuntu上設定iptables,可以參考「就是,蛋!」的介紹
    http://blog.jsdan.com/basic-iptables/

    回覆刪除
  5. 瞭解了,感謝您的回覆!

    回覆刪除

留言工具: