NetBird VPN 서버 직접 호스팅 및 구축 방법
VPS에서 NetBird 제어 평면을 직접 운영하는 방법을 설명합니다. DNS와 TLS 설정, setup keys를 활용한 자동 피어 연결, Headscale과의 차이점 및 v0.76.2 버전 기준의 최신 퀵스타트 스크립트 사용법을 상세히 안내합니다.
NetBird VPN 서버를 직접 호스팅할 때의 이점
NetBird VPN 서버를 직접 호스팅하면 제어 평면(control plane)을 사용자가 소유한 VPS에 둘 수 있습니다. 제어 평면은 피어 목록을 유지하고, 어떤 장치가 어디에 연결될 수 있는지 결정하며, NAT(network address translation) 환경 뒤에 있는 두 피어가 서로를 찾을 수 있도록 돕는 역할을 합니다. 터널 자체는 여전히 WireGuard를 사용하며 장치 간에 직접 암호화됩니다. 달라지는 점은 외부 기업이 사용자의 장치 목록이나 로그인 흐름을 보관하지 않는다는 것입니다. 이것이 어떤 이점을 주는지 명확히 이해해야 합니다. 호스팅된 제어 평면 역시 트래픽을 암호화하는 키를 보관하지 않으며, 조정 서버가 침해되었을 때 실제로 수행할 수 있는 작업은 대부분의 사람이 생각하는 것보다 훨씬 제한적이기 때문입니다.
NetBird는 이미 알고 있을 법한 두 가지 개념 사이에 위치합니다. NetBird는 메시 오버레이(mesh overlay)이므로 모든 트래픽을 하나의 게이트웨이로 보내는 대신 피어들이 서로 직접 연결됩니다. 또한 종단 간 직접 호스팅이 가능하며, 이는 Tailscale의 자체 호스팅 제어 서버인 Headscale과 비교됩니다. 단일 게이트웨이 터널만 운영해 보았다면, 먼저 일반 WireGuard와 메시 오버레이의 차이를 읽어보시기 바랍니다. 해당 개념을 이해해야 이 페이지의 나머지 내용을 유용하게 활용할 수 있습니다.
모든 트래픽이 나가는 단일 서버가 필요한 경우라면, 메시 구성은 작업에 비해 지나치게 복잡합니다. 단일 VPS에서의 일반 WireGuard VPN이나 Tailscale exit node를 사용하는 것이 훨씬 적은 운영 부담으로 동일한 목적을 달성할 수 있습니다. 또한 장치 간 연결이 아니라 특정 사설 네트워크에 접근하는 것이 목적이라면, VPS의 Tailscale subnet router를 통해 아래의 복잡한 스택 없이도 기존 tailnet에 해당 대역을 광고할 수 있습니다.
실제 실행되는 스택 구성
최근 레이아웃이 변경되어, 대부분의 구형 문서는 이전 방식을 설명하고 있습니다. 2026년 10월 기준으로 v0.80.0 및 이 가이드가 고정 버전으로 사용하는 v0.76.2를 확인한 결과, 퀵스타트 스크립트는 기본적으로 3개의 서비스가 포함된 Compose 파일을 작성합니다.
netbird-server는 관리 API, 신호 서비스, STUN 리스너가 내장된 릴레이, 그리고 내장 ID 공급자를 포함합니다. 이전 릴리스에서는 이들이 별도의 컨테이너였으며, ID 공급자는 먼저 빌드해야 하는 별도의 Zitadel 설치본이었습니다.dashboard은 관리자 웹 콘솔입니다.traefik은 TLS(transport layer security)를 종료하고 첫 시작 시 Let's Encrypt에 인증서를 요청합니다.
프롬프트에서 승인하지 않는 한 꺼져 있는 서비스가 2개 더 있습니다. NetBird Proxy 서비스는 내부 서비스를 공용 호스트 이름으로 게시합니다. CrowdSec은 악성 트래픽을 필터링합니다. 둘 다 작동하는 메시를 구축하는 데는 필요하지 않으며, 소형 서버에서는 메모리를 소모합니다.
단일 Docker 컨테이너의 wg-easy에서 전환하는 경우, 구성 요소 수가 증가한 것처럼 보일 수 있습니다. 하지만 이를 통해 접근 정책, 사용자별 계정, 그리고 하나의 게이트웨이를 거치지 않고 피어끼리 직접 연결되는 기능을 얻게 됩니다.
시작하기 전에 필요한 준비 사항
공용 도메인 이름은 필수입니다. 대시보드, API, 릴레이는 모두 443 포트에서 HTTPS를 사용하며, Traefik은 TLS-ALPN-01 챌린지를 통해 Let's Encrypt에서 인증서를 발급받습니다. 이 챌린지는 443 포트에서 응답해야 하므로, 공용 인터넷에서 해당 VPS로 연결되는 도메인 이름이 필요합니다. 단순히 IP 주소만으로는 이 과정을 수행할 수 없습니다.
VPS의 공용 IPv4 주소를 가리키는 A 레코드를 하나 생성하고, netbird.example.com 명령을 실행하여 도메인 설정이 반영될 때까지 기다린 후 다음 단계를 진행하십시오.
dig +short netbird.example.com위 명령은 서버의 주소를 출력해야 합니다. DNS 전파가 완료되기 전에 설치 프로그램을 실행하면 첫 시작 시 인증서 요청이 실패합니다. 검증 실패가 반복되면 Let's Encrypt의 속도 제한(rate limit)에 걸리게 되며, 제한이 풀릴 때까지 다시 시도할 수 없게 됩니다.
인터넷에서 다음 세 가지 포트에 접근할 수 있어야 합니다. HTTPS 리다이렉트를 위한 TCP 80, 대시보드·API·신호·릴레이 트래픽 및 인증서 챌린지를 위한 TCP 443, 그리고 STUN을 위한 UDP 3478입니다.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw status제공업체의 네트워크 방화벽에서도 해당 포트를 개방하십시오. 대부분의 VPS 관리 패널에는 별도의 방화벽 설정이 존재하며, 서버 내부의 ufw status 설정이 올바르더라도 연결이 거부되는 주된 이유가 바로 이 때문입니다.
STUN(Session Traversal Utilities for NAT)은 피어가 자신의 NAT에 할당된 공용 주소와 포트를 확인하여 피어 간 직접 터널링을 시도할 수 있게 합니다. UDP 3478 포트를 차단해도 피어는 TCP 443의 릴레이를 통해 연결되므로 겉으로는 문제가 없어 보입니다. 하지만 실제로는 모든 피어에서 Connection type: Relayed 상태가 나타나며, 모든 트래픽이 피어 간 직접 통신이 아닌 VPS를 거쳐 전달됩니다.
소프트웨어 측면에서는 Docker와 Compose v2 플러그인, 그리고 jq 및 curl이 필요합니다. 설치 스크립트는 Docker, Compose, jq의 설치 여부를 확인하며, 하나라도 누락되면 중단됩니다. curl은 별도의 확인 과정 없이 사용하므로 미리 설치해야 합니다. 이 서버에 Docker를 처음 설치한다면 먼저 VPS에서 Docker Compose 설정하기를 참고하십시오.
번들로 제공되는 리버스 프록시를 사용하지 않는 경우의 포트 설정
Traefik을 사용하지 않더라도 통합 서버는 관리, 신호, 릴레이를 하나의 HTTP 백엔드에서 처리하므로 포트 목록은 크게 늘어나지 않습니다. 생성된 Compose 파일은 다음 포트를 노출합니다.
- TCP 8080: 대시보드 (127.0.0.1에 바인딩)
- TCP 8081:
netbird-server(127.0.0.1에 바인딩) - UDP 3478: STUN (직접 노출)
사용자가 직접 구성한 프록시에서 TCP 443의 TLS를 종료하고 위 두 로컬 포트로 전달해야 합니다. STUN은 프록시를 통과하지 않으므로, 어떤 방식을 사용하든 UDP 3478 포트는 방화벽에서 열려 있어야 합니다. 관리용 gRPC, 신호용 gRPC, 릴레이용 포트를 각각 나열하는 가이드는 구형 다중 컨테이너 구성을 설명하는 것입니다.
이 방식은 서버에서 이미 다른 서비스의 TLS를 종료하고 있는 경우에만 선택하십시오. 그렇지 않다면 번들로 제공되는 Traefik을 사용하는 것이 설정 규칙도 적고 오류 발생 가능성도 낮습니다.
퀵스타트 스크립트로 NetBird 서버 설치하기
문서화된 한 줄짜리 명령어는 최신 릴리스를 셸로 바로 파이프합니다.
curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash대신 버전을 고정하십시오. latest은 계속 변하므로, 2주 간격으로 같은 명령어를 실행하면 서로 다른 버전이 설치됩니다. 또한 디스크 어디에도 어떤 버전이 설정을 작성했는지 기록되지 않습니다. 태그가 지정된 릴리스를 다운로드하여 내용을 확인한 뒤 실행하십시오.
mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.sh스크립트는 먼저 도메인을 묻습니다.
Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):그다음 TLS 처리 방식을 묻습니다.
Which reverse proxy will you use?
[0] Traefik (recommended - automatic TLS, included in Docker Compose)
[1] Existing Traefik (labels for external Traefik instance)
[2] Nginx (generates config template)
[3] Nginx Proxy Manager (generates config + instructions)
[4] External Caddy (generates Caddyfile snippet)
[5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):[0]을 선택하십시오. 2번부터 4번 옵션은 설정 조각만 작성하고 연결은 사용자에게 맡기며, 5번 옵션은 Compose 파일만 작성하고 설정 문서를 터미널에 출력합니다. 이는 이미 프록시가 실행 중인 서버에는 적합하지만, 새로 설치하는 서버에는 부적절합니다. 0번 옵션은 이메일 주소를 묻는데, Traefik은 이를 Let's Encrypt 계정에 등록합니다. 프롬프트에서는 여전히 인증서 알림용 주소라고 안내하지만, Let's Encrypt는 2025년 6월 4일부터 만료 안내 이메일 발송을 중단했습니다. 따라서 갱신 문제는 받은 편지함이 아닌 Traefik 로그에서 확인해야 합니다.
최초 설치 시에는 NetBird Proxy 서비스를 사용하지 않도록 설정하십시오. 이 서비스는 netbird.example.com을 가리키는 와일드카드 *.netbird.example.com CNAME 레코드가 하나 더 필요하며, 단순 메쉬 구성에는 아무런 역할을 하지 않습니다. CrowdSec 프롬프트는 프록시를 활성화해야만 나타나므로, 프록시를 거부하면 이 설정도 건너뛰게 됩니다. 두 기능 모두 나중에 추가할 수 있습니다.
스크립트는 현재 디렉터리에 파일을 작성합니다: docker-compose.yml, 모드 600으로 설정된 config.yaml, 그리고 dashboard.env입니다. 번들로 제공되는 Traefik을 사용하면 NetBird Proxy를 활성화할 때만 traefik-dynamic.yaml과 proxy.env이 추가됩니다. 해당 디렉터리는 상태를 유지해야 하는 중요 데이터로 취급하십시오. config.yaml에는 저장소의 데이터를 암호화하는 키가 들어 있기 때문입니다. 이 키를 분실하면 재설치로도 복구할 수 없습니다.
docker compose ps
docker compose logs -f netbird-server모든 서비스는 running을 읽어야 하며, 서버 로그는 루프를 돌며 재시작되지 않고 안정화되어야 합니다. 인증서는 별도로 모니터링하십시오.
docker compose logs traefik | grep -i acmeACME(automatic certificate management environment)는 Traefik이 인증서를 발급받기 위해 사용하는 프로토콜입니다. 여기서 발생하는 오류는 대부분 DNS 문제이거나 443 포트가 닫혀 있기 때문입니다.
첫 번째 관리자 계정 생성
https://netbird.example.com을 엽니다. 새로 설치한 경우 로그인 폼 대신 설정 페이지가 나타납니다. 이메일 주소, 이름, 비밀번호를 입력한 뒤 Create Account를 클릭합니다. 해당 계정이 첫 번째 관리자가 되며, 페이지는 로그인 폼으로 리다이렉트됩니다.
이 계정은 netbird-server 컨테이너에 내장된 ID 공급자가 관리하는 NetBird 자체 사용자 저장소에 저장됩니다. 외부 서비스는 관여하지 않습니다. 이는 1년 전의 셀프 호스팅 NetBird와 비교했을 때 가장 큰 변화입니다. 당시에는 설치를 위해 먼저 Zitadel이나 Keycloak을 구축하고, 4개의 OIDC(OpenID Connect) 값을 setup.env에 복사해 넣어야만 서비스가 시작되었습니다.
설정 페이지 대신 브라우저 인증서 경고가 표시된다면 인증서가 발급되지 않은 것입니다. 대시보드는 동일한 호스트네임을 통해 API와 통신하므로, 잘못된 인증서가 있으면 혼란스러운 방식으로 오류가 발생합니다. 따라서 다음 단계로 넘어가기 전에 이 문제를 먼저 해결하십시오.
첫 번째 피어 연결하기
메시 네트워크에 포함하고 싶은 VPS를 포함하여, Linux 머신이라면 어디든 클라이언트를 설치합니다.
curl -fsSL https://pkgs.netbird.io/install.sh | shDebian 및 Ubuntu 환경에서 해당 스크립트는 NetBird 패키지 저장소를 구성한 뒤 apt를 통해 클라이언트를 설치하므로, 결과적으로 패키지 관리자가 설치를 관리하게 됩니다. 스크립트를 셸로 바로 파이핑하는 것이 꺼려진다면, 먼저 curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh으로 저장한 뒤 내용을 확인하고 sh install.sh로 실행하십시오. 어떤 방식을 선택하든 설치 결과를 확인합니다.
apt-cache policy netbirdnetbird은 명령줄 클라이언트이자 데몬입니다. netbird-ui는 데스크톱 트레이 앱이므로, 헤드리스 서버에서는 사용할 필요가 없습니다.
이제 클라이언트가 서버를 가리키도록 설정합니다.
sudo netbird up --management-url https://netbird.example.com--management-url을 생략하면 클라이언트는 컴파일된 기본값에 따라 NetBird 호스팅 서비스에 등록됩니다. 이 경우에도 명령어는 성공하고 머신은 주소를 할당받지만, 직접 호스팅하는 대시보드에는 아무것도 나타나지 않습니다. 거의 모든 사용자가 한 번씩 겪는 실수입니다.
명령어를 실행하면 브라우저에서 열어 로그인을 완료할 수 있는 URL이 출력됩니다. 완료 후 다음을 확인합니다.
netbird status
ip addr show wt0netbird status에서 네 줄을 확인합니다. Management: Connected, Signal: Connected, 사용 가능한 모든 릴레이를 보고하는 Relays: 라인, 그리고 오버레이 범위 내의 NetBird IP:가 출력되어야 합니다. wt0은 NetBird가 생성하는 WireGuard 인터페이스이며, 동일한 주소를 가지고 있어야 합니다.
설정 키를 사용하여 두 번째 머신을 무인으로 연결하기
브라우저가 없거나 사용자가 직접 조작할 수 없는 머신에서는 브라우저 로그인을 사용할 수 없습니다. 설정 키(setup key)는 대화형 단계 없이 머신을 등록할 수 있는 사전 인증 토큰입니다. 대시보드의 Setup Keys 메뉴에서 키를 생성하십시오.
키에는 두 가지 종류가 있습니다. 일회용 키(one-off key)는 정확히 하나의 머신을 인증한 뒤 소멸합니다. 재사용 가능 키(reusable key)는 여러 머신을 등록할 수 있으며, 등록 가능한 최대 개수를 선택적으로 제한할 수 있습니다. 두 유형 모두 만료 시간을 설정할 수 있으며, 새로운 피어를 특정 그룹에 자동으로 할당하여 머신이 등록되는 즉시 해당 그룹의 접근 규칙이 적용되도록 할 수 있습니다.
sudo netbird up --setup-key <SETUP-KEY> \
--management-url https://netbird.example.com \
--hostname build-runner-01--hostname은 대시보드에 표시될 이름을 설정합니다. 이 옵션을 사용하지 않으면 머신이 스스로를 부르는 이름을 그대로 사용하게 되며, 모든 항목이 ubuntu로 표시되는 수많은 머신 목록은 관리에 도움이 되지 않습니다.
컨테이너나 단기 빌드 에이전트의 경우, 키를 생성할 때 ephemeral(일회성)로 표시하십시오. ephemeral 키로 등록된 피어는 오프라인 상태가 10분 이상 지속되면 자동으로 제거되므로, 피어 목록에 죽은 항목이 쌓이지 않게 관리할 수 있습니다.
설정 키를 활용하기 전에 이해해야 할 한 가지 제한 사항이 있습니다. 키를 만료시키거나 취소하면 새로운 등록은 차단되지만, 이미 해당 키로 등록된 머신들의 연결이 끊기지는 않습니다. 머신의 접근 권한을 제거하려면 해당 피어 자체를 삭제해야 합니다.
별도의 ID 공급자가 여전히 필요한가요?
소규모 설치 환경이라면 필요하지 않습니다. 내장된 사용자 저장소가 대시보드에서 생성된 계정을 처리하며, 소수의 인원에게는 이것으로 충분합니다.
이미 ID 공급자를 사용 중이고 사용자 목록을 이중으로 관리하고 싶지 않다면 외부 ID 공급자가 필요합니다. NetBird는 OIDC를 지원하는 모든 공급자를 수용합니다. 공급자에 confidential OIDC 클라이언트를 등록한 다음, NetBird 대시보드에 이름, client ID, client secret, issuer 등 4가지 값을 추가하십시오. NetBird가 제공하는 리다이렉트 URL을 공급자 설정에 붙여넣으면 됩니다. Google, Microsoft Entra ID, Okta, Zitadel, Keycloak, Authentik, Pocket ID에 대해서는 전용 통합 설정이 존재하며, 그 외의 서비스는 일반 OIDC로 추가할 수 있습니다. 이미 자체 호스팅 싱글 사인온으로 Authentik을 운영 중이라면, 이 방식을 통해 계정 목록을 하나로 통합하여 관리할 수 있습니다.
공급자를 추가한 후에도 로컬 로그인은 계속 사용할 수 있으며, 설정된 모든 공급자가 로그인 페이지에 표시됩니다. 강력한 암호를 설정한 로컬 관리자 계정을 하나 유지하십시오. OIDC 설정에 문제가 생기더라도 시스템에 접근할 수 있는 경로가 확보됩니다.
NetBird와 Headscale: 어떤 컨트롤 플레인을 운영해야 하는가?
두 프로젝트 모두 클라이언트가 외부로 통신해야 하는 호스팅된 컨트롤 서버에 대한 의존성을 제거한다는 점은 같습니다. 하지만 두 프로젝트의 성격은 다릅니다.
Headscale은 Tailscale 컨트롤 서버를 재구현한 것이며, 사용자는 공식 Tailscale 클라이언트를 그대로 사용합니다. 공식 웹 콘솔은 제공되지 않습니다. 사용자와 사전 인증 키는 설정 파일을 대상으로 하는 headscale 명령어를 통해 관리합니다. 커뮤니티에서 만든 웹 인터페이스가 존재하지만, 이는 프로젝트의 일부가 아닙니다. 상태를 파일로 관리하고 변경 사항을 버전 관리 시스템에 기록하려는 사용자에게 적합합니다.
NetBird는 자체 클라이언트, 자체 대시보드, 내장된 ID 공급자, 브라우저에서 편집 가능한 접근 정책 등 제품 전체를 제공합니다. VPS에서 관리해야 할 요소가 더 많지만, 터미널을 사용하지 않는 동료에게 업무를 위임하기에는 훨씬 수월합니다.
이미 Tailscale 클라이언트를 사용 중이거나 가장 가벼운 컨트롤 플레인을 원한다면 Headscale을 선택하십시오. 여러 사람이 피어를 관리해야 하고, 별도의 구성 없이 콘솔과 SSO를 사용하고 싶다면 NetBird를 선택하십시오. 어느 쪽을 선택하기 전에 Tailscale 무료 플랜의 실제 적용 범위를 확인하십시오. 6명 이하의 비영리 그룹이라면 호스팅된 컨트롤 플레인을 무료로 사용할 수 있으며, 사용자당 무제한 기기와 50개의 태그된 리소스를 기본으로 제공하므로 직접 서버를 운영할 이유가 없을 수도 있습니다. 이 제한을 넘어서면 비용은 기기 수가 아닌 인원수에 따라 증가하므로, Tailscale의 예상 청구 금액을 계산하여 VPS 운영 비용 및 관리 시간과 비교해 보시기 바랍니다.
이 서비스를 운영하기 위한 최소 VPS 사양은 어느 정도입니까?
문서화된 최소 사양은 1 CPU와 2 GB 메모리입니다. 사용자 관리가 로컬에서 이루어지게 변경되면서, NetBird 측에서는 현재 최소 사양을 1 GB RAM 정도로 보고 있습니다. 과거 Zitadel 전체 배포가 스택에 포함되었을 때 필요했던 2 GB에서 4 GB보다는 낮아진 수치입니다. 2 GB 사양을 구매하십시오. 여유 메모리가 있어야 기존 이미지가 디스크에 남아 있는 상태에서 업그레이드를 위해 새로운 이미지를 내려받을 수 있습니다.
소규모 서버라면 다음 세 가지는 제외해도 안전합니다. 내부 서비스를 공개 호스트명으로 게시하는 용도일 뿐 피어 연결과는 무관한 NetBird Proxy 서비스는 설치하지 마십시오. 스크립트에서 프록시와 함께 제공하는 CrowdSec 역시 초기 단계보다는 서버가 외부에 노출된 이후에 추가하는 것이 좋습니다. 데이터 저장소는 netbird_data 볼륨의 기본 SQLite를 유지하십시오. PostgreSQL로의 전환은 배포를 여러 장비로 분산하거나 실제 동시 접속자가 늘어난 뒤에 수행해도 충분하며, 이는 나중에 수행할 수 있는 마이그레이션 작업으로 문서화되어 있습니다.
릴레이(relay)는 절대 제외할 수 없는 구성 요소입니다. 목적지마다 서로 다른 포트를 할당하는 NAT 환경의 두 피어는 직접 터널을 생성할 수 없으므로, 릴레이가 유일한 연결 경로가 됩니다. 릴레이를 비활성화하면 메모리 절감 효과는 미미한 반면, 연결 문제를 추적하기 매우 어려워집니다.
한 대의 서버로 부족해지면 릴레이를 가장 먼저 분리하십시오. 독립형 릴레이는 NB_LISTEN_ADDRESS, NB_EXPOSED_ADDRESS, NB_AUTH_SECRET 및 NB_ENABLE_STUN을 사용하여 실행됩니다. 릴레이와 메인 서버의 공유 비밀값(shared secret)이 일치해야 하며, 그렇지 않으면 클라이언트가 인증에 실패합니다.
실패 유형 및 확인 사항
대시보드에 인증서 경고가 표시됩니다. Traefik이 인증서를 획득하지 못했습니다. docker compose logs traefik | grep -i acme를 실행하십시오. 원인은 두 가지입니다. dig +short netbird.example.com이 아직 이 VPS를 가리키지 않거나, Let's Encrypt와 컨테이너 사이의 어딘가에서 TCP 443 포트가 닫혀 있는 경우입니다. 이는 보통 ufw의 설정보다는 제공업체의 네트워크 방화벽에서 발생합니다. 챌린지는 443 포트를 통해 응답하므로 80 포트가 열려 있는 것만으로는 해결되지 않습니다. Let's Encrypt는 호스트 이름당 시간당 5회의 검증 실패만 허용하므로, 반복적으로 재시도하기 전에 원인을 먼저 해결하십시오. 제한을 초과하면 해당 제한이 초기화될 때까지 재시도가 차단됩니다.
클라이언트는 연결되었다고 표시되지만 대시보드가 비어 있습니다. --management-url가 누락되어 클라이언트가 NetBird의 호스팅 서비스에 등록되었습니다. netbird status --detail을 실행하고 실제로 통신 중인 서버를 나타내는 Management: 줄을 확인하십시오. Management: Connected to https://api.netbird.io:443가 보인다면 클라우드로 연결된 것입니다. sudo netbird down을 실행한 다음 sudo netbird up --management-url https://netbird.example.com을 다시 실행하십시오.
모든 피어에 Connection type: Relayed이 표시됩니다. 직접 터널이 형성되지 않아 모든 트래픽이 VPS를 거치게 되며 지연 시간이 추가됩니다. STUN은 피어가 자신의 공인 IP 주소와 포트를 파악하는 데 사용되므로, VPS 방화벽과 제공업체 방화벽에서 UDP 3478 포트를 확인하십시오. netbird status --detail를 실행하면 Direct: false과 각 피어에 대한 ICE(Interactive Connectivity Establishment) 후보 유형이 출력되어 연결 시도 단계를 확인할 수 있습니다. 일부 네트워크에서는 relayed 방식만 가능할 수 있으며, 이 경우 설정에 문제가 있는 것은 아닙니다.
피어가 참여했지만 아무것도 연결할 수 없습니다. 메시에 포함되었다고 해서 두 피어가 반드시 통신할 수 있는 것은 아닙니다. 통신 여부는 접근 정책(Access policies)에 따라 결정되며, 정책이 연결되지 않은 그룹은 아무것도 연결할 수 없습니다. 경로와 방화벽을 디버깅하기 전에 대시보드에서 정책을 먼저 확인하십시오.
netbird status에서 데몬 문제가 보고됩니다. 서비스가 실행 중이지 않습니다. sudo netbird service status와 sudo netbird service start을 사용하십시오. 클라이언트 로그는 /var/log/netbird/client.log에 있습니다. 원인을 파악할 수 없는 경우, netbird debug bundle --anonymize --system-info를 사용하면 로그, 상태, 경로, DNS 설정 및 방화벽 상태를 하나의 아카이브로 수집할 수 있습니다.
백업 및 업그레이드
전체 설치본을 유지하는 핵심 요소는 docker-compose.yml와 config.yaml이 포함된 디렉터리, 그리고 데이터베이스와 암호화 키를 담고 있는 Docker 볼륨입니다. 이 둘을 함께 백업하십시오. config.yaml에는 저장소의 데이터를 암호화하는 키가 들어 있으므로, 이 키 없이 데이터베이스만 복사하면 읽을 수 없는 데이터만 남게 됩니다.
docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -dCompose는 프로젝트 디렉터리 이름을 볼륨 이름 앞에 접두사로 붙입니다. 따라서 netbird_data로 문서화된 볼륨은 보통 netbird_netbird_data이라는 이름으로 나타납니다. 먼저 docker volume ls을 실행하여 출력되는 이름을 사용하십시오. 그렇지 않으면 docker run이 빈 볼륨을 생성하고 아무것도 아카이빙하지 않은 채 종료될 수 있습니다. 아카이브는 VPS 외부에 보관하십시오. 이미 백업 도구를 사용 중이라면 restic 또는 BorgBackup을 사용하여 외부 저장소로 전송할 수 있습니다.
서버 업그레이드는 이미지를 내려받고 컨테이너를 다시 생성하는 과정입니다.
docker compose pull
docker compose up -d
docker compose ps이 과정을 수행하기 전에 docker compose config | grep image:를 먼저 실행하십시오. latest으로 표시된 모든 태그는 특정 버전으로 고정해야 합니다. 설치 스크립트를 고정했던 이유와 마찬가지로, 현재 실행 중인 버전을 명확히 파악하고 업그레이드 후 문제가 발생했을 때 이전 버전으로 즉시 되돌리기 위함입니다. 클라이언트는 해당 패키지를 설치한 패키지 관리자를 통해 업그레이드합니다.
FAQ
NetBird를 직접 호스팅하려면 자체 ID 공급자가 필요한가요?
아니요. 현재 릴리스에는 내장 사용자 저장소가 포함되어 있습니다. 따라서 브라우저의 https://netbird.example.com에서 첫 번째 관리자 계정을 생성한 뒤 대시보드에서 사용자를 추가하면 됩니다. 외부 OIDC 공급자는 선택 사항이며, 나중에 이름, client ID, client secret, issuer라는 네 가지 값을 사용하여 추가할 수 있습니다. NetBird 이전에 Zitadel이나 Keycloak을 배포하라고 안내하는 가이드는 더 이상 필요하지 않은 설정을 설명하고 있으며, 이를 따르면 운영해야 할 서비스만 하나 더 늘어날 뿐입니다.
모든 피어(peer)가 Connection type: Relayed로 표시되는 이유는 무엇인가요?
직접 연결이 형성되지 않아 트래픽이 VPS의 릴레이를 거치고 있기 때문입니다. 일반적인 원인은 피어가 자신의 공인 주소와 포트를 확인하는 데 사용하는 STUN 포트인 UDP 3478이 차단된 경우입니다. VPS 방화벽과 제공업체의 별도 네트워크 방화벽에서 해당 포트를 개방한 뒤, netbird status --detail을 다시 실행하여 Direct: 줄을 확인하십시오. 목적지마다 서로 다른 포트를 할당하는 NAT 네트워크 환경이라면 릴레이 방식이 유일한 연결 방법이며, 설정이 잘못된 것이 아닙니다.
클라이언트는 연결되었는데 대시보드에 피어가 보이지 않습니다. 어떻게 된 일인가요?
--management-url 옵션을 생략하여 클라이언트가 귀하의 서버가 아닌 NetBird의 호스팅 서비스에 등록된 경우입니다. netbird status --detail은 현재 통신 중인 서버를 Management: 줄에 출력하므로, https://api.netbird.io:443과 같은 값이 나오면 이를 확인할 수 있습니다. sudo netbird down를 실행한 뒤 sudo netbird up --management-url https://netbird.example.com를 실행하면 대시보드에 피어가 나타납니다.
직접 호스팅하는 NetBird는 Headscale과 어떻게 다른가요?
둘 다 호스팅된 제어 서버를 직접 운영하는 서버로 대체한다는 점은 같습니다. Headscale은 제어 평면(control plane) 역할만 수행합니다. headscale 명령과 설정 파일로 관리하며 공식 웹 콘솔이 없고, 공식 Tailscale 클라이언트를 사용합니다. 반면 NetBird는 자체 클라이언트, 관리자 대시보드, ID 공급자 통합 기능을 하나의 스택으로 제공합니다. Headscale은 운영 리소스가 적고 상태를 파일로 유지합니다. NetBird는 터미널 사용을 어려워하는 사용자에게 제공하기 더 쉽습니다.
직접 호스팅하는 NetBird 서버에는 어느 정도 크기의 VPS가 필요한가요?
문서상 최소 사양은 1 CPU와 2 GB 메모리이며, 2 GB를 선택하는 것이 좋습니다. 최근 릴리스에서는 ID 공급자가 별도 배포 방식에서 내장 방식으로 변경되어 실질적인 최소 사양은 약 1 GB까지 낮아졌습니다. 설치 과정에서 선택 사항인 프록시 서비스를 거부하면 CrowdSec 프롬프트도 건너뛸 수 있으며, PostgreSQL이 반드시 필요한 상황이 아니라면 기본값인 SQLite 저장소를 그대로 사용하는 것이 좋습니다.