서론
드디어 서버가 도착했다.
25.08.21에 구매하고 25.09.23에 수령하였으니, 거의 한 달이 걸린 셈이다.
참고로 사용할 서버의 스펙은 다음과 같다.
베어본 : AOOSTAR WTR PRO AMD Ryzen 7 5825u 4 Bay Nas Mini PC
RAM : PUSKILL DDR4 16GB 3200 x 2 pcs, 총 32GB
SSD : Western Digital WD BLACK SN850X M.2 NVMe 1TB
HDD : Western Digital WD RED 5400/64M 2TB x 4, 총 8TB
HDD는 거의 새것과 같은 중고로 구매해서 총 60만 원 정도 들었다.
이제 실제 사용할 서비스들을 올릴 건데,
서비스를 올리기에 앞서 외부(WAN) 접근을 고려하여 방화벽을 먼저 설정하고자 한다.
참고로 본 글은 기본적으로 아래 글을 베이스로 하여 기본적인 설치 및 설정을 진행하였다.
혹시 관심 있는 사람은 참고해 보면 좋을 것 같다.
Proxmox로 사설 클라우드 구축하기
더이상 프리티어는 그만. 나만의 홈서버 구축기 - proxmox 설치 및 설정
velog.io
본론
Cloudflare
우선 앞선 글과 가장 큰 차이점은, 외부에서도 서비스를 접근할 수 있도록 하기 위해 도메인을 구매했다는 것이다.
글을 쓰는 지금 생각해 보면 굳이 구매할 필요가 없었을 것 같긴 한데, 뭐 어쩌겠는가. 1년만 산 게 다행이다 싶다.
그리고 해당 도메인의 네임서버(Name Server) Cloudflare에서 제공하는 것으로 변경해 주었다.
참고로 Cloudflare를 통해 도메인을 관리할 경우 관리의 편의성 외에도 아래와 같은 장점이 있다.
- DDoS(Distribution Denial of Service) 공격 방어
- 웹 애플리케이션 방화벽(WAF) 제공
- 콘텐츠 전송 네트워크(CDN) 제공
도메인은 내 이름에서 착안해서 knowsu.in으로 구매했다.

참고로 .in 도메인은 인도 국가 도메인인데, 해당 도메인을 등록하고 나니 인도 인터넷 관리청? 같은 데서 환영 메일이 왔다.

방화벽(Firewall)
우선 내가 처음 생각한 구성은 아래 이미지와 같은 매우 간단한 구성이다.

Cloudflare > 공유기 공인 IP > pfSense > NPM(Nginx Proxy Manger) > 내부 서비스
처음 생각한 것은, 각 서비스별로 서브도메인을 생성해서 NPM을 통해 리버스 프록시를 진행하는 것이었다.
다만 이렇게 할 경우 해당 서브도메인을 통해 외부에서 직접 서비스에 접근할 수 있게 된다.
필자에게는 이 부분이 굉장히 큰 두려움으로 다가왔다.
물론 접근 시 ID, PW, 2FA 같은 인증을 필요로 하긴 하겠지만 내가 모르는 뚫는 방법이 있을 수도 있지 않겠는가?
혹자는 그 정도 실력의 해커가 뭐 하러 내 서버에 침입하겠느냐고 물을 수 있겠지만 유비무환이라고 생각했다.
그래서 떠올린 방안은 VPN(Virtual Private Network)였다.
또한 VPN을 쓸 경우, 휴대폰에서도 내부망에 접속이 가능하다는 장점이 있다.
휴대폰은 이동하면서 기지국에 따라 IP가 계속 변경되므로,
방화벽에서 특정 IP에 대해서만 허용할 경우 휴대폰에서는 접속이 불가능할 수 있다.
따라서 IP에 구애받지 않는 VPN을 통하면 휴대폰에서도 안정적인 서비스를 제공할 수 있게 되다.
VPN(Virtual Private Network)
VPN은 기본적으로 사용자가 해당 내부망과 통신하기 위한 터널(Tunnel)을 생성하는 것에서 시작한다.
해당 터널을 통해 내부망과 통신하기 위한 2가지 방법이 존재하는데,
첫 번째는 풀 터널링(Full Tunneling) 방식으로 아래의 특징을 갖는다.
- 사용자의 모든 트래픽을 VPN 서버로 전송
- 내부망과 연관된 트래픽일 경우 포워딩
- 내부망과 무관한 트래픽도 VPN을 경유하여 인터넷으로 전송
이것만 들어도 얼핏 짐작이 가겠지만, 사용자의 모든 트래픽을 VPN 서버로 전송한다는 점에서
VPN 서버의 부하가 심해질 뿐만 아니라 네트워크 지연이 발생하게 된다.
이것도 체감될 정도는 아니라고는 하는데, 좋은 게 좋은 거 아닌가
그래서 필자가 고려한 방식은 두 번째인 스플릿 터널링(Split Tunneling) 방식이다.
해당 방식은 첫 번째와는 달리 모든 트래픽이 아닌, 내부망으로 향하는 트래픽만 VPN을 거치도록 설정한다.
다만 이 시점에서 자연스레 궁금증이 한 가지 생기게 된다.
'어떻게 해당 트래픽이 내부망인지 구분할 것인가?'
당면한 이 문제를 해결하기 위해 굉장히 많은 자료를 찾아봤다.
복잡해서라기보다는 그냥 내가 네트워크 지식을 잘 몰라서다.
DNS Resolver
얼핏 생각하기엔 매우 간단할 것도 같다.
'그냥 Cloudflare에 해당 서브도메인을 등록해서 라우팅 하면 되는 거 아닌가?'
결론부터 말하면 되긴 한다.
일반적으로 알다시피 우리가 브라우저에 도메인을 입력하면 아래 과정을 거친다.

퍼블링 DNS 서비스 중 하나인 Cloudflare는 기본적으로 Proxy 모드를 통해 포워딩을 직접 수행해 주는데,
DNS Only(=Proxy Off) 모드를 사용하면 포워딩 없이 해당 서버의 IP 만을 돌려주게끔 할 수 있다.
즉, DNS Only 모드를 통해 서브도메인들을 pfSense의 LAN IP를 돌려주게 하면,
VPN을 통해 내부망과의 터널이 형성된 상황이어야만 실제 서비스에 접근되도록 할 수 있다.
다만 크게 2가지 이유로 인해 Cloudflare가 아닌 DNS Resolver를 사용하려고 한다.
- 일반적으로 Cloudflare 같은 공인 DNS 서버를 통해 사설망 대역을 노출하는 것은 권장되지 않는다.
- 내부망 대역과 서비스가 존재 정보를 외부로 알리게 된다. - 공인 DNS 서버에 의존하면 외부 장애가 발생할 경우 내부망 접속이 불가능해질 수 있다.
- 내 집 전기가 내려갈 확률과 Log4j와 같은 사태가 터질 확률을 비교하면 좀 애매하긴 하다
블로그 글에 첨부된 사설망 대역은 설치 과정의 실수로 현재는 싹 갈아엎어져서 괜찮다.
이러한 이유로 인해 Cloudflare가 아닌 pfSense의 DNS Resolver 기능을 사용하려 하는데,
DNS Resolver란 일종의 외부로 공개되지 않는 사설 DNS 서버라고 이해하면 된다.
이 방법을 통하면 사설망 대역을 외부로 공개하지 않으면서도 VPN이 연결된 상태에서만 접근되도록 할 수 있다.
참고로 Cloudflare Tunnel을 이용하면 내부망 대역 공개 없이도 인증된 사용자만이 내부망에 접근하도록 할 수 있다.
문제는 해당 기능은 토큰/세션 기반이라 주기적으로 Cloudflare 인증을 필요로 하기에 필자는 배제하였는데,
혹시 해당 방안이 더 궁금한 사람은 아래 링크를 참고해 보면 좋을 듯하다.
네트워크 보안을 지키면서 외부 접속을 활성화 하는 정석, Cloudflare Tunnel
2주정도 삽질 끝에 세팅 성공 했습니다. 키포인트는 Port Forwarding을 하나도 개방하지 않고도 HomeAs...
blog.naver.com
구현 과정
앞서 언급한 글과 pfSense 설치 과정까지는 동일하므로 본 글에서는 이후 과정부터 다루고자 한다.
1. LAN 네트워크 구축
앞서 언급한 글에서는 리눅스 브릿지를 기본 설정(vmbr1, 192.168.1.X 대역)으로 생성하였다.
하지만 필자의 경우는 해당 대역은 회사 VPN이 점유하고 있어서 충돌이 발생하였다.
이걸 모르고 진행했다가 VPN 연결이 안 돼서 몇 시간 내다 버렸다. 회사 VPN 끄니까 잘 되더라
때문에 LAN 대역을 '10.10.80.0/24' 대역으로 변경해 주었다.

해당 브릿지를 pfSense VM에 추가하고 설치를 진행하면, 자동으로 해당 사설망의 LAN IP를 할당받을 줄 알았다.
안타깝게도 그런 마술 같은 일은 일어나지 않았다.

pfSense는 LAN IP를 항상 '192.168.1.1/24'로 고정하여 생성하기에, 이를 수동으로 변경해줘야 했다.
다행히도 콘솔(2번)로 손쉽게 변경할 수 있었고, pfSense의 LAN IP를 사설망 대역에 맞게 변경해 주었다.
참고로 설치 과정에서 pfSense를 LAN 대역의 DHCP 서버로 쓸 거냐고 물어보는데,
이거 안 하면 해당 브릿지를 사용하는 모든 VM마다 IP를 수동으로 부여해줘야 하니 귀찮다면 꼭 켜주자.
이것도 몰라서 Ubuntu VM 띄우고 왜 IP 부여가 안 되는 거지 하고 한참 머리 싸맸다.

이제 해당 브릿지(vmbr1)를 사용하는 Ubuntu VM을 하나 띄워보면 pfSense GUI도 접근이 가능하다.
참고로 pfSense는 기본적으로 외부망으로부터의 접근을 모두 차단하기에 내부망을 통해서만 접근이 가능하다.

2. WireGuard VPN
pfSense를 설치했으니 이제 VPN을 설치할 차례이다.
참고로 여기서부터는 복사 & 붙여 넣기를 할 일이 꽤 생기는데, 기본적으로는 Proxmox와 Host 사이의 클립보드 동기화가 안된다.
이를 위해 Display를 SPICE로 변경한 뒤, Clipboard를 VNC로 해 두면 좌측 사이드바를 통해 붙여 넣기가 가능해진다.
다만 이렇게 하면 해상도가 살짝 줄어들어서 모바일 뷰처럼 동작하긴 하는데 뭐 한 땀 한 땀 치는 거보단 낫지 않은가.

앞으로 진행할 과정을 요약하면 아래 그림과 같다.

참고로 위 그림은 공개 키 암호화 과정을 알고 있다는 전제하에 축약해서 표현한 것이므로 모르겠다면 링크를 참고하길 바란다.
필자의 경우는 WireGuard VPN을 사용하기로 하였는데, 이유는 다음과 같다.
- Tailscale VPN - 회사에서 이미 사용 중임. 다중 클라이언트, 연결 지원 안됨
- OpenVPN - 더 가벼운 WireGuard VPN이 있는데 굳이?
- WireGuard VPN - OpenVPN 보다 가볍고 고성능인데 이걸 참아?
참고로 설정 자체는 Tailscale이 보다 간단하니 특별한 이유가 없다면 Tailscale 사용하자.
필자는 Tailscale VPN이 다중 클라이언트, 연결이 안 돼서 차선책으로 WireGuard VPN을 선택하였다.
pfSense GUI를 통해 WireGuard를 간편하게 설치할 수 있다.

설치가 되었다면 이제 터널(Tunnel)을 만들 차례이다.
앞서 언급하였듯이 VPN은 결국 외부에서 내부망에 접속하기 위한 터널을 만드는 과정이다.

해당 페이지에서 터널이 사용할 IP 대역(10.10.60.0/24)과 터널에 연결될 Peer가 사용할 공개키를 생성해 주었다.

터널을 생성하였다면 이제 해당 터널을 사용할 Peer를 생성해야 한다.
VPN 터널은 상호 공개키 교환을 통해 형성되므로, 키를 교환할 클라이언트가 필요하다.
맥북 클라이언트 기준으로 WireGuard VPN Client를 설치한 뒤 터널을 생성하려고 하면 아래와 같이 보인다.

위 공개키 정보를 기반으로 이제 사용할 터널과 IP를 지정하여 Peer를 추가해 주면 된다.
필자의 경우 이전 터널이 사용할 IP 대역을 '10.10.60.0/24'로 지정하였기에,
해당 서브넷을 사용하는 '10.10.60.100/32'으로 VPN Client의 IP를 지정해 주었다.

터널에 해당 정보를 등록하였으니, 마찬가지로 Client에도 똑같이 등록해 주면 된다.
기본적으로 아래와 같은 구조를 띤다.
필자의 경우엔 외부에서 접근하는 것이기에 공유기 WAN IP를 Endpoint로 지정해 주었다.
[Interface]
PrivateKey = Client Private Key
Address = 할당한 Peer IP
[Peer]
PublicKey = Tunnel Public Key
AllowedIPs = 할당한 Tunnel Interface Address, 연결될 LAN IP 대역
Endpoint = 공유기 WAN IP:할당한 WireGuard Port

위 과정을 정상적으로 마쳤다면 이제 연결이 정상적으로 이루어질 것 같지만, 아직 아니다.
앞서 언급하였듯이 pfSense는 기본적으로 외부(WAN)로부터 들어오는 모든 트래픽을 차단하게끔 되어있다.
즉, VPN 연결을 위해 상호 간의 악수(handshake)를 위한 패킷이 WireGuard VPN에 도달할 수 있어야 한다.
현재 상황은 마치 악수할 상대방이 문을 걸어 잠근 채 세상을 등지고 은거하고 있는 것과 같다.
이를 위해선 앞서 첨부하였던 그림과 같이 아래 과정을 거쳐야 한다.
공유기 WAN IP > 포트 포워딩 > pfSense > 포워딩 > WireGuard VPN
순서대로 하나씩 해보자.
우선 내부망을 통해 공유기 관리자 페이지(192.168.0.1)에서 포트 포워딩 설정을 추가해 주었다.
여기서 주의해야 할 점은 WireGuard VPN의 handshake는 UDP 기반이기에 프로토콜을 UDP로 해주어야 한다.
당연한 얘기겠지만, 목적지는 'pfSense WAN IP:51820'으로 보내면 된다.

포트 포워딩을 해 주었다면, 이제 해당 패킷은 pfSense까지는 도달할 수 있는 상황이다.
그렇다면 이제 pfSense Firewall의 WAN Rule을 추가하여 해당 패킷을 WireGuard VPN으로 넘겨주어야 한다.

WireGuard Rule은 보다 간단하게 들어오는 모든 프로토콜에 대한 트래픽을 받아주도록 하면 된다.

여기까지 모두 마쳤다면 드디어 VPN이 정상적으로 연결되는지 테스트해 볼 차례이다.
정상적으로 연결되었다면 VPN을 켰을 때 아래 이미지처럼 Handshake가 이루어졌어야 한다.

내부망으로의 Ping도 정상적으로 도달하는 것을 확인할 수 있다.

3. DNS Resolver
이제 외부에서 내부망에 접근할 수 있게 되었으니, 각 서비스에 접근할 수 있도록 설정할 차례이다.
앞서 언급하였듯이 pfSense가 제공하는 DNS Resolver 기능을 통해 사설 DNS 서버를 운영할 것이다.
혹자는 여기서 VPN Full Tunnel 방식과 뭐가 다르냐고 볼 수도 있을 것 같다.
VPN Full Tunnel 방식은 실제 패킷 전송이 VPN 서버로 이루어지는 것이고,
DNS Resolver 방식은 단순 DNS 질의(도메인 > IP) 과정만 이루어지기에 명백한 차이가 있다.
해당 과정은 비교적 간단하다.
아래 이미지처럼 pfSense가 제공하는 서비스 목록에 DNS Resolver가 존재함을 확인할 수 있다.
여기에 사용할 서브도메인(pfsense, npm)들을 만들고 해당 도메인들이 모두 NPM LAN IP를 가리키도록 하였다.
분명 Domain Override만 설정해도 된다고 하는 것 같은데 왜인지 안되더라.
내가 뭔가 누락한건지 Host Override도 해주니까 연결은 됐다. 나중에 기회가 된다면 보완해보겠다.

그리고 이전 WireGuard VPN Client 설정해도 DNS 서버를 pfSense로 사용하겠다고 설정해주어야 한다.
pfSense = 방화벽 + 라우터 + VPN 서버 + DHCP + DNS = 그저 신

그리고 NPM Container로 해당 넘어온 패킷에 대해 실제 서비스로 프록시를 해주면 끝이다.

여기까지 설정을 완료했다면, 이제 해당 서브도메인을 기반으로 GUI에 접근할 수 있다.

상기 과정을 그림으로 표현하면 아래와 같은 구조이다.

마지막으로 VPN을 끈 상태에서 도메인을 검색해 보면 아래처럼 외부에서는 조회되지 않는 걸 확인할 수 있다.

결론
이번 글을 통해 Proxmox OS 설치부터 VPN을 통한 내부망 연결,
DNS Resolver를 통한 서브도메인 연결까지 전반적인 초기 세팅을 다루어 보았다.
후에 공유기 포워딩 규칙을 설정하면서 발견한 사실인데,
공유기에서 자체적으로 WireGuard VPN을 제공한다는 것을 세팅이 거의 다 끝나갈 때쯤 발견했다.
그렇다곤 해도 관리 포인트를 pfSense 하나로 통일한다는 점에서 괜찮을 것 같으면서도,
pfSense가 장애가 날 경우 모든 서비스로의 접근이 불가능하게 된다는 점에서 리스크도 존재한다.
아직은 이 둘 중 뭐가 더 리스크가 큰지는 잘 모르겠고, 운영해 나가며 보완하지 않을까 싶다.
정 안되면 pfSense를 하나 더 띄워서 이중화라도 하면 어떻게든 되지 않을까 싶다.
참고자료
Proxmox로 사설 클라우드 구축하기
더이상 프리티어는 그만. 나만의 홈서버 구축기 - proxmox 설치 및 설정
velog.io
Godaddy 도메인을 Cloudflare에서 사용하는 법 A to Z
도메인 구입은 다른 곳에서 하고 Cloudflare를 사용하는 방법에 대해 알아봅니다.
kmpedia.dev
Proxmox 내부에 가상 사설망 구축
현재 집에서 운영하고 있는 Proxmox 서버의 대부분의 서비스는 외부에서 직접 IP를 이용하여 접근이 불가능하도록 가상 사설망에서 동작을 하고 있다.이러한 네트워크 구성을 만들기 위해 어떤 작
hwanstory.kr
[강좌] Proxmox에서 가상 네트워크망 구축
네트워크 연결기본이라 할 수 있는 네트워크 연결이다.처음 Proxmox를 설치하면 네트워크를 설정 하는 창이 다음처럼 나온다. 여기서 연결할 네트워크 포트 지정 및 IP, 게이트웨이, DNS를 지정한
codename393.tistory.com
proxmox 네트워크 설정 과정
https://malwareanalysis.tistory.com/190에서 언급한것처럼 proxmox안에 쿠버네티스를 구성했었는데요! 이번 글에서는 어떻게 구성했는지 그 과정을 조금 더 살펴보려고 합니다. 네트워크 카드(NIC) proxmox는
malwareanalysis.tistory.com
네트워크 보안을 지키면서 외부 접속을 활성화 하는 정석, Cloudflare Tunnel
2주정도 삽질 끝에 세팅 성공 했습니다. 키포인트는 Port Forwarding을 하나도 개방하지 않고도 HomeAs...
blog.naver.com
DNS Resolver Mode | pfSense Documentation
DNS Resolver Mode The DNS Resolver can act in either a DNS resolver or forwarder role. These roles are described in detail on DNS Resolution Process. Resolver mode In resolver mode (default) the DNS Resolver contacts root DNS servers and other authoritativ
docs.netgate.com
Reddit의 PFSENSE 커뮤니티: pfSense에 WireGuard 설치하는 방법 (튜토리얼)
PFSENSE 커뮤니티에서 이 게시물을 비롯한 다양한 콘텐츠를 살펴보세요
www.reddit.com
공개 키 암호 방식 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 공개 키 암호 방식(公開 - 暗號 方式, public-key cryptography)은 암호 방식의 한 종류로 비밀 키 암호 방식과 달리 암호화와 복호화에 이용하는 키가 다른 방식을 말
ko.wikipedia.org
pfSense DNS 구성하기
pfSense DNS 구성하기⛳ 목표 설정 내부망에서 쓰일 DNS 구성 방법을 설명합니다.SSL/TLS를 위해 Server Certificate가 필요합니다. 단, DNS(53)
pcloud.tistory.com