· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
iptables

iptables

WikiPedia:Iptables는 리눅스 2.4 이전 버전에서 쓰이던 WikiPedia:Ipchains를 대신하는 IP 수준의 패킷 처리 유틸리티입니다. Netfilter라 불리는 커널 내의 패킷 필터링 기능을 사용자 공간에서 제어하는 데에 사용됩니다. 기본적으로는 특정 조건을 가진 패킷에 대한 허용(ACCEPT)과 차단(DROP) 등을 지정해 줄 수 있지만, 수많은 확장 기능을 통해 다양한 방식의 필터링(match: 프로토콜, 길이, ToS, ...)과 처리 방식(target: NAT, 로깅, 마킹, 전환, ...)을 지원하고 있습니다. 리눅스 기반의 여러 공개/상용 방화벽들 및 기타 네트워크 장비들이 iptables를 이용하고 있습니다.

  • http://www.netfilter.org/ : netfilter/iptables 홈페이지
  • /lib/modules/{version}/kernel/net/ipv4/netfilter 디렉터리에 확장 기능을 위한 오브젝트 파일들이 있습니다.
  • 커널 옵션 트리의 'Device Drivers/Networking support/Networking options/Network packet filtering' 하에 관련 옵션들이 위치합니다. (2.6 기준)
  • Netfilter 설정의 저장과 복구를 위해 iptables-saveiptables-restore 프로그램이 사용됩니다.
  • 유사한 프로그램으로 arptables가 있습니다. 브리지 방화벽에서 링크 레이어(이더넷)에서의 필터링 등을 수행하는 [http]bridge-netfilter의 사용자 공간 유틸리티입니다.

KLDPWiki 내의 관련 문서

  • target을 지정하지 않고 규칙을 집어넣으면 패킷 카운트만 올라가고 다음 규칙으로 넘어갑니다. 간단하게 패킷 카운팅을 하는 데에 사용할 수 있습니다. '-v' 옵션을 붙여서 리스팅을 하면 패킷/바이트 카운트가 함께 표시됩니다.

iptables script

  • 각자 사용하고 있는 일반화된 사용목적의 rule script를 소개해주세요.
  • "/etc/sysctl.conf"에서 다음 항목을 확인하여 활성화를 반드시 해주어야 합니다.
    net.ipv4.ip_forward = 1
    
    # IPv6 forward를 지원하려면 (이 경우는 ip6tables를 사용하는 경우겠죠)
    # net.ipv6.ip_forward = 1
    
  • 두개의 Interface를 사용하여 간단한 인터넷 공유기로 만들어주는 rule script
    #!/bin/sh
    # by minzkn <minzkn@infoeq.com>
    
    # 외부 인터넷이 되는 interface (ADSL인 경우는 ppp0가 되겠죠)
    IF_EXTERN=eth0
    # 내부 gateway가 될 interface
    IF_LOCAL=eth1
    # 사용할 local 주소대역
    MASQUE_ADDRESS=192.168.0.0/24
    #MASQUE_ADDRESS=10.0.0.0/8
    
    /sbin/iptables -P INPUT ACCEPT
    /sbin/iptables -F INPUT
    /sbin/iptables -P OUTPUT ACCEPT
    /sbin/iptables -F OUTPUT
    /sbin/iptables -P FORWARD DROP
    /sbin/iptables -F FORWARD
    /sbin/iptables -t nat -F
    
    /sbin/iptables -A FORWARD -i ${IF_EXTERN} -o ${IF_LOCAL} -m state --state ESTABLISHED,RELATED -j ACCEPT
    /sbin/iptables -A FORWARD -i ${IF_LOCAL} -o ${IF_EXTERN} -j ACCEPT
    /sbin/iptables -A FORWARD -j LOG
    
    /sbin/iptables -t nat -A POSTROUTING -o ${IF_EXTERN} -s ${MASQUE_ADDRESS} -j MASQUERADE
    
    # 외부로부터 내부의 IP로 특정 포트를 포워드시킬때 다음과 같이 하면 됨. (아래 예시는 cvs port인 2401를 192.168.0.100 에 포워드 시키는 예제)
    #/sbin/iptables -t nat -A PREROUTING -i ${IF_EXTERN} -p tcp --dport 2401 -j DNAT --to 192.168.0.100:2401
    
    # End if masq_ip.sh
    
  • 방화벽 및 공유기 두가지 모두를 손쉽게 설정하려고 만들었던 script
    #!/bin/sh
    
    # Copyright (C) INFOEQ co.,LTD.
    # All rights reserved.
    # 
    # Author: JaeHyuk Cho <minzkn@infoeq.com>
    #
    # mzfirewall.sh version 1.0.0 20080530
    
    EXEC_IPTABLES=/sbin/iptables
    EXEC_IFCONFIG=/sbin/ifconfig
    
    SERVER_INTERFACE=eth0
    #SERVER_INTERFACE=eth1
    #SERVER_INTERFACE=tun6to4
    #SERVER_INTERFACE=bond0
    
    # *** 공유기 설정 ***
    USE_NAT=yes
    # 외부 인터넷이 되는 interface (ADSL인 경우는 ppp0가 되겠죠)
    EXTERN_INTERFACE=${SERVER_INTERFACE}
    # 내부 gateway가 될 interface
    LOCAL_INTERFACE=eth1
    # 사용할 local 주소대역
    MASQUE_ADDRESS=192.168.0.0/24
    
    # -----------------------------------------------------
    # 기반작업 준비
    
    # Interface IP를 얻어온다.
    SERVER_IP=`${EXEC_IFCONFIG} ${SERVER_INTERFACE} | grep "\<inet addr\>" | awk '{ gsub("addr:", "" ) ; print $2}'` 
    CHAIN_NAME_PREFIX=MZSERVER
    
    # -----------------------------------------------------
    # 기반함수 (라이브러리)
    
    # 신규 chain을 생성 함수 - chain target
    s_mzfirewall_create_chain() {
        # 새로운 chain을 생성한다.
        ${EXEC_IPTABLES} -t filter -N ${2}
        
        # 넘겨줄 chain을 형성한다.
        ${EXEC_IPTABLES} -t filter -A ${1} -j ${2}
    }
    
    # 입력 개별거부정책 함수 - protocol source sport destination dport
    s_mzfirewall_block_input_drop() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_BLOCK_INPUT -p ${1} -s ${2} --sport ${3} -d ${4} --dport ${5} -j DROP
    }
    
    # 입력 개별거부정책 함수 - protocol source destination
    s_mzfirewall_block_input_drop_noport() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_BLOCK_INPUT -p ${1} -s ${2} -d ${3} -j DROP
    }
    
    # 입력 거부정책 함수 - protocol source sport destination dport
    s_mzfirewall_input_drop() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_INPUT -p ${1} -s ${2} --sport ${3} -d ${4} --dport ${5} -j DROP
    }
    
    # 입력 거부정책 함수 - protocol source destination
    s_mzfirewall_input_drop_noport() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_INPUT -p ${1} -s ${2} -d ${3} -j DROP
    }
    
    # 입력 허용정책 함수 - protocol source sport destination dport
    s_mzfirewall_input_accept() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_INPUT -p ${1} -s ${2} --sport ${3} -d ${4} --dport ${5} -j ACCEPT
    }
    
    # 입력 허용정책 함수 - protocol source destination
    s_mzfirewall_input_accept_noport() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_INPUT -p ${1} -s ${2} -d ${3} -j ACCEPT
    }
    
    # 출력 거부정책 함수 - protocol source sport destination dport
    s_mzfirewall_output_drop() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_OUTPUT -p ${1} -s ${2} --sport ${3} -d ${4} --dport ${5} -j DROP
    }
    
    # 출력 거부정책 함수 - protocol source destination
    s_mzfirewall_output_drop_noport() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_OUTPUT -p ${1} -s ${2} -d ${3} -j DROP
    }
    
    # 출력 허용정책 함수 - protocol source sport destination dport
    s_mzfirewall_output_accept() {
        ${EXEC_IPTABLES} -I ${CHAIN_NAME_PREFIX}_OUTPUT -p ${1} -s ${2} --sport ${3} -d ${4} --dport ${5} -j ACCEPT
    }
    
    # 출력 허용정책 함수 - protocol source destination
    s_mzfirewall_output_accept_noport() {
        ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_OUTPUT -p ${1} -s ${2} -d ${3} -j ACCEPT
    }
    
    # -----------------------------------------------------
    # 수행함수
    
    # 초기화 과정
    mzfirewall_clean() {
        # 모든 chain들의 규칙을 삭제한다.
        ${EXEC_IPTABLES} -F
    
        # 규칙이 없는 chain을 제거한다.
        ${EXEC_IPTABLES} -X
    }
    
    # 기본 정책 설정
    mzfirewall_default_raw() {
        # 입력은 기본적으로 모두 막는다.
        ${EXEC_IPTABLES} -P INPUT DROP
        
        # 출력은 기본적으로 모두 허용한다.
        ${EXEC_IPTABLES} -P OUTPUT ACCEPT
        
        # 출력은 기본적으로 모두 허용한다.
        ${EXEC_IPTABLES} -P FORWARD ACCEPT
    }
    
    # 상식수준의 방화벽 정책을 설정한다.
    mzfirewall_default_rule() {
        # 잘못된 TCP상태는 모두 막는다.
        ${EXEC_IPTABLES} -A INPUT -p tcp -m state --state INVALID -j DROP
    
        # 이미 접속되어 있는 연결은 입력을 허용한다.
        ${EXEC_IPTABLES} -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
    
        # loopback의 모든 입력은 허용한다.
        ${EXEC_IPTABLES} -A INPUT -i lo -j ACCEPT
        ${EXEC_IPTABLES} -A INPUT -p tcp -d any/0 --dport auth -j ACCEPT
    }
    
    # 신규 chain을 생성
    mzfirewall_create_chain() {
        s_mzfirewall_create_chain INPUT ${CHAIN_NAME_PREFIX}_BLOCK_INPUT
        s_mzfirewall_create_chain INPUT ${CHAIN_NAME_PREFIX}_INPUT
        s_mzfirewall_create_chain OUTPUT ${CHAIN_NAME_PREFIX}_OUTPUT
        s_mzfirewall_create_chain FORWARD ${CHAIN_NAME_PREFIX}_FORWARD
    }
    
    # 입력 방화벽 정책
    mzfirewall_input_rules() {
        # domain accept
        s_mzfirewall_input_accept udp 0/0 domain 0/0 0:
        s_mzfirewall_input_accept tcp 0/0 domain 0/0 0:
    
        # ICMP 입력 허용
        s_mzfirewall_input_accept_noport icmp 0/0 0/0
    
        # FTP 입력 허용
        s_mzfirewall_input_accept tcp 0/0 1024: 0/0 ftp
        s_mzfirewall_input_accept tcp 0/0 0: 0/0 ftp-data
    
        # TELNET 입력 허용
        s_mzfirewall_input_accept tcp 0/0 1024: 0/0 telnet
    
        # SSH 입력 허용
        s_mzfirewall_input_accept tcp 0/0 1024: 0/0 ssh
    
        # HTTP 입력 허용
        s_mzfirewall_input_accept tcp 0/0 1024: 0/0 http
    
        # 특정 포트 입력 허용
        s_mzfirewall_input_accept tcp 0/0 1024: 0/0 2744
    }
    
    # 출력 방화벽 정책 - 거부정책을 먼저 기술합니다.
    mzfirewall_output_rules() {
        # 외부로의 IRC접속 거부 - IRC를 사용하지 않는다면 IRC출력거부를 추천합니다.
        #s_mzfirewall_output_drop tcp 0/0 0: 0/0 ircd
    
        # DOMAIN 출력 허용
        s_mzfirewall_output_accept udp 0/0 0: 0/0 domain
        s_mzfirewall_output_accept tcp 0/0 0: 0/0 domain
        
        # SMTP 출력 허용
        s_mzfirewall_output_accept udp 0/0 0: 0/0 smtp
    }
    
    # 블랙리스트 차단
    mzfirewall_block_input_rules() {
        # 그냥 스크립트 수정해서 추가할때...
        s_mzfirewall_block_input_drop_noport all 210.212.219.61/32 0/0
    
        # block.list 파일에 차단할 IP목록을 열거하면 되는 방법
        #exec < "block.list"
        #while read block_ip
        #do
        #    block_ip=`echo ${block_ip} | sed 's/ //g'`
        #    if ! [ $(echo ${block_ip} | grep "^#") ] ; then
        #        if [ "${block_ip}" != "" ]  ; then
        #            s_mzfirewall_block_input_drop_noport all ${block_ip} 0/0
        #        fi
        #    fi
        #done
    }
    
    # 공유기
    mzfirewall_nat() {
        if [ "${USE_NAT}" = "yes" ]; then
            # POSTROUTING은 내부에서 외부로 전송할때 규칙이고 PREROUTING은 외부에서 내부로 전송할때 규칙임.
    
            # 기본적으로 통과시키는 Interface 경로를 형성한다.
            ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_FORWARD -i ${EXTERN_INTERFACE} -o ${LOCAL_INTERFACE} -m state --state ESTABLISHED,RELATED -j ACCEPT
            ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_FORWARD -i ${LOCAL_INTERFACE} -o ${EXTERN_INTERFACE} -j ACCEPT
            ${EXEC_IPTABLES} -A ${CHAIN_NAME_PREFIX}_FORWARD -j LOG
    
            # Local IP address 대역을 Masquerade 시킨다.
            ${EXEC_IPTABLES} -t nat -A POSTROUTING -o ${EXTERN_INTERFACE} -s ${MASQUE_ADDRESS} -j MASQUERADE
    
            # 외부로부터 내부의 IP로 특정 포트를 포워드시킬때 다음과 같이 하면 됨. (아래 예시는 cvs port인 2401를 192.168.0.100 에 포워드 시키는 예제)
            #${EXEC_IPTABLES} -t nat -A PREROUTING -i ${EXTERN_INTERFACE} -p tcp --dport 2401 -j DNAT --to 192.168.0.100:2401
        fi
    }
    
    # 결과 확인
    mzfirewall_report() {
        echo "iptables path is \"${EXEC_IPTABLES}\""
        echo "server ip is \"${SERVER_IP}\" (${SERVER_INTERFACE})"
    
        ${EXEC_IPTABLES} --list
    }
    
    # 방화벽 사용
    mzfirewall_start() {
        mzfirewall_clean
        mzfirewall_default_raw
        mzfirewall_default_rule
        mzfirewall_create_chain
    
        mzfirewall_input_rules
        mzfirewall_output_rules
    
        mzfirewall_block_input_rules
    
        mzfirewall_nat
    }
    
    # 방화벽 사용안함
    mzfirewall_stop() {
        mzfirewall_clean    
        
        # 입력은 기본적으로 모두 허용한다.
        ${EXEC_IPTABLES} -P INPUT ACCEPT
        
        # 출력은 기본적으로 모두 허용한다.
        ${EXEC_IPTABLES} -P OUTPUT ACCEPT
        
        # 출력은 기본적으로 모두 허용한다.
        ${EXEC_IPTABLES} -P FORWARD ACCEPT
    
    }
    
    # 방화벽 재시작
    mzfirewall_restart() {
        mzfirewall_stop
        mzfirewall_start
    }
    
    # -----------------------------------------------------
    
    case "$1" in
        start)
            mzfirewall_start
            ;;
        stop)
            mzfirewall_stop
            ;;
        restart|reload)
            mzfirewall_restart
            ;;
        report|show|list|status)
            mzfirewall_report
            ;;
        *)
            echo $"Usage: $0 {start|stop|restart|status}"
            exit 1
    esac
    
    # End of mzfirewall.sh
    


전달 메시지

링크 걸어놓으신 페이지를 직접 위키에 붙여서 번역해도 될까요? - jachin 2019-09-20




sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-03-12 14:58:04
Processing time 0.0017 sec