Skip to content

victortrac/narc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NARC

Network and Access Runtime Control

narc.mp4

NARC is an eBPF-powered Linux security daemon that catches supply-chain attacks before they exfiltrate your secrets. It watches sensitive files (SSH keys, cloud creds, .env, kubeconfig, wallet data), taints any process that reads them, and blocks suspicious network egress from tainted processes — all locally, with no cloud dependency.

                              ┌─────────────────────────────────┐
                              │         YOUR WORKSTATION        │
                              │                                 │
  ~/.ssh/id_ed25519  ─┐       │  ┌───────────┐                  │
  ~/.aws/credentials ─┼──▶ NARC │ WATCHLIST │                  │
  .env ───────────────┘   (eBPF) │ file_open │                  │
                              │  └─────┬─────┘                  │
                              │        │ read detected          │
                              │        ▼                        │
                              │  ┌───────────┐                  │
                              │  │  TAINTED  │                  │
                              │  │  PROCESS  │ ◀─── npm install│
                              │  └──┬────┬───┘      (malicious  │
                              │     │    │          dependency) │
                              │     │    │                      │
                              │     ▼    ▼                      │
                              │  fork() connect()               │
                              │     │    │                      │
                              │     ▼    ▼                      │
                              │  ┌───────────┐  ┌────────────┐  │
                              │  │  CHILD IS │  │   RULES    │  │
                              │  │  ALSO     │  │            │  │
                              │  │  TAINTED  │  │ ✓ allow    │──┼──▶ api.github.com
                              │  │ (implicit)│  │ ✗ deny     │──┼──✗ evil.example.com
                              │  └───────────┘  │ ? prompt   │  │
                              │                 └────────────┘  │
                              └─────────────────────────────────┘

Why This Matters

A compromised npm package or pip dependency reads your ~/.aws/credentials and curls it to an attacker's server. This has happened — axios via plain-crypto-js, litellm via PyPI — and traditional tools miss it because the read and the exfiltration happen in separate steps.

NARC connects those steps. It taints the process on read, follows forks and derived files, and intercepts the outbound connection. You get a prompt before anything leaves your machine.

What It Does

Narc lets you define a watchlist for:

  • files: examples: ~/.aws/config, ~/**/wallet.dat
  • network hostnames: example: api.openai.com:443
  • executables: example: /usr/bin/curl

Any time a file, network hostname, or executable in your watchlist is read, requested, or run, Narc logs the event in the audit history. You can one-click create policies around these events to block requests or edit the ~/.config/narc/watchlist.yaml` directly.

Example ~/.config/narc/watchlist.yaml: id is an optional field that narc will auto-generate if omitted. ids need to be globally unique

files:
    # watch access to anything in ~/.ssh
    - id: db6043af
      path: ~/.ssh/

    # deny reads from any executable to ~/.aws/credentials
    - id: 008ccf64
      path: ~/.aws/credentials
      rules:
        - id: 1
          executable: '*'
          decision: deny
          enabled: true

    # deny by default access to ~/.config/gcloud but allow the gcloud python CLI access
    - id: 3da7a644
      path: /home/victor/.config/gcloud/*
      rules:
        - id: 2
          executable: *
          decision: deny
        - id: 3
          executable: /home/victor/bin/google-cloud-sdk/platform/bundledpythonunix/bin/python3
          decision: allow

network:
    # block curl from making requests to github.com
    - id: 308981da
      destination: github.com:443
      rules:
        - id: e268d5b0
          executable: /usr/bin/curl
          decision: deny

    # watch requests to registry.npmjs.org from any process
    - id: 812ab543
      destination: registry.npmjs.org:443

executables:
    # Block nc from making any connections
    - id: bb8d8f78
      path: /usr/bin/nc
      rules:
        - id: 4b9a912e
          resource: '*'
          type: network
          decision: deny
          enabled: true

    # block /usr/bin/cat from reading /tmp/1.txt
    - id: 906778b8
      path: /usr/bin/cat
      rules:
        - id: 7833ce9a
          resource: /tmp/1.txt
          type: file
          decision: deny
          enabled: true
  • File monitoring — eBPF LSM file_open hook watches sensitive file reads
  • Taint propagation — taints flow to child processes and files written by tainted processes
  • Network gating — eBPF LSM socket_connect hook intercepts public connections from tainted processes
  • Hostname-aware rules — allow/deny/prompt policies per destination hostname
  • Local web UI — live event stream, pending prompts, taint state, watchlist editing, policy management
  • Zero trust, fully local — daemon on 127.0.0.1, all state on disk, token-authenticated UI

Run

Start NARC in the foreground:

./narc start

On first run, NARC will request sudo once so it can apply the required Linux capabilities to the binary and restart itself. After that, the same binary should start without another privilege prompt. Narc will ask for a sudo password every time the binary is replaced or upgraded.

Useful commands if narc is running in the background:

# Show current narc status, including the local admin UI URL and token
./narc status

# Launch the local UI
./narc ui

The UI is served at http://127.0.0.1:8844. narc status and narc ui use a #token=... bootstrap URL, and the browser strips that fragment after load so the token only stays in memory for the session. The local auth token is stored at ~/.config/narc/auth_token.

Install

Copy the binary anywhere on your system then make it executable:

# locally in your home dir
mv narc ~/bin/narc && chmod 755 ~/bin/narc

# install narc system wide
sudo install -m 755 ./narc /usr/local/bin/narc

Then configure systemd, x11, .bashrc, hyprland, etc to run narc in the background.

# ~/.config/hypr/hyprland.conf
...
exec-once = ~/bin/narc start

Configuration

NARC stores its local state in ~/.config/narc/:

  • auth_token: local API/UI bearer token
  • config.json: daemon settings
  • watchlist.yaml: file and network watchlist entries
  • taint-state.json: live and historical taint state plus derived watched files

The Watchlist supports wilcards and recursive globbing, so these are all valid:

  • ~/.aws/credentials
  • ~/.azure/**
  • ~/**/.env

Note: The more recursive globs you have in the watchlist, the longer it takes for NARC to start.

Architecture

The runtime is split into three pieces:

  • eBPF programs enforce or observe file and network activity in-kernel.
  • A Go daemon resolves process and hostname context, persists policy and taint state, and translates kernel events into operator-facing actions.
  • An embedded static web app exposes prompts, events, settings, and policy management over a localhost-only API and WebSocket stream.

Build Requirements

  • Linux with kernel 5.7+.
  • BPF LSM enabled: CONFIG_BPF_LSM=y and bpf present in the active LSM list.
  • BTF available at /sys/kernel/btf/vmlinux.
  • Go 1.22+.
  • clang and llvm (only needed for go generate; pre-built BPF artifacts are checked in).
  • setcap/getcap available for the capability bootstrap flow.

Build

Build the daemon and embedded UI:

make build

Run the test suite:

go test ./...

Development Notes

  • make build runs go generate ./internal/bpf/ before compiling.
  • The generated BPF artifacts are checked into the repository.
  • A pre-built vmlinux.h from the libbpf/vmlinux.h project (kernel 6.19, x86) is checked in. CO-RE ensures the compiled BPF programs work across kernel versions with BTF support. To regenerate from your running kernel instead: bpftool btf dump file /sys/kernel/btf/vmlinux format c > internal/bpf/vmlinux.h.
  • Static assets live in web/static.

About

NARC watches sensitive files and blocks exfiltration by unknown processes

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors