Rayfish: Iroh 기반 P2P VPN
요약
Rayfish는 중앙 제어 평면과 계정 없이 동작하는 Iroh 기반의 P2P 메시 VPN입니다. 사용자가 네트워크 상태를 서명된 기록으로 직접 관리하여, 운영 주체가 사라져도 네트워크가 지속되는 탈중앙화된 사설 네트워크 환경을 제공합니다.
핵심 포인트
- 중앙 서버나 계정 없이 기기 간 직접 연결되는 P2P 구조
- Iroh v1을 활용한 QUIC 연결, NAT 통과 및 홀 펀칭 지원
- 여러 격리된 네트워크에 동시 가입 및 독립적 운영 가능
- 중앙 운영자 의존성을 제거하여 사용자 소유권 강화
- Rayfish는 서버·계정 없이 사용자 기기 사이에
**P2P 메시 VPN (P2P Mesh VPN)**을 만드는 첫 릴리스로, 네트워크 상태를 멤버들이 보관하는 서명된 기록으로 유지함 - 중앙 제어 평면 (Control Plane)을 없애 회사 계정, 운영자, 항상 켜져 있어야 하는
조정 서버 (Orchestration Server) 없이도 가입 이후 네트워크가 계속 동작함 - Iroh v1이 암호화된
QUIC 연결 (QUIC Connection), NAT 통과, 홀 펀칭 (Hole Punching), 직접 경로가 없을 때의 릴레이 폴백 (Relay Fallback)을 맡아 출시 기반이 됨 - 현재는 여러 격리 네트워크 동시 가입, 초대 코드·승인 기반 가입, Magic DNS, 기기별 방화벽, 선언형 플릿 프로비저닝 (Declarative Fleet Provisioning), 1:1 연결, 파일 전송을 제공함
- Tailscale보다 성숙도와 처리량에서 불리할 수 있고 SDK도 아니지만,
중앙 당사자 없는 사설 네트워크가 필요한 경우에 초점을 맞춤
Rayfish가 해결하려는 문제
- Rayfish는 기기들 사이에 사설 네트워크를 만드는
**P2P 메시 VPN (P2P Mesh VPN)**임 - 중간 서버나 계속 운영을 믿어야 하는 회사 없이 동작함
- 사용자는 키를 받고, 기기들은 그 키로 서로를 찾으며, 만들어진 네트워크는 그 안의 사람들에게 속함
중앙 제어 평면을 없앤 설계
-
많은 현대 VPN은 회사가 운영하는 제어 평면 (Control Plane)에 의존함
-
회사가 네트워크 멤버와 정책을 결정함
-
기기들이 통신하는 동안에도 회사가 흐름 안에 남아 있음
-
회사가 중단되거나 가격을 올리거나 고객 관계를 끊으면 사설 네트워크가 완전히 사용자 소유로 남기 어려움
-
Rayfish는
**계정 (Account)**과 중앙 운영자를 제거함 -
네트워크 상태는 멤버 누구나 다른 멤버에게 전달할 수 있는
**서명된 기록 (Signed Record)**임 -
Rayfish 제작자가 사라져도 기존 네트워크는 계속 동작함
한 기기에서 여러 네트워크를 다루는 방식
- Rayfish는 사용자가 하나의 평평한 네트워크만 쓰지 않는다는 전제에서 출발함
- 한 기기가 친구용, 사이드 프로젝트용, 업무용 네트워크에 동시에 속할 수 있음
- 구현은 하나의 프로세스와 하나의 가상 인터페이스 뒤에서 동작함
- 각 네트워크는 서로
**격리 (Isolation)**되며, 사용자는 가입한 모든 네트워크의 정식 멤버가 됨
Iroh v1이 가능하게 한 출시
-
Rayfish는 전송 계층의 어려운 부분을 Iroh에 맡김
-
피어 간 암호화된
QUIC 연결 (QUIC Connection) -
NAT 통과
-
홀 펀칭 (Hole Punching)
-
직접 경로가 없을 때의 릴레이 폴백 (Relay Fallback)
-
Iroh v1은 빌드 도중 전송 계층이 흔들리지 않을 안정성을 제공해 이번 릴리스를 가능하게 함
-
다음 과제는 초기 도구를 프로덕션에서 부담 없이 실행할 수 있는 도구로 다듬는 것임
Field Technologies에서 나온 스핀오프
- Rayfish는 고빈도 거래 회사 Field Technologies에서 분리된 프로젝트임
- 내부에서 분산 시스템을 다루며 기기 탐색, 공유 상태 합의, 빠르고 사적인 통신을 여러 차례 구축한 경험이 바탕이 됨
- 이런 내부 인프라는 주로 다른 회사의 제어 평면 (Control Plane)에 의존하지 않기 위해 만들어졌음
- Rayfish는 4년 넘게 이어진 아이디어였지만, 중앙 운영자가 없다는 특성 때문에 명확한 과금 지점이 없어 제품화가 늦어짐
- 향후 플릿 관리 (Fleet Management)나 감사 같은 기업형 문제로 확장할 수 있지만, 그런 기능은 아직 존재하지 않음
현재 제공 기능
점대점 구조
-
Rayfish는 허브 앤드 스포크 (Hub and Spoke)가 아니라
점대점 (Peer-to-Peer) 구조임 -
모든 멤버가 다른 모든 멤버와 직접 연결됨
-
멤버십은 서버에 묻는 값이 아니라 각 멤버가 들고 다니는 서명된 기록임
-
네트워크를 만든 조정자는 새 멤버를 받아들일 때만 필요하고, 가입 이후에는 중앙의 누군가 없이 네트워크가 동작함
닫힌 네트워크와 가입 방식
-
네트워크는 기본적으로
**닫힌 상태 (Closed State)**임 -
조정자는 두 가지 방식으로 새 멤버를 들일 수 있음
-
1회용 초대 코드
-
가입 요청에 대한 실시간 승인
-
공개 네트워크가 필요하면
ray create --open
으로 게이트를 열 수 있으며, 이 경우 room id만으로 가입할 수 있음
- 가입한 멤버는 안정적인 IP와 친숙한 Magic DNS 이름으로 접근 가능함
- 기본 호스트명은
ray up --hostname dario
처럼 설정할 수 있고, 네트워크별로 --hostname을 덮어쓸 수 있음
ray up --hostname dario
ray create --name prod
ray invite prod --hostname web
...
기기별 방화벽 (Device Firewalls)
-
각 기기는 자체 방화벽을 가지며, 무엇을 누구로부터 받을지 스스로 결정함
-
조정자 (Orchestrator)는 네트워크별 권장 방화벽 규칙을 게시할 수 있음
-
각 호스트는 규칙을 수락하거나 자동 설치를 선택할 수 있음
-
모두가 반드시 따라야 하는 중앙 정책 서버 없이 **공유 기본값 (Shared Defaults)**을 제공하는 방식임
플릿 프로비저닝 (Fleet Provisioning)
- 여러 대의 기기는 선언형 (Declarative) 파일로 네트워크와 방화벽 규칙을 정의하고 적용할 수 있음
- 명세 (Specification)는
networks:맵이며, 각 네트워크 아래에 호스트별 허용 피어 (Peer)와 포트를 작성함
networks:
prod:
web:
...
ray apply deploy.yaml --dry-run
ray apply deploy.yaml --invite-missing
- 플릿 (Fleet)에는 각 박스마다 코드를 발급하는 대신 **재사용 키 (Reusable Keys)**를 만들 수 있음
ray invite prod --reusable
ray join <key> --hostname web01 --auto-accept-firewall
-
키를 폐기하면 새로운 가입만 차단되며, 이미 접속한 서버에는 영향을 주지 않음
-
ray apply는 멱등적 (Idempotent)으로 동작하여 명세 파일이 플릿의 기준 상태 (Desired State)로 유지됨
1:1 연결과 파일 전송 (1:1 Connections and File Transfer)
- 네트워크를 별도로 생성할 필요가 없을 때는
ray connect를 통해 연락처 ID (Contact ID) 기반의 1:1 연결을 만들 수 있음
ray contact id
ray connect <their-contact-id>
ray connections approve <id>
- 승인되면 사설 2피어 (2-peer) 네트워크가 자동으로 생성됨
- Magic DNS, 방화벽, 메시 (Mesh) 기능은 동일하게 동작하며,
ray status에는[direct]로 표시됨 - 연락처 ID는 회전 (Rotate)할 수 있으며, 이미 생성된 연결은 계속 유지됨
- 멤버 간에는 이미 인증되고 암호화된 경로가 존재하므로 별도의 서비스 없이 파일을 보낼 수 있음
ray send ./build.tar.gz web01
ray files accept 1
Tailscale과의 차이점
-
Tailscale과 Rayfish는 모두 안정적인 IP, Magic DNS, NAT 통과 (NAT Traversal), P2P 데이터 평면 (Data Plane)을 제공함
-
가장 큰 차이점은 **제어 위치 (Control Location)**임
-
Tailscale은 Tailscale 조정 서버나 self-hosted Headscale 같은 제어 평면 (Control Plane)을 사용함
-
Rayfish는 중앙 제어 평면 없이, 네트워크 상태를 P2P로 전달되는 서명된 기록 (Signed Records)으로 관리함
-
데이터 평면도 다름
-
Tailscale은 커널 (Kernel)에서 동작하는 WireGuard를 사용함
-
Rayfish는 사용자 공간 (User Space)의 Iroh/QUIC 데이터그램을 사용함
-
속도는 보통 Tailscale이 유리함
-
WireGuard가 커널에서 동작하므로 빠른 링크에서 대용량 전송 시 차이가 뚜렷할 수 있음
-
Rayfish는 중앙 당사자가 없는 구조를 위해 약간의 원시 처리량 (Raw Throughput)을 양보하는 형태임
-
Rayfish는 계정이나 SSO가 아니라 디스크의 **키쌍 (Keypair)**을 정체성으로 사용함
-
Rayfish는 초기 단계이며 최소 기능 중심(Minimalist)인 반면, Tailscale은 성숙하고 기능 폭이 넓음
Yggdrasil과의 차이점
-
Yggdrasil은 중앙 권한이 없는 종단 간 암호화 (End-to-End Encrypted) IPv6 네트워크를 제공함
-
사용자가 직접 다뤄야 하는 마지막 단계에서 차이가 남
-
Yggdrasil은 하나의 전역 네트워크와 IPv6 주소를 제공함
-
Rayfish는 사용자가 만들고 멤버를 들이는 별도 사설 네트워크를 제공함
-
Rayfish는 초대 코드, 친숙한 DNS 이름, 네트워크별 방화벽, 가입 승인 프롬프트 같은 편의 기능을 포함함
-
Yggdrasil은 네트워크 지식이 있는 엔지니어에게 적합하고, Rayfish는 몇 명이 쓰는 사설 네트워크를 쉽게 만들려는 사용자까지 겨냥함
만들 수 있는 것과 만들 수 없는 것
-
Rayfish는 라이브러리가 아니라
완성된 도구임 -
애플리케이션 안에 SDK처럼 임베드할 수 없음
-
Rayfish가 설치된 기기끼리 사적으로 통신해야 하는 용도에 맞음
-
친구들이 이름으로 접속하는 P2P 게임 서버
-
공개 인터넷에 닿지 않는 내부 API
-
백업 대상
-
네트워크 멤버 간 채팅이나 통화 앱
-
서로 보지 않아야 하는 두 팀이 공유하는 데이터베이스
-
애플리케이션은
name.network.ray
로 피어 (Peer)에 접근할 수 있음
- Rayfish가 설치되지 않은 외부인은 네트워크에 접근할 수 없고, 외부인을 위한 게이트웨이는 없음
실제 구성 예시
두 부서가 데이터베이스를 공유하는 경우
payments
와 analytics
를 별도 네트워크로 두면 두 부서는 서로를 볼 수 없음
- 데이터베이스 박스만 두 네트워크에 모두 가입함
- 각 네트워크에서 필요한 포트만 열도록 권장 방화벽을 설정함
networks:
payments:
db:
...
- 각 팀은
db.payments.ray
또는 db.analytics.ray
로 접근함
-
두 네트워크는 서로 존재를 알지 못하며, 중앙 ACL (Access Control List) 감사 없이 네트워크 분리와 공유 호스트로 접근 제어가 구성됨
친구용 Minecraft 서버
- 닫힌 네트워크를 만들고 친구들을 초대하면 IP 주소, 포트 포워딩 (Port Forwarding), 동적 DNS (Dynamic DNS) 없이 이름으로 접속할 수 있음
ray create --name mc
ray invite mc
- 클라이언트는
mc-host.mc.ray:25565
를 대상으로 접속함
모두가 포트를 여는 닫힌 그룹
- 모든 멤버가 TCP 6969를 열어야 하는 경우 관리자가 한 번 규칙을 제안할 수 있음
ray firewall suggest mc --subject '*' --allow '*:tcp:6969'
- 각 멤버는 제안된 규칙을 검토하고 수락하거나 거부함
ray firewall pending mc
ray firewall accept mc
- 방화벽 제안은 강제 규칙이 아니며, 멤버가 원하지 않으면 거부할 수 있음
보안과 주소 처리
- IP 주소는 서버가 할당하지 않고 각 피어의
**암호학적 정체성 (Cryptographic Identity)**에서 파생됨 - 주소 충돌은 거의 없지만, 충돌이 나면 조정자 (Coordinator)가 두 번째 피어를 다음 빈 슬롯에 배치함
- 모든 피어는 중앙 할당자 없이 같은 주소 배정에 결정적으로 수렴함
- Rayfish는 중앙 ACL 대신 두 가지로 보안을 구성함
- 같은 네트워크를 공유한 피어끼리만 통신 가능한
분할 (Partitioning) - 각 기기의 네트워크별 방화벽
prod
와 dev
를 격리하려면 두 네트워크로 만들면 됨
- 여러 네트워크에 속한 호스트는 각 네트워크에서 자기 방화벽을 들고 있음
서버와 포트 개방 필요 여부
- 별도 제어 서버를 호스팅할 필요가 없음
- 네트워크를 만든 조정자는 모든 멤버가 가입한 뒤에는 오프라인이어도 됨
- Iroh가 NAT 통과 (NAT Traversal)와 홀 펀칭 (Hole Punching)을 처리하고, 직접 경로가 불가능하면 암호화된 릴레이 (Relay) 폴백 (Fallback)을 사용함
- 라우터를 제어하고 특정 박스에 보장된 직접 경로를 원하면 Rayfish의 고정 UDP 포트를 포워딩할 수 있지만 선택 사항임
앞으로의 계획과 맞지 않는 경우
-
현재 데스크톱과 서버에서는 명령줄 도구 (Command-line tool)로 제공됨
-
다음 작업은 사용자가 실제로 들고 다니는 기기로 확장하는 것임
- Android 클라이언트
- iOS 클라이언트
- 제대로 된 데스크톱 앱
-
동시에 프로덕션 (Production) 환경에서 부담 없이 쓸 수 있도록 기존 기능을 단단하게 만드는 작업을 진행함
-
이미 Tailscale, 회사 VPN, 직접 구성한 WireGuard 메시 (Mesh)가 잘 동작한다면 Rayfish로 바꿀 이유는 크지 않음
-
Rayfish는 더 젊고 기능이 적으며, 기존 도구들이 더 매끄럽게 제공하는 기능도 많음
-
Rayfish가 제거하는 것은 하나임
- 계정
- 네트워크를 중단할 수 있는 회사
- 계속 켜져 있어야 하는 제어 서버 (Control server)
- 다른 사람이 운영하는 정책 데이터베이스 (Policy database)
시작 방법
curl -fsSL https://rayfish.xyz/install.sh | sh
- 첫 네트워크 생성과 초대 절차는 문서에서 이어서 안내함
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기