본문 바로가기

iptables와 IPVS 조합으로 패킷 포워더 구축하기

오토씨 2024. 10. 15.

서버 네트워크의 성능과 확장성을 극대화하기 위해 iptables와 IPVS를 조합하여 패킷 포워더를 구축하는 방법에 대해 소개합니다. iptables는 Linux 시스템에서 네트워크 트래픽을 제어하기 위한 방화벽 역할을 수행하며, IPVS는 로드 밸런싱 기능을 제공하여 다수의 서버로 패킷을 효율적으로 분산시킬 수 있습니다. 이 두 가지 기술을 결합하면 유연한 트래픽 관리와 부하 분산이 가능해져 시스템의 안정성을 크게 향상시킬 수 있습니다.

 

iptables와 IPVS 조합으로 패킷 포워더 구축하기

 

1. iptables와 IPVS 조합의 장점

iptables와 IPVS의 조합은 다양한 장점을 제공합니다.

  • 성능 최적화: IPVS는 커널 레벨에서 동작하므로 로드 밸런싱을 매우 빠르게 처리할 수 있습니다. 이는 트래픽 처리 성능을 크게 향상시킵니다.
  • 유연한 트래픽 관리: iptables를 사용하여 트래픽을 세분화하고, IPVS를 통해 분산시킴으로써 보다 유연하게 네트워크 트래픽을 관리할 수 있습니다.
  • 확장성: IPVS를 활용하여 여러 서버에 걸쳐 부하를 분산시킬 수 있어, 시스템의 확장성이 향상되고 서버 장애 시에도 대응이 용이합니다.



2. Ubuntu 22.04에 IPVS 설치하는 방법

Ubuntu 22.04에 IPVS를 설치하는 것은 간단합니다. 다음과 같은 단계를 따라 설치를 진행할 수 있습니다.

2.1 필요한 패키지 설치

sudo apt update
sudo apt install ipvsadm

 

2.2 IPVS 커널 모듈 로드

IPVS를 사용하기 위해 필요한 커널 모듈을 로드합니다.

sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
sudo modprobe nf_conntrack

 

2.3 모듈 확인

올바르게 로드되었는지 확인합니다.

lsmod | grep ip_vs

 

2.4 모듈을 자동으로 로드하도록 설정

재부팅 후에도 자동으로 커널 모듈이 로드되도록 /etc/modules 파일을 업데이트합니다:

echo "ip_vs" | sudo tee -a /etc/modules
echo "ip_vs_rr" | sudo tee -a /etc/modules
echo "ip_vs_wrr" | sudo tee -a /etc/modules
echo "ip_vs_sh" | sudo tee -a /etc/modules
echo "nf_conntrack" | sudo tee -a /etc/modules



3. 특정 인터페이스에서 들어오는 UDP 트래픽을 IPVS로 전달하는 설정 파일 작성

세 개의 네트워크 인터페이스(eth0, eth1, eth2)를 통해 들어오는 UDP 트래픽을 각각 다른 대상 서버로 전달하려면 다음과 같이 설정 파일을 작성할 수 있습니다.

3.1 IPVS 설정

다음 명령어를 통해 eth0, eth1, eth2 인터페이스로 유입되는 트래픽을 각 서버로 전달할 수 있습니다.

# eth0 인터페이스에서 들어오는 UDP 514 트래픽만 IPVS로 전달
sudo iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 514 -j MARK --set-mark 1
sudo ipvsadm -A -f 1 -s rr
sudo ipvsadm -a -f 1 -r 192.168.1.2:514 -g
sudo ipvsadm -a -f 1 -r 192.168.1.3:514 -g

# eth1 인터페이스에서 들어오는 UDP 515 트래픽만 IPVS로 전달
sudo iptables -t mangle -A PREROUTING -i eth1 -p udp --dport 515 -j MARK --set-mark 2
sudo ipvsadm -A -f 2 -s rr
sudo ipvsadm -a -f 2 -r 192.168.1.4:515 -g
sudo ipvsadm -a -f 2 -r 192.168.1.5:515 -g

# eth2 인터페이스에서 들어오는 UDP 516 트래픽만 IPVS로 전달
sudo iptables -t mangle -A PREROUTING -i eth2 -p udp --dport 516 -j MARK --set-mark 3
sudo ipvsadm -A -f 3 -s rr
sudo ipvsadm -a -f 3 -r 192.168.1.6:516 -g
sudo ipvsadm -a -f 3 -r 192.168.1.7:516 -g

 

3.2 iptables 명령 옵션 설명

아래는 각 iptables 명령에 사용된 옵션들의 의미에 대한 상세 설명입니다.

  • -t mangle: 패킷 수정용으로 사용하는 mangle 테이블을 지정합니다. 이 테이블은 패킷의 내용을 변경할 때 사용됩니다.
  • -A PREROUTING: 패킷이 라우팅 되기 전에 규칙을 추가합니다. PREROUTING 체인은 패킷이 인터페이스에 도착했을 때 가장 먼저 적용됩니다.
  • -i ethX: 지정된 인터페이스(예: eth0, eth1, eth2)에서 들어오는 패킷을 대상으로 합니다.
  • -p udp: UDP 프로토콜을 사용하는 패킷을 필터링합니다.
  • --dport XXX: 특정 목적지 포트(예: 514, 515, 516)로 들어오는 패킷을 필터링합니다.
  • -j MARK --set-mark X: 지정된 값(X)으로 패킷에 마크를 설정합니다. 이 마크는 이후 IPVS에서 트래픽을 처리할 때 사용됩니다.

 

3.3 ipvsadm 명령 옵션 설명

아래는 각 ipvsadm 명령에 사용된 옵션들의 의미에 대한 상세 설명입니다.

  • -A: 새로운 가상 서비스를 추가합니다.
  • -f X: 마크 X로 식별된 트래픽을 처리합니다.
  • -s rr: 라운드 로빈 방식으로 트래픽을 분산합니다.
  • -a: 기존 서비스에 리얼 서버를 추가합니다.
  • -r IP:포트: 리얼 서버의 IP 주소와 포트를 지정합니다.
  • -g: Direct Routing 모드(DR 모드)를 사용하여 트래픽을 리얼 서버로 전달합니다. DR 모드에서는 클라이언트의 요청 패킷이 로드 밸런서를 거쳐 리얼 서버로 전달되지만, 패킷의 원본 IP(src IP)는 변경되지 않습니다. 따라서 리얼 서버는 클라이언트의 실제 IP를 그대로 인식할 수 있습니다. 응답 패킷은 리얼 서버가 클라이언트로 직접 전송하므로, 로드 밸런서의 네트워크 부하를 줄여 고성능 처리가 가능합니다. 이 방식은 특히 높은 트래픽 환경에서 로드 밸런서의 처리량을 증가시키는 데 효과적입니다.



4. 전체 설정을 스크립트로 작성해서 관리하는 방법

위의 설정들을 스크립트로 만들어 관리하면 편리합니다. 스크립트를 작성하여 시스템 시작 시 자동으로 설정을 적용할 수 있습니다.

4.1 스크립트 작성

아래는 설정을 자동화하기 위한 Bash 스크립트 예시입니다.

#!/usr/bin/env bash

# eth0 인터페이스에서 들어오는 UDP 514 트래픽만 IPVS로 전달
iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 514 -j MARK --set-mark 1
ipvsadm -A -f 1 -s rr
ipvsadm -a -f 1 -r 192.168.1.2:514 -g
ipvsadm -a -f 1 -r 192.168.1.3:514 -g

# eth1 인터페이스에서 들어오는 UDP 515 트래픽만 IPVS로 전달
iptables -t mangle -A PREROUTING -i eth1 -p udp --dport 515 -j MARK --set-mark 2
ipvsadm -A -f 2 -s rr
ipvsadm -a -f 2 -r 192.168.1.4:515 -g
ipvsadm -a -f 2 -r 192.168.1.5:515 -g

# eth2 인터페이스에서 들어오는 UDP 516 트래픽만 IPVS로 전달
iptables -t mangle -A PREROUTING -i eth2 -p udp --dport 516 -j MARK --set-mark 3
ipvsadm -A -f 3 -s rr
ipvsadm -a -f 3 -r 192.168.1.6:516 -g
ipvsadm -a -f 3 -r 192.168.1.7:516 -g

echo "IPVS 및 iptables 설정 완료"

 

4.2 스크립트 실행 권한 부여

작성한 스크립트에 실행 권한을 부여합니다.

chmod +x setup_ipvs.sh

 

4.3 스크립트 실행

./setup_ipvs.sh

이렇게 스크립트를 사용하여 전체 설정을 자동화하면 관리가 쉬워지고, 재부팅 시에도 동일한 설정을 간편하게 적용할 수 있습니다.



5. IPVS 동작 상태 확인

설정한 IPVS의 동작 상태를 확인하려면 다음 명령어를 사용합니다.

sudo ipvsadm -L -n
  • -L: 현재 설정된 IPVS 가상 서버 및 리얼 서버의 상태를 표시합니다.
  • -n: 숫자 형식(예: IP 주소와 포트 번호)으로 출력을 표시하여, 이름 해석으로 인한 지연을 방지합니다.

이 명령을 통해 현재 설정된 가상 서비스와 리얼 서버의 상태, 연결 수, 스케줄링 방식 등을 확인할 수 있습니다.

명령 실행 결과 예시는 다음과 같습니다:

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
FWM  1 rr
  -> 192.168.1.2:514              Route   1      0          0
  -> 192.168.1.3:514              Route   1      0          0
FWM  2 rr
  -> 192.168.1.4:515              Route   1      0          0
  -> 192.168.1.5:515              Route   1      0          0
FWM  3 rr
  -> 192.168.1.6:516              Route   1      0          0
  -> 192.168.1.7:516              Route   1      0          0
  • Prot: 프로토콜 유형입니다. 여기서는 FWM(Firewall Mark)으로, iptables에서 마크된 패킷을 의미합니다.
  • LocalAddress:Port: 가상 서버의 IP 주소와 포트 번호를 나타냅니다. 스케줄링 방식은 rr(Round Robin)입니다.
  • RemoteAddress:Port: 리얼 서버의 IP 주소와 포트 번호를 나타냅니다.
  • Forward: 포워딩 모드를 나타내며, 여기서는 Route로 Direct Routing을 의미합니다.
  • Weight: 해당 리얼 서버의 가중치를 나타냅니다. 가중치는 로드 밸런싱 시 각 서버에 할당되는 부하의 비율을 결정합니다.
  • ActiveConn: 현재 리얼 서버로 향하는 활성 연결 수를 나타냅니다.
  • InActConn: 현재 리얼 서버로 향하는 비활성 연결 수를 나타냅니다. 이는 이전에 연결되었지만 현재 활성 상태가 아닌 연결입니다.

위의 출력 결과를 통해 각 리얼 서버의 상태와 연결 수를 쉽게 확인할 수 있으며, 이를 통해 IPVS 설정이 올바르게 동작하는지 검증할 수 있습니다.

공식사이트: http://www.linuxvirtualserver.org/software/ipvs.html

댓글