{"id":34246497,"url":"https://github.com/carvilsi/caetra","last_synced_at":"2026-05-31T19:31:47.564Z","repository":{"id":326763921,"uuid":"1089461526","full_name":"carvilsi/caetra","owner":"carvilsi","description":"Linux Phisical Security based on eBPF","archived":false,"fork":false,"pushed_at":"2026-03-16T16:43:40.000Z","size":1023,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-17T04:06:22.069Z","etag":null,"topics":["canarytokens","ebpf","ebpf-programs","monitoring","physical-security","security","security-tools","telegrambot"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carvilsi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":null,"dco":null,"cla":null}},"created_at":"2025-11-04T11:28:03.000Z","updated_at":"2026-03-16T16:43:45.000Z","dependencies_parsed_at":"2026-02-23T16:03:06.398Z","dependency_job_id":null,"html_url":"https://github.com/carvilsi/caetra","commit_stats":null,"previous_names":["carvilsi/caetra"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/carvilsi/caetra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvilsi%2Fcaetra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvilsi%2Fcaetra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvilsi%2Fcaetra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvilsi%2Fcaetra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carvilsi","download_url":"https://codeload.github.com/carvilsi/caetra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carvilsi%2Fcaetra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33746506,"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-31T02:00:06.040Z","response_time":95,"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":["canarytokens","ebpf","ebpf-programs","monitoring","physical-security","security","security-tools","telegrambot"],"created_at":"2025-12-16T07:07:55.397Z","updated_at":"2026-05-31T19:31:47.557Z","avatar_url":"https://github.com/carvilsi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cp\u003e\n    \u003cimg src=\"https://github.com/carvilsi/caetra/blob/main/.github/images/caetra_lusitan.png\" style=\"width:20%; height:auto;\" alt=\"caetra_lusitan\" \u003e\n\u003c/p\u003e\n\n\u003cpre\u003e\n       ▗      \n▛▘▀▌█▌▜▘▛▘▀▌\n▙▖█▌▙▖▐▖▌ █▌\nLinux Physical Security based on eBPF\nWhen eBPF met CanaryTokens\n\u003c/pre\u003e\n\u003c/div\u003e\n\n# Caetra\n\nCaetra ([/kaˈetɾa/](https://ipa-reader.com/?text=ka%CB%88et%C9%BEa\u0026voice=Conchita)) was the [shield used by Iberian](https://en.wikipedia.org/wiki/Caetra)\n\nCaetra uses [eBPF](https://ebpf.io/) (**extended Berkeley Packet Filters**) to try secure a Linux machine against **physical threats**, like implants installation or badUSB usage, or at least be aware about a potential attack, monitoring kernel *kprobes* related with hardware interactions like **attaching an USB**, **detaching an HID** or **uplug** the laptop from **power source**. It uses **BPF Compiler Collection** [BCC](https://github.com/iovisor/bcc/) to do the **kernel tracing** and **manipulation program**.\n\nIn order to be able to **notify the user or cybersecurity responsables** by now **Caetra** uses [Thinkst Canary](https://canary.tools/#why) and/or [Telegram Bot](https://core.telegram.org/bots/api). On the other hand a more defensive approach has been implemented on *USB Shield* that allows to [de-authorize](https://www.kernel.org/doc/html/v5.15/usb/authorization.html) the attached device.\n\nThe idea is to leave Caetra running when you leave your machine unattended, e.g. when it's lock or on suspension mode.\n\nThe first release *v1.0.0* has been wirten for the [eBPF Summit: Hackathon Edition 2025](https://ebpf-summit-2025.devpost.com/). [Videos for Hackathon](https://youtube.com/playlist?list=PLuSN43tiMwqYnsBcXQh7vrhIM7LWOWlhk\u0026si=_Lxf-EbyXLu6wA1k)\n\n--- \n\n## TOC\n\n1. [Install](#install)\n    1. [Dependencies](#dependencies\")\n2. [Run](#run)\n3. [Shields](#shields)\n    1.  [ambient_light](#ambient_light)\n    2.  [blt_connect](#blt_connect)\n    3.  [blt_disconnect](#blt_disconnect)\n    4.  [hibernation](#hibernation)\n    5.  [hid_add_remove](#hid_add_remove)\n    6.  [hid_interact](#hid_interact)\n    7.  [inet](#inet)\n    8.  [input_event](#input_event)\n    9.  [mmc](#mmc)\n    10. [power](#power)\n    11. [usb](#usb)\n    12. [cd_dvd_rom](#cd_dvd_rom)\n    13. [webcam](#webcam)\n4. [Senders](#senders)\n    1. [CanaryTokens](#canarytokens)\n    2. [Telegram](#telegram)\n6. [Logging](#logging)\n7. [Project Structure](#project-structure)\n8. [Tools](#tools)\n    1. [caetra_shield_generator](#caetra_shield_generator)\n    2. [follow_rabbit_hole](#follow_rabbit_hole)\n9. [Notes](#notes)\n    1. [TODOS](#todos)\n        1. [Shields TODOS](#shields-todos)\n        2. [Code](#code)\n        3. [Senders TODOS](#senders-todos)\n\n---\n\n## Install\u003ca name=\"install\" /\u003e\n\n`$ git clone https://github.com/carvilsi/caetra`\n\n`$ cd caetra`\n\nCheck next [Dependencies section](#dependencies).\n\n### Dependencies\u003ca name=\"dependencies\" /\u003e\n\n- Python vers \u003e= 3.12\n\n- [bcc](https://github.com/iovisor/bcc/blob/b63d7e38e8a0f6339fbd57f3a1ae7297e1993d92/INSTALL.md)\n\n#### Linux Kernel Headers\n\nIt is possible that after upgrading the Linux Kernel, compiling the BPF modules could fail, with the next message:\n\n`Unable to find kernel headers. Try rebuilding kernel with CONFIG_IKHEADERS=m (module) or installing the kernel development package for your running kernel version.`\n\nTry to install the kernel development package for your distro:\n\n##### Arch Linux\n\n`$ sudo pacman -S linux-headers`\n\n## Run\u003ca name=\"run\" /\u003e\n\nRight now **eBPF** requires to be execute as **root**.\n\n`sudo ./caetra.py`\n\n## Shields\u003ca name=\"shields\" /\u003e\n\nShields are the *eBPF* programs that monitors the physical interaction with the equip.\n\nConsists on kernel space code in c and user space script in python.\n\nRight now all the Shields are based on [kprobes](https://github.com/iovisor/bcc/blob/b63d7e38e8a0f6339fbd57f3a1ae7297e1993d92/docs/reference_guide.md#1-kprobes)\n\nCurrent implemented **Caetra's Shields**:\n\n### 1. ambient_light\u003ca name=\"ambient_light\" /\u003e\n\nShield that triggers notification when the **backlight** of screen changes.\n\nThis could means that someone aproached to your machine.\n\n**kprobe:** `backlight_device_set_brightness`\n\n### 2. blt_connect\u003ca name=\"blt_connect\" /\u003e\n\nThis shields triggers when a **Bluetooth** device connects or tries to connect or bind to your machine.\n\n**kprobe:** `hci_conn_request_evt`\n\n### 3. blt_disconnect\u003ca name=\"blt_disconnect\" /\u003e\n\nTriggers when a **Bluetooth** device has been disconected from the machine.\n\n**kprobe:** `hci_disconn_complete_evt`\n\n### 4. hibernation\u003ca name=\"hibernation\" /\u003e\n\nThis Shield will trigger when the machine goes out from **hibernation** mode.\n\n**kprobe:** `unregister_pm_notifier`\n\n### 5. hid_add_remove\u003ca name=\"hid_add_remove\" /\u003e\n\nTriggers when an **HID device** has been deatached from your machine. \n\nHere we are thinking about a possible keyboad **implant** e.g. a [keylogger](https://github.com/therealdreg/okhi)\n\n**kprobe:** `hid_add_device`\n\n**kprobe:** `hid_device_remove`\n\n### 6. hid_interact\u003ca name=\"hid_interact\" /\u003e\n\nThis Shield triggers when there is a **HID interaction**; the mouse has been moved or a key from external keyboard has been pressed.\n\n**kprobe:** `hid_report_raw_event`\n\n### 7. inet\u003ca name=\"inet\" /\u003e\n\nTriggers when there is changes on networking for **inet device**\n\n**kprobe:** `inet_alloc_ifa`\n\n**kprobe:** `inetdev_event`\n\n### 8. input_event\u003ca name=\"input_event\" /\u003e\n\nShield that triggers when there is any input interaction, e.g. trackpad, touchscreen, keyboard, etc...\n\n**kprobe:** `input_handle_event`\n\n### 9. mmc\u003ca name=\"mmc\" /\u003e\n\nThe Shield reacts when a **MMC** (MultiMediaCard) is inserted. e.g. SDCard.\n\n\n**kprobe:** `mmc_sd_runtime_suspend`\n\n### 10. power\u003ca name=\"power\" /\u003e\n\nTriggers when the **power** source changes.\n\nThinking that someone has been disconnected the laptop from power plug, e.g. to access hardware parts to perform a [phiysical RAM memory dump](https://docs.buspirate.com/docs/overview/ddr-ram-i2c-adapter/). (\n\n**kprobe:** `power_supply_changed`\n\n### 11. usb\u003ca name=\"usb\" /\u003e\n\nThis Shield reacts when an **USB** has been connected to the machine.\n\nWe are thinking here about a **badUSB** or data exfiltration from the equip. (same idea than [CanaryUSB](https://github.com/carvilsi/canaryusb))\n\nThis Shields can **de-authorize** the USB device, via configuration.\n\n\n**kprobe:** `usb_notify_add_device`\n\n### 12. cd_dvd_rom\u003ca name=\"cd_dvd_rom\" /\u003e\n\nThis Shield reacts on open or close CD-DVD tray.\n\nFor example, with this shield we are trying to avoid some king of Live CD/DVD for System Access.\n\n**kprobe:** `cdrom_open`\n\n### 13. webcam\u003ca name=\"webcam\" /\u003e\n\nThis Shield reacts when a webcam turns it on/off.\n\nWith this shield we are trying to avoid privacy leaks from you and others, among possible security visual breaches like harvesting information about your surroundings.\nDo not forget to cover your webcam with a nice cat sticker :3\n\n**kprobe:** `video_ioctl2`\n\n## Senders\u003ca name=\"senders\" /\u003e\n\nWhat Caetra uses to send you a notification, when any Shield has been trigger.\n\nIt is possible to configure each shield to handle custom notification for it, via *toml* file under `src/shields/[shield]/[shield.toml]`. e.g. if you want that specific shield to send the notification to a certain Telegram Bot or mail in case of CanaryToken usage. Check an example [here](https://github.com/carvilsi/caetra/blob/main/src/shields/usb/usb.toml#L24)\n\n### CanaryTokens\u003ca name=\"canarytokens\" /\u003e\n\nWill send an email with data related with the triggered Shield via DNS Canarytoken powered by [Thinkst Canary](https://canary.tools/).\n\nGet your [DNS Canarytoken](https://docs.canarytokens.org/guide/dns-token.html#what-is-a-dns-canarytoken) and add it to the *token* variable on [general configuration file](https://github.com/carvilsi/caetra/blob/main/config/develop.toml#L14) or [specific shield](https://github.com/carvilsi/caetra/blob/main/src/shields/usb/usb.toml#L28) one. \n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003cimg src=\"https://github.com/carvilsi/caetra/blob/main/.github/images/caetra_canarytoken.png\" alt=\"caetra_canarytoken\" \u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n### Telegram\u003ca name=\"telegram\" /\u003e\n\nWill use [Telegram Bot API]() to send data related with the triggered Shield to the configured **Telegram Chat**.\n\nCreate your [Telegram Bot](https://core.telegram.org/bots/features#creating-a-new-bot) and set the *bot_api_key* variable on [general configuration](https://github.com/carvilsi/caetra/blob/main/config/develop.toml#L18) or on [specific shield](https://github.com/carvilsi/caetra/blob/main/src/shields/usb/usb.toml#L33) one.\n\nThen add the bot to a chat and set the *chat_id* on [general configuration](https://github.com/carvilsi/caetra/blob/main/config/develop.toml#L18) or on [specific shield](https://github.com/carvilsi/caetra/blob/main/src/shields/usb/usb.toml#L32) one.\n\nNote: To retrieve the desired telegram *chat ID* after added the bot to the chat and interacted with it, run:\n\n`$ curl https://api.telegram.org/bot\u003cBOT_API_KEY\u003e/getUpdates | jq .result[0].message.chat.id`\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003cimg src=\"https://github.com/carvilsi/caetra/blob/main/.github/images/caetra_telegram_bot.png\" alt=\"caetra_telegram_bot\" \u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n\n## Logging\u003ca name=\"logging\" /\u003e\n\nCaetra by default will do logging on *logs/* folder with file rotating behaviour. The main logging level could be set on *toml* configuration file with the variable **level** under *logging* [section](https://github.com/carvilsi/caetra/blob/main/config/develop.toml#L9).\n\nThe Shields by default will log on **syslog** with **warning** level.\n\nTo check the **syslog** Caetra's messages:\n\n`$ journalctl -r --grep='caetra_shields'`\n\n## Project Structure\u003ca name=\"project-structure\" /\u003e\n\n```\n.\n├── caetra.py (main script)\n├── config (general configuration)\n├── logs (Caetra logs)\n├── src\n│   ├── caetra_exceptions.py\n│   ├── constants.py\n│   ├── senders (all the things related with notifications)\n│   ├── shields (the Shields, code for kernel and user space among specific Shield configuration)\n│   └── utils (the utils stuff)\n└── tools\n    ├── caetra_shield_generator\n    └── follow_rabbit_hole\n\n```\n## Tools\u003ca name=\"tools\" /\u003e\n\nThings that could help Caetra's Shields development.\n\nYou'll find it under [tools folder](https://github.com/carvilsi/caetra/tree/main/tools)\n\n### caetra_shield_generator\u003ca name=\"caetra_shield_generator\" /\u003e\n\nAn interactive Caetra's Shield interactive generator:\n\nRun it with:\n\n`$ python caetra_bpf_generator.py`\n\nThe above command without parameters will ask for related variables to generate the new Caetra's Shield.\n\nThe new Shield will be under the **generator-output** folder.\n\n```\nUsage: caetra_bpf_generator.py [OPTIONS]\n\nOptions:\n  --shield-name TEXT           New caetra shield name.\n                               [required]\n  --shield-description TEXT    Write down about what this Shield\n                               does.\n  --kprobe-event TEXT          Kprobe event.  [required]\n  --kheaders-include TEXT      Linux header to includ on kernel c\n                               code, e.g. 'linux/usb.h'\n                               [required]\n  --kstrct TEXT                Linux struct to retrieve data,\n                               e.g. 'usb_device'  [required]\n  --shield-enable BOOLEAN      If this Shield will be enabled or\n                               not  [required]\n  --shield-feature TEXT        Will be the feature variable for\n                               the Shield.\n  --action-label TEXT          The label that describes the\n                               physical interaction, e.g. 'usb\n                               attached'  [required]\n  --canarytoken-sender\n  --canarytoken TEXT\n  --telegram-sender\n  --telegram-chat-id TEXT\n  --telegram-bot-api-key TEXT\n  --help                       Show this message and exit.\n```\n\n### follow_rabbit_hole\u003ca name=\"follow_rabbit_hole\" /\u003e\n\nA bash script to help follow related *kprobes* **structures**.\n\n`$ sudo ./rabbit_hole_structures.sh \u003cstructure_name\u003e`\n\nNote and example:\n    In order to check the related structs for a specific *kprobe* use **bpftrace** tool:\n\n`$ sudo bpftrace -lv kprobe:backlight_device_set_brightness`\n\nOutput:\n\n```\nkprobe:backlight_device_set_brightness\n    struct backlight_device * arg0\n    long unsigned int arg1\n```\n\nSo for this output you could follow the rabbit into the hole like:\n\n`$ sudo ./rabbit_hole_structures.sh backlight_device`\n\nThis will create a file called **backlight_device_rabbit_hole.strct** that has all the related structures.\n\n## Notes\u003ca name=\"notes\" /\u003e\n\nShield image on this README by [lion.kanzen](https://opengameart.org/users/lionkanzen-0) licensed under: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) [OGA-BY 3.0](https://opengameart.org/content/oga-by-30-faq)\n\n### TODOS\u003ca name=\"todos\" /\u003e\n\n#### Shields TODOs\u003ca name=\"shields-todos\" /\u003e\n\n- [ ] accelerometers (I don't have a device with an accelerometer sensor)\n- [x] camera things\n- [ ] monitor nearby WiFi AP\n- [x] CDs \u0026 DVDs\n- [ ] microphone\n \n#### Code\u003ca name=\"code\" /\u003e\n\n- [ ] cli\n- [ ] general logger configuration\n- [ ] rethink how to run the whole thing; ponder about running all the shields on multithread mode\n- [ ] check if **kprobe** it's available on startup\n\n#### Senders TODOs\u003ca name=\"senders-todos\" /\u003e\n\n- [ ] implement something to do data ingestion, dashboards and alarms\n- [ ] improve format for Telegram sender\n\n---\n\nFeedback from usage and contributions are very welcome.\nAlso if you like it, please leave a :star: I would appreciate it ;)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarvilsi%2Fcaetra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarvilsi%2Fcaetra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarvilsi%2Fcaetra/lists"}