우리 집 홈네트워크는 어떻게 동작할까? — OPNsense, VLAN, Tailscale 그리고 NPM+

2026. 11. 2. 10:30·기타/일상
728x90
반응형

지난 글에서는 홈서버를 정리하다가 집 네트워크까지 바꿔버린 이야기를 남겼다. WTR MAX와 M8에 역할을 나누고, OPNsense와 Omada로 집 안의 연결도 새롭게 구성했다.

그런데 장비를 소개하고 나니 한 가지 이야기가 빠진 것 같았다. 그래서 이 장비들이 실제로 어떻게 같이 움직이는 걸까? ㅎㅎ

이번에는 장비 사양 대신 집에서 인터넷을 사용할 때, 도메인으로 서버에 접속할 때, 집 밖에서 관리 페이지를 열 때 어떤 과정을 거치는지 기록해보려고 한다. 중간에 Tailscale 때문에 꽤 오래 삽질했던 이야기도 함께 남겨본다. ㅋㅋㅋ

이전 글: 나의 홈서버 그 이후, 이제는 집 네트워크까지 바꿔버렸다

본문의 서비스 주소는 설명용 예시인 example.com으로 바꿨다. 구성도에는 실제 서버 주소를 넣지 않았고, 기존 설정 화면은 정보를 가려둔 상태 그대로 사용했다.

1. 인터넷을 쓰면 어디를 지나갈까?

현재 집 네트워크의 중심은 M8의 Proxmox 위에서 실행하는 OPNsense다. 인터넷으로 나가는 길, 네트워크 사이를 오가는 길, 그리고 그 길을 통과시킬지 결정하는 방화벽을 이쪽에서 관리한다.

OPNsense와 Omada, 다섯 네트워크 및 Tailscale 원격 접속의 논리 구성도
현재 구성의 논리적인 연결 흐름. 실제 케이블 연결이나 스위치 포트 배치는 생략했다.

예를 들어 스마트폰이 Private Wi-Fi에 연결되면, AP와 스위치를 거쳐 해당 네트워크의 게이트웨이인 OPNsense로 통신이 전달된다. 인터넷으로 향하는 요청은 방화벽 정책과 NAT 처리를 거쳐 WAN으로 나간다.

같은 네트워크 안의 기기끼리 주고받는 통신까지 전부 OPNsense를 통과하는 것은 아니다. 다른 네트워크나 인터넷으로 넘어가는 길목을 맡는다고 생각하면 이해하기 편했다.

여기서 Omada Controller는 스위치와 AP의 설정·상태를 관리한다. 실제 데이터가 매번 컨트롤러를 경유하는 구조는 아니고, 유선·무선 연결 자체는 스위치와 AP가 처리한다.

구성 요소 우리 집에서 맡은 일
OPNsense 인터넷 연결, 네트워크 간 라우팅, 방화벽, DHCP
Omada 스위치·AP 유선 포트와 Wi-Fi를 각 네트워크에 연결
Omada Controller 스위치·AP 설정과 연결 상태 관리
Unbound DNS 내부 서비스 이름을 NPM+ 내부 주소로 안내
NPM+ HTTPS 요청을 해당 웹서비스로 전달하고 접근 정책 적용
Tailscale 허용된 외부 기기에서 집 안으로 들어오는 암호화된 경로

처음에는 이름도 많고 비슷해 보였는데, 연결해주는 역할과 허용 여부를 결정하는 역할을 나눠 생각하니 조금씩 정리가 됐다.

2. 같은 집 안에서도 네트워크를 나눈 이유

예전에는 집 안에 있는 기기라면 그냥 같은 공유기에 연결하면 된다고 생각했다. 그런데 서버와 IoT 기기가 늘어나니, 스마트홈 기기와 서버 관리 화면이 굳이 같은 공간에 있을 필요가 있을까 싶었다.

그래서 기본 LAN을 포함해 다섯 용도로 네트워크를 구분하고, VLAN을 이용해 유선 포트와 무선 SSID를 용도에 맞게 연결했다.

네트워크 주로 연결한 기기 운영 방향
LAN 기본 연결·관리용 장비 기반 네트워크와 관리 용도
Private 개인 PC, 스마트폰 등 필요한 내부 서비스에 접근
IoT 스마트홈·IoT 기기 내부망 접근을 제한하고 필요한 통신만 예외 허용
Guest 방문객 기기 인터넷 사용 중심, 내부망 접근 제한
Server NAS, Plex, Docker, NPM+ 등 서비스를 모아두고 네트워크 간 통신을 규칙으로 관리

중요한 건 VLAN을 만들기만 한다고 접근 제한까지 자동으로 완성되지는 않는다는 점이다. IoT에서 서버로 갈 수 있는지, 개인 PC에서 NAS에 접근할 수 있는지는 OPNsense의 방화벽 규칙으로 따로 정해야 했다.

민감정보를 가린 OPNsense 대시보드의 네트워크 인터페이스 현황
지난 구축기에 사용한 OPNsense 화면. 2026년 10월 당시 화면이며 가려둔 원본을 그대로 사용했다.

나누고 나니 장비가 하나 추가되어도 어느 쪽에 연결해야 할지 기준이 생겼다. 대신 규칙을 잘못 건드리면 내가 접속하지 못하는 일도 생긴다. 이 부분은 확실히 직접 해보면서 배우게 된다. ㅋㅋ

주소를 가린 Omada Controller의 스위치와 AP 상태 대시보드
Omada에서는 유선·무선 장비와 연결 상태를 확인한다. 이 화면도 2026년 10월에 사용한 원본 그대로다.

3. 도메인을 입력하면 NAS와 Docker 서비스가 열리는 과정

서비스가 늘어날수록 IP와 포트를 외워서 접속하는 게 번거로워졌다. 그래서 내부에서도 서비스별 도메인으로 접속하도록 Unbound DNS와 NPM+를 함께 사용하고 있다.

예를 들어 브라우저에서 dockge.example.com을 입력한다고 해보자. 먼저 Unbound DNS가 그 이름에 해당하는 NPM+의 내부 주소를 알려준다. 브라우저는 그 응답을 받은 뒤 NPM+로 별도의 HTTPS 연결을 만든다.

① 이름 조회
내 기기 → Unbound DNS
        ← NPM+ 내부 주소 응답

② 웹 접속
내 기기 → NPM+ → 요청한 웹서비스
          HTTPS · 도메인별 전달 · 접근 정책

내부에서는 서비스 도메인의 하위 주소들이 NPM+를 가리키도록 DNS를 재정의해두었다. NPM+에서는 요청한 도메인에 따라 Plex, NAS, Dockge 등 알맞은 서비스로 요청을 전달한다.

여기서 DNS는 주소를 알려주는 역할이다. 웹 요청 자체가 DNS 서버를 통과해 서비스로 전달되는 건 아니다. 그리고 도메인이 내부 주소로 풀린다고 해서 접근까지 허용되는 것도 아니다. 실제 연결은 방화벽과 NPM+ 정책을 통과해야 한다.

이렇게 해두니 서비스를 추가할 때도 접속 주소와 전달 대상을 정리하기가 편해졌다. 예전에는 포트 번호부터 찾아봤는데, 이제는 도메인을 먼저 떠올리게 된다. ㅎㅎ

4. 집 밖에서 들어올 때는 Tailscale

집 안에서는 내부망으로 연결하면 되지만, 밖에서 관리자 페이지를 열고 싶을 때는 다른 경로가 필요하다. 관리 서비스마다 인터넷에 포트를 하나씩 열어두고 싶지는 않아서 Tailscale을 사용했다.

현재는 OPNsense를 Tailscale의 Subnet Router로 운영한다. 외부의 내 기기가 집 안 서브넷으로 가는 경로를 이용하도록 하는 방식이라, 접속 대상 서버마다 Tailscale을 설치할 필요를 줄일 수 있었다.

물론 경로를 광고했다고 곧바로 모든 접근이 허용되는 건 아니다. Tailscale 쪽의 경로 승인과 접근 정책, OPNsense 방화벽, 서비스 앞단의 접근 제한이 함께 맞아야 한다. 내 구성에서는 신뢰하는 기기를 Alias로 묶고 필요한 목적지와 포트만 허용하도록 정리했다.

외부의 허용 기기
  → Tailscale 암호화 경로
  → OPNsense의 Tailscale 인터페이스·방화벽
  → NPM+의 HTTPS·접근 정책
  → Dockge 같은 관리 서비스

여기까지 보면 생각보다 간단해 보인다. 그런데 실제로는 접속은 되는 것 같은데 관리 페이지에서 403이 나오는 문제가 있었다. 이때부터 IP가 어디서 어떻게 보이는지 확인하기 시작했다. ㅋㅋㅋ

5. 연결은 됐는데 403? SNAT에서 한 번 막혔다

처음에는 NPM+에서 내 기기의 Tailscale 주소를 허용하면 될 거라고 생각했다. 그런데 NPM+ 쪽에서 확인되는 출발지 주소가 예상과 달랐다. 내 기기 주소가 아니라 서브넷 라우터 쪽 주소로 보였다.

원인은 SNAT, 즉 출발지 주소 변환이었다. 중간에서 출발지 주소가 바뀌니, NPM+에서 허용한 주소와 실제 요청에 찍히는 주소가 맞지 않았다. Tailscale에 연결되어 있다는 사실만 보고 접근 정책도 통과할 거라고 생각했던 셈이다.

내 구성에서는 Tailscale의 서브넷 경로에 대한 SNAT을 비활성화해 원래 기기의 주소가 유지되도록 바꿨다. 그런데 그것만으로 끝나지 않았다. 이번에는 OPNsense 방화벽에서 통신이 막혔다. 하나 고치면 또 하나 나오는 느낌이었다. ㅋㅋㅋㅋ

결국 Tailscale 인터페이스를 OPNsense에 할당하고, 허용 기기를 묶은 Alias를 기준으로 NPM+의 HTTPS 접속을 허용했다. NPM+의 관리 서비스용 접근 정책도 그 출발지 주소와 맞췄다.

겪었던 증상 확인한 지점 내 구성에서 정리한 내용
VPN 연결 후에도 관리 페이지에서 403 NPM+가 보는 출발지 IP와 접근 정책 SNAT으로 주소가 바뀌는지 확인하고 원본 주소 기준으로 정책 정리
SNAT 변경 뒤 연결이 막힘 OPNsense Tailscale 인터페이스·방화벽 허용 기기 Alias에서 필요한 목적지·포트로 가는 규칙 추가
도메인 조회 실패 Unbound까지의 경로와 DNS 허용 허용 기기의 TCP/UDP 53 접근과 DNS 수신·접근 설정 확인
설정 변경 후에도 이전 주소로 접속 DNS 응답과 브라우저 캐시 응답이 내부 주소인지 확인한 뒤 기존 캐시 정리

SNAT을 끄면 응답이 원래 기기로 돌아가는 경로도 맞아야 한다. 내 환경처럼 OPNsense가 게이트웨이와 Subnet Router를 함께 맡는 경우와, 별도 장비에 Subnet Router를 설치하는 경우는 조건이 다르다. 다른 환경에서는 반환 경로를 따로 설정해야 할 수 있으니, 이 글의 구성을 그대로 복사하기보다는 양방향 경로를 함께 확인하는 게 좋겠다.

이 과정을 겪고 나니 “VPN이 연결됐는가”와 “이 요청이 어느 주소에서 온 것으로 보이는가”는 따로 봐야 한다는 걸 알게 됐다.

6. 집 밖에서도 같은 주소를 쓰기 위한 Split DNS

접속 경로를 맞춘 뒤에는 DNS가 남았다. 집 안에서는 내부 주소가 나오는데, 밖에서는 공개 DNS의 주소가 나와서 의도한 내부 경로로 연결되지 않는 경우가 있었다.

그래서 Tailscale의 Split DNS를 사용했다. 예를 들어 example.com에 대한 질의는 집 안의 Unbound DNS로 보내고, 그 응답으로 NPM+ 내부 주소를 받도록 하는 방식이다.

외부에서 Dockge에 접속하는 상황을 순서대로 정리하면 이렇다.

  1. 기기에서 Tailscale을 연결하고, 해당 DNS 설정을 사용한다.
  2. dockge.example.com의 DNS 질의를 Tailscale 경로로 Unbound에 보낸다.
  3. Unbound가 NPM+의 내부 주소를 돌려준다.
  4. 브라우저가 그 주소로 새 HTTPS 연결을 만든다.
  5. OPNsense와 NPM+의 접근 정책을 통과한 뒤 Dockge가 열린다.

처음에는 HTTPS 쪽을 맞추느라 DNS도 방화벽을 통과해야 한다는 점을 놓쳤다. Unbound로 가는 DNS 통신이 막혀 있으면 서비스 주소부터 찾지 못한다. 허용 기기에서 DNS 서버로 가는 TCP/UDP 53 접근을 확인하고, Unbound의 수신·접근 설정도 함께 봐야 했다.

그 뒤에는 DNS 응답이 정상인데도 브라우저가 예전 주소로 접속하는 일이 남았다. 캐시까지 정리하고 나서야 원하는 흐름으로 연결됐다. 설정 하나보다, 어느 단계가 막혔는지 좁혀가는 데 시간이 더 걸렸던 것 같다. ㅋㅋ

Split DNS도 기기에서 Tailscale의 DNS 설정을 사용해야 적용된다. VPN 연결만 켰다고 모든 기기의 이름 조회 방식까지 같아지는 건 아니라는 점도 함께 기억해두려고 한다.

7. 공개 서비스와 관리 서비스는 다르게

현재는 Plex처럼 외부에서 이용하는 서비스와 Dockge 같은 관리 서비스를 구분해서 운영한다. 공개 서비스는 공개 DNS와 WAN 포트포워딩을 거쳐 NPM+로 연결하고, 관리 서비스는 Tailscale로 들어온 허용 기기만 접근하도록 정책을 적용했다.

다만 NPM+가 공개 HTTPS 진입점을 함께 사용하는 만큼, 관리 서비스가 네트워크상에서 완전히 숨겨진 별도 VPN 전용 리스너인 것은 아니다. 공유된 프록시 앞단에서 서비스별 접근 정책으로 제한하는 구성이라고 설명하는 편이 정확하다.

도메인을 아는 것, VPN에 연결된 것, 서비스에 접근할 수 있는 것, 로그인에 성공하는 것은 각각 다른 단계다. 그래서 NPM+의 접근 제한과 각 서비스의 자체 로그인도 함께 유지하고 있다.

8. 결국은 누가 어떤 길로 들어오는지 정하는 일

이번에 가장 많이 배운 건 서버를 하나 더 설치하는 방법보다, 그 서버에 누가 어떤 경로로 접근할지 정하는 일이었다.

VLAN은 연결할 공간을 나누고, OPNsense는 그 사이의 길을 관리한다. Unbound는 서비스 주소를 알려주고, NPM+는 웹 요청을 실제 서비스에 전달한다. Tailscale은 밖에서 들어오는 경로를 만들어준다. 각각 따로 보면 이해가 됐는데, 한꺼번에 연결하니 중간중간 예상하지 못한 일이 생겼다.

특히 SNAT, 방화벽, DNS 캐시까지 차례로 확인했던 경험은 오래 기억에 남을 것 같다. 처음에는 왜 안 되는지만 보였는데, 이제는 DNS 응답부터 보고 그다음 경로와 방화벽, 프록시 정책을 확인하게 됐다.

한 번 기준을 잡아두니 새 서비스를 올릴 때도 어디에 배치하고 누구에게 열어줄지 생각하기가 편해졌다. 물론 OPNsense가 올라간 M8을 재부팅하면 집 인터넷도 영향을 받는다. 장비 두 대를 운영한다고 자동으로 이중화되는 건 아니라서, 이제는 업데이트 시간도 조금 더 신경 쓰고 있다. ㅎㅎ

분명 처음에는 NAS 하나 잘 써보자는 생각이었는데, 어느새 집 방화벽과 DNS까지 직접 관리하고 있다. 다음에는 또 뭘 바꾸고 있을지 모르겠다. ㅋㅋㅋㅋ

일단 지금 우리 집 네트워크가 돌아가는 방식은 여기까지다.


함께 참고한 문서
Tailscale 공식 문서 — Subnet routers
Tailscale 공식 문서 — DNS 설정

728x90
반응형

'기타 > 일상' 카테고리의 다른 글

나의 홈서버 그 이후, 이제는 집 네트워크까지 바꿔버렸다  (0) 2026.10.21
파워목업(PowerMockup)으로 화면 설계 & 리뷰 무료 라이센스 혜택  (0) 2025.02.13
나의 홈서버 구축 후 현재까지  (1) 2024.09.26
'기타/일상' 카테고리의 다른 글
  • 나의 홈서버 그 이후, 이제는 집 네트워크까지 바꿔버렸다
  • 파워목업(PowerMockup)으로 화면 설계 & 리뷰 무료 라이센스 혜택
  • 나의 홈서버 구축 후 현재까지
키큰난쟁이
키큰난쟁이
개발 블로그
    반응형
    250x250
  • 키큰난쟁이
    키큰난쟁이의 놀이터
    키큰난쟁이
  • 전체
    오늘
    어제
    • 분류 전체보기 (40) N
      • AI (1)
        • AI 응용 (1)
      • 프로그래밍 언어 (5)
        • Java (3)
        • PHP (1)
        • JavaScript (1)
      • 프레임워크 (3)
        • Spring (3)
      • 서버 (8)
        • Web Server (2)
        • WAS (2)
        • Hypervisor (4)
      • 데이터베이스 (5)
        • MySQL•MariaDB (2)
        • Oracle (1)
        • Cubrid (2)
      • 운영체제 (4)
        • Linux (4)
      • 클라우드 (1)
        • Ncloud (1)
      • 데브옵스 (7)
        • VCS (2)
        • CICD (3)
        • Docker (2)
      • 지식 (2)
        • Web (2)
      • 기타 (4) N
        • 일상 (4) N
  • 블로그 메뉴

    • 일상
  • 링크

    • Instagram
    • github
  • 공지사항

    • 라이믹스 → 티스토리 이사
  • 인기 글

  • 태그

    Apple Silicon
    PROXMOX
    devops
    마리아디비
    opnsense
    애플실리콘
    GitHub
    java
    Omada
    홈서버
    db
    프록시모스
    docker
    CI/CD
    자바
    jenkins
    우분투
    DBMS
    리눅스
    도커
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
키큰난쟁이
우리 집 홈네트워크는 어떻게 동작할까? — OPNsense, VLAN, Tailscale 그리고 NPM+
상단으로

티스토리툴바