[CentOS LVM 기반 XEN 가상화 구축하기]에서 XEN 환경의 가상화 시스템을 구축하는 경우를 정리하였습니다. 하지만 실제 서비스 환경에서는 공인 IP가 넉넉하게 주어지지 않기 때문에 IP를 아껴써야 하는 경우가 있을 수 있습니다. 이번에는 이런 환경에서 호스트서버의 특정 포트로의 요청을 공인 IP가 없는 내부 내트워크의 특정 가상 게스트에 포트 포워딩 하는 방법에 대해서 정리해 보겠습니다.
구글링해서 얻은 이미지입니다만, 내부 아이피만을 가진 게스트 서버들의 경우 virbr0를 통해 내부끼리의 통신을 할 수 있게 됩니다. 이러한 내부 내트웍으로의 통신이 가능해 지려면 virt-install 명령을 사용할 때 잊지 말고 다음과 같이 default 네트워크 설정을 해주시면 됩니다.
$ virt-install ... --network=network:default
작업에 앞서 /etc/sysctl.conf 파일의 내용을 수정해 줍니다. 사용하는 이더넷 포트가 eth0일 경우
# Controls IP packet forwarding net.ipv4.ip_forward = 1 net.ipv4.conf.eth0.proxy_arp = 1 # Disable netfilter on bridges. net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
이제 변경된 설정 정보를 다시 로드 하겠습니다.
$ sysctl -p /etc/sysctl.conf
설정되어있는 브릿지 설정을 확인해 보겠습니다. 여기에서는 virbr0가 존재하는것을 확인하는것이 목적입니다.
$ brctl show bridge name bridge id STP enabled interfaces xenbr0 8000.60eb69fe4c72 no eth0 vif1.0 virbr0 8000.feffffffffff yes vif1.1 vif6.0
존재하는군요. eth0의 브릿지 이름이 xenbr0인것도 확인해 둡니다. virbr0의 아이피 대역을 확인해 보겠습니다. 위의 그림처럼 192.168.122.1 이기를 바랍니다.
$ ifconfig . . . virbr0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:278257 errors:0 dropped:0 overruns:0 frame:0 TX packets:407325 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:17814889 (16.9 MiB) TX bytes:590232428 (562.8 MiB)
다행이도 192.168.122.1인것을 확인했습니다. 여기서는 iptables의 NAT 설정을 통한 포트포워딩을 구현해 보겠습니다. 먼저 준비사항으로 /etc/sysconfig/iptables에 다음과 같은 내용이 추가되어야 합니다.
# Firewall configuration written by system-config-firewall # Manual customization of this file is not recommended. *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535 -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535 -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE -A POSTROUTING -s 192.168.122.0/24 -o xenbr0 -j MASQUERADE COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] . . . -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT COMMIT
2014포트 이후의 모든 포트들에 대하여 외부의 연결이 내부로 라우팅이 가능하도록, 또 그 결과를 다시 반환할 수 있도록 설정하였습니다.
PREROUTING, FORWARD 정의를 통해 라우팅이 결정되기 전에 로컬의 다른 네트워크로 패킷을 전달할 수 있습니다. POSTROUTING 설정을 통해 내부의 패킷이 다시 외부로 전달될 수 있도록 합니다.
이제 호스트 서버의 8080포트로 접근하는 패킷을 내부 게스트인 192.168.122.100의 80번 포트에 포트포워딩 하는 설정을 진행해 보겠습니다. 다시한번 /etc/sysconfig/iptables의 내용에 다음을 추가합니다.
# Firewall configuration written by system-config-firewall # Manual customization of this file is not recommended. *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] -A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.122.100:80 -m comment --comment "port forwarding test" -A POSTROUTING ... COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] ... -A FORWARD -d 192.168.122.100/32 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 80 -j ACCEPT -m comment --comment "port forwarding test" -A FORWARD ... COMMIT
여기서 주의할 점은 지금 추가하는 PREROUTING, FORWARD 룰은 먼저 추가했던 룰보다 위에 존재해야 한다는 점입니다.
외부에서 호스트 서버의 8080포트로 접속해 봤더니 내부의 192.168.122.100 서버의 80번 포트로 연결되는것을 확인할 수 있었습니다.
참고
- http://serverfault.com/questions/332684/remote-access-to-internal-machine-ssh-port-forwarding
- http://wiki.xen.org/wiki/Xen_FAQ_Networking