{"id":17383613,"url":"https://github.com/g1eng/l8ash","last_synced_at":"2025-04-15T10:02:52.938Z","repository":{"id":190404417,"uuid":"682064582","full_name":"g1eng/l8ash","owner":"g1eng","description":"A restrictive shell for system operators","archived":false,"fork":false,"pushed_at":"2023-08-24T14:51:18.000Z","size":51,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T19:07:42.737Z","etag":null,"topics":["command-line-tool","shell","system-shell"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/g1eng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.apache","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-23T11:09:05.000Z","updated_at":"2023-09-26T23:23:43.000Z","dependencies_parsed_at":"2023-08-24T16:38:46.177Z","dependency_job_id":null,"html_url":"https://github.com/g1eng/l8ash","commit_stats":null,"previous_names":["g1eng/leash","g1eng/l8ash"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g1eng%2Fl8ash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g1eng%2Fl8ash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g1eng%2Fl8ash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g1eng%2Fl8ash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/g1eng","download_url":"https://codeload.github.com/g1eng/l8ash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249048731,"owners_count":21204306,"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":["command-line-tool","shell","system-shell"],"created_at":"2024-10-16T07:43:15.757Z","updated_at":"2025-04-15T10:02:52.900Z","avatar_url":"https://github.com/g1eng.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n\n[![codecov](https://codecov.io/gh/g1eng/l8ash/graph/badge.svg?token=GG320A1HH8)](https://codecov.io/gh/g1eng/l8ash)\n\n__*l8ash*__ is a command line shell which is designed to have the least attack surface \non its command line interface.\n\nIf you need to **leash shells and shell users**, you would like to permit certain operation only on your shells\nwith pre-defined operational procedures, which contain a set of commands and corresponding arguments, without\nany unnecessary statements including  shell variables, variable expansions, inline command invocation,\ndeclaration of shell functions nor command expansions.\n\n`l8ash` provides very limited shell features but strong support to restrict command invocation.\nYou can permit users only to do typical administration tasks with pre-defined pipelines and its environments.\nTo enable this feature, a runtime configuration file (~/.l8ashrc) is required and its whitelist table must contain `named pipelines` (pipeline alias) for target operations.\nOptionally, l8ash can also check the integrity of command binaries when it is invoked on the shell (as a pre-defined pipeline).\n\n`l8ash` empowers you to protect systems and assets you should keep it always safe.\n\n# Installation\n\n```shell\ncargo install l8ash\n```\n\n(Be careful, binary name is `l8ash`, not `l8ash`!)\n\nOr you can install binary, building from your local source code:\n\n```shell\ncd path/to/this/repo\nmake\nsudo make install\n```\n\nIf you do not have permission to access to the system path, you can install it under your home directory:\n\n```shell\nmake\nPREFIX=$HOME/local make install\n\n# set your PATH if you need\n# echo PATH=\\$HOME/local/bin:\\$PATH | tee -a $HOME/.bashrc\n```\n\n# Quick start\n\n### 1. Simply invoke it as a program\n\n```shell\n$ l8ash\n```\n\n### 2. Feed an acceptable shell script\n\n```shell\n$ cat some_l8ash_script.sh\n#!/bin/sh\nls -l | tr -d \\\\\\n \n$  cat some_l8ash_script.sh | l8ash\n```\n\n### 3. Feed shell script as the argument\n\n```shell\n$  l8ash some_l8ash_script.sh \n```\n\n### 4. Set *l8ash* as the user's default shell\n\n```shell\n{ \n  [ -x /bin/l8ash ] || {\n    echo l8ash not found \u003e\u00262\n    false\n  } \u0026\u0026\n  grep /bin/l8ash /etc/shells \u003e /dev/null || {\n    echo failed to set l8ash as your default shell. consider to add `/bin/l8ash` to your /etc/shells. \u003e\u00262\n    false\n  } \n} \u0026\u0026 chsh -s /bin/l8ash \n```\n\n### 5. Play.\n\n```shell\nls -l | awk {gsub(\"-\",\"neko\",$0);print;} | tr 0  @ | tee -a something.funny | bzip2 | dd of=sf.bz2\n```\n\n# Features\n\n* Generic commandline interface to invoke commands with raw argument, **without any shell variables and shell functions**.\n* Some of POSIX shell functionalities are **NOT IMPLEMENTED** to achieve the hardened shell experience. The l8ash has:\n  - No builtin commands (no `echo`, `printf`, `cd`, `kill` nor `exit` as a builtin. No other builtins in the world too.)\n  - No shell variable `var=val` and `$var`\n  - No expansion (no path expansion with * or other special glob characters, neither variable nor command expansion.)\n  - No command alias `alias name=\"cmd arg1 arg2\"`\n  - No shell function `function f1 { ... }`, `f1(){ ... }` nor `function f1 () { ... }`\n  - No string literal `'...'` nor `\"...\"`\n  - No subcommand `(...)`\n  - No group command `{...}`\n  - No background tasks `cmd \u0026`\n  - No redirection `cmd \u003e file` nor `cmd \u003e\u003e file`\n  - No indirection `cmd \u003c file`\n  - No command termination with semicolon `cmd1; cmd2; cmd3`\n* **No string literals** (said again). A whitespace is always recognized as a word separater.\n\n\n* **Pipeline**: Ordinal pipeline for system shell. It is only the way to modify temporary input/output in a shell session.\n* **Runtime configuration**: You can write operation **whitelist** and other configuration in ~/.l8ashrc.\n* Command **whitelist**: l8ash prohibits any commands other than listed names (named pipeline) on the whitelist table.\n* **named pipeline / pipeline alias**: permitted operations can be declared as **named pipeline**s in a configuration file.\n* **Environmental variables**: Environmental variable for a pipeline can be specified and applied to all command in the pipeline.\n* **Integrity checker**: l8ash can check the integrity of command binaries which composes a pipeline.\n\n# Configuration Tips\n\n## Make whitelist only to permit specific programs\n\nTo run l8ash in restricted mode, create `~/.l8ashrc` and declare `[[whitelist]]` in that:\n\n```toml\n[[whitelist]]\nname = \"ls\"\ncommand_line = \"/bin/ls\"\nenv = []\nintegrity = []\n```\n\nWith this configuration, user on the l8ash session cannot execute program, other than `/bin/ls`.\nFor an operation with a single program like this case, `command_line` fields should be a full path of the program and its arguments.\n\n#### ATTENTION\n\nThe path of .l8ashrc can be switched with `LEASH_CONF` environmental variable. If `l8ash` binary is invoked with preset `LEASH_CONF`, it refers customized path for the runtime configuration.\n\n## Set pipeline aliases (or named pipeline) on the whitelist\n\nYou can declare command alias in a whitelist table.\nFor the previous example, set an alias in the `name` field for the operation:\n\n```toml\n[[whitelist]]\nname = \"l\"\ncommand_line = \"/bin/ls\"\nenv = []\nintegrity = []\n```\n\nWith this configuration, you can invoke `/bin/ls` with the name (alias) `l`, but not with its real name `ls`.\nYou cannot invoke `/bin/ls` with its full path or its real name. (and you cannot invoke the program named `l`, if it exists in your PATH).\n\nAlso, you can declare pipeline alias with the same mechanism. Set pipeline statement in the command attribute like following:\n\n```toml\n[[whitelist]]\nname = \"count_files\"\ncommand_line = \"/bin/ls | wc -l\"\nenv = []\nintegrity = []\n```\n\n## Pass environmental variables for a pipeline\n\n```toml\n[[whitelist]]\nname = \"kci\"\ncommand_line = \"/home/mofuzawa/bin/kubectl cluster-info\"\nenv = [\"KUBECONFIG=/var/conf/dist/your-kube-config\"]\nintegrity = []\n```\n\n## Check integrity for each command for a pipeline\n\n```\n[[whitelist]]\nname = \"lstr\"\ncommand_line = \"/bin/ls -l | /bin/tr - o\"\nenv = []\nintegrity = [\n        \"a3604f3968fda1471dfdb51a3a4454d8a1b6c3dead99e84f442b515b9b49da53\",\n        \"3138ff15c875f111613407f39261babafbfe8cdc77a4c1cebb834334b78b9f0b\",\n]\n```\n\n#### ATTENTION\n\nFor integrity checking, all command must be spelled with its full path, unless the command is not invokable because of failure on path discovery.\n\n# Design concept\n\nSee the second clause of the [Features](#features) above.\nEach condition, which means the lack of the generic shell feature, is a building block of the \u003cu\u003e**l8ash security model**\u003c/u\u003e.\n\n| Specification                  | Description (especially for the security)                                                            |\n|--------------------------------|------------------------------------------------------------------------------------------------------|\n| No builtins                    | No hack with shell builtins                                                                          |\n| No shell variable              | No worry about any dangerous contents inside variables                                               |\n| No expansion                   | No worry about unexpected expansion to be evaluated as malformed commands or strings                 |\n| No command aliases             | No new set of attack codes in the shell session                                                      |\n| No shell functions             | No new set of attack codes in the shell session                                                      |\n| No string literal              | No confusion of several equivalent text expressions. Escape character is the only permitted way.     |\n| No subcommand                  | No fork in the shell by itself. Only processes are spawned by the shell in a pipeline                |\n| No group command               | No bundle of stdout/stderr. A command has single I/O in a pipeline.                                  |\n| No background tasks            | No unmanaged processes which is hanged up after the spawning.                                        |\n| No redirection nor indirection | No read/write operation for the shell itself. Filesystem I/O is only permitted for commands.         |\n| No semicolon                   | EOL is the only-one op code for the list evaluation. Thus, a list must be a pipeline in the *l8ash*. |\n\nIn addition, l8ash ensures users only to invoke trusted programs via whitelist.\n\n### ATTENTION\n\nLeash does not cover the protection of filesystem or its contents.\nIt is recommended to use other mechanisms to protect filesystem from potentially malicious programs or exploits.\nThe risk of overwriting or replacing l8ashrc/l8ash itself, is a critical factor for the l8ash safety.\n\n# Bug reports\n\nMake issues, thanks!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg1eng%2Fl8ash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fg1eng%2Fl8ash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg1eng%2Fl8ash/lists"}