linux iptables 설명

in linux •  7 years ago 
  1. iptables 란?

iptables는 리눅스상에서 방화벽을 설정하는 도구로서 커널 2.4 이전 버전에서 사용되던 ipchains를 대신하는 방화벽 도구이다.
iptables는 커널상에서의 netfilter 패킷필터링 기능을 사용자 공간에서 제어하는 수준으로 사용할 수 있다.

패킷필터링이란 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다.
일반적으로 패킷은 해더와 데이터를 가진다.
해더에 필터링할 정보인 출발지IP:PORT, 도착지IP:PORT, checksum, 프로토콜 옵션등을 가지며 데이터는 각각의 전송데이터가 들어간다.

특정 조건을 가지고 있는 패킷에 대해 허용(ACCEPT)과 차단(DROP)등을 지정할 수 있으며, 특정 조건등을 통해 다양한 방식의 패킷 필터링과 처리 방식을 지원한다.

iptables 정책은 여러 구분으로 나눠지며 중요한 부분은 Chain이다.
Chain은 패킷이 조작될 상태를 지정하며 iptables에 내장된 기본 Chain은 다음과 같다.
(기본 Chain은 영구적이며 삭제가 불가능하다. 이외에 -N 옵션으로 지정하는 사용자 정의 Chain이 있다.)

Chain INPUT : 서버로 들어오는 기본 정책
Chain FORWARD : 서버에서 forwarding 기본 정책
Chain OUTPUT : 서버에서 나가는 기본 정책
------> INPUT ------> Linux Server ------> OUTPUT ------>
| |
+------------- FORWARD ---------------+

Linux Server를 목적지로 삼는 모든 패킷은 INPUT Chain을 통과하고
Linux Server에서 생성되 외부로 보내지는 모든 패킷은 OUTPUT Chain을 통과하게 된다.
FORWARD Chain의 경우 현재의 Linux Server가 목적지가 아닌 패킷이 통과하는 Chain이다.
(FORWARD Chain은 NAT(네트워크 공유) 기능 사용을 위해 사용된다.)

2 iptables의 구조

먼저 iptables에 대해 살펴보도록 하자.
iptables는 다음의 구조로 구성된다.
iptables -A INPUT -s [발신지] --sport [발신지 포트] -d [목적지] --dport [목적지 포트] -j [정책]

iptables 명령
-A : 새로운 규칙을 추가한다.
-D : 규칙을 삭제한다.
-C : 패킷을 테스트한다.
-I : 새로운 규칙을 삽입한다.
-R : 새로운 규칙으로 교체한다.
-L : 새로운 규칙을 출력한다.
-F : 체인의 모든 규칙을 삭제한다.
-Z : 모든 체인의 패킷과 바이트 카운터 값을 0으로 만든다.
-N : 새로운 체인을 만든다.
-X : 체인을 삭제한다.
-P : 기본 정책을 변경한다.

iptables 옵션
-p : 패킷의 프로토콜의 포트번호 또는 이름을 명시한다. (ex : tcp, udp, 21, 22)
-s : 패킷의 발신지를 명시한다. (ex : address[/mask])
-d : 패킷의 도착지를 명시한다.
-i : 규칙을 적용할 인터페이스 이름을 명시한다. (ex : eth0, eth1)
-j : 규칙에 맞는 패킷을 어떻게 처리할 것인가를 명시한다.
-y : 접속 요청 패킷인 SYN 패킷을 허용하지 않는다.
-f : 두 번째 이후의 조각에 대해 규칙을 명시한다.

3 iptables 규칙 추가

예를 들어 만약 127.0.0.1 즉, 로컬에서 요청하는 모든 ICMP 패킷에 대해 무시하고자 할 때 어떻게 하면 될까?
ping 요청에 사용되는 프토토콜은 ICMP 프로토콜이며, 발신 주소는 127.0.0.1이다.
패킷 필터의 목표는 폐기(DROP)이며, 사용하는 프로그램은 ping이다.
이를 기반으로 룰을 만들면 다음과 같다.
// 체인을 추가하기 전 iptables

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

// 127.0.0.1 로 ping이 정상적으로 허용됨을 알 수 있다.

ping -c 3 127.0.0.1

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.026 ms
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.026/0.027/0.029/0.006 ms

// 127.0.0.1 로 가는 ping을 거부하는 체인 추가

iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

// iptables에 체인이 추가됨을 확인할 수 있다.

iptables -L // 현재 iptables에 icmp DROP 룰이 적용되어 있다.

Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- SUNSYSTEM anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

// ping이 거부됨을 확인할 수 있다.

ping -c 3 127.0.0.1

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2008ms

4 iptables 규칙 제거

iptables의 체인 입력과 마찬가지로 삭제를 할 때에도 동일하게 입력하면 된다.
iptables -D INPUT -s [발신지] --sport [발신지 포트] -d [목적지] --dport [목적지 포트] -j [정책]
iptables -D INPUT [필터링 번호]
(필터링 번호는 service iptables stat을 통해 확인할 수 있다.)
※ iptables -F INPUT 을 입력할 경우 모든 체인이 삭제된다.

그러면 위에 입력했던 체인을 제거해보도록 하자.

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- SUNSYSTEM anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

iptables -D INPUT 1

// iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP를 사용해서 삭제할 수도 있다.

iptables -L

Cain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

  1. iptables 정책 순서

모든 방화벽은 순차적 실행이다.
즉 등록 순서에 있어서 먼저 등록한 대해서 효력이 유효하기 때문에 등록시에는 순서가 매우 중요하다.
모든 입출력 패킷에 대해 거부하는 설정이 먼저 등록되면 그 이후에 포트를 열어주는 설정을 하여도 효과가 없다.
그러므로 허용하는 정책을 먼저 정의한 다음 거부하는 정책을 설정해야 한다.

// 아래와 같이 설정하면 우선적으로 22번 포트가 열린 후 나중에 22번~30번 포트가 막히기 때문에 SSH 접속이 가능하다.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

iptables -A INPUT -p tcp --dport 22:30 -j DROP

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
DROP tcp -- anywhere anywhere tcp dpts:ssh:30

// 아래와 같이 설정하면 우선적으로 22번~30번 포트가 막히기 때문에 뒤에서 아무리 22번 포트를 열어도 외부에서 SSH로
접속할 수 없게 된다.
// iptables로 입력할 경우 바로 적용이 되기 때문에 원격에서 작업할 경우엔 주의하자.

iptables -A INPUT -p tcp --dport 22:30 -j DROP

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

  1. 서비스를 위한 기본 설정

처음 설치시 방화벽을 설정하면 /etc/sysconfig/iptables 파일이 생성된다.
디폴트 iptables 파일을 삭제한 후 아래의 포트를 추가하도록 하자
// 기존 iptables 파일 제거

rm -rf /etc/sysconfig/iptables

rm: remove 일반 파일 `/etc/sysconfig/iptables"? y

// iptables 정책 추가

iptables -A INPUT -p tcp --dport 20 -j ACCEPT // ftp-data

iptables -A INPUT -p tcp --dport 21 -j ACCEPT // ftp

iptables -A INPUT -p tcp --dport 22 -j ACCEPT // ssh

iptables -A INPUT -p udp --dport 53 -j ACCEPT // named

iptables -A INPUT -p tcp --dport 80 -j ACCEPT // http

iptables -A INPUT -p tcp --dport 110 -j ACCEPT // pop3

iptables -A INPUT -p tcp --dport 143 -j ACCEPT //imap

iptables -A INPUT -p tcp --dport 3306 -j ACCEPT // mysql

iptables -A INPUT -p icmp --icmp-type echo-request -j DROP // ping에 대한 응답 거부

iptables -A INPUT -p tcp --dport 1:65335 -j DROP // 서비스포트 모두 거부

// iptables 확인

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:pop3
ACCEPT tcp -- anywhere anywhere tcp dpt:imap
ACCEPT tcp -- anywhere anywhere tcp dpt:mysql
DROP icmp -- anywhere anywhere icmp echo-request
DROP tcp -- anywhere anywhere tcp dpts:tcpmux:65335

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

// iptables 를 저장

service iptables save

방화벽 규칙을 /etc/sysconfig/iptables에 저장 중: [ OK ]

ls /etc/sysconfig/iptables*

/etc/sysconfig/iptables /etc/sysconfig/iptables-config

// iptables 재시작

service iptables start

방화벽 규칙을 삭제하는 중: [ OK ]
chains를 ACCEPT 규칙으로 설정함: filter [ OK ]
iptables 모듈을 제거하는 중: [ OK ]
iptables 방화벽 규칙들을 적용하는 중: [ OK ]
추가 iptables 모듈을 읽어오는 중: ip_conntrack_netbios_ns [ OK ]

// iptables 상태

service iptables status

테이블: filter
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:20
2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:21
3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
4 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:110
7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:143
8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
9 DROP icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 8
10 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:1:65335

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

// nmap 포트 스캔

nmap localhost

Starting Nmap 4.11 ( http://www.insecure.org/nmap/) at 2009-04-14 13:45 KST
Interesting ports on SUNSYSTEM (127.0.0.1):
Not shown: 1673 filtered ports
PORT STATE SERVICE
20/tcp closed ftp-data
21/tcp closed ftp
22/tcp open ssh
80/tcp closed http
110/tcp open pop3
143/tcp closed imap
3306/tcp open mysql

  1. iptables의 확장
    1초동안 80포트에 똑같은 IP가 10번 이상의 SYN가 들어오면 드랍시킨다.
    (즉, 정상적인 요청이 아닌 웹서비스 공격으로 간주하여 요청패킷을 폐기시켜 응답하지 않도록 한다.)
    이외의 자세한 사항은 http://netfilter.org의 HOWTO를 읽어보길 바란다.

iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP

스티밋에서의 큐레이션이 목적이 아니라.
평소 기록해둔 개발관련 내용을 블로깅 하는중입니다.

해당 포스팅의 출처를 찾기 어려워서 기록하지 못했습니다.
해당 포스팅의 제작자라면 출처를 알려주세요~

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @skysparrow! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

Click here to view your Board

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @skysparrow! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!