{"id":13928868,"url":"https://github.com/ashuio/shavee","last_synced_at":"2025-07-19T10:32:12.940Z","repository":{"id":38892724,"uuid":"382710511","full_name":"ashuio/shavee","owner":"ashuio","description":"shavee is a Program to automatically decrypt and mount ZFS datasets using Yubikey HMAC as 2FA or any File on USB/SFTP/HTTPS drive with support for PAM to auto mount home directories.","archived":false,"fork":false,"pushed_at":"2024-01-20T11:29:45.000Z","size":262,"stargazers_count":64,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-06T19:08:55.434Z","etag":null,"topics":["pam-module","two-factor-authentication","yubikey","zfs","zfsonlinux"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ashuio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-07-03T21:14:38.000Z","updated_at":"2024-10-28T18:52:44.000Z","dependencies_parsed_at":"2023-11-14T01:47:08.327Z","dependency_job_id":"89207acf-638a-4bf8-a99c-44d618969a04","html_url":"https://github.com/ashuio/shavee","commit_stats":{"total_commits":47,"total_committers":5,"mean_commits":9.4,"dds":0.6170212765957447,"last_synced_commit":"8cd4ff776aa50f39c3dcd83f061ebf38f1c5147e"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashuio%2Fshavee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashuio%2Fshavee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashuio%2Fshavee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashuio%2Fshavee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashuio","download_url":"https://codeload.github.com/ashuio/shavee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226588855,"owners_count":17655797,"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":["pam-module","two-factor-authentication","yubikey","zfs","zfsonlinux"],"created_at":"2024-08-07T18:01:57.559Z","updated_at":"2024-11-26T17:31:04.570Z","avatar_url":"https://github.com/ashuio.png","language":"Rust","funding_links":[],"categories":["others","🛠️ ZFS tools"],"sub_categories":["ZFS other tools"],"readme":"# shavee\n\n\u003c!-- ![rust workflow](https://github.com/ashuio/shavee/actions/workflows/rust.yml/badge.svg) --\u003e\n\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/ashuio/shavee/blob/master/LICENSE)\n\nshavee is a simple program and a pam module to automatically decrypt and mount encrypted ZFS user home directories using Yubikey HMAC or a Simple USB drive as 2FA written in rust.\n\n**NOTE: Shavee v1.0.0 and greater are NOT backwards compatible with Datasets created with earlier versions. See [Migration Guide.](MIGRATION.md)**\n\n## Supported methods\n\nThis program currently supports two methods for 2FA:\n\n### 1. Yubikey\n\n[Yubikeys](https://www.yubico.com/products/) are secure authetication USB devices we can use for our Strong second factor.\n\nYubikey comes pre-programmed with a HMAC key on Slot 2 which can be used to derive our final encryption key along with our password.\n\nProgrammed HMAC secret in the Yubikey CANNOT be extracted once programmed in.\n\nIf you want to use Multiple keys on the same dataset (eg. backup keys) it is required for you to program SAME fresh HMAC secrets on all those keys.\n\nNOTE: You will need to use the manual unlock options if you want to use a diffrent key as auto mode looks for keys by serial.\n\nYubikey mode is set with the `-y` flag.\n\nIf diffrent datasets require diffrent keys you can plug all of them together.\n\nIn this mode the program looks for a Yubikey on login and uses it's HMAC mode along with your password to derive the final encryption key.\n\nYubikey HMAC Slot can be set with the `-s` flag, defaults to SLOT 2\n\n### 2. File/HTTP(S)/SFTP\n\nIn this mode the program looks for a file (can be any file) and use that along with your password to derive the final encryption.\n\nFile mode is set using the `-f \u003cpath to file\u003e` option.\n\nFile can be a local file, a http(s) or a sftp location\n\nExample HTTPS\n\n```bash\nshavee -f https://foo.org/secret.png\n```\n\nExmaple SFTP\n\n```bash\nshavee -f sftp://user@foo.org/mnt/secretfile -P 4242\n```\n\n`-P` Option Sets port for both HTTP and SFTP.\n\nExmaple Local File\n\n```bash\nshavee -f /mnt/usb/secret.png\n```\n\nThe idea with this method is to keep the file on a USB storage device or a Netork location you control and have it present during the login to derive the final encryption key.\n\nYou can use any pre existing file of your choice.\n\nOr create one using\n\n```bash\ndd if=/dev/uranson of=./secretfile bs=4096 count=4096\n```\n\n**Note: Since the file becomes part of your encryption key and its Security cannot be guaranteed as with Yubikey you are responsible for keeping it secure.**\n\n### 3. Password only\n\nIf no second factor is specified the program will use only password as a single factor.\n\n## Build and Install\n\n1. Install [Rust](https://www.rust-lang.org/tools/install)\n2. Clone repo using\n\n```bash\ngit clone https://github.com/ashuio/shavee.git\n```\n\n- [Optional] Enable or diasable `yubikey` and `file` feature by modifying `shavee-bin` [`Cargo.toml`](https://github.com/ashuio/shavee/blob/master/shavee-bin/Cargo.toml) to include or remove those features from the compiled binary.\n- [Optional] Enable or disable verbose debug `trace` logs by modifying `shavee-core` [`Cargo.toml`](https://github.com/ashuio/shavee/blob/master/shavee-core/Cargo.toml) to include or remove that feature from the compiled binary.\n  - If `trace` log feature is enabled, `RUST_LOG=trace` environment variable must also be set to generate logs. Otherwise no log will be generaged.\n    **NOTE: Enabling the trace logs, will increase the binary size and may expose the passphrase in the output logs. ONLY ENABLE IT FOR DEBUGGING PURPOSE AND DISABLE IT IN THE FINAL BINARY!**\n\n3. Build using the binary\n\n```bash\ncargo build --release\n```\n\n4. Place the binary in your bin directory with\n\n```bash\nsudo cp target/release/shavee /usr/bin\n```\n\n5. Place Pam module in your module directory with\n\n```bash\n sudo cp target/release/libshavee_pam.so /usr/lib/security/\n```\n\nModes\n\n- Shavee PAM Module : shavee PAM module to unlock home dir on login\n- Shavee Binary : Admin function for dataset management using shavee\n\nFlags/Options\n\n- `-y` : Use Yubikey for 2FA. Optionally takes in yubikey serial number or uses the first key\n- `-f` : Use any file as 2FA, takes filepath or a HTTP(S) location as an argument.\n- `-p` : Prints out the secret key.\n- `-d` : Adds dataset name to print output.\n- `-P` : Set port for HTTP and SFTP requests (Upper case P )\n- `-s` : Set Yubikey HMAC Slot (Can be either 1 or 2)\n- `-c` : Create/Change key of ZFS dataset with the derived encryption key\n- `-m` : Unlocks and Mounts the ZFS Dataset.\n- `-r` : Perform Operations Recursively to all child datasets.\n- `-a` : Automatically Detect Dataset Unlock Properties ( can only be used with `Print` and `Mount` )\n- `-z` : ZFS Dataset(s) to operate on. ( can take multiple options )\n\n**NOTE: The `-y` (Yubikey mode) flag and the `-f \u003cpath to file\u003e` (File mode) option are interchangeable.**\n\nIt is recommended to run the command to change keys again of your Datasets after version updates.\n\n## Configure ZFS Datasets\n\n**NOTE: If using with PAM your dataset password should be the SAME as your user account password for it to work automatically**\n\n**NOTE: Remember to update your encryption key as well if you update your password.**\n\n\u003cbr\u003e\n\n**You can change/update the key for existing ZFS datasets by running**\n\n```bash\nshavee -c -z \u003czfs dataset path\u003e\n```\n\n**Example**\n\n```bash\nshavee -y -c -z zroot/data/home/hunter zroot/data/home/hunter2\n```\n\nOr to use a specific key eneter it's serial number\n\n```bash\nshavee -y 12345678 -c -z zroot/data/home/hunter zroot/data/home/hunter2\n```\n\nHere we use Yubikey as our second factor. (Can be omitted for password only auth) and operate on TWO datasets together.\n\n**Note: Encryption must already be enabled and the key loaded to change key of an exisiting dataset if not created with shavee.**\n\n**Create a new dataset**\n\nTo create a new dataset with our derived encryption key simply run\n\n```bash\nsudo shavee -c -z \u003cDesired dataset\u003e\n```\n\nExample\n\n```bash\nsudo shavee -f /mnt/usb/secretfile -c -z zroot/data/home/hunter\n```\n\nHere we use a FILE for our second factor (Can be omitted for password auth only)\n\n## Use shavee to unlock and mount any zfs patition\n\nSimply use the option `-m` to unlock any zfs dataset\n\n**Example**\n\n```bash\nshavee -y -m -z zroot/data/home/hunter/secrets\n```\n\n## Backup Keys\n\nTo backup the key simply use the `-p` option to print the secret key to stdout\n\n**Example**\n\n```bash\nshavee -p -y -z zroot/data/home/hunter/secrets\n```\n\n**NOTE: Secret Keys are unique to your dataset even if you use the same password for multiple datasets.**\n\n## Use in Scripts\n\n**You can also pipe the password directly into shavee to use with scripts**\n\n**Example**\n\n```bash\necho \"hunter2\" | shavee -y -m -z zroot/data/home/hunter/secrets\n```\n\nHere \"hunter2\" will be treated as the password\n\n## Use a USB Drive instead of a Yubikey\n\nYou can use the `-f` option instead of the `-y` flag to substitute a Yubikey with any USB Drive.\n\nAuto mount the USB so shavee can find the required keyfile on login\n\n**We can use `udev` for this, simply create and add the following to `/etc/udev/rules.d/99-usb-automount.rules`**\n\n```\nACTION==\"add\", SUBSYSTEMS==\"usb\", SUBSYSTEM==\"block\", ENV{ID_FS_UUID}==\"\u003cUUID of partition\u003e\", RUN{program}+=\"/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode \u003cDesired Mount point\u003e\"\n```\n\n**Example**\n\n```\nACTION==\"add\", SUBSYSTEMS==\"usb\", SUBSYSTEM==\"block\", ENV{ID_FS_UUID}==\"ADB0-DA9C\", RUN{program}+=\"/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/usb\"\n```\n\nHere we're mounting the first partition of the usb disk to `/media/usb`\n\nYou can get the UUID by running\n\n```bash\nudevadm info --query=all --name=\u003cTarget disk\u003e | grep ID_FS_UUID=\n```\n\nExample\n\n```bash\nudevadm info --query=all --name=/dev/sdb1 | grep ID_FS_UUID=\n```\n\nRun `udevadm control --reload-rules` after to make sure new rules are loaded.\n\n## Use shavee with PAM to auto unlock homedir\n\nThis program comes with a pam module to execute during the login process.\n\nsimply add the following line to your desired pam login method file.\n\nIn our example we will be adding it to **/etc/pam.d/sddm** to handle graphical logins and **/etc/pam.d/login** to handle CLI logins.\n\n**Add the following line to you pam config file**\n\n```\nauth       optional    libshavee_pam.so \u003cBase home Dataset\u003e\nsession    optional    libshavee_pam.so \u003cBase home Dataset\u003e\n```\n\n**Example**\n\n```\nauth       optional    libshavee_pam.so zroot/data/home\nsession    optional    libshavee_pam.so zroot/data/home\n```\n\nWhere `zroot/data/home` mounts to `/home`\n\nNOTE: PAM module unlocks and mounts datasets recursively, any failure in any dataset will result in Failed Auth. This shold not stop you from logging in if PAM module is set to `optional` like we did in the Example.\n\nTo Force fail auth on dataset mount failure change it from `optional` to `required`\n\n## Dual home directories in ZFS\n\nSince ZFS mounts datasets OVER preexisting directories and we defined our module in PAM as optional we still get authenticated with JUST the pass even though our dataset is NOT decrypted (eg. Because Yubikey was not inserted).\n\nWe can use this to our advantage and essentially have TWO home directories.\n\nFirst which would be your normal encrypted home directory which would be unlocked and mounted when your Yubikey is present at login.\n\nSecond would be the directory which would already be present and would be loaded on decryption failure i.e when no Yubikey is inserted during login.\n\n[Let me know](mailto:?to=Ashutosh%20Verma%20%3cshavee@ashu.io%3e) if interested and maybe i can write up a more detailed guide.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashuio%2Fshavee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashuio%2Fshavee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashuio%2Fshavee/lists"}