#!/bin/bash #################################################################### # # iptables Firewall Script # # by hasu0707@gmail.com # #################################################################### IS_DEBUG=1 ###################################################################### # 화이트 리스트 (,로 구분한다) ###################################################################### WHITE_LIST="10.202.18.161,10.202.207.59,10.202.205.209" ###################################################################### # 기본 정책 ###################################################################### #DEFAULT_POLICY="DROP" DEFAULT_POLICY="ACCEPT" ###################################################################### # Linux Command Path ###################################################################### IP6TABLES_CMD="ip6tables" IPTABLES_CMD="iptables" ###################################################################### # Usage ###################################################################### func_usage() { echo echo "Usage (as root): $0 [start | restart | stop]" echo echo "Examples:" echo " # ${0} start" echo " # ${0} restart" echo " # ${0} stop" echo } ###################################################################### # 디버깅 메세지 출력 ###################################################################### func_debug_msg() { if [[ ${IS_DEBUG} -eq 1 ]] then echo "DEBUG:${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9}" fi } ###################################################################### # 커맨드 디버깅 메세지 출력 ###################################################################### func_run_cmd() { if [[ ${IS_DEBUG} -eq 1 ]] then echo "CMD: ${1}" eval "${1}" echo else eval "${1}" fi } ############################# # 시스템 IP주소 알아내기 ############################# get_system_ip_addr() { SYSTEM_IP_ADDR=$(hostname -I | awk '{print $1}') if [ -z ${SYSTEM_IP_ADDR} ] then echo "ERROR: Unknown IP Address." exit 1 fi echo "IP_ADDR: ${SYSTEM_IP_ADDR}" } ###################################################################### # 기본 정책 셋팅 ###################################################################### func_set_default_policy() { func_debug_msg ${FUNCNAME[0]} ${IPTABLES_CMD} -P INPUT ${DEFAULT_POLICY} ${IPTABLES_CMD} -P OUTPUT ${DEFAULT_POLICY} ${IPTABLES_CMD} -P FORWARD ${DEFAULT_POLICY} } ###################################################################### # Clean rules ###################################################################### func_clean_rules() { func_debug_msg ${FUNCNAME[0]} # Remove any existing rules form all chains ${IPTABLES_CMD} -F ${IPTABLES_CMD} -F -t nat ${IPTABLES_CMD} -F -t mangle ${IPTABLES_CMD} -F -t raw ${IPTABLES_CMD} -F -t filter # Remove any pre-existing user-defined chains ${IPTABLES_CMD} -X ${IPTABLES_CMD} -X -t nat ${IPTABLES_CMD} -X -t mangle ${IPTABLES_CMD} -X -t raw ${IPTABLES_CMD} -X -t filter # Zero all packet and byte counters ${IPTABLES_CMD} -Z ${IPTABLES_CMD} -Z -t nat ${IPTABLES_CMD} -Z -t mangle ${IPTABLES_CMD} -Z -t raw ${IPTABLES_CMD} -Z -t filter } func_block_ipv6_traffic() { func_debug_msg ${FUNCNAME[0]} # If the ip6tables command is available, try to block all IPv6 traffic. if [ -x ${IP6TABLES_CMD} ]; then # Set the default policies (drop everything). ${IP6TABLES_CMD} -P INPUT ${DEFAULT_POLICY} 2>/dev/null ${IP6TABLES_CMD} -P FORWARD ${DEFAULT_POLICY} 2>/dev/null ${IP6TABLES_CMD} -P OUTPUT ${DEFAULT_POLICY} 2>/dev/null # Delete all rules. ${IP6TABLES_CMD} -F 2>/dev/null ${IP6TABLES_CMD} -t mangle -F 2>/dev/null # Delete all (non-builtin) user-defined chains. ${IP6TABLES_CMD} -X 2>/dev/null ${IP6TABLES_CMD} -t mangle -X 2>/dev/null # Zero all packet and byte counters. ${IP6TABLES_CMD} -Z 2>/dev/null ${IP6TABLES_CMD} -t mangle -Z 2>/dev/null else echo "${IP6_TABLES} not available" fi } ###################################################################### # Input rules ###################################################################### func_set_default_lo_rules() { func_debug_msg ${FUNCNAME[0]} ####################################################### # Allow unlimited traffic on loopback interface ####################################################### ${IPTABLES_CMD} -A INPUT -i lo -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -o lo -j ACCEPT } ###################################################################### # 외부에서 방화벽으로 접근 (WAN→this device) # ${1} : 외부 서버 주소 # ex) "-s 123.123.123.12/32" : 특정 외부 주소 # "-m geoip --src-cc KR" : geoip 적용 # "-s ${ANY_NET}" : 모든 주소 # ${2} : 목적지 # ${3} : 프로토콜 # ${4} : 포트 번호 # ${5} : comment # ${6} : ACCEPT (1=ACCEPT, 0=DENY, *=REJECT) # ex) "-s ${WHITE_LIST}" "tcp" "52400:52450" "WAN->this device:ftp-data" "1" ###################################################################### func_add_user_incoming() { func_debug_msg ${FUNCNAME[0]} "${1}" "${2}" "${3}" "${4}" "${5}" "${6}" RULE_CMD="${IPTABLES_CMD} -A INPUT ${1} -d ${2} -p ${3} -m ${3} --dport ${4} -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment \"${5}\"" case "${6}" in "0") RULE_CMD="${RULE_CMD} -j DROP" ;; "1") RULE_CMD="${RULE_CMD} -j ACCEPT" ;; *) RULE_CMD="${RULE_CMD} -j REJECT" ;; esac func_run_cmd "${RULE_CMD}" RULE_CMD="${IPTABLES_CMD} -A OUTPUT -p ${3} -m ${3} --sport ${4} -m conntrack --ctstate ESTABLISHED -m comment --comment \"${5}\"" case "${6}" in "0") RULE_CMD="${RULE_CMD} -j DROP" ;; "1") RULE_CMD="${RULE_CMD} -j ACCEPT" ;; *) RULE_CMD="${RULE_CMD} -j REJECT" ;; esac func_run_cmd "${RULE_CMD}" } ###################################################################### # 외부에서 들어오는 트래픽을 추가한다. ###################################################################### func_add_incoming_rules() { func_debug_msg ${FUNCNAME[0]} "${1}" "${2}" "${3}" "${4}" "${5}" "${6}" # nslookup 내부에서 외부로 통신 가능하게 셋팅 ${IPTABLES_CMD} -A INPUT -p udp --dport 53 -j ACCEPT ${IPTABLES_CMD} -A INPUT -p udp --sport 53 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p udp --sport 53 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p udp --sport 53 -j ACCEPT # https 내부에서 외부로 통신 가능하게 셋팅 ${IPTABLES_CMD} -A INPUT -p tcp --dport 443 -j ACCEPT ${IPTABLES_CMD} -A INPUT -p tcp --sport 443 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p tcp --sport 443 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p tcp --sport 443 -j ACCEPT # http 내부에서 외부로 통신 가능하게 셋팅 ${IPTABLES_CMD} -A INPUT -p tcp --dport 80 -j ACCEPT ${IPTABLES_CMD} -A INPUT -p tcp --sport 80 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p tcp --sport 80 -j ACCEPT ${IPTABLES_CMD} -A OUTPUT -p tcp --sport 80 -j ACCEPT # icmp 허용 #${IPTABLES_CMD} -A INPUT -p icmp -j ACCEPT #${IPTABLES_CMD} -A OUTPUT -p icmp -j ACCEPT func_add_user_incoming "-s ${WHITE_LIST}" "${SYSTEM_IP_ADDR}" "tcp" "22" "Incoming Rule:ssh" "1" func_add_user_incoming "-s ${WHITE_LIST}" "${SYSTEM_IP_ADDR}" "tcp" "8080" "Incoming Rule:ssc2" "1" func_add_user_incoming "-s ${WHITE_LIST}" "${SYSTEM_IP_ADDR}" "tcp" "9090" "Incoming Rule:ssc1" "1" } ###################################################################### # 모두 차단 ###################################################################### func_final_rules() { func_debug_msg ${FUNCNAME[0]} "${1}" "${2}" "${3}" "${4}" "${5}" "${6}" ${IPTABLES_CMD} -A INPUT -j DROP ${IPTABLES_CMD} -A OUTPUT -j ACCEPT ${IPTABLES_CMD} -A FORWARD -j DROP } ###################################################################### # Main ###################################################################### if [ "$2" != "" ]; then echo echo "Argument \"$2\" not recognized." func_usage echo exit 1 fi get_system_ip_addr case "$1" in start|restart) func_clean_rules func_set_default_policy func_set_default_lo_rules DEFAULT_POLICY="DROP" func_block_ipv6_traffic func_add_incoming_rules func_final_rules ;; stop) DEFAULT_POLICY="ACCEPT" func_clean_rules func_set_default_policy func_block_ipv6_traffic ;; *) func_usage ;; esac exit 0