1. 실습 개요
- 목표
- VPC 2개(VPC-DMZ, VPC-Private)로 망분리 구축
- DMZ VPC에 OpenVPN 서버를 두고 사내망(Private VPC)에 안전하게 접속
- Private VPC에 내부 DNS, 위키·Git 서비스 배포
- 사전 준비물
- 카카오클라우드 계정, 콘솔 접속 권한
- 개인 노트북(OpenVPN Client 설치 가능)
- 기본 Linux(Ubuntu) 사용법
# Mermaid
flowchart LR
subgraph 원격 근무자
VPN_Client["노트북 (OpenVPN Client)"]
end
subgraph DMZ VPC 10.0.0.0/24
VPN_Server["OpenVPN 서버 (Ubuntu)"]
Bastion["Bastion Host (관리용 SSH)"]
end
subgraph Peering
end
subgraph Internal VPC 10.0.1.0/24
DNS_Server["DNS 서버 (BIND9)"]
Node_Registery_Server["Verdaccio"]
Gitlab_Server["Gitlab 서버"]
end
VPN_Client -- UDP 1194 --> VPN_Server
VPN_Server -- VPC Peering --> DNS_Server
VPN_Server -- VPC Peering --> Node_Registery_Server
VPN_Server -- VPC Peering --> Gitlab_Server
Internet -->|SSH 22| Bastion

3. 단계별 실습
3.1 VPC & 네트워크 분리
카카오클라우드 VPC는 3개로 제한되어있습니다. 실습은 아래 미리 생성해둔 VPC (jhj_DMZ_VPC,jhj_Internal_VPC ) 를 통해 진행합니다. 서브넷은 각자 생성하여 실습해봅니다.
- VPC 생성
- jhj_DMZ_VPC: CIDR 10.1.0.0/20
- jhj_Internal_VPC: CIDR 10.1.32.0/20
- 서브넷
위 항목을 보고 나의 Subnet 만들기VPC Region Subnet CIDR jhj_DMZ_VPC kr-central-2-a ooo_DMZ_Subnet_a 10.1.0.0/26 jhj_DMZ_VPC kr-central-2-b ooo_DMZ_Subnet_b 10.1.0.64/26 jhj_Internal_VPC kr-central-2-a ooo_Internal_Subnet_a 10.1.32.64/26 jhj_Internal_VPC kr-central-2-b ooo_Internal_Subnet_b 10.1.32.192/26
VPC Region Subnet CIDR Routing Table jhj_DMZ_VPC kr-central-2-a yji_DMZ_Subnet_a 10.1.6.0/26 main jhj_Internal_VPC kr-central-2-a yji_Internal_Subnet_a 10.1.33.64/26 tgw
- 인터넷 게이트웨이
- DMZ VPC에 IGW 연결 → 퍼블릭 인스턴스에 Public IP 부여
VPC PeeringTransit Gateway- DMZ ↔ Private
Peering 연결 - 각 VPC 라우팅 테이블에 피어링 대상 경로(10.0.0.0/24, 10.0.1.0/24) 추가
- DMZ ↔ Private
3.2 DMZ VPC 설정 (OpenVPN + Bastion)
DMZ Instance 설정
- 인스턴스 생성
- Ubuntu 22.04, 소형 사양(t2.small 정도)
- 보안 그룹:
- UDP 1194 (OpenVPN)
- TCP 22 (SSH, 관리용)
- OpenVPN 설치 & 구성
sudo apt update
sudo apt install -y openvpn easy-rsa
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-c a nopass
./easyrsa gen-dh
./easyrsa gen-req server nopass
./easyrsa sign-req server server
cp pki/{ca.crt,dh.pem,issued/server.crt,private/server.key} /etc/openvpn
- 서버 설정 (/etc/openvpn/server.conf 요약)
# OpenVPN 서버의 기본구조
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
# DMZ 서브넷
push "route 10.1.33.64 255.255.255.192"
# 내부망 서브넷
push "route 10.1.6.0 255.255.255.192"
# 내부망 VPC 전체 접근할 경우 (예: 10.1.32.0/20)
push "route 10.1.32.0 255.255.240.0"
# DNS 서버
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"
keepalive 10 120
user nobody
group nogroup
persist-key
persist-tun
- client 파일 생성 (Certificate)
cd ~/openvpn-ca
# 클라이언트 키 페어 생성
./easyrsa gen-req client1 nopass
# 입력 예시
# Common Name (eg: your user, host, or server name) [client1]: client1
# 서버 CA 로 클라이언트 인증서 서명
./easyrsa sign-req client client1
- base.conf 파일 생성
# ~/client-configs/base.conf
client
dev tun
proto udp
remote 210.109.55.82 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verb 3
# 외부 파일 참조 제거 (우리는 인라인 방식 사용할거라)
#ca ca.crt
#cert client.crt
#key client.key
- 키파일을 .ovpn 으로 변환 (인라인으로 SSL 옵션 합치기)
#!/bin/bash
# inline .ovpn 생성 스크립트
# 사용법: ./make_config_inline.sh client1
# 경로 설정
BASE_CONFIG=~/client-configs/base.conf
KEY_DIR=~/openvpn-ca/pki
OUTPUT_DIR=~/client-configs/files
# 인자 확인
if [ -z "$1" ]; then
echo "Usage: $0 <client-name>"
exit 1
fi
CLIENT_NAME="$1"
mkdir -p "${OUTPUT_DIR}"
OUTPUT_FILE="${OUTPUT_DIR}/${CLIENT_NAME}.ovpn"
# base.conf 내용 복사
cat "${BASE_CONFIG}" > "${OUTPUT_FILE}"
echo "" >> "${OUTPUT_FILE}"
# CA 인증서 인라인
echo "<ca>" >> "${OUTPUT_FILE}"
cat "${KEY_DIR}/ca.crt" >> "${OUTPUT_FILE}"
echo "</ca>" >> "${OUTPUT_FILE}"
echo "" >> "${OUTPUT_FILE}"
# 클라이언트 인증서 인라인
echo "<cert>" >> "${OUTPUT_FILE}"
cat "${KEY_DIR}/issued/${CLIENT_NAME}.crt" >> "${OUTPUT_FILE}"
echo "</cert>" >> "${OUTPUT_FILE}"
echo "" >> "${OUTPUT_FILE}"
# 클라이언트 키 인라인
echo "<key>" >> "${OUTPUT_FILE}"
cat "${KEY_DIR}/private/${CLIENT_NAME}.key" >> "${OUTPUT_FILE}"
echo "</key>" >> "${OUTPUT_FILE}"
echo "=> Generated inline profile: ${OUTPUT_FILE}"
# 경로: ~/openvpn-ca/make_config_inline.sh client1
# 실행 권한 부여 및 실행
chmod +x ./make_config_inline.sh
./make_config_inline.sh client1
# 결과 예시
# => Generated inline profile: /home/ubuntu/client-configs/files/client1.ovpn
- IP 포워딩 & NAT 설정
# IP 포워딩 활성화
sudo sysctl -w net.ipv4.ip_forward=1
# 포워딩 활성화 상태 확인 (결과가 1이면 성공)
cat /proc/sys/net/ipv4/ip_forward
# NAT(MASQUERADE) 설정 추가
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o <퍼블릭 인터페이스> -j MASQUERADE
# 예시: sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp3s0 -j MASQUERADE
# Tip) 퍼블릭 인터페이스 이름은 ip addr 로 확인 가능
# NAT 설정 잘 들어갔는지 확인
sudo iptables -t nat -L POSTROUTING -nv --line-numbers
- 서비스 시작
sudo systemctl enable --now openvpn@server
3.3 원격 근무자 VPN 연결
- 클라이언트 인증서/키 생성 & .ovpn 파일 배포
- 노트북에 OpenVPN Client 설치 (Windows, macOS, Linux)
https://openvpn.net/client-connect-vpn-for-windows/ - VPN 연결 테스트
curl https://api.myip.com

3.4 Private VPC 필요 서비스 설치 (내부 서비스)
DNS 서버 (BIND9)
sudo apt install -y bind9
# /etc/bind/named.conf.local에 zone 추가
zone "corp.local" {
type master;
file "/etc/bind/zones/db.corp.local";
};
- /etc/bind/zones/db.corp.local에 A 레코드(예: gitlab) 설정
Gitlab 설치
sudo apt update
sudo apt install -y docker.io
sudo usermod -aG docker $USER
sudo apt install -y docker-compose-plugin
sudo mkdir -p /srv/gitlab/{config,data,logs}
sudo chown -R 1000:1000 /srv/gitlab
docker run --detach \\
--hostname gitlab.example.com \\
--publish 443:443 --publish 80:80 --publish 22:22 \\
--name gitlab \\
--restart always \\
--volume /srv/gitlab/config:/etc/gitlab \\
--volume /srv/gitlab/logs:/var/log/gitlab \\
--volume /srv/gitlab/data:/var/opt/gitlab \\
gitlab/gitlab-ce:latest
4. 검증 및 정리
- 보안 테스트:
- DMZ 인스턴스 → Private 인스턴스 직접 접속 불가
- VPN 연결 시에만 Private VPC 접근 가능
'학습일지 > K-Digital Traing' 카테고리의 다른 글
| [KDT] AIaaS 마스터클래스 7주차 - NC Dinos 홈페이지의 버그 고쳐보기 (0) | 2025.05.07 |
|---|---|
| [KDT] AIaaS 마스터클래스 6주차 - 테라폼, 깃허브 액션 실습 (5) | 2025.04.28 |
| [KDT] AIaaS 마스터클래스 5주차 - 리눅스 ssh 실습 (0) | 2025.04.24 |
| [KDT] AIaaS 마스터클래스 5주차 - 리눅스 실습 (1) | 2025.04.23 |
| [KDT] AIaaS 마스터클래스 4주차 - 리눅스에 대해 (0) | 2025.04.18 |