홈 네트워크 지도: 공유기 포트 없이 집 서버를 쓰는 구성

미니PC Proxmox 한 대, GPU 서버, NAS로 꾸린 홈 네트워크 전체 그림. 공유기 포트를 하나도 열지 않고 Tailscale·AdGuard·Nginx Proxy Manager로 집 밖에서 쓰고, 블로그만 AWS로 공개한다.
집 서버는 공유기 포트를 하나도 열지 않고 쓴다. 집 밖에서는 Tailscale로 들어오고, 이름 풀이는 집 안 AdGuard Home이, HTTPS는 와일드카드 인증서 하나가 맡는다. 인터넷에 공개하는 것은 이 블로그 하나이고, 블로그는 집이 아니라 AWS에 있다. 이 블로그의 홈랩 글들은 모두 이 그림 위에서 출발한다.
집 안에 있는 것
| 장비 | 하는 일 |
|---|---|
| 공유기 | 인터넷 연결, 집 안 주소 배정. 밖에서 들어오는 포트 없음 |
| 미니PC (Proxmox) | 홈서버 본체. VM 1개와 LXC 3개 |
| GPU 서버 | 로컬 LLM 전용 |
| NAS | 백업 저장소로 정리 중 |
| 데스크톱 | 유선 연결. DNS를 AdGuard로 지정 |
미니PC 안은 하는 일별로 나눴다.
| 번호 | 종류 | 이름 | 하는 일 |
|---|---|---|---|
| 110 | LXC | 관문 | Tailscale, AdGuard Home, Nginx Proxy Manager. 모든 접속의 입구 |
| 100 | VM | Docker 앱 | Gitea, 사진 관리, 웹 UI 같은 앱 컨테이너 |
| 120 | LXC | 블로그 러너 | 블로그 빌드·배포, 내부 미리보기 사이트 |
| 121 | LXC | 개발 서버 | PC의 VS Code가 SSH로 붙어 Dev Container를 띄우는 곳 |
나눈 기준과 미니PC 사양은 미니PC 한 대로 홈서버 글에 따로 적었다. 블로그 러너가 하는 일은 Gitea Actions 배포 글에 있다.
바깥과 닿는 주요 지점 네 곳
| 바깥 서비스 | 쓰는 이유 | 방향 |
|---|---|---|
| 공개 DNS (Route 53) | 블로그와 루트 도메인 주소만 등록. 집 IP는 없다 | — |
| Tailscale | 집 밖 기기를 집 안 관문에 잇는다 | 기기끼리 암호화 연결 |
| Let’s Encrypt | 내부 서비스용 와일드카드 인증서 | 집 → 밖 |
| CloudFront + S3 | 블로그 공개 | 집 → 밖 (배포) |
넷 다 집에서 밖으로 나가는 연결이거나, Tailscale처럼 양쪽 기기가 서로를 확인한 뒤에만 이어지는 연결이다. 모르는 사람이 집 IP로 들어올 문은 없다.
집 밖에서 Gitea를 열 때
- 폰에서 Tailscale을 켠다. 폰이 집 관문과 같은 가상 네트워크에 들어온다.
- 주소창에 내부 서비스 주소를 친다. Tailscale에 붙은 기기의 DNS 질문은 AdGuard Home으로 간다.
- AdGuard Home이 “내 도메인의 모든 하위 주소는 관문”이라고 답한다 (DNS 재작성
*.도메인 → 관문). - 관문의 Nginx Proxy Manager가 주소를 보고 Docker VM의 Gitea로 넘긴다. 인증서는 와일드카드 하나를 모든 주소에 쓴다.
공개 DNS에는 이 주소들이 아예 없다. Tailscale 없이 밖에서 치면 주소부터 풀리지 않는다. 집 데스크톱은 유선 DNS를 AdGuard로 지정해 두어 Tailscale 없이 같은 주소로 들어간다.
포트를 닫고도 인증서가 갱신되는 이유
Let’s Encrypt 인증서는 “이 도메인이 내 것”임을 증명해야 나온다. 흔한 방법은 서버의 80번 포트로 확인 요청을 받는 것인데, 포트를 닫으면 이 방법을 못 쓴다.
그래서 DNS 인증을 쓴다. 인증서를 받을 때 Nginx Proxy Manager가 공개 DNS에 확인용 TXT 레코드를 잠깐 올리고, Let’s Encrypt는 그 레코드를 보고 발급한다. 들어오는 연결이 필요 없다.
이때 쓰는 AWS 키는 권한을 좁혀 두었다. _acme-challenge로 시작하는 TXT 레코드만 바꿀 수 있고, 블로그 주소나 다른 레코드는 건드리지 못한다. 키가 새도 할 수 있는 일이 인증용 레코드 쓰기뿐이다.
블로그만 AWS에 둔 이유
블로그는 누구나 와야 하는 곳이라, 집에서 공개하려면 포트를 다시 열어야 한다. 그래서 글은 집에서 쓰고 빌드하되 결과물만 S3에 올려 CloudFront로 내보낸다. 배포는 집 → AWS 한 방향이다. 이렇게 나눈 이유는 홈서버가 있는데 블로그는 AWS에 올린 이유에, AWS 쪽 설정은 CloudFront Free 플랜 글에 있다.
이렇게 바뀌어 왔다
| 시점 | 구성 |
|---|---|
| 처음 | 공유기 443 → 관문. 서브도메인마다 공개 DNS에 집 IP |
| 2026-09-25 | 공유기 80·443 포트포워딩 삭제. 내부 서비스는 Tailscale로만 |
| 2026-09-26 | 공개 DNS의 집 IP 레코드 전부 삭제 |
| 2026-09-27 | DNS를 Route 53으로 이전, 와일드카드 인증서를 DNS 인증으로 다시 발급 |
포트를 닫은 뒤 바뀐 것은 집 밖에서 Tailscale을 켜야 한다는 것 하나다. 대신 인터넷에 열린 관리 화면이 없어졌다.
다음에 정리할 것
앞으로 서비스를 네 칸으로 나눠 관리한다.
| 구분 | 들어오는 길 | 예 |
|---|---|---|
| 외부 공개 | 인터넷 | 블로그 (AWS) |
| Tailscale 전용 | Tailscale 기기 | Gitea, 사진, 웹 UI |
| 내부망 전용 | 집 안 유선·와이파이 | 공유기, 프린터 |
| 관리자 전용 | 관리 PC만 | Proxmox, NAS 관리 화면 |
지금은 외부 공개 하나와 나머지 전부로만 나뉘어 있다. 다음 홈랩 글에서 관문 LXC 안의 Tailscale·AdGuard Home·Nginx Proxy Manager를 어떻게 엮었는지 설정 단위로 적는다.