Rayfish: Iroh 기반 P2P VPN
10 hours ago
4
- Rayfish는 서버·계정 없이 사용자 기기 사이에 P2P 메시 VPN을 만드는 첫 릴리스로, 네트워크 상태를 멤버들이 보관하는 서명된 기록으로 유지함
- 중앙 제어 평면을 없애 회사 계정, 운영자, 항상 켜져 있어야 하는 조정 서버 없이도 가입 이후 네트워크가 계속 동작함
- Iroh v1이 암호화된 QUIC 연결, NAT 통과, 홀 펀칭, 직접 경로가 없을 때의 릴레이 폴백을 맡아 출시 기반이 됨
- 현재는 여러 격리 네트워크 동시 가입, 초대 코드·승인 기반 가입, Magic DNS, 기기별 방화벽, 선언형 플릿 프로비저닝, 1:1 연결, 파일 전송을 제공함
- Tailscale보다 성숙도와 처리량에서 불리할 수 있고 SDK도 아니지만, 중앙 당사자 없는 사설 네트워크가 필요한 경우에 초점을 맞춤
Rayfish가 해결하려는 문제
- Rayfish는 기기들 사이에 사설 네트워크를 만드는 P2P 메시 VPN임
- 중간 서버나 계속 운영을 믿어야 하는 회사 없이 동작함
- 사용자는 키를 받고, 기기들은 그 키로 서로를 찾으며, 만들어진 네트워크는 그 안의 사람들에게 속함
중앙 제어 평면을 없앤 설계
- 많은 현대 VPN은 회사가 운영하는 제어 평면에 의존함
- 회사가 네트워크 멤버와 정책을 결정함
- 기기들이 통신하는 동안에도 회사가 흐름 안에 남아 있음
- 회사가 중단되거나 가격을 올리거나 고객 관계를 끊으면 사설 네트워크가 완전히 사용자 소유로 남기 어려움
- Rayfish는 계정과 중앙 운영자를 제거함
- 네트워크 상태는 멤버 누구나 다른 멤버에게 전달할 수 있는 서명된 기록임
- Rayfish 제작자가 사라져도 기존 네트워크는 계속 동작함
한 기기에서 여러 네트워크를 다루는 방식
- Rayfish는 사용자가 하나의 평평한 네트워크만 쓰지 않는다는 전제에서 출발함
- 한 기기가 친구용, 사이드 프로젝트용, 업무용 네트워크에 동시에 속할 수 있음
- 구현은 하나의 프로세스와 하나의 가상 인터페이스 뒤에서 동작함
- 각 네트워크는 서로 격리되며, 사용자는 가입한 모든 네트워크의 정식 멤버가 됨
Iroh v1이 가능하게 한 출시
- Rayfish는 전송 계층의 어려운 부분을 Iroh에 맡김
- 피어 간 암호화된 QUIC 연결
- NAT 통과
- 홀 펀칭
- 직접 경로가 없을 때의 릴레이 폴백
- Iroh v1은 빌드 도중 전송 계층이 흔들리지 않을 안정성을 제공해 이번 릴리스를 가능하게 함
- 다음 과제는 초기 도구를 프로덕션에서 부담 없이 실행할 수 있는 도구로 다듬는 것임
Field Technologies에서 나온 스핀오프
- Rayfish는 고빈도 거래 회사 Field Technologies에서 분리된 프로젝트임
- 내부에서 분산 시스템을 다루며 기기 탐색, 공유 상태 합의, 빠르고 사적인 통신을 여러 차례 구축한 경험이 바탕이 됨
- 이런 내부 인프라는 주로 다른 회사의 제어 평면에 의존하지 않기 위해 만들어졌음
- Rayfish는 4년 넘게 이어진 아이디어였지만, 중앙 운영자가 없다는 특성 때문에 명확한 과금 지점이 없어 제품화가 늦어짐
- 향후 플릿 관리나 감사 같은 기업형 문제로 확장할 수 있지만, 그런 기능은 아직 존재하지 않음
현재 제공 기능
-
점대점 구조
- Rayfish는 허브 앤드 스포크가 아니라 점대점 구조임
- 모든 멤버가 다른 모든 멤버와 직접 연결됨
- 멤버십은 서버에 묻는 값이 아니라 각 멤버가 들고 다니는 서명된 기록임
- 네트워크를 만든 조정자는 새 멤버를 받아들일 때만 필요하고, 가입 이후에는 중앙의 누군가 없이 네트워크가 동작함
-
닫힌 네트워크와 가입 방식
- 네트워크는 기본적으로 닫힌 상태임
- 조정자는 두 가지 방식으로 새 멤버를 들일 수 있음
- 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
ray join <code>
-
기기별 방화벽
- 각 기기는 자기 방화벽을 가지고, 무엇을 누구에게서 받을지 스스로 결정함
- 조정자는 네트워크별 권장 방화벽 규칙을 게시할 수 있음
- 각 호스트는 규칙을 받아들이거나 자동 설치를 선택할 수 있음
- 모두가 반드시 따라야 하는 중앙 정책 서버 없이 공유 기본값을 제공하는 방식임
-
플릿 프로비저닝
- 여러 대의 기기는 선언형 파일로 네트워크와 방화벽 규칙을 정의하고 적용할 수 있음
- 명세는 networks: 맵이며, 각 네트워크 아래에 호스트별 허용 피어와 포트를 적음
networks:
prod:
web:
allows:
"*": "tcp:443"
db:
allows:
web: "tcp:5432"
game:
"*":
allows:
"*": "tcp:6969"
ray apply deploy.yaml --dry-run
ray apply deploy.yaml --invite-missing
- 플릿에는 박스마다 코드를 발급하지 않고 재사용 키를 만들 수 있음
ray invite prod --reusable
ray join <key> --hostname web01 --auto-accept-firewall
- 키를 폐기하면 새 가입만 막히고 이미 들어온 서버는 방해하지 않음
- ray apply는 멱등적으로 동작해 명세 파일이 플릿의 기준 상태로 남음
-
1:1 연결과 파일 전송
- 네트워크를 따로 만들 필요가 없을 때는 ray connect로 연락처 ID 기반 1:1 연결을 만들 수 있음
ray contact id
ray connect <their-contact-id>
ray connections approve <id>
- 승인되면 사설 2피어 네트워크가 자동으로 만들어짐
- Magic DNS, 방화벽, 메시 기능은 동일하게 동작하며 ray status에는 [direct]로 표시됨
- 연락처 ID는 회전할 수 있고, 이미 만들어진 연결은 계속 작동함
- 멤버 간에는 인증되고 암호화된 경로가 이미 있으므로 별도 서비스 없이 파일을 보낼 수 있음
ray send ./build.tar.gz web01
ray files accept 1
Tailscale과의 차이
- Tailscale과 Rayfish는 모두 안정적인 IP, Magic DNS, NAT 통과, P2P 데이터 평면을 제공함
- 가장 큰 차이는 제어 위치임
- Tailscale은 Tailscale 조정 서버나 self-hosted Headscale 같은 제어 평면을 사용함
- Rayfish는 중앙 제어 평면 없이, 네트워크 상태를 P2P로 전달되는 서명된 기록으로 둠
- 데이터 평면도 다름
- Tailscale은 커널에서 동작하는 WireGuard를 사용함
- Rayfish는 사용자 공간의 Iroh/QUIC 데이터그램을 사용함
- 속도는 보통 Tailscale이 유리함
- WireGuard가 커널에서 동작해 빠른 링크에서 대용량 전송 시 차이가 뚜렷할 수 있음
- Rayfish는 중앙 당사자가 없는 구조와 약간의 원시 처리량을 맞바꾸는 형태임
- Rayfish는 계정이나 SSO가 아니라 디스크의 키쌍을 정체성으로 사용함
- Rayfish는 젊고 최소 기능 중심이며, Tailscale은 성숙하고 기능 폭이 넓음
Yggdrasil과의 차이
- Yggdrasil은 중앙 권한이 없는 종단 간 암호화 IPv6 네트워크를 제공함
- 사용자가 직접 다뤄야 하는 마지막 단계에서 차이가 남
- Yggdrasil은 하나의 전역 네트워크와 IPv6 주소를 제공함
- Rayfish는 사용자가 만들고 멤버를 들이는 별도 사설 네트워크를 제공함
- Rayfish는 초대 코드, 친숙한 DNS 이름, 네트워크별 방화벽, 가입 승인 프롬프트 같은 편의 기능을 포함함
- Yggdrasil은 네트워크 지식이 있는 엔지니어에게 적합하고, Rayfish는 몇 명이 쓰는 사설 네트워크를 쉽게 만들려는 사용자까지 겨냥함
만들 수 있는 것과 만들 수 없는 것
- Rayfish는 라이브러리가 아니라 완성된 도구임
- 애플리케이션 안에 SDK처럼 임베드할 수 없음
- Rayfish가 설치된 기기끼리 사적으로 통신해야 하는 용도에 맞음
- 친구들이 이름으로 접속하는 P2P 게임 서버
- 공개 인터넷에 닿지 않는 내부 API
- 백업 대상
- 네트워크 멤버 간 채팅이나 통화 앱
- 서로 보지 않아야 하는 두 팀이 공유하는 데이터베이스
- 애플리케이션은 name.network.ray로 피어에 접근할 수 있음
- Rayfish가 설치되지 않은 외부인은 네트워크에 접근할 수 없고, 외부인을 위한 게이트웨이는 없음
실제 구성 예시
-
두 부서가 데이터베이스를 공유하는 경우
- payments와 analytics를 별도 네트워크로 두면 두 부서는 서로를 볼 수 없음
- 데이터베이스 박스만 두 네트워크에 모두 가입함
- 각 네트워크에서 필요한 포트만 열도록 권장 방화벽을 설정함
networks:
payments:
db:
allows:
"*": "tcp:8123,tcp:9000"
analytics:
db:
allows:
"*": "tcp:8123,tcp:9000"
- 각 팀은 db.payments.ray 또는 db.analytics.ray로 접근함
- 두 네트워크는 서로 존재를 알지 못하며, 중앙 ACL 감사 없이 네트워크 분리와 공유 호스트로 접근 제어가 구성됨
-
친구용 Minecraft 서버
- 닫힌 네트워크를 만들고 친구들을 초대하면 IP 주소, 포트 포워딩, 동적 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 주소는 서버가 할당하지 않고 각 피어의 암호학적 정체성에서 파생됨
- 주소 충돌은 거의 없지만, 충돌이 나면 조정자가 두 번째 피어를 다음 빈 슬롯에 배치함
- 모든 피어는 중앙 할당자 없이 같은 주소 배정에 결정적으로 수렴함
- Rayfish는 중앙 ACL 대신 두 가지로 보안을 구성함
- 같은 네트워크를 공유한 피어끼리만 통신 가능한 분할
- 각 기기의 네트워크별 방화벽
- prod와 dev를 격리하려면 두 네트워크로 만들면 됨
- 여러 네트워크에 속한 호스트는 각 네트워크에서 자기 방화벽을 들고 있음
서버와 포트 개방 필요 여부
- 별도 제어 서버를 호스팅할 필요가 없음
- 네트워크를 만든 조정자는 모든 멤버가 가입한 뒤에는 오프라인이어도 됨
- Iroh가 NAT 통과와 홀 펀칭을 처리하고, 직접 경로가 불가능하면 암호화된 릴레이 폴백을 사용함
- 라우터를 제어하고 특정 박스에 보장된 직접 경로를 원하면 Rayfish의 고정 UDP 포트를 포워딩할 수 있지만 선택 사항임
앞으로의 계획과 맞지 않는 경우
- 현재 데스크톱과 서버에서는 명령줄 도구로 제공됨
- 다음 작업은 사용자가 실제로 들고 다니는 기기로 확장하는 것임
- Android 클라이언트
- iOS 클라이언트
- 제대로 된 데스크톱 앱
- 동시에 프로덕션에서 부담 없이 쓸 수 있도록 기존 기능을 단단하게 만드는 작업을 진행함
- 이미 Tailscale, 회사 VPN, 직접 구성한 WireGuard 메시가 잘 동작한다면 Rayfish로 바꿀 이유는 크지 않음
- Rayfish는 더 젊고 기능이 적으며, 기존 도구들이 더 매끄럽게 제공하는 기능도 많음
- Rayfish가 제거하는 것은 하나임
- 계정
- 네트워크를 중단할 수 있는 회사
- 계속 켜져 있어야 하는 제어 서버
- 다른 사람이 운영하는 정책 데이터베이스
시작 방법
curl -fsSL
https://rayfish.xyz/install.sh | sh
- 첫 네트워크 생성과 초대 절차는 문서에서 이어서 안내함
-
Homepage
-
Tech blog
- Rayfish: Iroh 기반 P2P VPN