32个版本
0.5.5 | 2024年4月12日 |
---|---|
0.5.4 | 2023年2月8日 |
0.5.3 | 2022年6月10日 |
0.5.1 | 2021年12月5日 |
0.3.16 | 2020年11月19日 |
#249 in 命令行工具
115KB
2.5K SLoC
Please,一个sudo替代品
轻松委派精确的最小权限访问。用正则表达式轻松表达,仅暴露所需内容,不暴露更多。或者用pleaseedit
验证文件编辑。
在不给予用户完整root shell的情况下管理您的盒子,大多数管理员都有一段时间的regex经验,所以让我们以这种方式配置访问。
我看到正则表达式但不喜欢正则表达式。没问题,您仍然可以使用请和请edit而不使用正则表达式,使用exact_
对应的项,或者将每个字段/属性视为纯文本,并转义控制字符?(){}[]+
等。大多数正则表达式匹配语句都有exact
对应的项。
Please是用内存安全的rust编写的。避免了传统的C内存不安全,逻辑问题可能存在,但这个代码库相对较小。
我该如何安装它
它可能已经在您使用的仓库中
如果没有,安装很简单
git clone https://gitlab.com/edneville/please.git
cd please
cargo test && cargo build --release \
&& install -o 0 -g 0 -m4755 target/release/please target/release/pleaseedit /usr/local/bin
Arch
pacman -Syu git fakeroot devtools binutils gcc rust
git clone https://aur@aur.archlinux.org/pleaser.git
cd pleaser && makepkg -isr
Debian/Ubuntu
apt install pleaser
Fedora (35)
dnf install pleaser
NetBSD
pkgin install pleaser
SUSE Tumbleweed
zypper install pleaser
RHEL 7 (EPEL)
yum install cargo git pam-devel
git clone 'https://gitlab.com/edneville/please.git'
cd please/
cargo test && cargo build --release && install -oroot -groot -D -m4755 target/release/please target/release/pleaseedit /usr/local/bin
可选地,将sudo
作为please
的别名
alias sudo="please"
alias sudoedit="pleaseedit"
或者,如果您愿意,在本地创建符号链接
cd /usr/local/bin && ln -s /usr/local/bin/please sudo && ln -s /usr/local/bin/pleaseedit sudoedit
我该如何设置它
如果您没有使用发行版包,您可能需要配置PAM才能使require_pass
进行身份验证。基于Debian的需要在/etc/pam.d/please
和/etc/pam.d/pleaseedit
中类似的东西
#%PAM-1.0
# Set up user limits from /etc/security/limits.conf.
session required pam_limits.so
@include common-auth
@include common-account
@include common-session-noninteractive
基于Red Hat的需要在同一文件中有类似的东西
#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth
接下来,配置您的/etc/please.ini
,用适当的值替换用户名。ini
被分为部分选项、匹配和动作。
部分选项
部分 | 效果 |
---|---|
[section-name] | 部分名称,在列表模式下显示 |
include=file | 将文件作为另一个ini源文件,本节将跳过其他选项。 |
includedir=dir | 将.ini 文件的目录作为其他源,按ascii排序,本节将跳过其他选项。不匹配.ini 的文件将被忽略,以允许编辑器临时文件。 |
include
和includedir
将覆盖强制参数。
匹配
最简单的一种,不需要密码验证,可以定义如下,假设用户是jim
选项如下
部分 | 效果 |
---|---|
name=regex | 强制,将配置应用于此实体。 |
target=regex | 可能成为以下用户。 |
rule=regex | 这是该节区的命令正则表达式,默认为^$ |
notbefore=YYYYmmdd | 生效日期,或YYYYmmddHHMMSS |
notafter=YYYYmmdd | 过期日期,或YYYYmmddHHMMSS |
datematch=[Day dd Mon HH:MM:SS UTC YYYY] | 与日期字符串匹配的正则表达式 |
type=edit/run/list | 设置条目类型,run = 执行,edit = pleaseedit,list = 显示用户权限 |
group=true/false | 为true表示name=指的是组而不是用户。 |
hostname=regex | 应用此规则的宿主,默认为'localhost'。 |
target_group=regex | 当设置时,必须提供一个匹配的组。 |
dir=regex | 允许在执行前切换到正则表达式定义的目录。 |
permit_env=regex | 当与-a 结合使用时,允许匹配环境键 |
search_path=string | 将search_path更改为以冒号分隔的目录列表 |
精确匹配,必须完全匹配。当同时存在正则表达式和精确规则时,精确规则匹配将具有优先级。
部分 | 效果 |
---|---|
exact_name=string | 匹配此精确名称 |
exact_hostname=string | 匹配此精确主机名 |
exact_target=string | 匹配此精确目标用户 |
exact_target_group=string | 匹配此精确目标组 |
exact_rule=string | 匹配此精确规则 |
exact_dir=string | 匹配此精确目录 |
操作
部分 | 效果 |
---|---|
permit=true/false | 默认为true |
require_pass=true/false | 默认为true |
last=true/false | 当为true时,匹配后停止处理,默认为false |
reason=true/false/regex | 当设置时,要求提供-r 的原因,默认为false |
timeout=[number] | 等待密码输入的时间(以秒为单位) |
syslog=true/false | 将此活动记录到syslog,默认=true |
token_timeout=[number] | 认证令牌有效的时间(以秒为单位) |
env_assign.key=value | 强制将环境键key 分配为value |
exitcmd=[程序] | (pleaseedit) 如果程序退出0,则继续文件替换 |
editmode=[八进制模式/keep] | (pleaseedit) 设置目标文件模式为: ,或保留现有文件的模式。如果文件不存在或未声明模式,则模式回退为0600。如果存在文件,则读取并使用该模式在文件重命名之前 |
在正则表达式字段中使用贪婪的.*
相当于指定规则应该匹配任何命令。在之前的版本中,没有锚点(^
和$
),但是似乎更合理地遵循find
的方法,坚持在正则表达式周围有锚点。这避免了/bin/bash
匹配/home/user/bin/bash
。
如果遇到include
指令,则不会处理该节中的其他条目。对于includedir
也是同样的情况。
规则的顺序很重要。最后匹配的规则将获胜。如果您想排除某些内容,请设置permit=false
,但这应该很少见,因为许可应该是针对正则表达式,而不是使用正匹配然后是负匹配。最佳实践规则是避免开启失败,然后尝试排除大多数内容。
例如,使用以下两个条目
[jim_root_du]
name = jim
target = root
permit = true
rule = ^(/usr)?/bin/du (/home/[a-z0-9-]+\s?)+
require_pass=false
[jim_postgres]
name = jim
target = postgres
permit = true
rule = /bin/bash
require_pass = false
将允许以root
身份运行du
,作为/usr/bin/du
或/bin/du
$ please du /home/*
还将允许以postgres
身份运行bash shell
$ please -t postgres /bin/bash
postgres$
日期范围
对于大型环境,第三方可能需要在短时间内进行调试,这是很常见的。为了适应这种情况,有notbefore
和notafter
时间范围。这些可以是YYYYMMDD
或YYYYMMDDHHMMSS
。
使用较短的日期格式YYYYMMDD
时,整个一天都被考虑在内。
许多企业可能希望仅允许用户在有限的时间内访问,即使该个人永久担任该角色。
日期匹配
另一种日期类型是datematch
项,这限制了部分只能与日期字符串的正则表达式匹配。
您可以对一些用户组执行一些家务活。
[l2_housekeeping]
name = l2users
group = true
target = root
permit = true
rule = /usr/local/housekeeping/tidy_(logs|images|mail)
datematch = ^Mon.*
默认部分
当匹配部分名称以default
开头时,将设置默认设置,直到下一个匹配部分被覆盖。如果没有其他匹配的部分,则默认设置将保留。
请编辑
pleaseedit
允许编辑文件,而不是执行它们。
默认情况下,文件权限位将镜像现有文件权限。
按照以下方式执行
- 用户运行编辑作为
pleaseedit
。 /etc/fstab
被复制到/tmp/pleaseedit.$USER
。- 用户编辑文件。
- 用户保存并退出编辑器。
pleaseedit
将文件复制回/etc/fstab
。
exitcmd
exitcmd 可以在将临时编辑文件移动到源位置之前使用。这可以用来在就地重命名之前测试配置文件是否有效。
对于类似于 Apache 的东西,考虑在运行测试之前将配置树复制到临时目录,以适应包含。
其他示例
audio 组的成员可以使用 userdel
删除应用程序可能没有清理的临时用户,形式为 username_tmp.<10 随机字母数字>
[user_remove_tmp_user]
name = audio
group = true
permit = true
require_pass = false
rule = /usr/sbin/userdel -f -r %{USER}_tmp\.[a-zA-Z0-9]{10}
关于家务管理,一些用户可能被允许销毁看起来像日期戳的 zfs 快照
[user_remove_snapshots]
name = data
group = true
permit = true
require_pass = false
rule = /usr/sbin/zfs destroy storage/photos@\d{8}T\d{6}
列出你可以或不可以做的事情
$ please -l
You may run the following:
file: /etc/please.ini
ed_root_list:root: ^.*$
You may edit the following:
file: /etc/please.ini
ed_edit_ini:root: ^/etc/please.ini$
上面的输出显示我可以运行任何东西,并且可以编辑 please.ini
配置。
或者,也许任何名字以 admin
开头的用户都可以执行 useradd
和 userdel
[admin_users]
name = admin_\S+
permit = true
require_pass = false
rule = /usr/sbin/user(add -m|del) \S+
文件
/etc/please.ini
大型安装
对于大型安装,考虑以下
合并
当你可以使用组时,所有成员的最小权限匹配集合。在这里最好考虑人们通常执行相同的角色,所以尽量按照这种方式组织规则,使用组或使用单个 name
正则表达式匹配单个名称。
中央配置考虑因素
为了避免服务中的单点故障,ini
配置应在单个位置生成并推送到安装。与访问 LDAP 相比,ini
文件解析非常快,而访问 LDAP 不仅速度慢,而且容易出错。
可能可以使用缓存,但需要正面的(正确匹配)和负面的(错误匹配)。10,000 台计算机上有数百名活跃用户对 LDAP 服务器进行查找可能会有问题。
因此,我更喜欢使用 rsync 分发,因为该协议效率很高,总体上减少了网络传输。
将来可能会重新考虑 LDAP。
贡献
如果你发现任何你认为缺失的东西,无论初始设计如何,请随时提出问题,无论是否有拉取请求。
定位错误和记录问题非常受赞赏,我提前表示感谢。
我张开双臂欢迎拉取请求。
位置
此项目的源代码目前托管在 gitlab 上,并镜像到 github。它还有一个 主页,其中包含其他项目信息。
为什么在某些圈子中叫 pleaser?
这个项目命名为 "please"。在某些地方,这个项目名称被其他人用于其他事情。一些包将命名为 pleaser,一些将命名为 please。唯一重要的是,如果你想让人为你做三明治,首先说 "please"。
依赖关系
~6–33MB
~489K SLoC