Communitygithub.com

voluminor/skill-yggdrasil

Yggdrasil 메시 네트워크 앱을 Go로 구축하기 위한 에이전트 스킬입니다. (ratatoskr 라이브러리 기반): 임베디드 클라이언트, HTTP/TCP/UDP 서버, SOCKS5, 포트 포워딩, 피어 관리, NodeInfo/시길 — 사용자 공간에서 실행되며 TUN이나 루트 권한이 필요 없습니다.

skill-yggdrasil란 무엇인가요?

이 스킬은 Go로 작성된 애플리케이션이 Yggdrasil 종단간 암호화 IPv6 메시 네트워크에 연결하고 서비스할 수 있도록 지원합니다. ratatoskr 라이브러리를 사용하여 사용자 공간(gVisor netstack)에서 노드를 실행하므로 TUN 장치, 루트 권한, 외부 데몬이 필요 없습니다. 표준 Go 인터페이스(net.Conn, net.Listener, net.PacketConn, http.Transport)를 통해 Yggdrasil 위에서 다이얼하거나 리슨할 수 있습니다. SOCKS5 프록시, 포트 포워딩, NodeInfo/시길 게시, 피어 관리 등 다양한 기능을 지원하며, 제한된 메시 환경(고지연, 저대역폭, 손실 및 간헐적 연결)에 맞게 청크 전송, 타임아웃, 동시성 제한, 재시도 백오프 등의 패턴을 권장합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add voluminor/skill-yggdrasil

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Go에서 Yggdrasil 네트워킹

개요

이 스킬을 사용하여 Yggdrasil 종단간 암호화 IPv6 메시에 연결하고 서비스하는 Go 프로그램을 구축하십시오: 클라이언트, HTTP/TCP/UDP 서버, SOCKS5 프록시, 포트 포워더, 그리고 검색 메타데이터를 게시하는 노드. 노드는 사용자 공간의 gVisor netstack에서 실행됩니다 — TUN 장치, 루트, 외부 yggdrasil 데몬, yggstack 바이너리가 필요 없습니다. 표준 Go 인터페이스(net.Conn, net.Listener, net.PacketConn, http.Transport)로 Yggdrasil을 통해 다이얼하고 리슨합니다.

임베딩 라이브러리는 github.com/voluminor/ratatoskr입니다: ratatoskr.New로 노드를 생성하고 Go API를 통해 모든 것을 제어하십시오. 패키지의 범위와 안정성은 아래에 요약되어 있습니다.

제한된 메시를 위한 설계

Yggdrasil은 데이터센터 패브릭이 아닌 종단간 암호화 오버레이 메시입니다. 링크는 고지연, 저대역폭, 손실성, 간헐적입니다; 지금 연결 가능한 피어가 1초 후에는 사라질 수 있으며, 트래픽은 여러 홉을 거칠 수 있습니다. 모든 Yggdrasil 솔루션을 약하고 불안정한 연결을 위한 것으로 구축하십시오. 이것은 선택적 다듬기가 아니라 올바른 코드의 기본 형태입니다.

  • 무제한 금지. 모든 다이얼과 요청에 타임아웃(context.WithTimeout); 제한된 재시도; 제한된 큐. 무한 대기 없음.
  • 동시성 제한. 진행 중인 작업 제한: SOCKS MaxConnections, 포워드 SetMaxUDPSessions, http.Transport.MaxConnsPerHost/MaxIdleConnsPerHost, 자체 워커 풀. 기본값은 모두 무제한입니다 — 실제 제한을 설정하십시오.
  • 큰 전송은 청크, 검증, 재개. 큰 파일을 한 번에 옮기지 마십시오. 작은 청크로 나누고(예: HTTP Range), 각각 검증(크기/체크섬) 후 재개 가능하게 만들어 링크 끊김이 전체 전송이 아닌 하나의 청크 비용만 발생하도록 하십시오.
  • 백오프 + 지터, 멱등적으로 재시도. 작업 중간에 연결 끊김을 예상하십시오. 작업을 재개 가능/멱등적으로 만들고; 지터가 있는 지수 백오프; 시도 횟수 제한.
  • 페이로드 작게 유지. 잡담 많은 프로토콜과 폴링을 피하고; 압축하고; 간결한 인코딩을 사용하십시오. NodeInfo/시길을 16KB 제한보다 훨씬 작게 유지하십시오.
  • 링크에 맞게 버퍼 크기 조정. 패킷 버퍼에 node.MTU() 사용(사용자 공간 MTU는 동적이며, 최소 1280).
  • 강타하지 말고 저하시키기. 실패 시 백오프하고 부분 결과를 반환하십시오; 피어를 공격적으로 재시도하거나 메시를 플러딩하지 마십시오.

순진한 "net/http로 큰 파일 제공" 또는 "하나의 거대한 요청/응답"은 잘못된 형태입니다. 올바른 형태는 제한되고, 청크화되고, 재개 가능하며, 기본적으로 내결함성이 있는 것입니다. 제한된 메시 전송 패턴은 references/integrations.md를 참조하십시오.

진실의 원천

활성 모듈이 권위를 가집니다 — 메모리, 오래된 README 텍스트, 이 스킬이 아닙니다. 버전별 지침을 작성하기 전에 프로젝트가 실제로 의존하는 것을 검사하십시오:

go list -m github.com/voluminor/ratatoskr   # 선택된 버전
go doc github.com/voluminor/ratatoskr       # 컴파일된 루트 API
go doc github.com/voluminor/ratatoskr/mod/peermgr ConfigObj

선택된 버전의 실제 소스를 읽으려면 경로를 추측하는 대신 모듈 캐시에서 해결하십시오:

go list -m -f '{{.Dir}}' github.com/voluminor/ratatoskr

README 텍스트의 최소 Go 버전을 고정하지 마십시오 — go.mod 지시어보다 뒤쳐질 수 있습니다. 선택된 Ratatoskr 버전의 활성 go.mod를 읽으십시오.

기본 워크플로우

  1. 애플리케이션 형태를 식별하십시오: 임베디드 노드, HTTP 클라이언트/서버, 원시 TCP/UDP, SOCKS5, 포트 포워딩, 피어 관리, 또는 NodeInfo/시길.
  2. 애플리케이션에는 루트 패키지 github.com/voluminor/ratatoskr를 사용하십시오. mod/core는 core.Interface 계약을 통해서만 접근하십시오; 저수준 패키지가 진정으로 요구하지 않는 한 *core.Obj/UnsafeCore()를 피하십시오.
  3. context.Context를 소유하고, ratatoskr.ConfigObj.Ctx로 전달한 후 성공적인 시작 후에도 defer node.Close()를 하십시오. 둘 다 필요합니다.
  4. 피어를 정확히 한 곳에서 구성하십시오:
    • 정적 Yggdrasil 피어: cfg.Config.Peers
    • Ratatoskr 피어 관리자: ratatoskr.ConfigObj.Peers (cfg.Config.Peers는 비워 두십시오, 그렇지 않으면 New가 ErrPeersConflict를 반환).
  5. 아웃바운드 TCP/UDP에는 node.DialContext를, Yggdrasil 내부의 서비스에는 node.Listen / node.ListenPacket을 사용하십시오.
  6. URL과 호스트-포트 문자열에서 IPv6 주소를 대괄호로 감싸십시오: http://[200:abcd::1]:8080, 절대 http://200:abcd::1:8080이 아닙니다.
  7. 링크를 약한 것으로 취급하십시오: 모든 호출에 타임아웃을 설정하고, 동시성을 제한하며, 큰 전송은 청크/검증/재개하십시오(제한된 메시를 위한 설계 참조).
  8. 실제 프로젝트로 코드를 생성할 때는 빌드된다고 가정하지 말고 컴파일 검사 또는 집중 테스트를 추가하십시오.

모듈 범위 및 안정성

Yggdrasil 주소는 노드 키에서 파생되므로 네트워크 표면은 작고 안정적입니다. 라이브러리가 완성된 것으로 취급하는 부분을 선호하십시오; 나머지는 명시적으로 표시하고 그 위에 구축하지 마십시오.

패키지상태사용 방법
루트 ratatoskr안정, 기본 APINew, EnableSOCKS, Ask/AskAddr, Snapshot, Close
mod/core안정적인 계약노드에 임베드된 core.Interface 메서드
mod/peermgr안정ratatoskr.ConfigObj.Peers
mod/socks안정node.EnableSOCKS (직접 인스턴스화하지 마십시오)
mod/resolver안정EnableSOCKS에 의해 자동 생성됨; 직접 사용은 고급
mod/forward안정forward.New → Add* → Start
mod/sigils (+ info, services, public, inet)안정ratatoskr.ConfigObj.Sigils
mod/ninfo안정node.Ask / node.AskAddr
mod/probe고급 / 불안정 — UnsafeCore() 필요, API 변경 가능토폴로지/경로 추적이 명시적으로 필요한 경우에만
mod/settings작업 중 — 스키마 미확정피함; 대신 yggdrasil-go/src/config 직접 사용
cmd/*예제 앱, 가져올 수 있는 라이브러리 API 아님패턴으로 읽고, 절대 가져오지 마십시오

루트 vs 서브모듈: 기본적으로 ratatoskr.New 사용(코어 + SOCKS + 피어 관리자 + ninfo + 시길을 하나의 Close로). 가장 작은 표면(원시 다이얼/리슨)만 필요할 경우 core.New를 통해 mod/core로 내려가거나, 사용자 정의 전송 및 테스트를 위해 core.Interface 주변에 서브모듈을 구성하십시오. 모든 서브모듈(peermgr/socks/forward/resolver/ninfo)은 core.Interface를 받습니다. references/overview.md 참조.

시스템 시길 — 여기에 먼저 게시

NodeInfo는 노드가 네트워크에 자신을 설명하는 방법입니다. 네 가지 내장("시스템") 시길은 모든 노드에 의해 자동으로 파싱되므로, 여기에 넣은 데이터는 다른 참가자가 인식합니다. 사용자 정의 시길을 만들기 전에 이것들을 먼저 사용하십시오; ratatoskr.ConfigObj.Sigils를 통해 전달하십시오. 각각을 아주 작게 유지하십시오 — 하나의 16KB NodeInfo 예산을 공유합니다.

시길여기에 속하는 내용사용 이유
info노드 ID: 이름, 유형, 위치, 연락처, 설명다른 노드가 당신의 노드가 누구/무엇인지 알게 함.
servicesYggdrasil 내에서 노출하는 포트, name → port포트 스캔 없이 서비스 검색 가능.
public네트워크별 그룹화된 공개 피어링 URI다른 노드가 직접 피어링할 수 있게 함.
inet실제 주소(도메인/IP)Yggdrasil 노드를 클리어넷 ID에 매핑.

검색 가능하고 표준적인 데이터를 여기에 넣어 전체 네트워크가 읽을 수 있게 하십시오. 네 가지 중 어떤 것도 포함하지 않는 데이터에 대해서만 사용자 정의 시길을 정의하십시오 — 그리고 당신의 코드를 실행하는 피어만이 그것을 파싱할 것임을 기억하십시오. 생성자는 검증하고 오류를 반환합니다; ratatoskr.New 전에 처리하십시오. 세부 사항, 정확한 제한, 타입화된 접근, 사용자 정의 시길 작성: references/nodeinfo-sigils.md 및 references/custom-sigils.md.

참조 맵

현재 작업에 필요한 파일만 읽으십시오:

흔한 실수

실수수정
임베디드 앱에 외부 Yggdrasil 데몬을 시작함ratatoskr.New를 사용하십시오; 사용자 공간 gVisor netstack을 실행합니다.
라이브러리 통합에 yggstack을 권장함yggstack은 최종 사용자 바이너리입니다. Go API 제어에는 Ratatoskr를 사용하십시오.
cfg.Config.Peers와 ConfigObj.Peers를 모두 설정함정적 피어 또는 피어 관리자 중 하나를 선택하십시오; 둘 다 사용하면 → ErrPeersConflict.
Ctx를 전달하면서 Close를 건너뜀 (또는 반대)둘 다 하십시오: 취소는 종료를 트리거하고, Close는 리소스를 해제합니다.
IPv6 대괄호 없이 URL을 구축함fmt.Sprintf("http://[%s]:%d", ip, port)를 사용하십시오.
기본 쿼리에 ninfo.New를 생성함node.Ask / node.AskAddr를 사용하십시오; 루트 객체가 이미 ninfo를 구축합니다.
런타임에 동적으로 시길을 조립하거나 등록함시길은 코드에서만 조립됩니다; 중복되거나 키를 덮어쓰는 것은 설계상 조용한 병합이 아닌 하드 오류입니다. ConfigObj.Sigils를 통해 게시하십시오; res.Node.Extra에서 자체 키를 읽으십시오.
기본적으로 UnsafeCore() / mod/probe / mod/settings를 사용함루트 API에 머무르십시오; 이것들은 고급 또는 작업 중입니다.
README에서 Go 버전을 하드코딩함선택된 모듈 버전의 활성 go.mod를 읽으십시오.

검증

SKILL.md를 탐색 계층으로 유지하고 세부 API 내용은 references/에 넣으십시오. 게시 전에 evals/evals.json의 시나리오에 대해 변경 사항을 전향 테스트하십시오.

관련 스킬