본문 바로가기
Computer Science/OS (운영체제)

[Linux iptables를 이용해 방화벽 설정하기]

by happy coding! 2018. 1. 17.
반응형

[Linux iptables를 이용해 방화벽 설정하기]




iptables는 시스템 관리자가 리눅스 커널 방화벽(다른 넷필터 모듈로 구현됨)이 제공하는 테이블들과 그것을 저장하는 체인, 규칙들을 구성할 수 있게 해주는 사용자 공간 응용 프로그램이다. 


각기 다른 커널 모듈과 프로그램들은 현재 다른 프로토콜을 위해 사용되는데, iptables는 IPv4에, ip6tables는 IPv6에, arptables는 ARP에, ebtables는 이더넷 프레임에 적용된다.


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(네트워크 공유) 기능 사용을 위해 사용된다.) 



구성 요소

리눅스 커널에 탑재되어 있는 netfilter는 테이블(talbe) 또는 정책 목록(rules lists) 이라 불리우는다섯 가지의 패킷 필터링 설비를 갖고 있다.


filter

네트워크 패킷을 처리하기 위한 기본 테이블로  INPUT, OUTPUT, FORWARD 세 개의 내장 체인을 갖고 있다.


nat

네트워크 주소 변환(NAT- Network Address Translation) 을 처리하기 위한 테이블이다.


mangle

특별한 패킷(TCP 헤더의 QOS 비트등)을 변경하는데 사용되는 테이블이다.


raw

테이블의 연결 추적 기능을 더 상세하게 처리할 수 있으며 특정 패킷은 추적하지 않는 등의 설정이 가능한 테이블이다.


security 

SELinux 의 강제 접근 통제(MAC - Mandatory Access Control)를 지원하기 위한 정책이다.



각각의 테이블은 내장된 체인 그룹을 갖고 있으며  각 체인은 패킷과 일치하는 규칙의 목록이다. filter 테이블은 다음 세 가지 체인을 갖고 있다.


INPUT

목적지가 iptables 이 구동되는 현재 리눅스 박스인 네트워크 패킷에 대해서 적용된다.


OUTPUT

리눅스 박스 내에서 생성된 외부로 나가려는 로컬 패킷에 대해서 적용되는 체인이다.


FORWARD

리눅스 박스 밖으로 전달되는 패킷에 대해서 적용된다.



패킷이 테이블 내 특정 규칙과 일치할 경우 목적지와 상관없이 특정 행동을 수행하도록 지정할 수 있으며 이를 타겟이라고 한다.  타겟은 다음과 같은 종류가 있다.


ACCEPT - 패킷을 목적지로 보내는 것을 허용한다. INPUT 체인일 경우 해당 포트를 리슨하는 프로그램에 전달되며 OUTPUT 체인일 경우 목적지 서버로 전송된다.


DROP - 목적지로 가는 것을 차단하고 패킷을 버리며 패킷의 송신자에게 아무 응답도 보내지 않는다.


REJECT - 목적지로 가는 것을 차단하고 패킷을 버리지만 송신자에게 에러 패킷을 전송한다. 

REJECT 시 기본적으로 송신자에게 icmp-port-unreachable 이 전달되며 --rejct-with 옵션 뒤에 송신할 ICMP 에러 유형을 지정할 수 있으며 icmp-net-unreachable, icmp-host-unreachable,icmp-proto-unreachable, icmp-net-prohibited 등을 설정할 수 있다.


QUEUE  - 사용자 스페이스로 패킷을 전달한다.



1) 테이블(tables)

우선 iptables에는 테이블이라는 광범위한 범주가 있는데, 이 테이블은 filter, nat, mangle, raw 같은 4개의 테이블로 구성되며, 이중에서 우리에게 필요한 것은 필터링 규칙을 세우는 filter 테이블이다.


2) 체인(chain)

iptables에는 filter 테이블에 미리 정의된 세가지의 체인이 존재하는데 이는 INPUT, OUTPUT, FORWARD 이다. 이 체인들은 어떠한 네트워크 트래픽(IP 패킷)에 대하여 정해진 규칙들을 수행한다.


가령 들어오는 패킷(INPUT)에 대하여 허용(ACCEPT)할 것인지, 거부(REJECT)할 것인지, 버릴(DROP)것인지를 결정한다.


INPUT : 호스트 컴퓨터를 향한 모든 패킷

OUTPUT : 호스트 컴퓨터에서 발생하는 모든 패킷

FORWARD : 호스트 컴퓨터가 목적지가 아닌 모든 패킷, 즉 라우터로 사용되는 호스트 컴퓨터를 통과하는 패킷


3) 매치(match)

iptables에서 패킷을 처리할때 만족해야 하는 조건을 가리킨다. 즉, 이 조건을 만족시키는 패킷들만 규칙을 적용한다.


--source (-s) : 출발지 IP주소나 네트워크와의 매칭

--destination (-d) : 목적지 ip주소나 네트워크와의 매칭

--protocol (-p) : 특정 프로토콜과의 매칭

--in-interface (i) : 입력 인테페이스

--out-interface (-o) : 출력 인터페이스

--state : 연결 상태와의 매칭

--string : 애플리케이션 계층 데이터 바이트 순서와의 매칭

--comment : 커널 메모리 내의 규칙과 연계되는 최대 256바이트 주석

--syn (-y) : SYN 패킷을 허용하지 않는다.

--fragment (-f) : 두 번째 이후의 조각에 대해서 규칙을 명시한다.

--table (-t) : 처리될 테이블

--jump (-j) : 규칙에 맞는 패킷을 어떻게 처리할 것인가를 명시한다.

--match (-m) : 특정 모듈과의 매치


4) 타겟(target)

iptables는 패킷이 규칙과 일치할 때 동작을 취하는 타겟을 지원한다.


ACCEPT : 패킷을 받아들인다.

DROP : 패킷을 버린다(패킷이 전송된 적이 없던 것처럼).

REJECT : 패킷을 버리고 이와 동시에 적절한 응답 패킷을 전송한다.

LOG : 패킷을 syslog에 기록한다.

RETURN : 호출 체인 내에서 패킷 처리를 계속한다.

REJECT는 서비스에 접속하려는 사용자의 액세스를 거부하고 connection refused라는 오류 메시지를 보여주는 반면 DROP은 말 그대로 telnet 사용자에게 어떠한 경고 메시지도 보여주지 않은 채 패킷을 드롭한다. 관리자의 재량껏 이러한 규칙을 사용할 수 있지만 사용자가 혼란스러워하며 계속해서 접속을 시도하는 것을 방지하려면 REJECT를 사용하는 것이 좋다.


5) 연결 추적(Connection Tracking)

iptables는 연결 추적(connection tracking)이라는 방법을 사용하여 내부 네트워크 상 서비스 연결 상태에 따라서 그 연결을 감시하고 제한할 수 있게 해준다. 연결 추적 방식은 연결 상태를 표에 저장하기 때문에, 다음과 같은 연결 상태에 따라서 시스템 관리자가 연결을 허용하거나 거부할 수 있다.


NEW : 새로운 연결을 요청하는 패킷, 예, HTTP 요청

ESTABLISHED : 기존 연결의 일부인 패킷

RELATED : 기존 연결에 속하지만 새로운 연결을 요청하는 패킷, 예를 들면 접속 포트가 20인 수동 FTP의 경우 전송 포트는 사용되지 않은 1024 이상의 어느 포트라도 사용 가능하다.

INVALID : 연결 추적표에서 어디 연결에도 속하지 않은 패킷

상태에 기반(stateful)한 iptables 연결 추적 기능은 어느 네트워크 프로토콜에서나 사용 가능하다. UDP와 같이 상태를 저장하지 않는 (stateless) 프로토콜에서도 사용할 수 있다.


6) 명령어(commond)

-A (--append) : 새로운 규칙을 추가한다.

-D (--delete) : 규칙을 삭제한다.

-C (--check) : 패킷을 테스트한다.

-R (--replace) : 새로운 규칙으로 교체한다.

-I (--insert) : 새로운 규칙을 삽입한다.

-L (--list) : 규칙을 출력한다.

-F (--flush) : chain으로부터 규칙을 모두 삭제한다.

-Z (--zero) : 모든 chain의 패킷과 바이트 카운터 값을 0으로 만든다.

-N (--new) : 새로운 chain을 만든다.

-X (--delete-chain) : chain을 삭제한다.

-P (--policy) : 기본정책을 변경한다.


7) 기본 동작

패킷에 대한 동작은 위에서 부터 차례로 각 규칙에 대해 검사하고, 그 규칙과 일치하는 패킷에 대하여 타겟에 지정한 ACCEPT, DROP등을 수행한다.

규칙이 일치하고 작업이 수행되면, 그 패킷은 해당 규칙의 결과에 따리 처리하고 체인에서 추가 규칙을 무시한다.

패킷이 체인의 모든 규칙과 매치하지 않아 규칙의 바닥에 도달하면 정해진 기본정책(policy)이 수행된다.

기본 정책은 policy ACCEPT , policy DROP 으로 설정할 수 있다.

일반적으로 기본정책은 모든 패킷에 대해 DROP을 설정하고 특별히 지정된 포트와 IP주소등에 대해 ACCEPT를 수행하게 만든다.


8) iptables 출력

Iptables의 룰셋을 확인할때 아래와 같이 하면 보기 더 편리하다.


iptables -nL


  Chain INPUT (policy DROP)

  target     prot opt source               destination

  ACCEPT     all  --   0.0.0.0/0            0.0.0.0/0

  ACCEPT     all  --   0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED

  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22

  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:53

  ACCEPT     udp  --  0.0.0.0/0           0.0.0.0/0           udp dpt:53

  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80

  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443

  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:3306



iptable 설치 확인


# rpm -qa | grep iptables


iptables-1.4.7-9.el6.x86_64


iptables-ipv6-1.4.7-9.el6.x86_64


설치되어 있지 않다면 설치


# yum -y install iptables 


# chkconfig –list


ip6tables       0:해제  1:해제  2:해제  3:해제  4:해제  5:해제  6:해제


iptables        0:해제  1:해제  2:해제  3:해제  4:해제  5:해제  6:해제



서비스를 시작프로그램에 등록한다


# chkconfig iptables on



서비스를 시작한다


# service iptables start



iptables의 파일위치


/etc/sysconfig/iptables



방화벽 설정 정보 확인


# iptables -nL



방화벽 8000 TCP 포트 허용 추가


# iptables -A INPUT -p tcp --dport 8000 -j ACCEP



방화벽 9000 TCP 포트 차단 추가


# iptables -A INPUT -p tcp --dport 8000 -j DROP



방화벽 규칙 2번째 라인 삭제 : iptables -L 명령으로 표시된 규칙들 중 2번째 줄 라인을 삭제


# iptables -D INPUT 2



방화벽 설정 저장 및 재시작 : 위 명령을 실행시키더라도 저장하지 않으면 적용되지 않는다


# service iptables save



iptables 룰셋 저장


# iptables-save > /etc/iptables.rules



iptables 룰셋 복구


# iptables-restore < /etc/iptables.rules


이 경우에도 service iptables restart를 해주어야한다.


===================================================================


1. 패키지 설치여부 확인

# rpm -qa | grep iptables

iptables-ipv6-1.3.5-9.1.el5

iptables-1.3.5-9.1.el5



2. 설치된 패키지가 없다면 yum을 통해 패키지 설치

# yum install -y iptables



3. 서비스 상태 확인

# chkconfig --list iptables

iptables           0:해제    1:해제    2:해제    3:해제    4:해제    5:해제    6:해제



4. 부팅시 자동 실행

# chkconfig iptables on



5. iptables 시작

# service iptables start



Tip) iptalbes [시작|종료|재시작]

# service iptables [start|stop|restart]


iptables의 방화벽 규칙 파일은 /etc/sysconfig/iptables 이다.


Inbound (외부에서 서버로 들어오는) , Outbound(서버에서 외부로 나가는) 모두 port를 열기 위해서는 아래의 iptables로 INPUT, OUPUT 을 해주면 된다,

권한은 root에서 해주어야한다. 


iptables -I INPUT 1 -p tcp --dport 5900 -j ACCEPT 

iptables -I OUTPUT 1 -p tcp --dport 5900 -j ACCEPT 


예를 들면 FTP port 21번을 열고 싶다.


#iptables -I INPUT 1 -p tcp --dport 21 -j ACCEPT 

#iptables -I OUTPUT 1 -p tcp --dport 21 -j ACCEPT 


#service iptables save


#/etc/init.d/iptables restart


*확인 /etc/sysconfig/iptables (직접 추가해도 가능.) 



iptables -A INPUT -s [발신지] --sport [발신지 포트] -d [목적지] --dport [목적지 포트] -j [정책] 


1) 기본정책을 ACCEPT로 설정하는 법 :

    # iptables -P INPUT ACCEPT

    # iptables -P OUTPUT ACCEPT

    # iptables -P FORWARD ACCEPT


2) 현재 자신의 방화벽 규칙을 볼 수 있는 명령 :

    # iptables --list 또는 iptables -L


3) 규칙 추가 후에 저장하기 :

    # service iptables save  

       -> /etc/sysconfig/iptables 에 저장됨

   

4) 현재 iptables 규칙을 초기화 하기 :

    # iptables -F


모든 방화벽은 순차적 실행이다. 

즉 등록 순서에 있어서 먼저 등록한 부분에 대해서 효력이 유효하기 때문에 등록시에는 순서가 매우 중요하다. 

모든 입출력 패킷에 대해 거부하는 설정이 먼저 등록되면 그 이후에 포트를 열어주는 설정을 하여도 효과가 없다. 

그러므로 허용하는 정책을 먼저 정의한 다음 거부하는 정책을 설정해야 한다. 

   

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

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

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


다음같이 설정하면 우선적으로 22번~30번 포트가 막히기 때문에 뒤에서 아무리 22번 포트를 열어도 외부에서 SSH로 접속할 수 없게 된다.


※ iptables로 입력할 경우 바로 적용이 되기 때문에 원격에서 작업할 경우엔 주의하자.


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

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



iptables 활용 예 


1) 소스 ip가 192.168.0.111 인 접속의 모든 접속 포트를 막아라.

    # iptables -A INPUT -s 192.168.0.111 -j DROP


2) INPUT 사슬에 출발지 주소가 127.0.0.1(-s 127.0.0.1) 인 icmp 프로토콜(-p icmp) 패킷을 거부(-j DROP)하는 정책을 추가(-A)하라

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


3) INPUT 사슬에 목적지 포트가 23번(--dport23)인 tcp 프로토콜(-p tcp) 패킷을 거부하는(-j DROP)규칙을 추가(-A) 하라.

    # iptables -A INPUT -p tcp --dport 23 -j DROP


4) INPUT 사슬에 목적지 포트 번호가 80번(--dport 80)인 tcp 프로토콜(-p tcp)패킷을 받아들이는(-j ACCEPT) 규칙을 추가(-A) 하라

    # iptables -A INPUT -p tcp --dport 80 -j ACCEPT


5) INPUT 사슬에 목적지 포트번호가 1023번 보다 작은 모든 포트(--dport :1023)인 tcp프로토콜(-p tcp)패킷을 거부하는(-j DROP)규칙을 추가(-A)하라

    # iptables -A INPUT -p tcp --dport :1023 -j DROP


6) ftp포트를 열어라

    # iptables -I INPUT -p tcp --dport 21 -j ACCEPT


7) imap 서비스를 방화벽에서 열어라

    # iptables -I INPUT -s 192.168.0.0/255.255.255.0 -p udp --dport 143 -j ACCEPT


8) 웹서버 방화벽 열어라

    # iptables -I INPUT -p tcp --dport 80 -j ACCEPT


9) 웹서버 포트 80 -> 8880으로 교체하라( 웹서비스 포트 변경시 /etc/services 에서도 변경 해줘야 함)

   # iptables -R INPUT 2 -p tcp --dport 8880 -j ACCEPT


10) domain-access_log 파일에 있는 모든 ip의 모든 접속 포트를 막아라(DOS공격 방어시 사용)

   # cat domain-access_log |awk '{print $1}'|sort |uniq |awk '{print "iptables -A INPUT -s "$1" -j DROP"}'|/bin/bash




* Ubuntu iptables 방화벽 port 설정하기


Ubuntu에서 iptables를 사용하여 방화벽 port를 설정하는 방법이다.


Ubuntu는 ufw를 사용하여 기본 방화벽을 설정해줄 수 있는데 수준 높은 방화벽 구성을 위해서는 iptables를 사용하여 설정해주어야한다.


각각의 경우에 따른 사용방법을 알아보자.



1. 모든 포트 차단하기


Ubuntu 리눅스는 0번부터 65535번까지 포트를 사용할 수 있는데 아래 명령어를 실행할 경우 모든 포트를 차단할 수 있습니다.


$ sudo iptables -A INPUT -p tcp --dport 0:65535 -j DROP (TCP 포트 대상)


$ sudo iptables -A INPUT -p udp --dport 0:65535 -j DROP (UDP 포트 대상)



2. 특정 포트만 열어주기


다음은 tcp 80번 포트를 열어주는 명령어입니다.


$ sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT


$ sudo iptables -I OUTPUT -p tcp --sport 80 -j ACCEPT



3. 특정 IP에 특정 포트만 열어주기


다음은 111.222.333.444 IP에 tcp 80번 포트를 열어주는 명령어입니다. 


$ sudo iptables -I INPUT -p tcp --dport 80 -s 111.222.333.444 -j ACCEPT


$ sudo iptables -I OUTPUT -p tcp --dport 80 -d 111.222.333.444 -j ACCEPT



4. TCP 8080번 포트를 80번 포트로 REDIRECT 하기


※ Ubuntu 16.04 버전의 경우 기본 네트워크 인터페이스명이 eth0가 아니라 ens33 또는 eno1으로 되어있는 경우가 있습니다.


이런 경우엔 아래 명령어에서 eth0를 맞는 인터페이스명으로 바꿔서 실행해주시면 됩니다.


$ sudo iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT


$ sudo iptables -A INPUT -i eth0 -p tcp --dport 8080 -j ACCEPT


$ sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080



5. iptables 정보를 재부팅 이후에도 동작하도록 설정하기


먼저 루트 디렉터리(/)에 iptables_rule 디렉터리를 생성해줍니다. (디렉터리명은 자유롭게 생성해주시면 됩니다)


$ sudo mkdir /iptables_rule


다음으로 iptables_rule 디렉터리 하위의 iptables.rules 파일에 iptables 정보를 저장해줍니다.


$ sudo sh -c "iptables-save > /iptables_rule/iptables.rules"



마지막으로 intefaces 파일을 수정


$ sudo vi /etc/network/interfaces


하단에 아래 명령어를 추가하고 저장해줍니다.


pre-up iptables-restore < /iptables_rule/iptables.rules


이상으로 Ubuntu에서 iptables로 방화벽 port를 설정하는 방법을 알아보았습니다.




[출처]


http://webdir.tistory.com/170 [WEBDIR]

http://freestrokes.tistory.com/entry/Ubuntu-iptables로-방화벽-port-설정하기 [FREESTROKES' Develog]

http://fruitdev.tistory.com/96 [과일가게 개발자]

http://linuxstory1.tistory.com/entry/iptables-기본-명령어-및-옵션-명령어 [Linux 세상속으로]

http://www.v-eng.co.kr/?mod=document&uid=11&page_id=732



반응형

댓글