{"id":18016139,"url":"https://github.com/cpu/rfanotify","last_synced_at":"2025-03-26T18:31:46.956Z","repository":{"id":89702894,"uuid":"244491858","full_name":"cpu/rfanotify","owner":"cpu","description":"Rust port of the Linux 4.0.4 `man 7 fanotify` example program source (roughly).","archived":true,"fork":false,"pushed_at":"2020-04-15T13:44:12.000Z","size":27,"stargazers_count":3,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-10T01:16:10.044Z","etag":null,"topics":["fanotify","filesystem-events","filesystem-monitoring","libc","nix","rust"],"latest_commit_sha":null,"homepage":"","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/cpu.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}},"created_at":"2020-03-02T22:46:43.000Z","updated_at":"2023-04-30T18:11:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"8014df91-9a76-4c17-bab6-e3ba5ab60e8f","html_url":"https://github.com/cpu/rfanotify","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpu%2Frfanotify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpu%2Frfanotify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpu%2Frfanotify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpu%2Frfanotify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cpu","download_url":"https://codeload.github.com/cpu/rfanotify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245712833,"owners_count":20660302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["fanotify","filesystem-events","filesystem-monitoring","libc","nix","rust"],"created_at":"2024-10-30T04:16:16.648Z","updated_at":"2025-03-26T18:31:46.948Z","avatar_url":"https://github.com/cpu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rust fanotify example \u0026emsp; [![Travis Badge]][Travis CI]\n\n[Travis Badge]: https://img.shields.io/travis/com/cpu/rfanotify\n[Travis CI]: https://travis-ci.com/cpu/rfanotify\n\n---\n\n* [About](#About)\n* [Building](#Building)\n* [Usage](#Usage)\n* [Example](#Example)\n* [Filesystem vs Mount](#Filesystem-vs-Mount)\n* [Nix and Libc versions](#Nix-and-Libc-versions)\n* [Updates to the fanotify API](#Updates-to-the-fanotify-API)\n* [See Also](#See-Also)\n\n### About\n\nThis repository is a Rust port of the Linux [man-pages project]'s [example\nC program][fanotify-example] for the Linux `fanotify` API. It offers a simple\nprogram called `rfanotify` that responds to and logs permission requests to\nopen a file on a monitored filesystem or mount. It also logs when a process\nwrites a file on a monitored filesystem/mount.\n\nThe `fanotify` API is a linux-specific API for notification and interception of\nfilesystem events. In some ways it is similar to `inotify`, but more powerful.\nUnlike `inotify` based approaches to filesystem monitoring using `fanotify` has\nseveral advantages:\n\n* An entire filesystem/mount can be monitored with very low overhead.\n* The `pid` of the program causing the filesystem event is known.\n* The event handling program can **deny** file opens for the monitored\n  filesystem.\n\nFor more information, see:\n\n* [the LWN article on `fanotify`][LWN-Article].\n* [`man 7 fanotify`][man-fanotify].\n* [`man 2 fanotify_init`][man-fanotify_init].\n* [`man 2 fanotify_mark`][man-fanotify_mark].\n\n**NOTE: This is my first attempt at writing Rust and it's likely not especially idomatic/clean. Kind PRs/suggestions welcome.**\n\n[man-pages project]: https://www.kernel.org/doc/man-pages/\n[fanotify-example]: https://gist.github.com/cpu/b68e7bbdf60619c1cdf1ebc27b1e4ae5\n[LWN-Article]: https://lwn.net/Articles/339399/\n[man-fanotify]: http://man7.org/linux/man-pages/man7/fanotify.7.html\n[man-fanotify_init]: http://man7.org/linux/man-pages/man2/fanotify_init.2.html\n[man-fanotify_mark]: http://man7.org/linux/man-pages/man2/fanotify_mark.2.h\n\n### Building\n\nSince this project is written in Rust, you'll need to grab a [Rust\ninstallation] in order to compile it.\n\n`rfanotify` was developed with Rust 1.34.0 (stable). It may work with other\nversions, but this isn't guaranteed.\n\nTo build `rfanotify`:\n\n```bash\ngit clone https://github.com/cpu/rfanotify \u0026\u0026 cd rfanotify\ncargo build --release\n```\n\n[Rust installation]: https://www.rust-lang.org/learn/get-started\n\n### Usage\n\nAfter [building from source](#Building), run:\n\n```bash\nsudo ./target/release/rfanotify \u003cdirectory\u003e\n```\n\nIf no explicit `directory` argument is provided the filesystem/mount of the\ncurrent working directory is monitored.\n\nYou can avoid running `rfanotify` as `root` by instead giving the binary\nthe `CAP_SYS_ADMIN` capability, and then running it as a normal user:\n\n```bash\nsudo setcap cap_sys_admin+eip target/release/rfanotify\n./target/release/rfanotify \u003cdirectory\u003e\n```\n\nThe `rfanotify` program adds a `fanotify` watch on the entire filesystem/mount\nbacking `\u003cdirectory\u003e`. When a process tries to open a file on the monitored\nfilesystem/mount a `FAN_OPEN_PERM` event is received and logged by `rfanotify`\nand a `FAN_ALLOW` response is returned, allowing the open to complete. When a\nprocess closes a file a `FAN_CLOSE_WRITE` event is received and logged.\n\nEvents are logged to stdout including the absolute path of the accessed file\nand the program executable performing the access. Both of these values are\nretrieved by `fd` using the [Linux procfs][procfs]. If the accessed file has\nbeen deleted since the time the event was generated then the filename will have\n\"(deleted)\" appended by `readlink` and the procfs. If the pid that generated\nthe access has terminated since the time the event was generated then the\ngone pid is printed instead.\n\n[procfs]: http://man7.org/linux/man-pages/man5/proc.5.html\n\n### Example\n\nHere's an example of running `rfanotify` on a fresh Ubuntu 19.04 VM with a Linux\n5.0.0-38-generic kernel.\n\nFirst `rfanotify` is started inside of a `screen` session:\n\n```bash\nsudo rfanotify\n```\n\nNext, a separate window is created with `ctrl-a c` and a file is edited with vim:\n\n```bash\nvim /tmp/test.txt\n```\n\nAfter exiting `vim` and switching back to the first screen window running\n`rfanotify` you should see output like:\n\n```bash\nFAN_OPEN_PERM: File /usr/lib/x86_64-linux-gnu/utempter/utempter Exe /usr/bin/screen\nFAN_OPEN_PERM: File /usr/lib/x86_64-linux-gnu/ld-2.29.so Exe /usr/lib/x86_64-linux-gnu/utempter/utempter\nFAN_OPEN_PERM: File /etc/ld.so.cache Exe /usr/lib/x86_64-linux-gnu/utempter/utempter\n\u003csnipped\u003e\nFAN_CLOSE_WRITE: File /tmp/.test.txt.swx Exe /usr/bin/vim.basic\nFAN_CLOSE_WRITE: File /tmp/.test.txt.swp Exe /usr/bin/vim.basic\nFAN_OPEN_PERM: File /tmp/.test.txt.swp Exe /usr/bin/vim.basic\nFAN_OPEN_PERM: File /usr/share/vim/vim81/scripts.vim Exe /usr/bin/vim.basic\nFAN_OPEN_PERM: File /usr/share/vim/vim81/ftplugin/text.vim Exe /usr/bin/vim.basic\nFAN_OPEN_PERM: File /tmp/test.txt Exe /usr/bin/vim.basic\nFAN_CLOSE_WRITE: File /tmp/test.txt Exe /usr/bin/vim.basic\nFAN_CLOSE_WRITE: File /tmp/.test.txt.swp Exe /usr/bin/vim.basic\n```\n\nThe full program output can be viewed [here][example-output].\n\n[example-output]: https://github.com/cpu/rfanotify/blob/master/rfanotify.eg.output.txt\n\n### Filesystem vs Mount\n\nOn Linux kernel versions \u003e= 4.2.0 `rfanotify` uses `fanotify_mark` with the\n`FAN_MARK_FILESYSTEM` flag. On older versions `FAN_MARK_MOUNT` is used instead.\nWhen marking a filesystem **mount** instead of a filesystem it is possible\nevents will be missed.\n\nFor example, consider if the device `/dev/sdb1` is mounted to `/mnt/example` as well as having a bind mount to `/mnt/example-b` (e.g. `mount --bind /mnt/example /mnt/example-b`).\n\nIf `rfanotify /mnt/example` is run on a Linux kernel version \u003e= 4.2.0 then events will be logged regardless of which mount is used. (e.g editing `/mnt/example/foo.txt` or `/mnt/example-b/foo.txt` will both log `rfanotify` events). The **filesystem** for `/mnt/example` is monitored.\n\nIf `rfanotify /mnt/example` is run on a Linux kernel version \u003c 4.2.0 then events will be logged only for the `/mnt/example` mount. (e.g editing `/mnt/example/foo.txt` will log `rfanotify` events but editing `/mnt/example-b/foo.txt` will **not**. Only the **mount** of `/mnt/example` is monitored.\n\n### Nix and Libc versions\n\nThe `fanotify` system calls have been available since Linux 2.6.37 but FFI\nbindings for Rust were not available in the `nix` and `libc` crates as of\nMarch 2020.\n\nThe required FFI bindings were [added to the `libc` crate][libc-fanotify] in\nApril 2020 and released as part of [v0.2.69][libc-fanotify-release].\nThe `nix` wrappers are a work in progress and require using a [fork of the `nix`\ncrate][nix-fork] that has rough initial [fanotify support][nix-fanotify].\n\n[libc-fanotify]: https://github.com/rust-lang/libc/commit/5c7a82a1c8276a0ea67cdbdc5a917ec88bb1082a\n[libc-fanotify-release]: https://github.com/rust-lang/libc/releases/tag/0.2.69\n[nix-fork]: https://github.com/cpu/nix\n[nix-fanotify]: 1604fdb23871ae295f57d1770e59d4743b209907\n\n### Updates to the fanotify API\n\nThe `fanotify` API has been updated several times since it was enabled in Linux\n2.6.37. The `rfanotify` code was written using the man page content from\nrelease 4.04 of the Linux [man-pages project] and tested on Linux kernel version\n4.4.0 and 5.0.0.\n\n[Linux 4.20] added `FAN_MARK_FILESYSTEM` to \"enable monitoring of filesystem\nevents on all filesystem objects regardless of the mount where event was\ngenerated\". It also added `FAN_REPORT_TID` to get thread IDs that triggered\nevents.\n\n[Linux 5.0] added the ability to watch for when a file is opened with the intent\nto execute (`FAN_OPEN_EXEC`).\n\n[Linux 5.1] added many of `inotify`'s directory based events to `fanotify`\n(e.g. `FAN_ATTRIB`, `FAN_CREATE`, etc). It also added a new `fanotify_init`\nflag `FAN_REPORT_FID` that allows receiving an additional structure beyond the\nbase `fanotify_event_metadata` structure that contains information about the\nfilesystem object correlated with an event (e.g. a monitored directory or\nmount).\n\nThe forked `libc` and `nix` crates used by this project do not (yet) implement\nany of these updates (except for `FAN_MARK_FILESYSTEM`). This project does not\n(yet) port the `fanotify_fid.c` example C program included in release 5.05 of\nthe Linux [man-pages project].\n\n[Linux 4.20]: https://kernelnewbies.org/Linux_4.20#Core_.28various.29\n[Linux 5.0]: https://kernelnewbies.org/Linux_5.0#Core_.28various.29\n[Linux 5.1]: https://kernelnewbies.org/Linux_5.1#Improved_fanotify_for_better_file_system_monitorization\n\n### See Also\n\nMartin Pitt cleverly used the `fanotify` API to develop [`fatrace`][fatrace], a\nprogram for reporting system wide file access events tailored towards reducing\npower consumption.\n\n[fatrace]: https://piware.de/2012/02/fatrace-report-system-wide-file-access-events/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpu%2Frfanotify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcpu%2Frfanotify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpu%2Frfanotify/lists"}