gocryptfs with password saved in secret-tool
#!/usr/bin/env bash set -euo pipefail VAULT_NAME="${1:-vault}" if [[ ! "$VAULT_NAME" =~ ^[a-zA-Z0-9._-]+$ ]]; then echo "错误:保险库名称只能包含字母、数字、点、下划线和连字符" >&2 exit 1 fi CIPHER_DIR="$HOME/.local/share/${VAULT_NAME}.enc" MOUNT_DIR="$HOME/$VAULT_NAME" BIN_DIR="$HOME/.local/bin" SYSTEMD_DIR="$HOME/.config/systemd/user" CTL_SCRIPT="$BIN_DIR/gocryptfs-$VAULT_NAME" SERVICE_NAME="gocryptfs-$VAULT_NAME.service" SERVICE_FILE="$SYSTEMD_DIR/$SERVICE_NAME" SECRET_APP="gocryptfs" SECRET_VAULT="$VAULT_NAME" require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "错误:未找到命令 $1" >&2 exit 1 } } init_directories() { mkdir -p "$CIPHER_DIR" "$MOUNT_DIR" "$BIN_DIR" "$SYSTEMD_DIR" chmod 700 "$CIPHER_DIR" "$MOUNT_DIR" "$BIN_DIR" } store_password() { if secret-tool lookup app "$SECRET_APP" vault "$SECRET_VAULT" \ >/dev/null 2>&1; then echo "secret-tool 中已存在保险库密码" return fi local password confirm read -r -s -p "请输入 gocryptfs 密码: " password echo read -r -s -p "请再次输入密码: " confirm echo if [[ -z "$password" ]]; then echo "错误:密码不能为空" >&2 exit 1 fi if [[ "$password" != "$confirm" ]]; then echo "错误:两次输入的密码不一致" >&2 exit 1 fi printf '%s\n' "$password" | secret-tool store \ --label="gocryptfs $VAULT_NAME" \ app "$SECRET_APP" \ vault "$SECRET_VAULT" unset password confirm } init_vault() { if [[ -f "$CIPHER_DIR/gocryptfs.conf" ]]; then echo "加密目录已经初始化:$CIPHER_DIR" return fi gocryptfs -init \ -extpass "secret-tool lookup app $SECRET_APP vault $SECRET_VAULT" \ "$CIPHER_DIR" } install_control_script() { cat > "$CTL_SCRIPT" <<EOF #!/usr/bin/env bash set -euo pipefail CIPHER_DIR="$CIPHER_DIR" MOUNT_DIR="$MOUNT_DIR" SECRET_APP="$SECRET_APP" SECRET_VAULT="$SECRET_VAULT" get_password_command() { printf 'secret-tool lookup app %q vault %q' "\$SECRET_APP" "\$SECRET_VAULT" } case "\${1:-mount}" in mount) mkdir -p "\$MOUNT_DIR" if mountpoint -q "\$MOUNT_DIR"; then echo "已经挂载:\$MOUNT_DIR" exit 0 fi exec gocryptfs \ -extpass "\$(get_password_command)" \ "\$CIPHER_DIR" \ "\$MOUNT_DIR" ;; umount) if ! mountpoint -q "\$MOUNT_DIR"; then echo "未挂载:\$MOUNT_DIR" exit 0 fi if command -v fusermount3 >/dev/null 2>&1; then exec fusermount3 -u "\$MOUNT_DIR" else exec fusermount -u "\$MOUNT_DIR" fi ;; status) if mountpoint -q "\$MOUNT_DIR"; then echo "已挂载:\$MOUNT_DIR" else echo "未挂载:\$MOUNT_DIR" fi ;; *) echo "用法:\$0 {mount|umount|status}" >&2 exit 1 ;; esac EOF chmod 700 "$CTL_SCRIPT" } install_systemd_service() { cat > "$SERVICE_FILE" <<EOF [Unit] Description=Auto mount gocryptfs vault: $VAULT_NAME After=default.target [Service] Type=forking ExecStart=$CTL_SCRIPT mount ExecStop=$CTL_SCRIPT umount Restart=no [Install] WantedBy=default.target EOF chmod 600 "$SERVICE_FILE" } enable_service() { systemctl --user daemon-reload systemctl --user enable "$SERVICE_NAME" systemctl --user restart "$SERVICE_NAME" 2>/dev/null || systemctl --user start "$SERVICE_NAME" } main() { require_cmd gocryptfs require_cmd secret-tool require_cmd mountpoint require_cmd systemctl init_directories store_password init_vault install_control_script install_systemd_service enable_service echo echo "初始化完成" echo "加密目录:$CIPHER_DIR" echo "明文目录:$MOUNT_DIR" echo "服务名称:$SERVICE_NAME" echo echo "当前状态:" "$CTL_SCRIPT" status } main "$@"
secret-tool
命令格式是:
secret-tool lookup 属性名1 属性值1 属性名2 属性值2 ...

浙公网安备 33010602011771号