SunLionet is an offline-first, bundle-based privacy and resilient communication system designed for high-risk, restricted networks.
It ships as:
- SunLionet Inside: runs on end-user devices and keeps connectivity alive by detecting interference and rotating local sing-box configurations.
- SunLionet Outside: runs by supporters to generate, validate, and distribute signed/encrypted seed bundles to Inside users (via trusted channels such as Signal).
- SunLionet App: the Android wrapper for SunLionet Inside (VPN integration + configuration import UI).
- SunLionet Dashboard: the web UI for local operator visibility (including localhost-only runtime status).
Migration note: this repository is still named SUNLIONET-agent during the transition. Some paths, package imports, release artifacts, and protocol identifiers may still use legacy SUNLIONET-* naming until the release pipeline is fully renamed.
Documentation site (GitHub Pages): https://kaveh8866.github.io/Sunlionet/
Persian: see README.fa.md.
Start here: docs/getting-started.md.
It covers the three first-time paths:
- Linux: Download → Verify → Install → Import bundle → Connect
- Android: Install APK → Import bundle → Connect → Monitor
- Web: Open SunLionet Dashboard → Detect local runtime → Show status
Prerequisites:
- Go 1.25+
- Windows: PowerShell 7+
Run tests:
-
Windows:
.\scripts\run_tests.ps1
-
Linux/macOS:
./scripts/run_tests.sh
Prerequisites:
- Go 1.25+
- Optional:
sing-boxinstalled, or pass--sing-box-bin
Run the Linux MVP path (import -> select -> render -> execute):
go run ./cmd/inside \
--state-dir ./.tmp/state \
--import ./testdata/sample.bundle \
--master-key 0123456789abcdef0123456789abcdef \
--trusted-signer-pub-b64url "$(cat ./testdata/sample_signer_pub.b64url)" \
--age-identity "$(cat ./testdata/sample_age_identity.txt)"Render only (no process launch):
go run ./cmd/inside \
--state-dir ./.tmp/state \
--import ./testdata/sample.bundle \
--master-key 0123456789abcdef0123456789abcdef \
--trusted-signer-pub-b64url "$(cat ./testdata/sample_signer_pub.b64url)" \
--age-identity "$(cat ./testdata/sample_age_identity.txt)" \
--render-onlySunLionet is designed for long-term resilience and community-driven maintenance.
- Governance Model: How decisions are made and who manages the project.
- Contribution Guide: How to get involved safely and effectively.
- Security Policy: How we handle vulnerabilities and security updates.
- Sustainability Plan: Our model for long-term maintenance.
- Version 1.0 Readiness: Our current assessment of the project's maturity.
This repository produces two binaries using Go build tags.
go build -tags inside -ldflags="-s -w" -o bin/sunlionet-inside ./cmd/inside/./bin/sunlionet-insidego build -tags outside -ldflags="-s -w" -o bin/sunlionet-outside ./cmd/outside/./bin/sunlionet-outsideSunLionet intentionally avoids a central fetch API. Seed configs arrive via:
- Signal disappearing messages: signed/encrypted
snb://v2:bundles. - QR codes (in-person bootstrap).
- Local Bluetooth mesh (Inside ↔ Inside) for blackout scenarios.
Bundle parsing/validation lives in pkg/importctl and pkg/bundle.
Inside devices can be seized. Design goals:
- Seed profiles stored encrypted at rest via store.go.
- Config bundles authenticated with Ed25519 signatures via import.go.
- Default is receive-only from Inside (no outbound telemetry).
For the detailed threat model and dual-agent design, see /docs.
- Core Modules Architecture (Detector, Policy Engine, Secure Store)
- Production Map (What Ships)
- Website & Docs Specification
- Architecture Details
- Security Boundaries
- Security Audit Checklist
- Release Blockers
- Bundle Format
- Signal Integration
- Installation Guide (English)
- Linux MVP Install + Run
- Linux Smoke Test
- راهنمای نصب (Persian)
- Pi Orchestrator Integration (Local)
Generate keys:
go run -tags outside ./cmd/outside keygen \
--ed25519-priv ./keys/outside.ed25519 \
--ed25519-pub ./keys/outside.ed25519.pub \
--age-identity ./keys/inside.agekey \
--age-recipient ./keys/inside.agepubGenerate a bundle:
go run -tags outside ./cmd/outside \
--profiles ./profiles.json \
--templates-dir ./templates \
--signing-key ./keys/outside.ed25519 \
--recipient-pub ./keys/inside.agepub \
--out ./distVerify a bundle:
go run -tags outside ./cmd/outside verify \
--bundle ./dist/bundle.snb.json \
--signer-pub ./keys/outside.ed25519.pub \
--age-identity ./keys/inside.agekey \
--require-decryptVerify directly from URI text:
go run -tags outside ./cmd/outside verify \
--uri-file ./dist/bundle.uri.txt \
--signer-pub ./keys/outside.ed25519.pub \
--age-identity ./keys/inside.agekey \
--require-decryptDistribution helpers:
./dist/manifest.jsonis machine-readable (includes bundle SHA-256 and URI size hints)./dist/qr_payload.txtis written only if the URI is small enough (--qr-threshold-chars)./dist/bundle.chunks.txtis written only if the URI exceeds--chunk-threshold-chars(SNBCHUNK/1 lines)
See:
- “missing --signing-key”: provide
--signing-key(Ed25519 seed base64url) or runkeygen. - “refusing to generate unencrypted bundle…”: pass
--allow-plaintextor set--recipient-pubfor encryption. - “missing outbound template…”: ensure
--templates-dirpoints at./templatesand your profiles’template_refmatches an existing*.jsontemplate. - “SECURITY ALERT: signature verification…” (Inside import): you’re using the wrong trusted signer pub key, or the bundle/URI was corrupted.
- “note: header verified; payload not decrypted…” (Outside verify): provide
--age-identity, and use--require-decryptin CI to fail closed.
See CONTRIBUTING.md.
