네트웍 트래픽 분산 및 IP Masquerading, 그리고 PPP와 관련하여 리눅스 방화벽에 설치해야 할 소프트웨어를 살펴보자. 필자의 리눅스 방화벽에 설치되어 있는 소프트웨어 목록은 아래와 같다.
iproute-20001007
iptables-1.2.4
ppp-2.4.1
pppoe-3.2
iproute는 iproute2 라는 이름의 소프트웨어이며 데비안에서는 iproute 라는 이름의 패키지로 배포하고 있다. 이 소프트웨어는 기존의 route 명령을 대체하는 명령어(ip)를 포함하고 있으며 네트웍 대역폭을 조절하는 명령어(tc)도 포함되어 있다.
iptables는 커널 2.2에서 제공하던 ipchains를 대체하는 명령어로 ipchains보다 많은 기능을 제공한다.
본론에 들어가기 전에 네트웍 트래픽을 분산시키기 위해서 밟아야 할 순서를 짚어보자.
먼저 트래픽 분산 정책을 결정해야 할 것이다. 즉, a 종류의 패킷은 1번 문으로 내보내고, b 종류의 패킷은 2번 문으로 내보낸다는 식의 정책을 결정해야 할 것이다. 이러한 정책을 결정하기 위해서는 고려해야 할 것이 몇가지 있을 것이다. 예를 들면, 끊김이 없어야 하는 패킷은 전용선 쪽으로 내보내고, 그렇지 않은 패킷은 ADSL 쪽으로 내보낸다는 식이다. 그리고 전체적인 네트웍 트래픽의 양도 감안해야 할 것이다.
그 다음, 결정된 정책에 따라서 ip 명령으로 라우팅 룰을 설정하고, 라우팅 테이블을 만들어야 한다. 그리고 내보낼 패킷과 내보내지 않을 패킷, 들어와서는 안되는 패킷 등을 구분하여 필터링을 할 예정이라면 iptables 명령으로 패킷을 어떻게 걸러낼 것인지 설정한다. 그리고 iptables 명령으로 Masquerading 설정을 한다. 아래에 그 순서를 간단하게 정리하였다.
네트웍 트래픽 분산 정책을 결정한다.
분산 정책에 따라서 라우팅 룰을 설정한다.
분산 정책에 해당하는 라우팅 테이블을 설정한다.
iptables 명령으로 필터링 룰을 설정한다.
iptables 명령으로 Masquerading을 설정한다.
3절에서 설명한 네트웍 환경을 기준으로 하여, 네트웍 트래픽을 서브네트웍 별로 분산시키는 상황을 가정한다. 아래는 리눅스 방화벽에 설정되어 있는 라우팅 테이블을 route 명령과 ip 명령으로 본 결과이다. 그리고 그 뒤에 라우팅 룰과 main 라우팅 테이블도 표시 하였다.
# netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 200.200.200.1 0.0.0.0 255.255.255.255 UH 40 0 0 ppp0 100.100.100.0 0.0.0.0 255.255.255. U 40 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 40 0 0 eth1 0.0.0.0 100.100.100.1 0.0.0.0 UG 40 0 0 eth0 # ip route ls 200.200.200.1 dev ppp0 proto kernel scope link src 200.200.200.2 100.100.100.0/24 dev eth0 proto kernel scope link src 100.100.100.2 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.254 default via 100.100.100.1 dev eth0 # ip rule ls 0: from all lookup local 32766: from all lookup main 32767: from all lookup default # ip route ls table main 200.200.200.1 dev ppp0 proto kernel scope link src 200.200.200.2 100.100.100.0/24 dev eth0 proto kernel scope link src 100.100.100.2 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.254 default via 100.100.100.1 dev eth0 |
ip rule ls 명령의 결과를 보면 기본적으로 세개의 라우팅 테이블 local, main 그리고 default가 있음을 알 수 있다. 각 라우팅 테이블의 자세한 내용은 ip route ls table local과 같은 명령으로 알 수 있다. 여러분 각자 확인해 보기 바란다. 위에서 보다시피 각 라우팅 테이블 에는 번호가 붙어 있으며 리눅스 커널은 낮은 번호 순서대로 패킷을 처리한다. 즉 패킷이 네트웍을 통해서 들어오면 커널은 그 패킷이 어디로 향하는지 확인하고서는 어떻게 라우팅할 지 local 테이블에서 먼저 찾아본다. local 테이블에 적당한 처리 규정이 없으면 main 테이블을 찾아보고 거기에도 없으면 마지막으로 default 테이블을 찾아보는 것이다.
from all이 의미하는 바는 패킷이 어디에서 온 것인지를 정의하는 것이다. all 이므로 어디에서 온 것이든 상관없다는 의미이다. from all을 from 192.168.1.100으로 바꾸면 192.168.1.100 에서 출발한 패킷을 의미하게 된다. 즉 출발지에 따라서 라우팅을 결정할 수 있는 것이다. 이를 두고 Source Routing이라 한다.
ip route ls table main 명령의 실행 결과를 살펴보면, main 테이블에 ppp0에 대한 라우팅이 설정되어 있고, E1 전용선에 대한 라우팅이 default로서 설정되어 있음을 알 수 있다. netstat -rn 명령의 결과와 같음을 알 수 있다. 즉, netstat -rn 명령은 main 테이블을 표시한 것이다.
이제 5.2절트래픽 분산의 순서에서 설명한 대로 하나씩 해보자.
Net-A와 Net-B로부터 인터넷으로 향하는 패킷은 E1 전용선을 통하여 나간다.
Net-C로부터 인터넷으로 향하는 패킷은 ADSL(ppp0)을 통하여 나간다.
/etc/iproute2/rt_tables에 적당한 라우팅 테이블 이름을 넣어 준다. 라우팅 테이블 이름을 e1line, adslline 이라고 하자.
# echo 201 e1line >> /etc/iproute2/rt_tables # echo 202 adslline >> /etc/iproute2/rt_tables |
분산 정책에 따라서 라우팅 룰을 추가한다.
# ip rule add from 192.168.1.0/24 table e1line # ip rule add from 192.168.2.0/24 table e1line # ip rule add from 192.168.3.0/24 table adslline |
e1line과 adslline 라우팅 테이블을 만든다.
# ip route add default via 100.100.100.1 dev eth0 table e1line # ip route add default via 200.200.200.1 dev ppp0 table adslline |
필터링 룰을 설정하기 전에 설정된 라우팅 룰을 살펴보고 고려해야 할 사항을 알아보자.
# ip rule ls 0: from all lookup local 32763: from 192.168.3.0/24 lookup adslline 32764: from 192.168.2.0/24 lookup e1line 32765: from 192.168.1.0/24 lookup e1line 32766: from all lookup main 32767: from all lookup default |
192.168.1.10에서 111.111.111.100 으로 향하는 패킷을 생각해 보자. 그 패킷이 리눅스 방화벽에 들어가면 리눅스 커널은 0번 라우팅 룰부터 대조하여 어떻게 라우팅 할 것인지 결정할 것이다. 0번 라우팅 룰은 그 패킷이 어디에서 출발 한 것인지 상관없이 (from all) local 라우팅 테이블을 참조하도록 되어 있다. 그러나 local 테이블을 살펴보면 알겠지만 거기에는 111.111.111.100으로 향하는 패킷에 대하여 마땅히 처리할 라우팅 규칙이 없다. 그 다음 라우팅 룰(32763번)은 192.168.3.0네트웍으로부터 출발하는 패킷에 대한 것이므로 해당 사항이 없다. 32764번 룰도 비슷하다. 32765번 룰은 192.168.1.0 네트웍으로부터 출발하는 패킷에 대하여 적용 가능하다. e1line 라우팅 테이블을 살펴보자.
# ip route ls table e1line default via 100.100.100.1 dev eth0 |
또 다른 경우를 살펴보자. 192.168.3.10에서 웹서버인 100.100.100.10 으로 향하는 패킷을 생각해 보자. 앞에서 살펴본 과정과 비슷하게 따라가 보면 이 패킷은 ADSL을 통해서 빠져 나간 후 인터넷을 거쳐서 웹서버로 들어옴을 알 수 있다. eth0를 통해서 빠져 나가면 바로 갈 수 있는 길을 크게 돌아서 온 것이다. 따라서 이에 대한 보완도 필요함을 알 수 있다. ADSL도 비슷한 상황을 가정할 수 있으나 여기서는 굳이 고려하지 않겠다. 왜냐하면 귀찮으니까.... 그리고 생각해 본 적도 없으므로.... 게다가 별 필요가 없으므로...
한 가지 더 고려해야 할 사항은 리눅스 방화벽에서 192.168.1.0 네트웍으로 나가는 라우팅 규칙은 local 테이블에 명시되어 있지만 192.168.2.0, 192.168.3.0 네트웍으로 나가는 라우팅 규칙은 명시되어 있지 않다. 이를 local 테이블에 추가해 주어야 한다. 왜 local 테이블에 추가하는 지는 생각해 보면 알 수 있을 것이다.
위의 상황을 고려하여 라우팅 룰과 라우팅 테이블을 다시 만들어 보자. 앞에서 /etc/iproute2/rt_tables에 echo 문으로 추가했던 두 줄을 지운 후 아래 명령을 실행해야 할 것이다.
# echo 201 adslline >> /etc/iproute2/rt_tables # ip rule add from 192.168.3.0/24 table adslline # ip route add default via 200.200.200.1 dev ppp0 table adslline # ip route add 100.100.100.0/24 via 100.100.100.2 dev eth0 table local # ip route add 192.168.2.0/24 via 192.168.1.254 dev eth1 table local # ip route add 192.168.3.0/24 via 192.168.1.254 dev eth1 table local |
# echo 201 adslline >> /etc/iproute2/rt_tables # ip rule add from 192.168.3.0/24 table adslline # ip route add default via 200.200.200.1 dev ppp0 table adslline # ip route add 100.100.100.0/24 via 100.100.100.2 dev eth0 table local # ip route add 192.168.0.0/16 via 192.168.1.254 dev eth1 table local |
필터링 룰을 설정하는 것은 여기서 생략한다.
전용선 쪽으로 나가는 패킷과 ADSL 쪽으로 나가는 패킷에 대한 Masquerading 설정이 필요할 것이다.
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j SNAT --to 100.100.100.2 # iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE |
# echo 201 adslline >> /etc/iproute2/rt_tables # ip rule add from 192.168.3.0/24 table adslline # ip route add default via 200.200.200.1 dev ppp0 table adslline # ip route add 100.100.100.0/24 via 100.100.100.2 dev eth0 table local # ip route add 192.168.0.0/16 via 192.168.1.254 dev eth1 table local # iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j SNAT --to 100.100.100.2 # iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE |
port를 구분해서 패킷을 내보내는 방법과 호스트 또는 서브네트웍을 구분해서 패킷을 내보내는 방법은 한 가지를 제외하고는 큰 차이가 없다. 기본적으로 커널은 어떤 패킷이 어디로 향하는 지를 보고서 라우팅을 어떻게 할 지를 결정하며, 그 패킷이 www port를 사용하는지, telnet port를 사용하는지 등은 라우팅의 기준이 되지 않는다. 따라서 port를 구분해서 라우팅을 하기 위해서는 또 다른 기준을 만들어 주어야 하며, 그 방법은 특정 port를 사용하는 패킷에 표식을 해서 구분하는 것이다. 패킷에 표식을 하는 것은 iptables 명령을 이용한다.
www, ftp, ftp-data port를 사용하는 패킷은 ADSL(ppp0)을 통하여 나간다. 나간다.
이외의 나머지 패킷은 E1 전용선을 통하여 나간다.
/etc/iproute2/rt_tables에 ADSL을 통해서 나가는 패킷을 위해 adslline 라우팅 테이블 이름을 추가한다.
# echo 201 adslline >> /etc/iproute2/rt_tables |
분산 정책에 따라서 라우팅 룰을 추가한다.
# ip rule add fwmark 1 table adslline |
# iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport www -j MARK --set-mark 1 # iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport ftp -j MARK --set-mark 1 # iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport ftp-data -j MARK --set-mark 1 |
adslline 라우팅 테이블을 만들고 local 테이블에 필요한 라우팅 규칙을 추가한다.
# ip route add default via 200.200.200.1 dev ppp0 table adslline # ip route add 100.100.100.0/24 via 100.100.100.2 dev eth0 table local # ip route add 192.168.0.0/16 via 192.168.1.254 dev eth1 table local |
필터링 룰을 설정하는 것은 여기서 생략한다.
5.3절에서와 마찬가지로 전용선 쪽으로 나가는 패킷과 ADSL 쪽으로 나가는 패킷에 대한 Masquerading 설정이 필요할 것이다.
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j SNAT --to 100.100.100.2 # iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE |
# echo 201 adslline >> /etc/iproute2/rt_tables # ip rule add fwmark 1 table adslline # iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport www -j MARK --set-mark 1 # iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport ftp -j MARK --set-mark 1 # iptables -A PREROUTING -i eth1 -s 192.168.0.0/16 ! -d 192.168.0.0/16 \ -t mangle -p tcp --dport ftp-data -j MARK --set-mark 1 # ip route add default via 200.200.200.1 dev ppp0 table adslline # ip route add 100.100.100.0/24 via 100.100.100.2 dev eth0 table local # ip route add 192.168.0.0/16 via 192.168.1.254 dev eth1 table local # iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j SNAT --to 100.100.100.2 # iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE |
위와 같이 port 별로 네트웍 트래픽을 분산시키려 할 때 전혀 라우팅이 안되는 경우가 있다. 아마도 대부분의 리눅스 배포본에서 이런 현상이 발생할 것으로 생각된다. 이는 spoof protection을 위해 /proc/sys/net/ipv4/conf/*/rp_filter 파일의 값을 "1"로 설정했기 때문이다. 모든 디바이스에 대하여 rp_filter 파일의 값을 "0"으로 설정하면 문제가 해결될 것이다.