포트 포워딩으로 보안 다지기 CGI-bin이나 Java 애플릿을 사용해 데이타베이스의 다른 서비스로 접근시켜 대화식으로 하는 Web 사이트가 증가하고 있다. 이러한 방식의 접근은 보안 문제를 일으키기 쉽기 때문에, 데이터 베이스를 가지고 있는 머신은 인터넷에 직접 접속시키지 말아야 한다. Port forwarding은 이 접근 문제에 대하여 거의 이상적인 해결책을 제공할 수 있다. 이번 호에서는 이러한 Port Forwarding의 정의와 적용 및 실전 테스트까지 다루어 보기로 한다. (주)웹데이터뱅크 SE Team Manager 조윤석 yoon@debian-kr.org 1. 포트 포워딩이란 포트 포워딩(Port forwarding)이라는 말이 좀 생소하다고 느끼는 사람도 있을 것 이다. 하지만 말뜻 그래도 해석을 해보면 금방 이해할 수 있다. 포트를 밀어준다고 생각을 해도 쉽게 접근하기 좋다. 이 기법은 사용하는 사람의 입장에서 많은 이름이 붙여진다. 부하를 줄이기 위해 쓰이기도 하고 또한 보안상 유용하기 때문에 사용되기도 한다. 하지만 이 기법을 사용하기 위해서는 기본적으로 알아야 할 사항들이 많다. 기본적인 구성사항은 그림 1과 같다. 그림 1 : Port Forwarding의 기본적인 구성사항 그림 1에서 보면 한개의 공인IP를 가지는 서버에서 내부의 가상 IP가 있는 IP Masq의 구조이다. 그럼 이 구조에서 이제까지는 내부의 가상 IP대역에서 공인 IP를 통해서 외부로 나갈 수도 있었다. 즉 기본적인 메스커레이딩 역할을 했었다. 또한 Com A는 가상 IP들의 묶음을 가지고 있으므로 외부와 내부의 중간 다리역할을 하며 들어오고 나가는 패킷들의 정책인 ipchains의 역할이 필요하다. 바로 이부분에서 사용할 수 있는 것이 port 제어이다. 즉 이제까지는 가상IP에서 나가는 역할은 충분히 가능했지만 들어오지는 못했었다. 물론 Com A의 정책에 따라서 달라질 수는 있었다. 한개의 공인 IP만을 가지고 내부적으로 많은 PC를 연결시키기 위해 IP 메스커레이딩을 사용한적이 많이 있었고 공인IP가 부족하다고 하는 지금도 많이 사용되고 있기도 하다. 여기에서 각 port별로 분리를 한다고 생각하면 쉽다. 즉 Com A에 들어오는 WEB의 요청을 (보통 80번 port를 사용한다고 했을때) 가상 IP A에는 웹을, 가상 IP B에는 메일을(보통 25번을 사용), 가상 IP C에는 telnet을 사용하게끔 할 수 있다는 것이다. 이런 방법은 보안상이거나 또는 부하를 분산시키기 위한 기초적인 방법이다. 그럼 위의 내용을 조금 적용시킨 후 그림 2를 다시 살펴보도록 하자. 그림 2 : 분리시켜본 port의 역할 그림 2에서는 누군가 외부에서 Com A의 웹페이지에 있는 내용을 보려고 한다면 Com A는 그 요청 클라이언트를 192.168.1.1 번으로 forwarding해 준다는 것이다. 즉 들어오는 패킷을 방향을 바꾸어주는 역할이 Com A이고 그 패킷은 forwarding되어 192.168.1.1의 80번 포트로 간다는 것이다. 역시 다른 Mail이나 telnet 도 마찬가지로 해당 사용하는 포트를 지정해준다면 충분히 가능하다. 2. 필요한 도구들 Port Forwarding을 위해서는 몇가지 필요한 사항들이 있다. 먼저 알아 두어야 할 것은 IP Masquerade를 알아야 하고 그에 따른 IP chains를 알아야 한다. 물론 더 알아야 할 것이 있다면 Kernel Compile,...등등이 있지만 그 정도는 찾아서 해볼 수 있다는 가정하에 약간의 설명을 더하겠다. 2.1 IP Masquerade Port Forwarding은 IP Masquerade 기반 하에서 동작하므로 기본적으로 알아야 한다. 여러분들이 기존의 NAT()의 기능을 잘 알고 있으리라는 가정하에 설명하도록 하겠다. 이 기능은 라우터에서부터 공인 IP와 가상 IP의 역할을 충분히 해낸다. 또한 이와 유사한 기능을 하는 것이 리눅스에서의 IP Masquerade라고 할 수 있다. 만약 한개의 IP를 가지고 있는 PC가 있고 나머지 2까지 IP를 가지지 못했거나 모뎀을 사용해서 인터넷으로 나갈 수 있는 PC는 한대뿐이고 나머지 두대도 같이 인터넷을 사용하고 싶을 싶다고 가정해보자. 먼저 공인 IP는 한개인데 나머지 두대에서도 외부로 나갈 수도 있어야 하고 또는 메일을 보낸다거나 웹 요청을 할 때 외부 요청을 받는 서버들은 마치 앞 단에 있는 IP Masquerade가 설정된 PC에서 요청을 받는 것처럼 주소를 받는다. 그림 3 : IP Masqueradede의 계략도 그림 3에서 보면 가상 IP를 가진 (192.168.1.10-12) 내부의 어떤 PC가 접속 요청을 한다 해도 인터넷상에 있는 WEB Server는 마치 IP Masquerade 된 서버에서 요청하는 것처럼 느낀다. 보통 그림 3처럼 IP Masquerade PC는 두개의 IP를 가져야 한다. 한개는 외부로 나갈 수 있는 공인 IP를 가져야 하고 나머지 한개는 내부 네트워크와 통신할 수 있는 가상 IP를 가지며 내부의 모든 가상 IP를 가지는 PC들은 자신들의 게이트웨이를 내부 IP 192.168.1.1로 맞추어 놓게 된다. 그럼 그 요청에 대한 응답을 되돌려주는 역할이라던지 접근 거부, 허가의 관리를 하는 것은 공인IP를 가진 PC가 담당한다. 물론 IP Masquerade를 사용한다면 리눅스를 이용해야겠지만 그 외에 가상 IP를 가지는 PC들은 어떤 OS이던지 상관이 없다. 가상IP를 가지는 PC들의 입장은 단순하다. 우리의 네트워크 구성이 그렇듯이 자신은 보내는 곳의 정보만 정확히 보내어 게이트웨이로 보내기만 하면 된다는 것이다. 그 이후의 경로나 틀린 네트워크라 할지라도 그것은 가장 말단에 있는 PC가 신경써야 할 부분이 아닌 것이다. IP Masquerade의 내부 routing table의 내용을 잠시 보자. 리스트 1 : IP Masquerade의 내부 routing table [root@hmm-hmm hmm]# netstat -nr Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.1 * 255.255.255.255 UH 0 0 0 eth1 211.144.248.6 * 255.255.255.255 UH 0 0 0 eth0 211.144.248.0 * 255.255.255.128 U 0 0 0 eth0 192.168.1.0 * 255.255.255.0 U 0 0 0 eth1 127.0.0.0 * 255.0.0.0 U 0 0 0 lo default gw.hmm-gatewa 0.0.0.0 UG 0 0 0 eth0 리스트 1과 같은 내용을 보면 해당 인터페이스의 IP와 게이트웨이를 확인해 볼 수 있다. eth0 -> 211.144.248.6 eth1 -> 192.168.1.1 즉 두개의 랜카드에 각기 다른 IP를 부여한 것이다. 그리고 라우터나 스위치에서 나오는 선을 eth0에 접속시키고 다시 eth1에서 나가는 선은 분배할 허브나 스위치에 접속을 시킨다. 그러면 내부 PC의 netstat상태를 보면 리스트 2와 같다. 리스트 2 : PC의 netstat상태 [root@localhost guest]$ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 192.168.1.24 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 역시 내부의 모든 PC들은 게이트웨이를 192.168.1.1번으로 잡고 있는 것을 볼 수 있다. 그런데 위의 예를 보면 192.168.1.~~ 이런 C클래스 주소를 사용하고있다. 이는 RFC1918에 정해진 몇 가지 정의를 따르는 것으로 가능하면 지켜 주는 것이 좋다. 10.0.0.0 - 10.255.255.255 172.16.0.0 - 172.31.255.255 192.168.0.0 - 192.168.255.255 보통 위의 3가지 범위의 IP대역을 사용하고 있으며 각 주소에 어울리는 넷마스크 및 브로드케스트를 정의해 주어야 한다. 그러면 이제 IP Masquerade에 필요한 몇가지 사항을 알아보자 . 2.2 커널컴파일 커널을 IP Masquerade에 맞게 컴파일 해야 한다. 몇가지 옵션이 꼭 들어가야 하는데 그 옵션은 표 1과 같다. ~ Prompt for development and/or incomplete code/drivers (CONFIG_EXPERIMENTAL) [Y/n/?] ~ Enable loadable module support (CONFIG_MODULES) [Y/n/?] ~ Networking support (CONFIG_NET) [Y/n/?] ~ Packet socket (CONFIG_PACKET) [Y/m/n/?] ~ Kernel/User netlink socket (CONFIG_NETLINK) [Y/n/?] ~ Routing messages (CONFIG_RTNETLINK) [Y/n/?] NO ~ Network firewalls (CONFIG_FIREWALL) [Y/n/?] ~ TCP/IP networking (CONFIG_INET) [Y/n/?] ~ IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) [Y/n/?] NO ~ IP: verbose route monitoring (CONFIG_IP_ROUTE_VERBOSE) [Y/n/?] ~ IP: firewalling (CONFIG_IP_FIREWALL) [Y/n/?] ~ IP: firewall packet netlink device (CONFIG_IP_FIREWALL_NETLINK) [Y/n/?] ~ IP: always defragment (required for masquerading) (CONFIG_IP_ALWAYS_DEFRAG) [Y/n/?] ~ IP: masquerading (CONFIG_IP_MASQUERADE) [Y/n/?] ~ IP: ICMP masquerading (CONFIG_IP_MASQUERADE_ICMP) [Y/n/?] ~ IP: masquerading special modules support (CONFIG_IP_MASQUERADE_MOD) [Y/n/?] ~ IP: ip fwmark masq-forwarding support (EXPERIMENTAL) (CONFIG_IP_MASQUERADE_MFW) [Y/m/n/?] NO ~ IP: optimize as router not host (CONFIG_IP_ROUTER) [Y/n/?] ~ IP: GRE tunnels over IP (CONFIG_NET_IPGRE) [N/y/m/?] NO ~ IP: TCP syncookie support (not enabled per default) (CONFIG_SYN_COOKIES) [Y/n/?] ~ Network device support (CONFIG_NETDEVICES) [Y/n/?] ~ Dummy net driver support (CONFIG_DUMMY) [M/n/y/?] ~ /proc filesystem support (CONFIG_PROC_FS) [Y/n/?] 표 1 : IP Masquerade의 컴파일에 적용되는 옵션들 표 1에서 NO라고 설정한 부분만 빼고 모두 YES로 표시를 해주어야 한다. 표 1에는 일단 Port Forwarding에 대한 부분은 표시가 되어 있지 않다. 제대로 커널 컴파일이 되었다면 다음으로는 오고 가는 패킷의 규칙을 정해주어야 한다. 그런데 이 규칙이라는 것이 조금 까다로울 수도 있어 잘못했다가는 마냥 않아서 기다리는 경우가 생길 수도 있다. 이번 호는 Port Forwarding에 관한 내용이므로 간략히 규칙에 대해서만 알아보도록 하겠다. 2.3 IP chains 보통 방화벽 구축시 많이 쓰며 이전의 ipfwadm에서 한층 진보되었다 할 수 있다. 패킷을 걸러내는데에 있어 많은 유용성을 나타내지만 관리자의 능력도 요구가 될 수 있다. ipchains를 하기 위해서는 패킷을 걸러낼 줄 알아야 한다. 걸러낸다는 의미는 안에서 바깥쪽으로 나가는 패킷과 밖에서 안으로 들어오는 패캣을 하나의 동그란 팩으로 생각하고 그 각각을 걸러주는 역할이라고 생각한다면 쉽다. 흔히 TCP는 연결지향이며 확인 가능한 프로토콜이라고 알고 있다. 즉 A에서 B로 어떤 요청을 할 때 실제적인 데이터를 보내기 전에 약간의 인사를 한다고 할 수 있다. 만약 B에서 거절을 한다면 A는 접속을 거절당한 것이고 B가 응낙한다면 접속을 승인 받았다고 할 수 있는 것이다. 비유가 적절하지는 않지만 지난 호에 우리는 MTA에서 helo에 대해 알아본 바가 있다. 또한 전달과정은 크게 input, output, forward 정도로 나누어 볼 수 있으며 이 과정에서 그 패킷은 들어오고 전달되고 나가는 것이다. 그럼 장황하게 나올 법한 사용법을 조금씩 알아보도록 하자. 3. 포트 포워딩의 사용법 이전하고 똑같이 예제를 두고 하나씩 설명을 함으로써 각각의 옵션을 알아보고 변경해 보도록 하자. 늘 같은 얘기이지만 좋은 예제보다 좋은 선생은 없는 것 같다. 3.1 예제 1 1 #>ipchains -P forward DENY 위의 한 줄의 정책을 생각해 보자. 아주 간단하다. '-P' 옵션을 주고 forward 되는 패킷들은 거부한다라고 생각해 볼 수 있다. 기본적인 이해는 정책과 규칙으로 나누어보았다. 정책은 기본 골격을 칭하며 규칙은 좀더 작은 개념으로 세부항목에 대한 규칙이라고 할 수 있다. -A(--append) -D(--delete) -R(--replace): -I(--insert) -P(--policy) -N(--new-chain) -X(--delete-chain) -L(--list) -F(--flush) -Z(--zero) 정책안에 규칙을 덧붙인다. 한개또는 그이상의 선택된 규칙을 지운다. 선택된 규칙을 새로운 규칙으로 대체한다. 정책속에 새로운 규칙을 넣는다. 기본 정책을 변경한다. 새로운 정책수립한다. 정의되지 않은 규칙은 지운다. 각 정책을 나열한다. 모든정책을 지운다 정책안에있는 모든 규칙들의 패킷이나 카운터의 바이트값을 0으로 초기화한다. 표 2 : 각각의 옵션에 대한 설명 표 2의 항목대로면 '-P'옵션이 무엇인지는 알았을 것이다. 그럼 forward는 무엇인가. 원래 ipchains는 4가지 규칙에 의해 나뉘어져 있다. input chain, output chain, forwarding chain 그리고 userdefined chain으로 나뉘어져 있다. 구조는 다음과 같다. -------------- -------------- -------------- ->packet-> input chain ->Local process-> forward chain -> output chain -------------- -------------- -------------- 그림에서 보면 완전한 경로는 아니다. 다른쪽으로 진행되어야 한다면 forward를 사용한다. 마지막으로 ACCEPT, REJECT, DENY의 세가지의 구분을 해보도록 하겠다. ACCEPT는 당연히 받아들인다는 뜻이고 REJECT와 DENY는 거부한다는 뜻인데 REJECT는 친절하게 '거부되었습니다'라는 메시지를 보내는 것이고 DENY는 불친절하게 아무런 응답이 없는 것을 의미한다. 여기까지 위의 한 줄을 설명하기 위해 좀 길게 나열했다. 3.2 예제 2 #>ipchains -A forward -s 192.168.1.0/24 -j MASQ 조금 더 긴듯한 한 줄을 접하게 되었다. 차근차근 보면 일단 기존의 정책 안에 forward chain에서 -s (source)의 192.168.1.0/24에서 -j(jump)하는데 MASQ(Masquerade)로 jump한다라는 뜻이다. 몇 가지 생소한 듯한 내용을 보면 '-s','-j'를 볼 수 있을 것이다. 주석을 붙인 그대로 source와 jump를 가리킨다(표 3 참조). -p(--protocol) -s(--source) -sport(--source-port) -d(--destination) -dport(--destination-port) -icmp-type -j(--jump) -i(--interface) 이 규칙의 protocol 발신지 주소 발신지 port(모든주소에 대해서) 도착지 주소 도착지 port(모든 주소에 대해서) ICMP type을 나타낸다. 패킷을 점프시킨다. 인터페이스를 지정해준다. 표 3 : 각각의 옵션에 대한 설명 한가지 좀더 알아볼 것이 있다면 주소 표기법인데 192.168.1.0/24라는 표기법은 다른 말로 바꾸어 보면 192.168.1.0/255.255.255.0 이라고도 할 수 있다. 192.168.1.0/24를 CIDR 표기법이라고 하는데 이는 넷마스크를 이진수로 나누었을 때 비트수가 '1'인 것의 수를 나타낸 것이다. 쉽게 생각해서 255을 이진수로 바꾸면 11111111 이고 이것이 3개 모였으니 8x3=24 가 되는 것이다. 3.3 예제 3 #>ipchains -A forward -s 192.168.1.0/24 -d 0.0.0.0/0 -j MASQ -i eth1 좀 더 복잡해 보이는 예제이다. 전달되는 모든 패킷을 192.168.1.0/24에서 어떤 곳으로 나가거나 MASQ로 jump한다. 인터페이스는 eth1에서 이루어진다라는 대략적인 규칙이라고 이해해 볼 수 있다. 그럼 실제적으로 지난 호에서 배운 메일서버와 관련되어 사무실에서 사용하는 방화벽에는 모두 차단시킨 후 필요한 서비스만 연결시켜 사용하고자 할 때 필요한 정책을 수립해보자. 먼저 보안상 들어오는 모든 패킷을 차단한다. 즉 아무 것도 들어오고 나갈 수 없게 만든 다음 필요한 사항만 열어보도록 하자. 주의할 것은 호스트 레벨에서의 설정이다. 즉 한 개의 호스트 보안정도로 보아도 된다. 한 네트워크를 잡고 있는 방화벽 설정은 아니라는 것이다. 하지만 조금 융통성을 발휘한다면 충분히 네트워크 레벨로도 변경이 가능하다. 구분하기위해 설명부분은 /* ~ */으로 묶기로 하겠다. 리스트 3 : #>ipchains -A forward -s 192.168.1.0/24 -d 0.0.0.0/0 -j MASQ -i eth1 #>cat > firewall.sh #!/bin/sh ipchains -P input DENY ipchains -P output REJECT ipchains -P forward REJECT /* 먼저 들어오고 나가고 전달되는 기본 규칙인 모든 것을 다 거부한다. */ ipchains -A input -f -s 0/0 -d 0/0 -i eth0 -j DENY -l /* -f 옵션은 아주 작은 조각까지도 거부하기위해 설정한 것이다.(-f:fragment)*/ ipchains -A input -i lo -j ACCEPT ipchains -A output -i lo -j ACCEPT /*로컬 loopback에 대해서는 모두 허용을 한다.*/ ##Mail /*여기서부터 메일을 주고받기 위한 설정이 들어간다. 기본적으로 ipchains가 움직이는 머신을 중심으로 보았을 때 나가고 들어오는 패킷에 대한 설정을 잡았다.*/ #outgoing ipchains -A output -p tcp -s 192.168.1.5 1024:65535 -d 0/0 25 -j ACCEPT /*192.168.1.5(1024-65535 port)에서 0/0 (25 port) 로 나가는 모든 tcp 패킷들은 받아들여진다. 여기에서 한가지 모든 주소에서의 어떤 포트라면 위에서처럼 / 이렇게 표기하는 것보다는 좀더 효율적으로 표기할 수 있다. 위에서 설명된 옵션 중 하나인 --sport 와 --dport가 그것이다. 만약 모든 주소에서의 1024부터 65535번까지의 포트를 표기한다면 --sport 1024:65535 라고 표기가 가능하다. 혹은 --dport 1024:65535 이렇게 간단하게 표기하는 방법이 있다는 것을 알아두자. */ ipchains -A input -p tcp ! -y -s 0/0 25 -d 192.168.1.5 1024:65535 -j ACCEPT /*여기에서 한가지 추가된 것은 ! -y옵션이다.'!'은 'not'의 의미이다.'-y'는 syn 패킷을 의미한다. 그럼 '-y'옵션을 알기 위하여 TCP 연결 3단계(three-way handshaking)에 대해서 간략히 알아보자(그림 4 참조). 그림 4 : TCP 연결 3단계의 계략도 SYN : Synchronize Sequence Number ACK : Acknowledge Number ISN : Initial Sequence Number 먼저 호스트 A에서 Synbit를 설정해 ISN를 만든다. 그리고 B에 보내면 B는 A에서 받은 ISN에 +1을 한 다음 자신의 ISN과 같이 호스트 A에게 보내게 된다.호스트 A는 다시 호스트 B에게서 받은 ISN에 +1을 한 다음 호스트 B에게 보내게 된다. 이렇게 서로를 확인하는 작업을 거쳐 연결이 성립이 된다. 조금 생소한 단어에 대해 상당히 어려울 수 있는데 다시 생각해 보면 syn은 동기화 시키기 위한 일련 번호라고 풀어볼 수 있다. 이는 TCP의 연결지향이라는 특성과도 잘 어울린다. 그리고 그에 대한 초기값으로 ISN을 보낸다. 이는 연결하기 위한 초기값 정도로 생각을 한다. 보통 처음 연결을 하기위해 보내는 ISN값은 random값으로 사용한다. 그럼 다시 위의 내용으로 가서 메일을 보내기 위해 25번 포트로 접속 할 때 클라이언트쪽에서 접속을 요청했고 그 다음 다시 서버쪽에서 오는 syn, ack를 받고 다음으로 연결을 성립시키기 위해 ' ! -y '라는 옵션을 준 것이다. 만약 '!' 옵션을 주지 않는다고 했을 때를 생각해 보자. 요청한 쪽에서는 syn을 보냈고 받는 쪽에서는 다시 자신의 syn과 ack를 보내야 하는데 '!'이 없다면 syn만 요청한 쪽으로 넘어가고 ack는 넘어가지 않는다. 그러므로 요청한 쪽에서는 자신이 보낸 ISN+1의 값을 받지 못하므로 연결이 성립이 되지 않는다. 쉽게 얘기해서 서로간의 연결 확인절차 정도로 이해하면 된다. 이 설정을 요약해보면 어떤 주소이던지 25번 포트에서 192.168.1.5번의 1024-65535번으로 들어오는 모든 패킷들은 꼭 syn이 아니더라도 패킷을 받아들인다라는 뜻으로 해석해 볼 수 있다. 그럼 해당 호스트를 기준으로 나가는 패킷을 조정해 보았으면 들어오는 패킷도 한번 조정해 보자. 이것도 역시 ipchains를 기준으로 들어옴을 명시한다. */ #incoming ipchains -A input -p tcp -s 192.168.1.0/24 1024:65535 -d 192.268.1.5 25 -j ACCEPT /* 192.168.1.0/24 (1024-65535 port )에서 들어오는 모든 TCP 패킷들은 192.168.1.5 의 25번 포트로 들어옴을 허용해 준다는 것이다. 그래야 메일을 받아볼 수 있기 때문이다. .*/ ipchains -A output -p tcp ! -y -s 192.168.1.5 25 -d 192.168.1.0/24 1024:65535 -j ACCEPT /* 역시 마찬가지로 3-way handshaking 에 의해 '-y' 옵션을 주어 처음 받은 syn이외에 응답 syn,ack가 다시 올 수 있도록 설정을 한다. */ ^C 위의 몇 줄 안되는 규칙을 한번 시험해 볼 필요도 있을 것이다.어렵지 않으니 그대로 가져다가 테스트를 이리저리 해볼만하다. 위에서 명시한 방법은 아주 기초적인 방법중의 하나이고 더 많은 더 훌륭한 방법들이 인터넷 상에 존재한다. 좋은 예제들은 가져다가 사용해보고 수정하면서 직접 사용해 보길 바란다. 그리고 이번 호는 ipchains에 대한글이 아니므로 아주 기본적인 것만 알아보고 넘어가도록 한다. 4. 적용하기 그럼 이제 실질적인 port forwarding을 테스트를 해보자. 위의 두가지 IP Masquerade과 IP chains를 충분히 이해했다면 그리 어렵지 않은 적용을 할 수 있을 것이라 생각한다. 먼저 내부 네트워크의 상태를 맞추어 놓고 시작해 보자. 스위치에서 나오는 선을 IP Masquerad 된 서버의 eth0에 물려 놓고 다시 eth1에서 선을 물려 허브에 물린다. 그리고 그 밑단에 가상으로 사용할 리눅스 박스들을 놓는다. ============ Switch ============ | IP Masquerade | ----------------- -----------> eth0(211.144.248.6) 공인 IP <----------- eth1(192.168.1.1) 가상 IP | ----------------- | |-------- 192.168.1.2/24 WEB | ============== | |--------------->-----------------> HUB --|-------- 192.168.1.3/24 Mail ============== | |-------- 192.168.1.4/24 FTP 아주 훌륭한 그림이 되었다. 위에서 보면 허브 하단에 물린 3대의 서버는 각기 web, mail, ftp 서버용으로 사용할 것이고 밖에서는 찾지 못할 가상 IP쪽으로 forwarding을 시켜줄 서버는 허브 윗단에 있는 서버가 된다. 그림이 엉성해 브릿지처럼 나와 있지만 사실은 IP Masquerade 서버라 생각한다. 외부에서 누군가 211.144.248.6번으로 웹 접속을 시도해 온다면 IP Masquerade 서버에서 설정한대로 자신의 내부 네트워크인 192.168.1.2번으로 forwarding을 시켜준다. 이는 위에서 처음에도 했던 부분이다. 그럼 port forwarding에 필요한 것들은 무엇인지 알아보자. 먼저 커널 컴파일시 port forwarding에 대한부분을 yes해주어야 하고 port forwarding을 해주는 유틸리티를 설치한 후 설정을 해주면 된다. ~ IP: ipportfw masq support (EXPERIMENTAL) (CONFIG_IP_MASQUERADE_IPPORTFW) [Y/m/n/?] YES 이 옵션은 위에서 했던 커널 컴파일 옵션에 더해주면 된다. 그리고 ipmasqadm이라는 유틸을 설치해준다. 보통 패키징이 되어서 나오기도 하고 없으면 소스를 가져다가 설치를 하면 된다. 설명서를 읽어보면 mfw 와 autofw 를 같이 사용할 수 있다고 나왔는데 커널 컴파일시 옵션을 넣지 않은 이유는 현재는 거의 쓰이지 않고 있기 때문이다. 사용방법은 ipmasqadm portfw 이다. 이렇게 하면 도움말이 나온다. #> ipmasqadm portfw -h Usage: portfw -a -P PROTO -L LADDR LPORT -R RADDR RPORT [-p PREF] add entry portfw -d -P PROTO -L LADDR LPORT [-R RADDR RPORT] delete entry portfw -f clear table portfw -l list table portfw -n no names PROTO is the protocol, can be "tcp" or "udp" LADDR is the local interface receiving packets to be forwarded. LPORT is the port being redirected. RADDR is the remote address. RPORT is the port being redirected to. PREF is the preference level (load balancing, default=10) 위와 같은 도움말의 내용이 나오고 그리 어렵지 않은 내용이다. 직접 적용을 해보자. 먼저 기본적인 사항으로 모든 전달되는 패킷은 거부하고 192.168.1.0/24에서 오는 모든 패킷은 IP Masquerade 서버로 보내보자. #>cat > masq.sh #!/bin/sh ipchains -F ipchains -P forward DENY ipchains -A forward -s 192.168.1.0/24 -j MASQ ^C 만약 웹 서비스만 하고 싶다면 위에서 Mail을 설정했듯이 똑같이 설정해주면 된다. 그리고 나서 ipmasqadm으로 해당 포트를 밀어주는 설정을 하면 된다. 먼저 eth0(211.144.248.6) 의 80번 포트로 오는 모든 패킷은 192.168.1.2번의 80번 포트로 밀어주는 설정과 eth0(211.144.248.6) 의 25번으로 오는 모든 패킷은 192.168.1.3 의 25번 포트로 보내어 보자. 정확히 확인하기 위해서 211.144.248.6의 모든 서비스 데몬들은 전부 다운 시킨다(web,mail,ftp). #>ipmasqadm portfw -a -P tcp -L 211.144.248.6 80 -R 192.168.1.2 80 설정은 '-P' 이후에 해당 protocol을 적고 '-L' 다음엔 외부에서 받아들일 주소와 포트를 '-R' 다음엔 내부 네트워크로 보내고싶은 주소와 포트를 적어준 후 확인해보자. #>ipmasqadm portfw -l prot localaddr rediraddr lport rport pcnt pref TCP ipmasq.hmm-hm web.hmm-hmm. www www 3 10 #>ipmasqadm portfw -ln prot localaddr rediraddr lport rport pcnt pref TCP 211.144.246.6 192.168.1.2 80 80 3 10 옵션 두가지의 차이는 눈으로 볼 수 있다. 그리고 나서 정말 제대로 접속이 되는지 확인해 보기 위해 192.168.1.2번의 DocumentRoot에 index.html의 내용을 적어넣는다. 필자는 'Portforwarding............YOON'이라는 메시지를 한 줄 넣었다.그리고 211.144.246.6서버의 웹 데몬은 잠시 다운시킨다. 다시 공인 IP를 가진 곳 아무 곳에서나 이렇게 테스트를 해본다. #>telnet 211.144.246.6 80 Trying 211.144.246.6... Connected to 211.144.246.6. Escape character is '^]'. 이렇게 나오면 'GET /index.html '라고 입력을 한다. 그러면 아래와 같은 내용이 나온다. test portfowrarding
Portforwarding............YOON
Connection closed by foreign host. 위의 내용은 직접 브라우저로 확인해 보면 더욱 확실히 알게 될 것이다. 한가지 더 추가해 보자. 메일 서비스를 위에서 계획한 대로 추가해보자. 211.144.246.6:25->192.168.1.3:25로 forwarding하는 것이다. 역시 같은 방법으로 다음과 같이 해보자. #>ipmasqadm portfw -a -P tcp -L 211.144.248.6 25 -R 192.168.1.3 25 위의 내용을 확인해 보면 다음과 같다. #> ipmasqadm portfw -ln prot localaddr rediraddr lport rport pcnt pref TCP 211.144.248.6 192.168.1.2 80 80 3 10 TCP 211.144.248.6 192.168.1.3 25 25 6 10 간단히 테스트를 해보자. #>telnet 211.144.248.6 25 220 localhost.localdomain ESMTP Sendmail 8.10.1/8.10.1; Fri, 10 Nov 2000 01:50:15 +0900 접속이 되었다. 분명 IP Masquerade 서버에서는 메일서버를 죽였는데 메일서버에 접속이 되었다. 인사를 간단히 해보자 . helo yoon 250 localhost.localdomain Hello yoon.hmm.co.kr [----------], pleased to meet you *는 본인의 IP이므로 삭제하였습니다. 인사를 하자 답신이 바로 나온다. 좀더 자세히 알아보려면 network status를 이용하자. #>netstat -nMc prot expire source destination ports tcp 715826:23.06 192.168.1.3 <----IP-----> 25 -> 59135 (25) 위와 같이 확인해 볼 수 있다. 이상으로 포트 포워딩에 대해서 대략적으로 알아보았다. 어찌보면 별로 신기할 것도 어려울 것도 없는 방식이지만 유용하게 사용해 볼 수 있을 것이다. 그리고 여기에 사용된 ipchains,IP Masquerade 등은 아주 기초적인 부분만 다루었으므로 더 나은 문서와 서적으로 보충하기 바란다. 정리 : 모상진 기자 [msj7317@pserang.co.kr]