NAT 이용한 가상 서버

NAT를 이용해 가상 서버를 어떻게 설정하는지 설명한다.

Network address translation(네트웍 주소 변환)

IPv4에서는 IP주소가 부족하고 보안상에 몇가지 문제가 있어서, 점점 더 많은 네트웍에서 인터넷에서 사용할 수 없는 사설 IP(10.0.0.0/255.0.0.0, 172.16.0.0/255.240.0.0 , 192.168.0.0/255.255.0.0)를 사용하고 있다. 사설망에 있는 호스트에서 인터넷에 접속을 하거나 인터넷망에서 사설망의 호스트에 접속하기 위해서 NAT(network address translation)기능이 필요하다.

NAT는 특정한 IP 주소를 한 그룹에서 다른 그룹으로 매핑하는 기능이다. 주소를 N-to-N 형태로 매핑하는 경우를 정적 NAT라 하고 M-to-N(M>N)를 동적 NAT라고 한다. 네트웍 주소 포트 변환은 기본 NAT의 확장기능으로 여러 가지 네트웍 주소와 TCP/UDP 포트를 단일의 네트웍 주소와 TCP/UDP 포트로 변환한다. N-to-1 매핑이라고 하며 리눅스에서 IP 마스커레이딩도 이러한 방식을 이용한다. NAT에 대한 자세한 내용은 rfc1631draft-rfced-info-srisuresh-05.txt를 참고하기 바란다.

리눅스에서 NAT를 통한 가상 서버는 네트웍 주소 포트 변환을 통해 수행한다. 리눅스 IP 마스커레이딩 코드를 이용하며, 스티븐 클락(Steven Clarke)의 포트 포워딩 코드를 재사용하고 있다.

 

NAT를 통해 가상 서버를 어떻게 수행하는가?

먼저 다음 그림을 보자.

사용자가 서버 클러스터에서 제공하는 서비스에 접근할때, 가상 IP 주소(부하분산서버의 외부 IP 주소)로 향하는 요구 패킷이 부하분산서버로 간다. 부하분산서버에서 패킷의 목적지 주소와 포트 번호를 검사한다. 그 내용이 가상 서버 규칙 테이블에 따른 가상 서버 서비스와 일치하면 스케쥴링 알고리즘에 따라 클러스터에서 실제 서버를 선택한다. 그리고 접속이 이루어진 것을 기록하는 해쉬 테이블에 새로운 접속을 추가한다. 그러고나서 패킷의 목적지 주소와 포트가 선택한 서버에 맞게 변경되고 패킷을 해당 서버로 전송한다. 들어오는 패킷이 이러한 접속에 해당하고 해쉬 테이블에서 선택한 서버를 찾을 수 있으면 패킷을 재작성하여 선택한 서버로 전송을 할 것이다. 응답패킷이 돌아오면, 부하분산서버는 패킷의 출발 주소와 포트를 가상 서비스로 변경한다. 접속이 해제되거나 시간을 초과하면, 해쉬 테이블에서 연결 기록을 제거한다.

헷갈리는가? 예제를 보면 이해가 쉬울 것이다. 다음 예를 보자:

실제 서버에서는 TCP/IP를 지원하는 어떠한 OS도 사용할 수 있으며, 실제 서버의 default route 는 가상 서버로 설정해야한다. (위 예에서는 172.16.0.1이다) ipfwadm 프로그램을 이용 가상 서버에서 실제 서버의 패킷을 받을 수 있다. 위 예에서 해당하는 명령은 다음과 같다:

echo "1" > /proc/sys/net/ipv4/ip_forward
ipfwadm -F -a m -S 172.16.0.0/24 -D 0.0.0.0/0

다음 표는 가상 서버를 지원하는 리눅스 서버에서 사용한 규칙이다.

 

Protocoll

Virtual IP Address

Port

Real IP Address

Port

Weight

TCP

202.103.106.5

80

172.16.0.2

80

1

172.16.0.3

8000

2

TCP

202.103.106.5

21

172.16.0.3

21

1

 

IP 주소 202.103.106.5 포트 80을 향하는 모든 트래픽은 실제 주소가 172.16.0.2 포트 80과 172.16.03 포트 8000로 부하분산된다. IP 주소 202.103.106.5 포트 21로 향하는 모든 트래픽은 실제 IP 주소 172.16.0.3 포트 21로 포트-전송된다.

다음과 같이 패킷이 재작성된다.

웹서비스로 들어오는 패킷은 다음과 같은 출발지와 목적지 주소를 가지고 있다:

 

SOURCE

202.100.1.2:3456

DEST

202.103.106.5:80

 

부하분산서버에서 실제 서버로 172.16.0.3:8000을 고른다. 그러면 패킷은 다음과 같이 재작성되어 실제 서버로 전송된다:

 

SOURCE

202.100.1.2:3456

DEST

172.16.0.3:8000

 

다음과 같이 부하분산 서버로 응듭이 돌아온다:

 

SOURCE

172.16.0.3:8000

DEST

202.100.1.2:3456

 

패킷이 가상 서버 주소로 재변경되고 클라이언트로 다음과 같이 전송된다:

 

SOURCE

202.103.106.5:80

DEST

202.100.1.2:3456

 

커널 설정하기

먼저 적당한 버전의 리눅스 커널 소스를 구한다. 그러고나서 커널에 가상 서버 패치를 적용한다. 세 번째로 최소한 여기서 선택한 커널 컴파일 옵션을 선택했는지 확인한다.

 

커널 컴파일 옵션:

Code maturity level options --->

[*] Prompt for development and/or incomplete code/drivers

Networking options --->

[*] Network firewalls
....
[*] IP: forwarding/gatewaying
....
[*] IP: firewalling
....
[*] IP: masquerading
....
[*] IP: ipportfw masq & virtual server support

그리고 하나의 스케쥴링 알고리즘을 선택해야한다.

Virtual server scheduling algorithm
(X) WeightedRoundRobin
( ) LeastConnection
( ) WeightedLeastConnection

최종적으로 커널을 컴파일한다. 적절하게 커널이 컴파일되었다면, 시스템 커널을 업데이트하고 재부팅한다.

마지막으로, ippfvsadm.c 프로그램을 이용 ippfvsadm 유틸리티를 만든다.(** 컴파일한다는 말이겠지용) 그러고 ippfvsadm 유틸리티를 이용 가상 서버 규칙을 설정할 수 있다. 위에서 예제를 든 경우에는 다음과 같다.

ippfvsadm -A -t 202.103.106.5:80 -R 172.16.0.2:80 -w 1

ippfvsadm -A -t 202.103.106.5:80 -R 172.16.0.3:8000 -w 2

ippfvsadm -A -t 202.103.106.5:21 -R 172.16.0.3:21

 

2.2.9 커널 설정하기

커널 컴파일 옵션:

Code maturity level options --->

[*] Prompt for development and/or incomplete code/drivers

Networking options --->

[*] Network firewalls
....
[*] IP: forwarding/gatewaying
....
[*] IP: firewalling
[*] IP: always defragment (required for masquerading) (NEW)
....
[*] IP: masquerading
....
[*] IP: masquerading virtual server support (EXPERIMENTAL)(NEW)
(12) IP masquerading table size (the Nth power of 2)(NEW)
<M> IPVS: round-robin scheduling(NEW)
<M> IPVS: weighted round-robin scheduling(NEW)
<M> IPVS: weighted least-connection scheduling(NEW)
<M> IPVS: persistent client connection scheduling(NEW)

최종적으로 커널을 컴파일한다. 적절하게 커널이 컴파일되었다면, 시스템 커널을 업데이트하고 재부팅한다. 마지막으로 cd 명령을 이용, ipvsadm 소스로 이동하여 "make install" 이라고 명령을 치면 ipvsadm 프로그램을 시스템 디렉토리에 설치한다.

 

부하분산서버에서 마스커레이딩 패킷을 포워딩하도록 다음과 같이 설정한다.

echo "1" > /proc/sys/net/ipv4/ip_forward
ipchains -A forward -j MASQ -s 172.16.0.0/24 -d 0.0.0.0/0

가상 서비스를 추가하고 여기에 스케쥴러를 연결한다.

ipvsadm -A -t202.103.106.5:80 -s  wlc    (Weight least connections scheduling)
ipvsadm -A -t202.103.106.5:21 -s  wrr    (Weght round robing scheduling )

실제 서버를 추가하고 포워딩 방식을 선택한다. Add real server and select forwarding method

ipvsadm -a -t 202.103.106.5:80 -R 172.16.0.2:80 -m
ipvsadm -a -t 202.103.106.5:80 -R 172.16.0.3:8000 -m -w 2
ipvsadm -a -t 202.103.106.5:21 -R 172.16.0.2:21 -m


Last updated: 1999/6/24

Created on: 1998/5/28