Skip to content
 
 

Latest commit

 

History

1,024 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ReCasaOS

ReCasaOS CI CodeQL License Issues

ReCasaOS is a community continuation fork of IceWhaleTech/CasaOS. Its purpose is to keep the CasaOS ecosystem maintainable by fixing security defects, reliability bugs, dependency drift, unsafe release automation, and deployment gaps while preserving compatibility where that does not weaken the security boundary.

Current status

v0.5.2 is released at EdmundFu-233/ReCasaOS v0.5.2. All six required components are locked in release/components.lock.json with immutable source revisions, artifact digests, licenses, API/schema versions, and passed compatibility evidence:

Component Source
Root service this repository
UserService EdmundFu-233/ReCasaOS-UserService
Gateway EdmundFu-233/ReCasaOS-Gateway
Administrative UI EdmundFu-233/ReCasaOS-UI
AppManagement EdmundFu-233/ReCasaOS-AppManagement
Message Bus EdmundFu-233/ReCasaOS-MessageBus
Installer EdmundFu-233/ReCasaOS-Installer

The GitHub release carries musl-static Linux binaries (amd64, arm64, arm-7, riscv64) plus the migration tool, a checksums.txt GPG-signed with the ReCasaOS release key (fingerprint 65A1BD27 2E10 6BF7 983B 3D13 D3F5 9DC3 10EE 3539; public key in release/recasaos-release.pub), and a SLSA provenance attestation bound to the release tag and workflow. Verify before installing:

gpg --import release/recasaos-release.pub
gpg --verify checksums.txt.asc checksums.txt
sha256sum -c checksums.txt
gh attestation verify checksums.txt --repo EdmundFu-233/ReCasaOS

Install only through the offline installer, which verifies every artifact SHA-256 against its bundle manifest before writing anything and never uses the network:

./install.sh --bundle <dir> [--prefix /]

Do not use get.casaos.io install or update scripts. Those scripts are controlled by the upstream CasaOS project and do not install the fixes in this fork.

v0.5.2 extends the v0.5.0 hardening: root casaos.conf persistence and Samba configuration publishes now use the descriptor-pinned atomic replacement, the Samba compare-and-swap publisher resolves every staging, read, exchange, rollback, quarantine, and cleanup operation against one pinned config-directory descriptor, and each v2 resumable upload session holds its staging directory descriptor across chunk writes, assembly, and the final target commit instead of re-resolving the staging path per call. The v0.5.1 version was tagged during preparation, but its draft release was withdrawn before publication: no v0.5.1 release exists.

Post-release hardening on main extends the same boundary: the v1 upload registry also pins its staging directory and parent per session, and both registries now prove that the staging name still identifies the pinned directory inode, quarantine it under an unpredictable name, and refuse to recursively delete a name that no longer matches.

The full administrative dashboard is still not ready for unrestricted Internet exposure. Keep it on a private management network or mesh VPN, even at v0.5.2: post-release hardening continues on main (tracked in Issues), and an independent penetration test has not been performed.

The first hardening milestone includes:

  • default-off loopback authentication bypass and exact-origin CORS/WebSocket checks;
  • access/refresh JWT issuer separation and protected debug routes;
  • bounded, traversal-resistant multipart uploads and safer streaming downloads;
  • an opt-in, read-only /public-files portal confined with Linux openat2, served by a separate non-root, systemd-activated process with an isolated network and root filesystem, with share filesystem work delegated to bounded disposable workers, and authenticated by a header-only bearer whose server-side configuration contains only a versioned SHA-256 verifier;
  • bounded root file/SSH WebSockets, verified local SSH host keys, one-use SSH login tickets, and removal of an SSH infinite retry path;
  • capability-bound outbound fetches with exact endpoint allowlists and DNS/redirect/IP revalidation;
  • fail-closed cloud OAuth recovery until one-time state and PKCE are available;
  • maintained archive/OpenAPI implementations and upgraded vulnerable dependencies;
  • secret-safe request/OAuth logging, restrictive file permissions, CodeQL, Dependabot, reachable-vulnerability CI, and a default-branch-controlled exact-SHA promotion path for trusted-only privileged tests;
  • reviewed Caddy/Nginx edge examples, a threat model, and explicit component release gates.

See the threat model for the remaining blockers and the component lock policy for the full-stack boundary.

Contribution CI trust boundary

GitHub-hosted runners provide passwordless sudo; the normal fork-PR workflow is therefore not a sandbox for arbitrary contributor code. ReCasaOS does not give fork or Dependabot code a write token or repository secrets. Trusted-only filesystem tests for those PRs must be promoted by a maintainer from the default branch, using the PR's complete immutable head SHA. The workflow pins that object to a one-time same-repository ref, proves the commit and tree before testing, runs with read-only contents permission and no persisted checkout credential or shared cache, then revalidates the still-current PR head before publishing ReCasaOS / trusted privileged exact-SHA on that SHA.

See the trusted privileged CI runbook for the review, dispatch, verification, branch-protection, and rollback gates. Issue #27 remains open until the workflow is validated from main, the exact status provider is required by branch protection, and both stale-head and external-PR behavior are recorded. A skipped job is not privileged-test evidence.

Public access

The full administrative dashboard is not ready for unrestricted Internet exposure. Keep it on a private management network or mesh VPN. ReCasaOS now has a separate read-only public file binary. A systemd socket owns the dedicated literal-loopback listener (default 127.0.0.1:39777) and passes it to a non-root service whose network and filesystem views are isolated from the privileged CasaOS daemon. The socket is not automatically enabled. The examples in the public-access guide proxy only that listener and positive route allowlist. Gateway's /public-files registration is an intentional 404 tombstone for stale-route cleanup and is never the portal upstream.

A particular host is not public-ready until the guide's deployment, restore, scanning, and independent-review gates pass. The standalone coordinator now keeps share open, classification, list, and read syscalls in same-binary disposable workers. It admits at most eight active workers, applies fixed IPC deadlines, kills timed-out children through pidfds, and stops admitting work when killed children cannot be reaped. A non-ESRCH pidfd signaling failure closes all further worker admission and retains that slot until the child is reaped. The packaged service reports readiness only after bootstrap succeeds and the HTTP server enters its accept loop. Issue #25 remains open until exact-head Linux CI and real hung-storage/D-state tests prove those bounds on the supported deployment stack. The declared systemd 247 floor is qualified only for commits whose dedicated Debian 11/systemd 247 PID-1 VM job passes; the Ubuntu 24.04/systemd 255 integration job is not evidence for that floor. That hosted job runs the normal production build for activation, sandbox and API smoke checks. Only its deterministic worker-capacity and coordinator-cleanup phases swap in a non-release, CI-tagged binary whose exact synthetic fixture worker stops itself after one successful read. This proves admission, pidfd cancellation and control-group cleanup mechanics; it is not byte-identical release evidence and does not simulate uninterruptible storage.

The portal's large-file browser stream is still a candidate tracked in Issue #20. Its client does not intentionally persist the bearer in browser storage or a URL. During an authorized request the bearer necessarily passes through page, Worker, Authorization-header, edge, and server request memory. Stable Chromium/Firefox/WebKit HTTPS storage, log, crash, download, memory, transparent retry/resume, cancellation, and filename tests remain release gates; stable initial-Range behavior is also not yet a release claim. The repository's browser smoke job is deliberately narrower: it runs the bundled Playwright Chromium, Firefox, and WebKit engines on Ubuntu 24.04 against the real portal handler over loopback HTTPS, using an ephemeral CA installed into that disposable runner's trust stores. It does not disable TLS verification, record traces/HAR/video, receive production credentials, or run the production systemd service. Passing that job is useful frontend protocol evidence. It also makes one explicit initial byte-range request per bundled engine and checks the authenticated upstream counter and 206 response, but that is not stable Chrome/Firefox/Safari, proxy, target-host, transparent retry/resume, or Internet-readiness evidence and does not close Issue #20. Its cancel smoke has a deliberately narrower meaning: all three engines must report the local download as canceled to Playwright, and exactly one authorized upstream request must reach a terminal state within the 40-second test-harness deadline. Chromium and WebKit must classify that request as canceled; Firefox may classify it as canceled or completed. That Firefox outcome is consistent with Mozilla's open Bug 1825388, in which response-body cancellation is not propagated to a Service Worker, but the native-download path exercised here is not identical. It proves that the test fixture does not retain an active slot; it does not prove Firefox cancel propagation or satisfy Issue #20's release gate. The same bundled-engine matrix now also requires an already consumed navigation proof to fail replay without another authorization challenge or upstream request, and requires forgetting the page token to abort an already handed, still-active upstream stream. These are repository CI checks, not evidence of retail-browser, reverse-proxy, token-rotation, or target-host readiness.

The portal also verifies the already-pinned root descriptor's Linux mount ID and filesystem type before it becomes available. Only ext2/3/4, XFS, Btrfs, tmpfs, and F2FS are allowlisted; FUSE, network filesystems, overlayfs, ZFS, and unknown or unverified types fail startup. There is no unrestricted fallback. This keeps unsupported roots out of the isolated service's download-slot boundary; it does not certify the health or locality of an allowlisted filesystem's block device. Issue #22 remains open until the compatibility and blocking-I/O boundary is independently verified. The worker protocol limits coordinator exposure, but SIGKILL cannot complete a kernel syscall already stuck in uninterruptible sleep. Admission quarantine and the service cgroup provide finite containment; hostile-storage evidence remains tracked in Issue #25.

The supported credential candidate is verifier-only. Generate the 47-character rc1_ bearer from 32 random bytes on an independent administrator workstation, keep its durable copy only in a password manager, and provision only the strict versioned SHA-256 verifier as host credential material. Authorized HTTPS requests still carry the bearer transiently to the edge and portal process. The standalone service receives the verifier through systemd LoadCredential= and a strict CLI path; it has no environment-variable configuration fallback. Every non-empty legacy RECASAOS_PUBLIC_FILE_* setting fails startup so an old root-daemon drop-in cannot silently influence the new boundary. Verifier format, bind-alias, rotation, and rollback hardening was completed and reviewed in Issue #26.

Never expose Samba, SSH, daemon ports, debug/API documentation, setup routes, privileged v1/v2/v3 APIs, the dedicated portal listener, or root/Gateway listeners directly. Keep the management Gateway on a firewalled private/VPN address and non-public port; public 80/443 belong only to the route-allowlisted TLS edge. Never enable RECASAOS_TRUST_LOOPBACK_AUTH_BYPASS=1 behind a reverse proxy. The Nginx example includes rate and connection limits; a public stock Caddy deployment needs a separately reviewed rate-limiting edge/WAF in front.

Privileged management file roots

The private administrative file APIs fail closed outside the roots in RECASAOS_MANAGEMENT_FILE_ROOTS. The value is a comma-separated list of canonical absolute directories; when unset it defaults to /DATA,/mnt,/media. Every configured root must already exist, / is forbidden, and ReCasaOS pins the roots at startup before it registers file routes. Changing the setting or replacing a configured mount requires a service restart.

This boundary requires Linux 5.8 or newer for openat2 and mount-ID checks, plus the unified cgroup v2 hierarchy with effective memory and pids controllers for the worker task, memory, and no-swap limits. The service and socket fail their conditions before activation when those cgroup v2 files are unavailable. Before loading the verifier, the standalone service also proves its exact system.slice membership and validates three individually bound, read-only cgroup2 files for the effective 512 MiB memory, zero-swap, and 256-task limits. Reads and writes may cross operator-configured mounts below /mnt or /media for CasaOS storage compatibility, but recursive deletion refuses to cross a mount boundary. Treat the host mount namespace and CAP_SYS_ADMIN as trusted operator controls. Keep the administrative API private/VPN-only even when its paths are confined; RECASAOS_MANAGEMENT_FILE_ROOTS is not a public sharing configuration and is separate from the isolated portal share at /srv/recasaos-public.

Retained .recasaos-transfer-* directories are recovery evidence, not ordinary temporary files. The managed transfer inventory guide documents the authenticated, read-only inspection endpoint and its intentionally non-destructive operator workflow. It does not provide or authorize cleanup.

Development

ReCasaOS supports the service runtime only on a conventional Linux appliance; Android is not a supported target. Native Darwin builds are a contributor validation target, not a supported runtime. The root binary on unsupported platforms exits immediately instead of starting a partially functional service. The Go toolchain and generator versions are locked in go.mod; the remote Message Bus OpenAPI input is locked to an immutable commit.

Run the complete build and test suite on Linux:

go generate ./...
go test ./...
go vet ./...
govulncheck ./...

On Darwin, compile all native packages and tests without executing the Linux-oriented test suite, then run native vet:

go test -exec=true ./...
go vet ./...

The macOS GitHub Actions job repeats these checks and verifies that the root binary rejects unsupported runtime use with a clear, nonzero exit. To validate the complete Linux package graph from any non-Linux development host, use:

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -exec=true ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go vet ./...

-exec=true verifies compilation but does not execute the test binaries. GitHub Actions executes the full suite on Ubuntu with the patched Go version recorded in the workflow.

Contributing and security

Use ReCasaOS issues for bugs, compatibility work, and scoped roadmap items. Keep one security or reliability problem per commit where practical and include a regression test.

Report vulnerabilities privately through the repository Security tab as described in SECURITY.md. Do not put exploits, credentials, private host details, or personal data in a public issue.

Provenance and license

ReCasaOS preserves the upstream module path and binary/service names for compatibility while the component migration is staged. This does not imply endorsement by or affiliation with IceWhaleTech.

CasaOS was created by IceWhaleTech and its contributors. Their history remains in this Git repository, and upstream fixes should retain commit provenance. ReCasaOS is distributed under the repository's Apache-2.0 license.

About

ReCasaOS: a security-first community continuation of CasaOS

Topics

Resources

Code of conduct

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages