Proxmox 내부망 구축하기

    일반적으로 Proxmox를 사용하면 모든 VM과 컨테이너가 라우터로부터 새 IP를 할당 받게 됩니다. 라우터의 설정을 따라야 하기에 불편한 점도 있고, 서버를 무선랜으로 구축한다면 NIC에 virtual bridge 설정 자체가 불가하기도 합니다.

    필자의 경우 컨테이너가 10개가 넘어가는 순간부터는 공유기 DHCP로는 관리가 불가능해서, 자체 IP 체계가 필요하다 생각했습니다. 자체적인 내부망을 가지면 개별 컨테이너/VM과의 통신도 편리하고 보안성 또한 증가되니까 여러모로 좋다고 생각했습니다. 또한 컨테이너가 200개가 넘어간다면 일반적인 가정의 공유기에서 할당할 수 있는 IP 수가 모두 고갈될 수도 있으므로 서브넷 마스크를 조정하거나 내부망 구성이 필수적입니다.

    이를 해결하기 위해 nftables나 iptables, 또는 pfSense 등을 사용하여 자체 내부망을 구성할 수 있는데요. 고급 방화벽 구성이 필요하다면 pfSense를 사용하는 것이 좋겠으나, 이 글에서는 간단히 구축해보기 위해 iptables보다 더 모던한 버전인 nftables를 사용하겠습니다.

    내부망 구축하기

    계획하기

    내부망을 구축하기 전에 먼저 어느 IP 대역을 사용할 건지, 서브넷 마스크는 얼마로 할 건지 등의 구체적인 계획을 정해야 합니다. 내부망의 IP 대역대는 외부 IP와 충돌하면 안 되므로 RFC1918에 따른 내부망 대역만을 사용해야 합니다. 각 클래스별 내부망 대역은 다음과 같습니다.

    • Class A
      • 10.0.0.0/8 (16,777,216개)
    • Class B
      • 172.16.0.0/12 (1,048,576개)
    • Class C
      • 192.168.0.0/16 (65,536개)

    위 범위는 CIDR 표기법으로 표시된 범위입니다. 단순히 생각해서 앞에서 몇 bit를 고정해야 하는지를 나타낸다고 이해하면 됩니다.

    자신이 필요로 하는 IP수에 따라 알맞는 대역대를 선택하면 됩니다. 해당 대역 안에서 나만의 작은 대역을 만들어 사용해도 좋습니다. 다만 상위 공유기에서 할당하는 IP 주소와 충돌하면 안 됩니다. 예를 들어 라우터가 192.168.0.0/24(192.168.0.0 ~ 192.168.0.255) 범위에서 IP를 할당하는데, 해당 라우터에 연결된 서버에서 해당 범위를 침범하면 안 됩니다. 192.168.1.0/24(192.168.1.0 ~ 192.168.1.255) 와 같이 할당하여 서로 대역을 구분해야 합니다.

    필자의 경우 아래와 같이 망을 계획했습니다.

    IP 대역 : 10.57.0.0/16 게이트웨이 10.57.0.1

    게이트웨이 주소는 nftables가 설치된 OS의 IP입니다.

    nftables 설치하기

    nftables로 망을 구성하기 앞서, nftables를 설치해야 합니다. APT를 이용해 설치를 진행합니다.

    apt install nftables

    nftables 설정하기

    Config 파일 생성 및 기본 설정

    /etc/nftables.conf 파일을 생성하고 nftables 테이블과 체인을 정의합니다. 위에서 정의한 10.57.0.0/16 대역을 기준으로 예시를 작성하였습니다. 개개인에 상황에 맞게 계획한 대로 수정하여 적용하시기 바랍니다.

    #!/usr/sbin/nft -f
    flush ruleset
    table ip my_network {
        chain input {
            type filter hook input priority 0;
            # 내부망 트래픽 허용
            ip saddr 10.57.0.0/16 accept
        }
        chain output {
            type filter hook output priority 0;
            # 출력 트래픽 기본 허용
            accept
        }
        chain forward {
            type filter hook forward priority 0;
            # 내부망 간의 트래픽 허용
            ip saddr 10.57.0.0/16 ip daddr 10.57.0.0/16 accept
            # 외부망으로의 트래픽 허용
            ip saddr 10.57.0.0/16 accept
        }
    }

    위 설정은 내부망(10.57.0.0/16)에서 발생하는 트래픽을 허용합니다.

    NAT 설정

    내부망에서 외부와 통신을 하기 위해서는 NAT 설정을 해야 합니다. nftables 에서 NAT 규칙은 별도의 테이블로 관리됩니다. Config 파일에 NAT규칙을 주가해 줍니다. 완전히 외부와 통신하지 않는 망을 만든다면 이 부분을 생략해도 됩니다.

    table ip nat {
        chain postrouting {
            type nat hook postrouting priority 100;
            # NAT 변환 규칙: 내부망 -> 외부망
            oifname "eth0" ip saddr 10.57.0.0/16 masquerade
        }
    }

    ofiname "eth0" 부분을 자신의 서버의 네트워크 인터페이스명에 맞도록 설정합니다. 이 인터페이스를 통하여 내부망에서 외부망으로 통신하게 됩니다.

    포트포워딩

    서버로 사용하기 위해서는 특정 포트는 서비스를 위해 열어야 합니다. 서비스에 필요한 포트를 열기 위해 NAT 테이블에 prerouting 체인을 추가합니다.

    table ip nat {
        chain prerouting {
            type nat hook prerouting priority 0; policy accept;
            iif "eth0" tcp dport 80 dnat to 10.57.0.2:80;
        }
        chain postrouting {
            # 기존 코드...
        }
    }

    10.57.0.2 부분과 80번 포트 부분을 각자의 필요에 맞춰 변경하여 사용하시기 바랍니다. 한번에 여러 포트의 개방이 필요한 경우 아래와 같이 사용할 수도 있습니다.

    iif "eth0" tcp dport {80, 443, 81} dnat to 10.57.0.2;

    전체 예제

    모든 설정이 작성된 Config 파일 예제는 다음과 같습니다.

    #!/usr/sbin/nft -f
    flush ruleset
    table ip my_network {
        chain input {
            type filter hook input priority 0;
            # 내부망 트래픽 허용
            ip saddr 10.57.0.0/16 accept
        }
        chain output {
            type filter hook output priority 0;
            # 출력 트래픽 기본 허용
            accept
        }
        chain forward {
            type filter hook forward priority 0;
            # 내부망 간의 트래픽 허용
            ip saddr 10.57.0.0/16 ip daddr 10.57.0.0/16 accept
            # 외부망으로의 트래픽 허용
            ip saddr 10.57.0.0/16 accept
        }
    }
    table ip nat {
        chain prerouting {
            type nat hook prerouting priority 0; policy accept;
            iif "eth0" tcp dport {80, 443, 81} dnat to 10.57.0.2;
        }
        chain postrouting {
            type nat hook postrouting priority 100;
            # NAT 변환 규칙: 내부망 -> 외부망
            oifname "eth0" ip saddr 10.57.0.0/16 masquerade
        }
    }

    시스템 데몬 설정

    nftables가 작동해야 내부망이 작동하기 때문에, OS가 부팅되면 자동적으로 nftables가 켜지도록 설정하겠습니다.

    systemctl enable nftables

    IP 포워딩 활성화

    내부 내트워크에서 외부 네트워크로 트래픽을 전달하기 위해서는 IP 포워딩이 필요합니다. IP 포워딩을 활성화하겠습니다.

    sysctl -w net.ipv4.ip_forward=1

    내부망 Virtual Bridge 설정하기

    컨테이너와 VM을 내부망에 연결시키기 위해 Virtual Bridge를 사용하겠습니다. /etc/network/interfaces 파일에서 가상 브릿지를 다음과 같이 수정하고, 물리 NIC설정또한 변경하겠습니다. 기본 Proxmox 설정에서는 vmbr0 이 물리 NIC에 브릿지 역할을 하였지만, 이 때에는 vmbr0이 내부망에 연결되기 때문에, 물리 NIC의 설정 또한 바꿔야 합니다.

    필자의 경우 고정 IP를 사용하기 때문에 vmbr0에 설정되어 있던 고정 IP설정을 물리 NIC로 옮겨 주었습니다.

    auto eth0
    iface eth0 inet static
        address 192.168.0.4
        netmask 255.255.255.0
        gateway 192.168.0.1
        dns-nameservers 8.8.8.8
    
    auto vmbr0
    iface vmbr0 inet static
        address 10.57.0.1
        netmask 255.255.0.0
        bridge_ports none
        bridge_stp off
        bridge_fd 0

    테스트하기

    모든 설정을 완료했다면, 서버를 재부팅하고, 컨테이너를 만듭니다. 내부망에는 DHCP가 없기 때문에 컨테이너의 IP와 서브넷 마스크를 CIDR 표기법으로 수동 지정하고, Gateway 주소를 브릿지 호스트인 10.57.0.1로 설정합니다.

    설정을 마친 후, 컨테이너의 쉘에서 게이트웨이 주소로, 8.8.8.8 등 외부로도 ping을 보내 인터넷이 되는지 확인합니다.

    ping 10.57.0.1
    ping 8.8.8.8

    VPN 등록하기

    구성한 내부망에 때때로는 접근해야 할 때가 있습니다. 이때 안전하고 편리하게 접근하기 위해서는 VPN이 필요합니다. 필자는 이때 Cloudflare Zero Trust 를 사용했습니다. 컨테이너를 하나 생성한 후, cloudflared를 설치했습니다.

    VPN설정에 대한 자세한 내용은 Cloudflare Zero Trust VPN을 사용해보자 글을 참고해주세요.


    게시됨

    카테고리

    작성자

    태그:

    Obtuse의 테크 블로그 더 알아보기

    이 블로그에 새 글이 나올 때 마다 이메일로 알림을 받아보는 건 어때요?


    ※구독 버튼을 클릭하면 obtuse.kr의 개인정보 처리방침의 광고성 정보 수신에 동의하는 것으로 간주합니다.

    댓글

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

    이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.