#!/bin/sh # # A simple script for Firewall, used in Linux iptables Modules(kernel 2.4.x). # Update Date: 2003/05/06 # # Copyright (C) 2003 by CHENG, Liang-Hsing (jls@mail.sinsen.com.tw). # Website: http://www.sinsen.com.tw/ # # 以下Script如有任何錯誤或您有更好的設定 # 敬請您 E-Mail 來指正 謝謝 ! # PATH=/sbin:/usr/sbin:/bin:/usr/bin ###==============此段請依個人需要自行設定===============### ########## 設定內外網卡,請自行設定,要是用撥接請在外部網卡設ppp0 ########### ##### 外部網卡 EXT_IF="eth0" ##### 要是只有一張網卡就設 INT_IF="eth0" 吧 ##### 內部網卡 INT_IF="eth0" ##### 想要對外開放的PORT (依個人需要,增加或減少) OPEN_PORT="20 21 22 25 53 80 110 113 123 143 443 3128 10000 12000" ##### NAT 內部IP (依個人需要,如無需要請設為 NAT_IP="" ) NAT_IP="" if [ "$NAT_IP" != "" ]; then ##### 想要對 NAT 開放的 PORT (依個人需要,增加或減少) NAT_PORT="20 21 22 25 53 80 110 113 143 443 3128 10000 12000" fi ###============以下如無特別需要,不需做任何修改==========### netinfo () { IP="" MASK="" NET="" for NIC in "$@" ; do { IP=`ifconfig $NIC |grep 'inet addr' |awk '{print $2}'|sed -e "s/addr\://"` MASK=`ifconfig $NIC |grep 'inet addr' |awk '{print $4}'|sed -e "s/Mask\://"` IP1=`echo $IP |awk -F'.' '{print $1}'` if [ "$IP1" = "" ]; then echo "" echo "Warning: there is no IP found on $NIC." echo "Action is aborted." echo "Please make sure the interface is setup properly, then try again." echo "" exit 1 else IP2=`echo $IP |awk -F'.' '{print $2}'` IP3=`echo $IP |awk -F'.' '{print $3}'` IP4=`echo $IP |awk -F'.' '{print $4}'` MASK1=`echo $MASK |awk -F'.' '{print $1}'` MASK2=`echo $MASK |awk -F'.' '{print $2}'` MASK3=`echo $MASK |awk -F'.' '{print $3}'` MASK4=`echo $MASK |awk -F'.' '{print $4}'` let NET1="$IP1 & $MASK1" let NET2="$IP2 & $MASK2" let NET3="$IP3 & $MASK3" let NET4="$IP4 & $MASK4" NET="$NET1.$NET2.$NET3.$NET4" fi } done } ##### 變數設定 KVERSION="/lib/modules/`uname -r`/kernel/net/ipv4/netfilter" HI="1024:65535" HD_DEV="hda hdb hdc hdd" ###### 外部網段 netinfo "$EXT_IF" EXT_IP="$IP" EXT_NET="$NET"/"$MASK" ####### 內部網段 netinfo "$INT_IF" INT_IP="$IP" INT_NET="$NET"/"$MASK" ####### HD Ata 66 if [ -f "/proc/scsi/scsi" ] && [ "`cat /proc/scsi/scsi`" != "Attached devices: none" ]; then echo "為 SCSI 介面" else CHK_HDPARM=$(which hdparm 2>/dev/null) if [ -n "$CHK_HDPARM" ]; then ######起動 HD ATA 66 echo "啟動 HD ATA 66" #################### for HD in $HD_DEV; do hdparm -d1 -X1 -k1 -c3 -m1 /dev/$HD 2>/dev/null done fi fi ###### 載入相關模阻 echo 載入模阻 ################## for file in $KVERSION/ip_*.* do module=$(basename $file) modprobe ${module%%.*} &>/dev/null done for file in $KVERSION/ipt*.* do module=$(basename $file) modprobe ${module%%.*} &>/dev/null done ###### 關閉 ipchains CHK_IPCHAINS=$(which ipchains 2>/dev/null) CHK_IPCHAINS_M=$(lsmod | grep ipchains) if [ -n "$CHK_IPCHAINS" ] && [ -n "$CHK_IPCHAINS_M" ]; then echo "Disabling ipchains..." /etc/rc.d/init.d/ipchains stop &>/dev/null || ipchains -F &>/dev/null rmmod ipchains fi ####### 檢查 iptables 是否啟動 CHK_IPTABLES=$(which iptables 2>/dev/null) if [ -z "$CHK_IPTABLES" ]; then echo echo "$(basename $0): iptables program is not found." echo " Please install the program first." echo exit 1 fi ###### 重新設定 iptables -F iptables -X iptables -F -t filter iptables -X -t filter iptables -Z -t filter iptables -F -t nat iptables -X -t nat iptables -Z -t nat iptables -F -t mangle iptables -X -t mangle ###### 預設全部關閉 iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP ###### 將lo 的部份打開 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT ###### 將內部的通訊打開 if [ "$INT_IF" != "$EXT_IF" ] ; then iptables -A INPUT -i $INT_IF -j ACCEPT iptables -A OUTPUT -o $INT_IF -j ACCEPT iptables -A FORWARD -i $INT_IF -j ACCEPT iptables -A FORWARD -o $INT_IF -j ACCEPT fi ####### 防止超量攻擊 echo 1 > /proc/sys/net/ipv4/tcp_syncookies ####### 啟動 IP 轉送 echo 1 > /proc/sys/net/ipv4/ip_forward ####### 關閉 PING 的回應 echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all ####### 啟動所有介面的來源 IP 查核 if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] then for f in /proc/sys/net/ipv4/conf/*/rp_filter do echo "1" > $f done fi ####### 記錄所有PING的LOG iptables -A INPUT -p icmp -j LOG ######## 防止 Ping of Death iptables -N icmpfilter iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type echo-request -j DROP iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type echo-reply -j ACCEPT iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type parameter-problem -j ACCEPT iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type source-quench -j ACCEPT iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmpfilter -i $EXT_IF -p icmp --icmp-type fragmentation-needed -j ACCEPT iptables -A INPUT -i $EXT_IF -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT iptables -A OUTPUT -m state -p icmp --state INVALID -j DROP iptables -A OUTPUT -p icmp -s $EXT_IP --icmp-type 8 -d any/0 -j ACCEPT iptables -A INPUT -p icmp -s any/0 --icmp-type 0 -d $EXT_IP -j ACCEPT ######## 過瀘 iptables -N block iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A block -m state --state NEW -i ! $EXT_IF -j ACCEPT iptables -A INPUT -j icmpfilter iptables -A INPUT -j block iptables -A FORWARD -j icmpfilter iptables -A FORWARD -j block ######## 防止 sync flood 攻擊的設定 iptables -N synfoold iptables -A synfoold -p tcp --syn -m limit --limit 3/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 ######## 防止 SSL 攻擊 iptables -t nat -A OUTPUT -p tcp --sport 1000:3000 --dport 443 -j REDIRECT --to-port 10000 ######## 防止惡意掃描 iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags ALL NONE -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -i $EXT_IF -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 6/m -j ACCEPT ######## disable been scaned iptables -N tcp_packets iptables -A tcp_packets -p TCP --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags ALL ALL -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags ALL NONE -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "been scanned:" iptables -A tcp_packets -p TCP --tcp-flags ALL FIN,URG,PSH -j DROP iptables -A tcp_packets -p TCP --tcp-flags ALL ALL -j DROP iptables -A tcp_packets -p TCP --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP iptables -A tcp_packets -p TCP --tcp-flags ALL NONE -j DROP iptables -A tcp_packets -p TCP --tcp-flags SYN,RST SYN,RST -j DROP iptables -A tcp_packets -p TCP --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A FORWARD -p tcp -j tcp_packets ###-----------------------------------------------------### ###### 自訂 allowed 這個 chain 來處理 允許進入的 tcp 連線 ###### 凡 tcp_packets 中的 chain rule 目的是某些欲開放的 port 者, ###### 則跳至此一 allowed chain 來處理. ###-----------------------------------------------------### iptables -N allowed iptables -A allowed -p TCP --syn -j ACCEPT iptables -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A allowed -p TCP -j DROP iptables -A tcp_packets -p TCP -s 0/0 --dport 1024:65535 -j allowed for PORT in $OPEN_PORT; do iptables -A tcp_packets -p TCP -s 0/0 --dport $PORT -j allowed done ###### 對於主動連線或者是不合法連線,一律通通拒絕掉 iptables -A INPUT -i $EXT_IF -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $EXT_IF -m state --state NEW,INVALID -j DROP ###### 重導 www 請求至 Squid (透過代理伺服器) ###### 這樣可以強迫使用者使用 Proxy 而不必修改 Client 端設定 if [ "$INT_IF" != "$EXT_IF" ] ; then CHK_SQUID=$(/etc/rc.d/init.d/squid status 2>/dev/null | grep pid) if [ -n "$CHK_SQUID" ]; then echo "開啟 proxy 對外連線" INT_IP=$(ifconfig | grep $INT_IF -A 1 | awk '/inet/ {print $2}' | sed -e s/addr\://) if [ -z "$INT_IP" ]; then echo echo "$(basename $0): there is no IP found on $INT_IF." echo " Please make sure $INT_IF is setup properly." echo exit 3 fi iptables -t nat -A PREROUTING -i $INT_IF -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 fi fi ###-----------------------------------------------------### echo 啟動內部對外轉址 ###-----------------------------------------------------### if [ "$INT_IF" != "$EXT_IF" ] ; then iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -A POSTROUTING -s $INT_NET -j SNAT --to-source $EXT_IP iptables -t nat -A POSTROUTING -o $EXT_IF -s $INT_NET -j MASQUERADE fi ####### 語音 (依個人需要) #iptables -A PREROUTING -t nat -p tcp -i $EXT_IF --dport 389 -j DNAT --to 192.168.1.100 #iptables -A PREROUTING -t nat -p tcp -i $EXT_IF --dport 522 -j DNAT --to 192.168.1.100 #iptables -A PREROUTING -t nat -p tcp -i $EXT_IF --dport 1503 -j DNAT --to 192.168.1.100 #iptables -A PREROUTING -t nat -p tcp -i $EXT_IF --dport 1720 -j DNAT --to 192.168.1.100 #iptables -A PREROUTING -t nat -p tcp -i $EXT_IF --dport 1731 -j DNAT --to 192.168.1.100 ####### 將封包偽裝出去 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT ####### 單一USER的限制,只可連web 以IP為主(依個人需要) #iptables -I FORWARD -p all -s 他的IP -j DROP #iptables -I FORWARD -p tcp -s 他的IP --dport 80 -j ACCEPT ####### 單一USER的限制,只可連web 以網卡號碼為主(依個人需要) #iptables -I FORWARD -m mac --mac-source XX:XX:XX:XX:XX:XX -p all -j DROP #iptables -I FORWARD -m mac --mac-source XX:XX:XX:XX:XX:XX -p tcp --dport 80 -j ACCEPT ####### 阻擋指定的網卡號碼 (依個人需要) ####### 這是 Kernel 2.4 系列新功能,主要防止 Client 非法搶 IP #iptables -A INPUT -m mac --mac-source XX:XX:XX:XX:XX:XX -j DROP ####### 阻擋內部網卡號碼出去 (依個人需要) #iptables -I FORWARD -m mac --mac-source XX:XX:XX:XX:XX:XX -j DROP ###-----------------------------------------------------### echo "允許相關連結服務" ###-----------------------------------------------------### ####### 允許相關連結服務 for PORT in $OPEN_PORT; do iptables -A INPUT -i $EXT_IF -p tcp --dport $PORT -j ACCEPT iptables -A INPUT -i $EXT_IF -p udp --dport $PORT -j ACCEPT iptables -A INPUT -p tcp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT iptables -A INPUT -p udp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT iptables -A OUTPUT -o $EXT_IF -p tcp --dport $PORT -j ACCEPT iptables -A OUTPUT -o $EXT_IF -p udp --dport $PORT -j ACCEPT iptables -A OUTPUT -p tcp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT iptables -A OUTPUT -p udp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT iptables -A FORWARD -i $EXT_IF -p tcp --dport $PORT -j ACCEPT iptables -A FORWARD -i $EXT_IF -p udp --dport $PORT -j ACCEPT iptables -A FORWARD -p tcp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT iptables -A FORWARD -p udp --sport $HI -d $EXT_IP --dport $PORT -j ACCEPT done ###-----------------------------------------------------### #echo NAT部份對外網路轉址:eth0 IP位址:x.x.x.x ###-----------------------------------------------------### if [ "$NAT_IP" != "" ]; then clear echo "您已開啟對內轉址,IP:$NAT_IP" for NAT in $NAT_PORT; do iptables -t nat -A PREROUTING -p tcp -d $EXT_IP --dport $NAT -j DNAT --to-destination $NAT_IP:$NAT echo "外部IP=$EXT_IP PORT:$NAT ---------------> 轉內部IP=$NAT_IP PORT:$NAT" done fi #iptables -t nat -A PREROUTING -p tcp -d $EXT_IP -j DNAT --to-destination $NAT_IP exit 0