如何为已部署到/bin目录的C语言可执行命令添加特定用户密码保护
好的,我来帮你解决这个问题——给自定义系统命令添加密码保护,让root直接执行,特定普通用户需要验证密码才能使用。下面是一套简单可行的实现方案,分步骤操作:
实现步骤
1. 迁移原可执行文件
首先,把你的命令移到一个普通用户无法直接访问的目录,避免他们绕过验证直接执行原命令。我们用/usr/local/bin/这个目录,然后设置严格权限:
# 假设你的命令原名为mycmd,当前在/bin/mycmd sudo mv /bin/mycmd /usr/local/bin/mycmd_real sudo chmod 700 /usr/local/bin/mycmd_real sudo chown root:root /usr/local/bin/mycmd_real
这样只有root能直接运行mycmd_real,普通用户连执行权限都没有。
2. 创建包装脚本
在/bin/下创建和原命令同名的包装脚本,用来处理权限检查和密码验证。这里提供两种常用方案,你可以根据需求选择:
方案一:验证用户系统密码(推荐,更安全)
这种方案直接用用户的系统密码做验证,不需要额外存储密码,安全性更高。创建/bin/mycmd脚本:
#!/bin/bash # 替换成你允许执行该命令的特定用户名,多个用户用空格分隔 ALLOWED_USERS="alice bob" # 原命令的路径 REAL_CMD="/usr/local/bin/mycmd_real" # 获取当前执行命令的用户名 CURRENT_USER=$(whoami) # root用户直接跳过验证,执行原命令 if [ "$CURRENT_USER" = "root" ]; then exec "$REAL_CMD" "$@" exit $? fi # 检查当前用户是否在授权列表中 if [[ ! " $ALLOWED_USERS " =~ " $CURRENT_USER " ]]; then echo "Error: You don't have permission to run this command." >&2 exit 1 fi # 验证用户的系统密码(sudo -k 强制重置时间戳,确保每次都要输密码) echo "Enter your system password to proceed:" sudo -k if ! sudo -v; then echo "Invalid password." >&2 exit 1 fi # 密码验证通过,执行原命令(保留所有传入的参数) exec "$REAL_CMD" "$@"
方案二:使用独立专属密码
如果你不想依赖用户的系统密码,想要一个独立的命令专属密码,可以用这种方案,但要注意加密存储密码:
第一步:生成密码哈希
先把你的专属密码加密存储,避免明文泄露:
# 替换为你想要的命令密码和唯一密钥(密钥要保密) COMMAND_PASS="your_strong_command_password" SECRET_KEY="your_unique_secret_key_123" # 生成密码哈希并存储到只有root能读的文件 echo -n "$COMMAND_PASS" | openssl dgst -sha256 -hmac "$SECRET_KEY" | sudo tee /usr/local/etc/mycmd_passwd.hash sudo chmod 600 /usr/local/etc/mycmd_passwd.hash sudo chown root:root /usr/local/etc/mycmd_passwd.hash
第二步:创建包装脚本
#!/bin/bash ALLOWED_USERS="alice bob" REAL_CMD="/usr/local/bin/mycmd_real" HASH_FILE="/usr/local/etc/mycmd_passwd.hash" SECRET_KEY="your_unique_secret_key_123" # 要和上面的密钥完全一致 CURRENT_USER=$(whoami) if [ "$CURRENT_USER" = "root" ]; then exec "$REAL_CMD" "$@" exit $? fi if [[ ! " $ALLOWED_USERS " =~ " $CURRENT_USER " ]]; then echo "Error: Unauthorized user." >&2 exit 1 fi # 读取用户输入的密码(隐藏输入内容) echo -n "Enter command password: " read -s USER_PASS echo # 生成输入密码的哈希并和存储的哈希比对 USER_HASH=$(echo -n "$USER_PASS" | openssl dgst -sha256 -hmac "$SECRET_KEY") STORED_HASH=$(cat "$HASH_FILE") if [ "$USER_HASH" != "$STORED_HASH" ]; then echo "Invalid password." >&2 exit 1 fi # 验证通过,执行原命令 exec "$REAL_CMD" "$@"
3. 设置脚本权限
给包装脚本设置正确的权限,确保所有用户能执行,但只有root能修改:
sudo chmod 755 /bin/mycmd sudo chown root:root /bin/mycmd
4. 测试验证
现在可以测试效果了:
- 用root用户执行
mycmd:直接运行原命令,不会提示输入密码。 - 用授权的普通用户执行
mycmd:会提示输入密码,验证通过后执行原命令。 - 用未授权的普通用户执行
mycmd:直接返回权限错误,无法执行。
额外注意事项
- 务必确保原命令
mycmd_real的权限是700且属主为root,这是防止用户绕过脚本的关键。 - 方案一中,如果你想保留sudo的时间戳机制(比如5分钟内重复执行无需输密码),可以去掉脚本里的
sudo -k命令。 - 方案二中,密钥和哈希文件一定要严格保密,不要让其他用户读取到。
内容的提问来源于stack exchange,提问作者Tarang
相关产品推荐
相关产品推荐

