简介
keysudo.sh
是一个用于安全存储和调用 sudo 密码的 Bash
脚本工具,通过 GNOME Keyring
实现敏感信息的加密存储。脚本设计目标是通过密钥环系统减少密码的明文暴露,同时解决
sudo 验证失败导致的账户锁定问题。
主要功能
- 🔐 自动将 sudo 密码存储至 GNOME Keyring
- 🔄 支持 3 次验证尝试(可配置)
- ⚠️ 智能检测系统环境(支持 Arch/RHEL 系)
- 🔒 密码输入支持 systemd-ask-password 工具
- 🛡️ 密码错误时自动重置 sudo 失败计数
- 🚫 杜绝密码明文存储和传输
快速使用
基础用法
1 2 3 4 5 6
| syndns_password=$(./keysudo.sh)
echo $syndns_password | sudo -S your_command unset syndns_password
|
安装依赖
1 2 3 4 5
| sudo pacman -S pambase libsecret
sudo yum install pam libsecret-tools
|
卸载密码
1
| secret-tool clear syndns_password_key syndns_password
|
常见问题
Q1: 密码无法存储到密钥环
1 2 3 4
| gnome-keyring-daemon --start
echo "test" | secret-tool store --label="Test" test_key test_value
|
Q2: sudo 被锁定后如何处理
1 2 3 4 5
| sudo pam_tally2 --user $USER
sudo faillock --reset
|
程序源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #! /bin/bash
SYN_KEY="syndns_password" SYN_SUDO_NUM_MAX="3"
if ! command -v secret-tool &>/dev/null; then echo "错误:需要安装 secret-tool(包名:libsecret-tools)" >&2 exit 1 fi
SYN_RES_CMD="" if command -v faillock &>/dev/null; then SYN_RES_CMD="faillock --user $USER --reset" elif command -v pam_tally2 &>/dev/null; then SYN_RES_CMD="pam_tally2 --user $USER --reset" else echo "错误:未找到可用SUDO解锁工具 !" >&2 echo "请安装:Arch系安装pambase,RHEL系安装pam" >&2 exit 1 fi
SYN_KEY_GET(){ local SYN_AMT="$SYN_SUDO_NUM_MAX" while [[ "$SYN_AMT" -gt 0 ]]; do SYN_KEY_X=$(secret-tool lookup syndns_password_key "$SYN_KEY") if [[ -z "$SYN_KEY_X" ]]; then unset SYN_KEY_DATA if command -v systemd-ask-password &>/dev/null; then SYN_KEY_DATA=$(systemd-ask-password --timeout=30 "请求sudo密码:") else printf "$0 请求输入sudo密码(30秒超时):" >&2 if ! read -rs -t 30 SYN_KEY_DATA; then printf "\n输入超时,操作取消。\n" >&2 unset SYN_KEY_DATA exit 1 fi fi if [[ -z "$SYN_KEY_DATA" ]]; then printf "\n密码不能为空,请重新输入。\n" >&2 else if printf "%s" "$SYN_KEY_DATA" | secret-tool store --label="Syndns Password" syndns_password_key "$SYN_KEY"; then sudo -k if printf "%s" "$SYN_KEY_DATA" | sudo -S -v 2>/dev/null; then unset SYN_KEY_DATA printf "\n密码已成功存储到 GNOME Keyring 中。\n" >&2 return 0 else SYN_AMT=$((SYN_AMT - 1)) SYN_FAIL_RES "警告:当前系统可能需要手动重置失败计数!" fi else printf "\n无法存储密码,请检查 GNOME Keyring 是否可用。\n" >&2 exit 1 fi fi else sudo -k if ! printf "%s" "$SYN_KEY_X" | sudo -S -v 2>/dev/null; then SYN_AMT=$((SYN_AMT - 1)) secret-tool clear syndns_password_key "$SYN_KEY" SYN_FAIL_RES "警告:当前系统可能需要手动重置失败计数!" else return 0 fi fi done printf "尝试次数已达上限,操作终止。\n" >&2 SYN_FAIL_RES "请切换至ROOT权限解除锁定: $SYN_RES_CMD" exit 1 } SYN_FAIL_RES(){ if grep -qi 'arch' /etc/os-release 2>/dev/null; then faillock --user $USER --reset else printf "$1 \n" >&2 [ -n "$SYN_RES_CMD" ] && echo "可尝试执行: sudo $SYN_RES_CMD" >&2 fi } sudo -k SYN_KEY_GET echo $SYN_KEY_X
|