{"id":50361200,"url":"https://github.com/nning/ferronacc","last_synced_at":"2026-05-30T01:30:44.088Z","repository":{"id":359193318,"uuid":"1239039214","full_name":"nning/ferronacc","owner":"nning","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-20T20:07:03.000Z","size":355,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-21T01:00:00.864Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nning.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-14T17:44:55.000Z","updated_at":"2026-05-20T20:07:08.000Z","dependencies_parsed_at":"2026-05-21T01:00:15.470Z","dependency_job_id":null,"html_url":"https://github.com/nning/ferronacc","commit_stats":null,"previous_names":["nning/ferronacc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nning/ferronacc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nning%2Fferronacc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nning%2Fferronacc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nning%2Fferronacc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nning%2Fferronacc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nning","download_url":"https://codeload.github.com/nning/ferronacc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nning%2Fferronacc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33677258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T01:30:43.108Z","updated_at":"2026-05-30T01:30:44.078Z","avatar_url":"https://github.com/nning.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ferronacc\n\n\u003e ⚠️ **Vibe-coded proof of concept — use at your own risk.**\n\u003e This project was built with AI assistance as an experimental prototype.\n\u003e It has not been audited for production use. Do not rely on it as your\n\u003e sole security control.\n\nOn-access antivirus scanner for Linux. Intercepts file opens at the kernel\nlevel and scans with [ClamAV](https://www.clamav.net/) before allowing access.\n\n## Primary use case: scanning Windows programs before Wine/Bottles runs them\n\nIf you download Windows executables and run them with\n[Wine](https://www.winehq.org/) or [Bottles](https://usebottles.com/),\nthose programs are opened as ordinary Linux files before Wine interprets them.\nferronacc intercepts that `open()` call and scans the `.exe` / `.dll` / `.msi`\nwith ClamAV's Windows PE scanner before Wine is allowed to read a single byte.\n\n**What this protects against:**\n- Malicious `.exe` files in `~/Downloads/` before you run them in Wine\n- Infected `.dll` files silently loaded by a Windows program inside a Bottles prefix\n- `.msi` installers that drop malware into the Wine prefix at install time\n- Any file in `~/.wine/` or `~/.local/share/bottles/` that gets written and\n  then opened (e.g., by a Windows dropper)\n\n**Why ClamAV is right for this job:**\nClamAV has deep Windows PE support: PE header parsing, executable unpacking\n(UPX, ASPack, FSG, …), MSI/CAB archive extraction, and a large Windows malware\nsignature database maintained by Cisco Talos. It is the same engine you would\nuse to scan a Windows machine remotely.\n\n**Example config for Wine/Bottles use (add to `/etc/ferronacc.toml`):**\n```toml\n[paths]\ninclude = [\n    \"/home/YOUR_USER/Downloads\",\n    \"/home/YOUR_USER/.wine\",\n    \"/home/YOUR_USER/.local/share/bottles\",\n    \"/tmp\",\n]\nexclude_uid = []   # scan all UIDs, including your own\n```\n\n---\n\n## How it works\n\n```\nwine foo.exe\n     │\n     ▼  (open syscall for foo.exe)\nfanotify FAN_OPEN_PERM ──────────────────► ferronacc daemon\n                                               │\n                              cache hit:       │\n                              CLEAN ───────────┤──► FAN_ALLOW (instant)\n                              DIRTY ───────────┤──► FAN_DENY  (instant)\n                                               │\n                              cache miss:      │\n                              cl_scandesc(fd)──┤  (in-process, no socket)\n                              CLEAN ◄──────────┤──► FAN_ALLOW + update cache\n                              DIRTY ◄──────────┘──► FAN_DENY  + log denial\n```\n\nAfter the first scan of any file, subsequent opens are served from the LRU\ncache — zero additional overhead. The cache key is `(fsid, inode, size,\nmtime_ns, db_version)`, so a modified file is automatically re-scanned.\n\n---\n\n## Why not clamonacc?\n\nThe existing ClamAV `clamonacc` daemon works but has fundamental limitations:\n\n| | clamonacc | ferronacc |\n|---|---|---|\n| Scan caching | ✗ (rescans every access) | ✓ LRU cache keyed by inode+mtime |\n| File identity | pathname (broken by renames) | `(fsid, inode)` via `FAN_REPORT_FID` |\n| Scan transport | clamd socket (per-scan connect) | in-process `cl_scandesc(fd)` |\n| Parallelism | global mutex | thread pool, `Arc\u003cEngine\u003e` |\n| Directory watching | inotify DDD (8 k limit) | `FAN_MARK_FILESYSTEM` (one mark) |\n| eBPF in-kernel fast path | ✗ | ✓ Phase 2 |\n\n## Status\n\n| Phase | Description | Status |\n|-------|-------------|--------|\n| Phase 1 | fanotify + libclamav + LRU cache + CLI + GNOME notifier | ✅ Complete and validated |\n| Phase 2 | eBPF LSM in-kernel cache fast-path | 🔴 not started |\n\nPhase 1 has been fully validated: unit tests (stub engine), integration tests with real\n`libclamav` + fanotify, and end-to-end EICAR blocking all pass. See\n[`doc/architecture.md`](doc/architecture.md) for the work package execution plan.\n\n## Requirements\n\n- **Linux 5.9+** (Fedora 35+, RHEL 9, Ubuntu 22.04, Debian 12)\n- **ClamAV 1.4+** installed: `sudo dnf install clamav clamav-devel`\n- Rust stable toolchain\n- `CAP_SYS_ADMIN` or `CAP_DAC_READ_SEARCH` at runtime (fanotify)\n- `CAP_BPF` + `CAP_PERFMON` (Phase 2 only)\n\n## Installation on Fedora\n\n### Prerequisites\n\n```bash\nsudo dnf install clamav clamav-devel clamav-freshclam rpm-build clang-devel\n```\n\n`clamav-devel` is needed to build the ClamAV FFI bindings at compile time.\n`clang-devel` is needed by `bindgen` (generates Rust FFI from `clamav.h`).\n\n### Build and install the RPM\n\n```bash\n# Build\njust rpm\n\n# Install\nsudo rpm -ivh packaging/rpmbuild/RPMS/x86_64/ferronacc-0.1.0-1.fc44.x86_64.rpm\n```\n\nThe RPM installs:\n\n| Path | Contents |\n|------|----------|\n| `/usr/bin/ferronacc` | Daemon binary |\n| `/usr/bin/ferronacc-ctl` | CLI control tool |\n| `/usr/bin/ferronacc-notify` | GNOME desktop notifier |\n| `/etc/ferronacc/ferronacc.toml` | Config file (`%config noreplace`) |\n| `/usr/lib/systemd/system/ferronacc.service` | System service unit |\n| `/usr/lib/systemd/user/ferronacc-notify.service` | User service unit |\n| `/var/lib/ferronacc/` | State directory (`root:ferronacc 0750`) |\n\n### Post-install setup\n\n```bash\n# 1. Edit config (watched paths, cache size, etc.)\nsudoedit /etc/ferronacc/ferronacc.toml\n\n# 2. Start and enable the daemon\nsudo systemctl enable --now ferronacc\n\n# 3. Add your user to the ferronacc group (required for GNOME notifier)\nsudo usermod -aG ferronacc $USER\n# Log out and back in for the group change to take effect.\n\n# 4. Enable the GNOME notifier (per-user, runs in your desktop session)\nsystemctl --user enable --now ferronacc-notify\n```\n\n### Verify it works\n\n```bash\n# Check daemon status and ClamAV DB version\nferronacc-ctl status\n\n# Try to open the EICAR test file (should return EACCES)\ncurl -s https://secure.eicar.org/eicar.com -o /tmp/eicar.com\ncat /tmp/eicar.com   # → cat: /tmp/eicar.com: Permission denied\n\n# Allow a trusted file version (survives DB updates until the file changes)\nferronacc-ctl allow /absolute/path/to/file\n\n# List blocked files\nferronacc-ctl list-denials\n```\n\n## Configuration\n\nConfiguration is a single TOML file (default `/etc/ferronacc.toml`).\nKey sections:\n\n```toml\n[paths]\ninclude = [\"/home\", \"/tmp\", \"/var/www\"]\nexclude = [\"/home/user/.cache\"]\n\n[fanotify]\nprevention = true        # blocking mode; false = log-only (no FAN_DENY)\n\n[scanner]\nmax_threads = 8\n\n[cache]\nsize = 65536             # LRU entry count\nttl_seconds = 300\n\n[denial_log]\ndb_path = \"/var/lib/ferronacc/denials.db\"\nmax_entries = 10000      # rotate beyond this\n```\n\nSee `config/ferronacc.toml` for all options.\n\n## Viewing denials\n\n### CLI (server or desktop)\n\n```bash\n# List recent denials\nferronacc-ctl list-denials\n\n# Filter by last 24 hours\nferronacc-ctl list-denials --since 24h\n\n# Show daemon status (uptime, DB version, cache hit rate)\nferronacc-ctl status\n\n# Trust or revoke a specific file version\nferronacc-ctl allow /absolute/path/to/file\nferronacc-ctl unallow /absolute/path/to/file\nferronacc-ctl list-allowed\n\n# Trigger engine reload (also automatic on freshclam DB update)\nferronacc-ctl reload\n```\n\n### GNOME desktop (Fedora)\n\nThe user-session notifier is enabled as part of the post-install setup above\n(see [Installation on Fedora](#installation-on-fedora)). Your user must be a\nmember of the `ferronacc` group so it can read `denials.db`.\n\n```bash\n# Check group membership\ngroups $USER   # should include 'ferronacc'\n\n# Re-enable if needed\nsystemctl --user enable --now ferronacc-notify\n```\n\nWhen a file is blocked, a GNOME notification appears:\n\u003e **ferronacc blocked a file**\n\u003e `Eicar-Test-Signature` in `/tmp/test.exe` (accessed by `bash`, PID 1234)\n\nClicking the notification opens `ferronacc-ctl list-denials` in a terminal.\n\n## Denial policy\n\nAccess is **denied** (the calling process receives `EACCES`). Files are **not\nquarantined or deleted** — they remain on disk so that false positives don't\ncause data loss and the admin can inspect them.\n\nTo investigate a blocked file manually:\n```bash\n# Rescan with verbose output\nclamscan --debug /path/to/file\n\n# After confirming: delete or move to safe location\nsudo rm /path/to/file\n```\n\n## Architecture and design docs\n\n| Document | Contents |\n|----------|----------|\n| [`doc/architecture.md`](doc/architecture.md) | 3-layer architecture (eBPF LSM + fanotify + userspace daemon), adaptive scanner design, denial management, Rust crate layout, libclamav FFI surface, and the AI-agent execution plan with work packages and handoff rules |\n| [`doc/security-enhancements.md`](doc/security-enhancements.md) | Beyond signatures: YARA rules, SaneSecurity, PE entropy, Authenticode, CIRCL HASHLOOKUP, VirusTotal — enrichment pipeline design |\n| [`doc/quality.md`](doc/quality.md) | Code quality standards, test pyramid, coverage targets, CI pipeline, security-critical path requirements |\n| [`doc/testing.md`](doc/testing.md) | VM test setup (Vagrant + KVM), `just` task runner, integration and e2e test instructions |\n| [`doc/dev-setup.md`](doc/dev-setup.md) | Full development setup: host deps, Rust toolchain, VS Code config, debugging, Wine/Bottles testing walkthrough |\n\n## License\n\nTBD\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnning%2Fferronacc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnning%2Fferronacc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnning%2Fferronacc/lists"}