포스트

HomeLab 구축

집에서 네트워크 장비와 서버를 이용해 외부에서도 서비스를 사용할 수 있도록 구축합니다.

HomeLab 구축

이번 글에서는 제가 가지고 있는 네트워크 장비와 라즈베리파이, Dell R730xd, 그리고 ODROID-M1을 이용해 HomeLab을 구축해본 내용을 정리해 보겠습니다. 본 프로젝트에서는 외부 환경에서도 내부 자원에 안전하게 접근할 수 있는 원격 인프라 환경 설계 및 구축하는 것에 집중했습니다.


1. 설계

(토폴로지)
우선 모뎀에서 라우터로 ip를 받아와 외부와 통신할 수 있게 구성합니다. 그리고 각각 L3 Switch로 연결하여 이를 이중화 합니다. 이 사이는 HSRP를 이용해 VIP를 설정합니다.
내부 서비스는 ODROID-M1과 Dell R730xd를 서비스로 사용하고 ODROID-M1에 꺼지지 않을 서비스를 올려두고, Dell R730xd에는 그동안 구축해보고 싶었던 서비스를 올려두었습니다. 앞으로 서비스를 점차 늘려가고 싶어서 Dell R730xd OS는 Proxmox를 설치했습니다.
네트워크 서비스로 DNS와 DHCP를 구축했고, 더 나아가 Docker를 이용해 VPN, Proxy 등 컨테이너 서비스로 운영합니다.


2. 네트워크 구축

Router (C2911)

1
2
3
int g0/0
    no shutdown
    ip add dhcp

외부망과 통신이 원활하게 진행할 수 있게 업링크에 DHCP를 받아오게 했습니다.
이때 왜 DHCP로 받아오게 하냐면 모뎀의 보안 및 인증 시스템 때문입니다. 가정용 IP 회선은 통신사 서버와 공유기가 DHCP 요청 신호를 주고받으며 확인해야만 통신이 되게 설계되어 있습니다. 하지만 사용자가 임의로 고정 IP를 지정하면, 통신사 장비는 정식 인증 단계를 거치지 않은 불법 기기로 간주하여 인터넷 신호를 차단하기 때문입니다.
저는 통신사에서 고정 IP를 구매하지 않았기 때문에 DHCP를 사용했습니다.

1
2
3
4
5
6
7
8
9
int g0/1
    no shutdown
    ip add 182.192.1.1 255.255.255.252

int g0/2
    no shutdown
    ip add 182.192.2.1 255.255.255.252

do show ip route

show ip route

1
2
3
4
5
6
7
8
9
10
ip route 0.0.0.0 0.0.0.0 182.212.231.129

access-list 1 permit 192.168.0.0 0.0.0.255
ip nat inside source list 1 interface g0/0 overload

int g0/0
    ip nat ouside

int r g0/1-2
    ip nat inside

위 route 로그를 봤을 때 외부망 Gateway가 182.212.231.129임을 알 수 있습니다.
그렇기 때문에 외부망으로 나가기 위해 Default Routing으로 Gateway에 나갈 수 있게 구성해주었습니다.
그리고 내부망에서 외부로 나갈 수 있게 NAT 설정을 걸어주었습니다.

1
2
ip route 192.168.0.0 255.255.255.0 182.192.1.2
ip route 192.168.0.0 255.255.255.0 182.192.2.2

마지막으로 외부에서 내부망으로 들어갈 때 경로를 알 수 있도록 Static Routing을 걸어주었습니다.

L3 Switch (C3850)

1
2
3
4
5
6
7
8
9
10
11
12
13
int g1/0/48
    no switchport
    ip add 182.192.1.2 255.255.255.252
    no shutdown

int g1/0/1
    no switchport
    ip add 192.168.0.253 255.255.255.0
    no shutdown

    standby 1 ip 192.168.0.254
    standby 1 priority 150
    standby 1 preempt

인터페이스에 스위칭 기능을 꺼서 L3 역할을 하도록 해주었습니다.
HSRP를 할당해주기 위해 standby로 VIP 192.168.0.254를 지정해주었고, 이 장비가 Active 권한을 가지도록 priority를 150으로 지정해주었습니다. 마지막으로 preempt를 적용해주어 C3950이 죽었다 살아났을 때 다시 Active를 가져오도록 구성하였습니다.

1
2
ip routing
ip route 0.0.0.0 0.0.0.0 182.192.1.1

ip routing을 활성화 해주고 Default Routing을 설정해 외부로 나갈 시 182.192.1.1을 이용하도록 구성하였습니다.

L3 Switch (C3750G)

1
2
3
4
5
6
7
8
9
10
11
12
int g1/0/24
    no switchport
    ip add 182.192.2.2 255.255.255.252
    no shutdown

int g1/0/5
    no switchport
    ip add 192.168.0.252 255.255.255.0
    no shutdown

    standby 1 ip 192.168.0.254
    standby 1 preempt    

인터페이스에 스위칭 기능을 꺼서 L3 역할을 하도록 해주었습니다.
HSRP를 할당해주기 위해 standby로 VIP 192.168.0.254를 지정해주었고, 이 장비가 Standby권한을 가지도록 priority를 건들지 않았습니다. 마지막으로 preempt를 적용해주어 C3850이 죽었다 살아났을 때 다시 Active 기능을 가져가도록 구성했습니다.

1
2
ip routing
ip route 0.0.0.0 0.0.0.0 182.192.2.1

ip routing을 활성화 해주고 Default Routing을 설정해 외부로 나갈 시 182.192.2.1을 이용해도록 구성하였습니다.

Wireless (IPTime)

iptime1
iptime2
iptime3
iptime4


3. 서버 구축

서비스 구상

라즈베리파이를 Bastion Host로 두어 ODROID-M1에 접근 시 점프해야 들어올 수 있게 구성하였습니다.
ODROID-M1에 Web, Nginx Proxy Manager, CodeSRV, VPN 과 같은 무중단이 필요한 서비스들을 구축하였습니다.
Dell R730xd는 서버를 주로 끄고 실습용으로 사용할 것이기 때문에 DHCP, DNS, Grafana를 구축하고, pfsense를 사용해 방화벽까지 설정했습니다.

ODROID-M1 구축

Web Service

ODROID-M1에는 ubuntu를 설치했습니다.
Web을 구축하고 검증을 위해 임시로 내도메인. 한국이라는 사이트에서 무료 도메인을 사용했습니다.

tmp-domain1
tmp-domain2
tmp-domain3

그 후 nginx를 설치해주면 아래와 같이 서비스가 동작하는 것을 확인할 수 있습니다.

1
apt install -y nginx

tmp-domain3

NPM(Nginx Proxy Manager) Service

NPM을 이용해 Proxy 서비스를 구축해보려 합니다. 왜냐하면 NPM을 통해 구축할 때 Let’s Encrypt를 자동으로 발급받아 인증서 관리를 알아서 해주기 때문에 선택하였습니다.
Docker Compose를 이용해서 서비스를 올려보려고 합니다. Nginx로 돌아가는 거기 때문에 앞서 설정한 Web은 비활성화 하고 진행합니다.

1
2
3
4
apt stop nginx
apt disable nginx

apt install -y docker.io docker-compose

이제 기본 디렉토리 설정과 docker-compose.yml 파일을 작성합니다.

1
2
mkdir -p /root/npm/data
mkdir -p /root/npm/letsencrypt

vim /root/npm/docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3"
services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    container_name: npm
    restart: unless-stopped
    ports:
      - "80:80"     # HTTP
      - "81:81"     # 관리자 UI
      - "443:443"   # HTTPS
    volumes:
      - /root/npm/data:/data
      - /root/npm/letsencrypt:/etc/letsencrypt

이재 docker-compose를 해주도록 하겠습니다.

1
2
cd /root/npm
docker-compose up -d

docker-compose-error

오류가 발생했습니다. python pkg가 없어서 일어난 문제인거 같은데 안전하게 docker 공식 리포지터리를 추가하고 설치해보도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
# 1. Docker 공식 GPG 키 등록
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 2. Docker 공식 apt 리포지토리 등록
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 3. 패키지 업데이트 후 설치
apt update
apt install docker-compose-plugin
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.