· 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 2025-06-20


ID
Password
Join
If you always postpone pleasure you will never have it. Quit work and play for once!


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.0078 sec