Linux에서의 방화벽설정 - ipchains (1)
이전 글에서 우리는 TCP Wrapper의 사용에 관해서 알아보았다.
TCP Wrapper는 inetd 데몬에의해 서비스되는, telnet이나 ftp등 /etc/inetd.conf에 설정되어있는 특정 서비스에 대해서만 Wrapper기능이 적용되었지만, 상당히 단순한 접근통제만 가능하기 때문에 좀 더 다양한 기능을 원할 때는 적합하지 않았다.
그래서 이 이상의 좀더 세련된 접근통제를 하기 위해 필요한 것이 바로 방화벽이다.
1. 방화벽
1.1 port란?
인터넷에서 제공되는 대표적인 서비스들은 각각 자신들의 고유한 port 번호들을 가지고 있는데, 예를 들어, telnet 접속은 23번, ftp 접속은 21번, 가장 대표적인 web의 경우 80번 port를 사용하여 서비스를 한다.
이처럼 서비스별로 port 번호가 다르기 때문에, 하나의 ip주소만 가지고도, 여러 가지 인터넷서비스들을 동시에 운영할 수 있게된다.
일단 서버 측에서 열어놓은 port들은 특별한 제한이 없는 이상, 외부의 어떠한 요청에도 응답을 하며, 접속을 허락한다. 이는 인터넷상의 아무에게나 대문을 열어놓고, 집안을 마음대로 구경시켜주는 격이다. 물론 집안의 귀중품들이 들어있는 금고는 잘 잠겨있겠지만, 끈질기고 실력있는 도둑은 열린 대문을 통해 집안을 들락거리면서, 언젠가는 자물쇠를 풀고, 원하는 것을 가져갈 수 있을 것이다. (보통의 해커들은 시스템관리자보다 훨씬 시간이 많다.)
그렇다고, 모든 방문객을 도둑으로 생각하고, 모든 대문을 잠궈버릴수도 없는 노릇이다. 그래서 방화벽이란 것이 필요하게되었다.
1.2 방화벽이란?
클라이언트에서 서버로 오는 모든 요청들은 출발지(클라이언트)의 IP주소와 port번호, 그리고 목적지(서버)의 IP주소와 port번호에 대한 정보를 가지고있다. 이 정보를 사용하면, 특정주소로부터 오는 요청이나, 특정 서비스로 향하는 요청들을 구별할 수 있어, 해당 요청을 허락 또는, 거부할 수 있다. 이런 역할을 해주는 것이 방화벽(Firewall)이다.
방화벽은 보통 네트워크의 최 앞단의 라우터(혹은 게이트웨이)라는 장비 바로 뒤에 위치해서, 외부에서 내부로, 혹은 내부에서 외부로 오고가는 모든 패킷을 관리자가 설정한 일정한 규칙들과 비교해본다. 이런 '규칙'의 집합(일반적으로 ruleset 이라고 한다.)에 오가는 패킷들을 적용하여 해당 요청을 받아들일지 아니면 거부할지를 결정한다. 거부 판정을 받은 패킷은 방화벽에 의해 걸러지게 되고, 허가받은 패킷만 방화벽을 통과하여 방화벽 안쪽의 서버에 도달하게된다.
2. IPCHAINS의 활용
2.1 설치
보통 REDHAT계열 리눅스 6.0 이상의 버젼을 Full install했다면 ipchains는 이미 설치가 되어있을 것이다. 설치가 이미 되어있다면, rpm 패키지로 설치가 되어 있을 테니, 다음과 같이 확인해본다.
[root@fw /root]# rpm -qa | grep ipchains
ipchains-1.3.9-3 <--설치된 상태
보통 ipchains프로그램은 /sbin 디렉토리 밑에 설치된다.
2.2 IPCHAINS사용법
자세한 내용은 IPCHAINS에 관해 전문적으로 다룬 많은 공개된 문서들을 살펴보길 바란다. 여기서는 간단히 핵심적인 내용만 언급하겠다.
우선 간단히 예제로 사용법을 알아보면 아래와 같다.('#'는 쉘을 의미한다.)
#ipchains -A input -p tcp -s 0.0.0.0/0 -d 123.45.56.67 23 -j DENY
이 예는 외부에서 들어오는 모든 텔넷접속을 거부한다는 의미이며, 이 명령이 실행됨으로서 하나의 ruleset이 만들어지는 것이다.
이제 위의 예제에서 사용한 각 옵션들을 알아보면,
-A(add) : input,output,forward 등을 사용할 수 있으며, 들어오거나 나가는 트래픽 중 어느것을 필터링 할 것인가를 지정한다.
-p(protocol) : 어떤 종류의 protocol에 대해 검사할 것인가를 결정 대표적으로 tcp,udp 등을 사용한다.
-s(source) : source IP address 를 나타내며, 특정 ip한 개 혹은 어떤 영역의 IP주소를 지정할 수 있다.
0.0.0.0/0 은 전체 IP주소를 뜻한다. 즉, 인터넷 전체가 된다.
-d(destination) : destination IP address로 트래픽이 향하는 곳의 주소이다. 위의 예에서 주소(123.45.56.67)다음에 한칸 space를 주고 23이라고 써준 것은 port번호를 의미한다.
특별히 port번호를 표기하지 않는다면, '해당 IP주소에서 제공하는 port'전부를 의미한다.
-j : jump! 정도로 생각해두면 이해하기 쉬울 것이다. 앞에서 기술한 규칙에 걸려든 트래픽에 대해서 어떻게 조치를 할지 결정한다.
즉, 규칙에 부합하면 DENY(거부)로 jump! 라는 의미이다. '-j'다음에 올 수있는 명령들은 DENY,REJECT, ACCEPT등이 있고,
밑에서 다시 얘기하겠지만, DENY와 REJECT는 약간의 차이가 있다.
ruleset이 제대로 만들어졌는지 확인해보려면 다음과 같이 -L 옵션을 사용한다.
[root@fw /root]# /sbin/ipchains -L
Chain input (policy ACCEPT):
target prot opt source destination ports
DENY tcp ------ anywhere 123.45.56.67 any -> telnet
Chain forward (policy ACCEPT):
Chain output (policy ACCEPT):
-L옵션만 사용하면 위와 같이 현재 설정된 룰셋 들을 확인해볼 수 있다.
방화벽의 일반적인 ruleset은 대부분 외부로부터의 접속요청에 대한 필터링이다.
따라서 -A 다음의 input 을 가장 많이 사용하게될 것이다. 내부에서 외부로 나가는 트래픽에 대해 제한을 두고 싶으면 input대신 output을 사용하면 된다.
#ipchains -A output -p tcp -s 222.22.22.0/24 -d www.EXAMPLE.net 80 -j REJECT
이것은 www.EXAMPLE.net 사이트에 내부 네트워크 사용자들의 접속을 막는 기능을 한다. 이 경우 source 부분에 ip주소 한 개가 아닌 C클래스의 네트워크 한 개를 통째로 집어넣었다.
어떤 한 네트워크가 이 룰셋을 셋팅한 리눅스서버 뒤에 위치하고 있다면, 해당 네트워크의 모든 사용자들은 이 사이트에 접근조차 할 수 없게 된다.
그런데, 여기서는 -j 다음에 DENY가 아닌 REJECT를 사용하였다. DENY는 어떤 경고도 없이 완전히 패킷을 차단해버리는 반면, REJECT는 접속을 시도하는 상대방에게 당신이 보낸 패킷이 drop되었다는 기본적인 정보를 제공하기 때문에, 약간의 눈치만 있으면, 상대방은 방화벽의 존재여부를 눈치챌 수 있다. 하지만, DENY의 경우는 네트워크가 마치 다운된 것같이 응답이 전혀 없다.
2.3 REJECT와 DENY???
둘 중 어떤 것을 선택할 것인가? 개인적으론 DENY가 속 편한 선택이라고 생각한다. REJECT는 트래픽이 많은 경우, DENY가 하지 않는 한가지 일을 더 해야하기 때문에(drop된 사실을 알리기 위해 패킷을 만들어 보내줘야 한다!!)시스템에 좀더 부담을 줄 수 있기 때문이다.
2.4 !!!!!!!!!!!
ipchains에서 또 하나의 재밌고, 편리한 기능이 있다. NOT을 의미하는 '!' 이다.
#ipchains -A input -p tcp -s 111.222.33.44 -d 111.222.33.45 23 -j ACCEPT
#ipchains -A input -p tcp -s ! 111.222.33.44 -d 111.222.33.45 23 -j DENY
이상의 두 가지 룰셋은 결국은 같은 의미이다.
즉, 111.222.33.44 의 주소에서만 111.222.33.45번 주소의 23번 포트(telnet)에 접속할 수 있게 한것이다.
'!' 의 NOT의 의미를 잘 생각해보면 금방 이해할 수 있을 것이다.
이번엔 destination 주소에 port번호를 써주고, port 번호 앞에 ! 를 사용했다.
#ipchains -A input -p tcp -s 111.222.33.44 -d 111.222.33.45 ! 23 -j DENY
전체적인 의미는 "source IP주소 111.222.33.44에서 111.222.33.45의 23번이 아닌 port로 오는 tcp요청은 DENY한다." 라는 의미가 된다. 즉, 23번 port에만 접속할 수 있다는 의미가 된다.
참고로 보통 source IP주소의 port번호는 특별한 경우가 아닌 이상 일반적으로 써주지 않는다.
source 주소의 port번호는 목적지의 port번호와는 달리 보통 랜덤 하게 결정되기 때문이다. 목적지의 port에 접속하기 위해서는 source에서도 어떤 port(보통 1024번 이상의 영역에서...)를 열어주어야 한다.
2.5 ruleset 지우기
지정한 ruleset을 지우는 방법은 간단하다.
#ipchains -A input -p tcp -s 111.222.33.44 -d 111.222.33.45 ! 23 -j DENY
이와 같이 -A 로 add가 되었다면, -A를 -D(delete)로 바꾸고, 나머지 부분은 add시킬 때와 동일하게만 적어주면 된다.
#ipchains -D input -p tcp -s 111.222.33.44 -d 111.222.33.45 ! 23 -j DENY
-A가 -D로 바뀌었을 뿐 나머지 부분은 완전히 동일하다.
한 부분이라도 차이가 난다면 ruleset은 지워지지 않을 것이다.
2.6 rebooting 이후에도 룰셋 보존하기
힘들게 설정해놓은 다양한 룰셋 들은 아무런 조치가 없다면, 시스템의 리부팅과 함께 사라진다. 설정한 룰셋이 3~4개정도라면, 그냥 /etc/rc.d/rc.local 파일의 마지막부분에 해당 ipchains 명령을 그대로 써준다.
ipchains로 설정한 내용을 save해주는 스크립트가 있긴 하나 여기서는 다루지 않겠다.
2.7 주의할 점
여러분의 풍부한 상상력을 이용하여 ruleset을 적용하다보면, 분명히 몇 번쯤은 네트워크가 먹통이 되는 경험을 하게되겠지만, 여러 ruleset을 적용해보는 재미도 만만치 않을 것이다. telnet에서 이 작업을 하다 실수하게되면, 서버에 바로 연결된 콘솔로 달려가서 사태를 수습하기 전까지는 다시는 telnet접속을 못할 수도 있다. 원래 방화벽 룰셋 작업은 콘솔 상에서만 해야 하는 것이 정석이다.
2.8 마치면서
이번 문서에서는 Linux용 방화벽 프로그램인 ipchains에 관한 기본적인 사용법만 알아보았다.
좀더 궁금하신 분들은 아래의 참고문헌을 살펴보시고, 다음 번 문서에서는 실제 운영중인 ruleset을 예로 ipchains의 다양한 사용법에 대해 얘기하겠다.
2.9 참고문헌
http://kldp.org/Translations/IPCHAINS-HOWTO
Written and Edited by 임준형
[저작권]
이 글의 작성 및 편집자는 임준형 님(saster@hitel.net)이며 상업적인 목적이 아니라면 이 글을 원작자의 이름과 함께, 배포하는 것은 자유입니다.

운영자
01-06-02 10:41
0개
2,494회
Linux에서의 방화벽설정 - ipchains (1)
댓글목록
등록된 댓글이 없습니다.