= 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-save}}}와 {{{iptables-restore}}} 프로그램이 사용됩니다. * 유사한 프로그램으로 arptables가 있습니다. 브리지 방화벽에서 링크 레이어(이더넷)에서의 필터링 등을 수행하는 [http://ebtables.sourceforge.net/ bridge-netfilter]의 사용자 공간 유틸리티입니다. == KLDPWiki 내의 관련 문서 == * [wiki:LinuxdocSgml/Packet_Filtering-TRANS 리눅스 2.4 패킷 필터링 하우투]: 패킷 필터링 총알 가이드 * [wiki:DocbookSgml/Netfilter-extensions-TRANS Netfilter 확장 HOWTO]: 여러 확장 기능에 대한 사용법 * [wiki:DocbookSgml/Masquerading-Simple-HOWTO Masquerading Simple HOWTO]: NAPT에 대한 간단한 설명 * [wiki:LinuxdocSgml/2.4_NAT-TRANS 리눅스 2.4 NAT HOWTO]: NAT에 대한 좀더 넓은 설명 * [wiki:DocbookSgml/BridgeFirewall-HOWTO 리눅스로 Bridge Firewall 만들기]: [iptables]와 bridge 패치를 이용한 브리지 방화벽 만들기 * [wiki:Kernel%202.6%20%B1%E2%B9%DD%C0%C7%20Bridge%20Firwall%20%2B%20PPTP%28VPN%29%20%B1%B8%C3%E0%C7%CF%B1%E2%20Part%201. Kernel 2.6 기반의 Bridge Firewall + PPTP(VPN) 구축하기 Part 1.]: 커널 2.6으로 브리지 방화벽 만들기 * [wiki:DocbookSgml/Traffic_LoadBalancing-KLDP Linux kernel 2.4 네트웍 트래픽 분산]: [iptables]와 iproute2를 이용한 트래픽 분산 방법 == 기타 관련 문서 == 현재 iptables 에 관한 정보를 모으고 있습니다. 함께 모아 정리해요. * [http://www.yolinux.com/TUTORIALS/LinuxTutorialIptablesNetworkGateway.html http://www.yolinux.com/TUTORIALS/LinuxTutorialIptablesNetworkGateway.html] * [http://iptables-tutorial.frozentux.net/iptables-tutorial.html http://iptables-tutorial.frozentux.net/iptables-tutorial.html] * [http://www.linuxguruz.com/iptables/howto/ http://www.linuxguruz.com/iptables/howto/] * [http://www.sns.ias.edu/~jns/security/iptables/ http://www.sns.ias.edu/~jns/security/iptables/] == 팁 == * 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 # 외부 인터넷이 되는 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 # # 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 "\" | 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] [[Date]] ---- CategorySecurity