Sunshine + Moonlight + WireGuard를 하나로 묶는 macOS 메뉴바 앱. 게임 스트리밍 호스트 설정의 모든 마찰(권한, 페어링, 외부 접속)을 없애는 것이 목표.
- M1 — Sunshine 매니저 ✅
- 메뉴바에서 서비스 시작/중지/재시작, 상태 표시
- 로그 기반 건강 진단 (인코더 실패 → "화면 기록 권한 없음"으로 번역)
- 권한 설정 화면 바로가기, 원클릭 진단 리포트
- Sunshine 웹 UI 네이티브 창 (인증서 경고 없음)
- M2 — 연결 자동화 ✅: 내장 headscale WireGuard 네트워크, 페어링 3종(코드/QR/링크), Moonlight 호스트 자동 등록
- M3 — 연결 안정화 ✅: 사전 점검 진단, Sunshine 크래시 자동 복구, 잠자기 방지, Wake-on-LAN 확인
- M4 — 외부 접속 ✅: UPnP/NAT-PMP 자동 포트 개방(직결) + 원격 조정 서버 모드(자체 VPS)
- 향후: 네이티브 PIN 페어링, 로그인 시 자동 시작, Homebrew cask 배포
- macOS 13+
- Sunshine —
brew install lizardbyte/homebrew/sunshine - 네트워크 오버레이:
brew install headscale-cli tailscale - (외부 접속, 선택) UPnP용
brew install miniupnpc libnatpmp
계정도, 로그인도, IP 입력도 없습니다. 같은 와이파이의 두 Mac에 moonbridge가 있으면:
- 받는 쪽: 메뉴바 → 스트리밍 받을게요… → 주변 호스트가 자동으로 목록에 뜸(Bonjour) → 선택 후 연결
- 보내는 쪽: "○○을(를) 연결 허용할까요? — 코드 확인" 창에서 허용 (신뢰) 클릭 (양쪽 화면의 확인 코드가 같은지 눈으로 확인)
- 스트리밍 시작. 한 번 허용(신뢰)한 기기는 다음부터 창 없이 자동 연결됩니다 (한 번만 인증). 신뢰를 취소하려면 진단 → 신뢰 기기 초기화.
집 밖에서 쓸 거면 집에서 미리 신뢰해 두세요. 첫 연결 승인은 호스트 Mac에서 사람이 직접 눌러야 합니다(화면 공유는 민감하므로 기기당 1회 확인). 집에 아무도 없을 때는 이 승인을 누를 수 없으니, 외출 전 집에서 한 번 연결해 신뢰 기기로 등록해 두면 이후 밖에서는 승인 창 없이 바로 붙습니다. 이게 무인 원격 접속의 정상 준비 절차입니다.
Sunshine 관리자 계정은 moonbridge가 내부적으로 자동 생성해 Keychain으로 관리합니다 — 사용자가 만들거나 기억할 것이 없습니다. 호스트 이름과 앱 목록은 스트리밍 설정… 에서, 세부 옵션은 고급 설정 (웹)… 에서.
스트리밍 중 조작 (원격 데스크톱 기본값)
- 종료:
Ctrl+Alt+Shift+Q(화면 속 종료 버튼은 없습니다 — Moonlight 특성) - 빠져나오기: 창 없는 전체화면(borderless)이라
Cmd+Tab·Mission Control로 로컬 화면에 바로 오갈 수 있고, 마우스 커서도 화면 밖으로 나옵니다 (absolute-mouse 모드). - 끊김이 잦으면: 화질을 "원격/불안정망 (720p)" 으로 — 원격 접속은 집 회선의 업로드 대역폭에 묶이므로 비트레이트를 낮추면 멈춤이 줄어듭니다.
다른 클라이언트 유형
- 모바일 등 Moonlight 앱: 앱에서 이 Mac 선택 → 표시된 PIN을 호스트 메뉴바 기기 연결 → PIN으로 기기 허용… 에 입력.
- 집 밖(원격) 기기: 호스트 메뉴바 → 집 밖 기기 연결 (코드 발급)…
으로 1회용 조인 코드(15분 만료)를 발급해 클라이언트 터미널에서 실행.
tailscale이 필요하며(macOS:
brew install tailscale), 데몬이 꺼져 있으면 스크립트가 자동으로 시작합니다(sudo 1회).
주의
~/.config/sunshine/sunshine_state.json을 지우면 Sunshine의 고유 ID가 재생성되어 기존에 페어링된 모든 기기가 무효화됩니다. 이때는 클라이언트 쪽 Moonlight의 저장된 PC 목록도 초기화해야 다시 페어링됩니다 (Moonlight 앱에서 호스트 삭제 후 재추가).
LAN 페어링과 집 안 스트리밍은 설정 없이 바로 됩니다. 집 밖에서 접속하려면 공유기에서 이 Mac으로 향하는 포트가 열려 있어야 하고, moonbridge가 이를 자동화하지 못하는 경우(UPnP 꺼짐/미지원) 아래 순서로 진행하세요.
순서가 중요합니다: 조인 코드(
curl … | sh)는 같은 LAN에서만 동작하므로, 기기는 집에서 미리 페어링한 뒤 들고 나가세요 (외부 접속을 켠 상태에서 페어링해야 밖에서도 연결됩니다). 밖에 있는 기기는 링크/QR을 메신저로 전달해 조인시킬 수 있습니다.외부 접속은 10분마다 자동 점검됩니다 — 공유기 재부팅으로 포트가 닫히거나 외부 IP가 바뀌면 메뉴에 알림이 뜹니다.
메뉴바 → 외부 접속 (집 밖에서 연결) 클릭. 성공하면 끝. 실패 시 뜨는 안내 창에 공유기 주소와 필요한 규칙이 정확히 표시됩니다.
공유기 관리 페이지 접속 → 로그인 → 둘 중 하나:
- UPnP 켜기 (이후 자동 개방 재시도), 또는
- 포트포워딩 2줄 추가:
TCP 8383,UDP 3478→ 이 Mac의 IP
| 공유기 | 관리 페이지 | 비고 |
|---|---|---|
| ipTIME | http://192.168.0.1 | 고급설정 → NAT/라우터관리 → UPnP / 포트포워드 |
| KT (기가 와이파이) | http://172.30.1.254 | 계정은 공유기 라벨 참고 (기본 ktuser) |
| SK브로드밴드 | http://192.168.35.1 | 라벨의 관리자 계정 |
| LG U+ | http://192.168.219.1 | 라벨의 관리자 계정 |
통신사 임대 공유기: 관리자 계정이 기기 하단 라벨에 인쇄되어 있는 경우가 대부분입니다. 라벨에 없으면 해당 통신사 고객센터/앱에서 "포트포워딩 설정"을 요청할 수 있습니다 (원격으로 넣어주기도 합니다).
일부 통신사 관리형 장비는 LAN에서 웹 관리가 아예 차단되어 있습니다 (모든 관리 포트가 닫혀 있고 페이지가 열리지 않음). 이 경우 웹 설정은 불가능하며, 통신사 앱(마이케이티 등)이나 고객센터를 통해 포트포워딩을 요청하거나 아래 3단계 대안을 사용하세요.
- IPv6 직결: 양쪽 기기 모두 IPv6가 되면 포트포워딩 없이 직결이 가능합니다 (한국 주요 통신사 IPv6 지원 확대 중). 별도 설정 불필요 — 자동 시도됩니다.
- VPS 릴레이 (무료 가능): VPS에 headscale+DERP를 올리고 moonbridge의 조정 서버 주소만 바꾸면 어떤 네트워크에서도 동작합니다 (TCP 443 경유, 카페/회사 와이파이에서도 차단되지 않음). Oracle Cloud Always Free 등 무료 티어로도 충분합니다 (트래픽 대부분은 P2P 직결, 릴레이는 보조).
- 브리지 모드 + 개인 공유기: 통신사 장비를 브리지로 두고 설정 가능한 공유기를 직접 연결.
# 개발용: 맨 바이너리 실행
swift build && .build/debug/moonbridge &
# 배포용 .app 번들 (URL 스킴 등록, Dock 아이콘 없음, 안정적 권한 유지)
scripts/bundle.sh
cp -r .build/moonbridge.app /Applications/
open /Applications/moonbridge.app메뉴바에 🌙 아이콘이 나타납니다. 첫 실행 시 화면 기록과 손쉬운 사용 권한을 요청하니 시스템 설정에서 허용하세요 (메뉴 → 진단에 바로가기 있음).
서명: 번들은 ad-hoc 서명입니다. 정식 배포(Gatekeeper 경고 제거)에는 Apple Developer ID 서명 + 공증이 필요하지만, 소스 빌드/개인 사용에는 불필요합니다.
공유기가 포트 개방을 지원하지 않으면(통신사 관리형 장비 등) 어디서든 접속 가능한 자체 조정 서버를 둘 수 있습니다.
Oracle Cloud Always Free로 CLI만으로 구축하는 전체 절차는 docs/remote-oracle-cli.md 참고 (VCN·인스턴스 생성부터 headscale 설치, moonbridge 연동까지). 저렴하거나 무료인 VPS(Oracle Cloud Always Free 등)에 headscale을 올리고 아래 두 파일만 만들면 moonbridge가 원격 모드로 전환됩니다:
~/Library/Application Support/moonbridge/remote_control_url # 예: https://hs.example.com
~/Library/Application Support/moonbridge/remote_api_key # headscale API 키 (chmod 600)
- VPS에
headscale설치 →server_url: https://hs.example.com, Let's Encrypt TLS, 내장 DERP(derp.server.enabled: true,verify_clients: true), STUN(3478) 설정 - 도메인은 DNS only(프록시 미사용) 로 VPS IP를 가리켜야 함 — Cloudflare 프록시는 tailscale 제어 프로토콜(ts2021)의 업그레이드 헤더를 제거하므로 동작하지 않음
- API 키:
headscale apikeys create— moonbridge가 이 키로 페어링 키를 REST API로 발급
이 모드에서는 스트리밍 트래픽 대부분이 기기 간 P2P 직결(홀펀칭)이고, 직결이 안 되는 네트워크에서만 VPS의 DERP로 중계됩니다.
GPL-3.0-or-later — LICENSE 참고. 기반 프로젝트인 Sunshine과 Moonlight이 GPL-3이며, headscale은 BSD-3입니다.