learn command traces a command’s file accesses and network activity, then reports which paths and endpoints it needs. This helps you build accurate profiles without guessing.
On Linux, nono learn uses strace. On macOS, it uses fs_usage for filesystem tracing and nettop for network connection discovery (both require sudo).
Linux requires
strace to be installed (apt install strace or equivalent). macOS requires root privileges for fs_usage and nettop.Basic Usage
strace (Linux) or fs_usage + nettop (macOS), captures all file access and network activity, and produces a summary:
Comparing Against a Profile
Use--profile to see only the paths that a profile doesn’t already cover:
JSON Output
Use--json to get machine-readable output suitable for adding to a profile:
Options
| Flag | Description |
|---|---|
--profile NAME | Compare against an existing profile, showing only missing paths |
--json | Output as JSON fragment for profile creation |
--timeout SECS | Kill trace after N seconds (useful for long-running commands) |
--all | Show all accessed paths, including those covered by system defaults |
--no-rdns | Skip all DNS resolution for discovered IPs |
--verbose | Show detailed trace output |
How It Works
Linux (strace)
Under the hood,nono learn runs:
strace -f follows forks, so network and filesystem activity from subprocesses is captured automatically. Both filesystem and network syscalls are traced in a single pass.
macOS (fs_usage + nettop)
On macOS, two tools run concurrently:fs_usage -w -f filesys -f pathnametraces filesystem operations (open, stat, mkdir, etc.)nettop -L 0 -n -s 1polls active network connections at 1-second intervals
fs_usage is started before the child command and filters by process name. nettop is started after the child and filters by PID, which causes it to follow the entire process tree and capture network activity from subprocesses (e.g. node spawned by a wrapper binary). nettop identifies outbound connections (Established state) and listening ports (Listen state) from its CSV output.
Processing
On both platforms, the raw trace data is then:- Categorized as read, write, or readwrite (filesystem) or connect/bind (network)
- Filtered to remove paths already covered by base groups (system libraries, etc.)
- Collapsed from individual file paths to parent directories where appropriate
- Resolved from IP addresses to hostnames
- Formatted as summary or JSON output
Network Discovery
nono learn captures outbound connections and listening ports alongside filesystem accesses on both Linux and macOS.
On Linux, network activity is discovered by tracing connect, bind, and sendto syscalls. On macOS, nettop polls active TCP and UDP connections.
Hostname Resolution
Captured IP addresses are resolved to hostnames. On Linux, three strategies are applied in priority order:- Timing correlation — attaches the hostname from the preceding DNS query directly to each
connect()call. This handles DNS round-robin correctly because the mapping is per-PID. - Forward DNS — resolves captured hostnames to build an IP-to-hostname map. This gives the hostname the program intended (e.g.,
google.com) rather than infrastructure names from reverse DNS. - Reverse DNS — fallback for IPs with no other mapping.
sendto to port 53) and systemd-resolved (Varlink JSON protocol over Unix socket) are supported on Linux.
On macOS, reverse DNS is used to resolve IP addresses to hostnames since nettop provides IP-level data without DNS query interception.
Use --no-rdns to skip all DNS resolution, which avoids network calls during analysis:
--block-net to restrict network access at sandbox time.