以下の内容はhttps://rubyu.hatenablog.com/entry/2025/07/11/171948より取得しました。


Secure Password Management in WSL: Building an Integrated Backup Environment with Pass and GPG

Secure Password Management in WSL: Building an Integrated Backup Environment with Pass and GPG

Introduction

Password management is an eternal challenge for developers. Especially in WSL (Windows Subsystem for Linux) environments, how to backup credentials managed on the Linux side becomes a critical issue.

This article explains how to build a system that combines the command-line password manager "Pass" with GPG encryption to automatically backup to the Windows side.

Goals

  • Security: Strong security through GPG encryption
  • Convenience: Quick access from the command line
  • Automation: Automatic backup via Git integration
  • Recoverability: Reliable restoration from Windows-side backups
  • Unified Management: Managing passwords and GPG keys in a single repository

Understanding Pass and GPG

What is Pass?

Pass, short for "password store," is a simple password management tool for Unix/Linux. Developed by Jason A. Donenfeld in 2012, it has the following features:

  • Text file-based: Each password is stored as an individual file
  • Combination of standard tools: Utilizes GPG, Git, tree commands, etc.
  • Extensibility: Easily customizable with shell scripts

What is GPG (GNU Privacy Guard)?

GPG is encryption software based on the OpenPGP standard:

  • Public key cryptography: Uses public and private key pairs
  • Digital signatures: Ensures data integrity and authentication
  • Web of Trust: Decentralized trust model

Role Division between Pass and GPG

┌─────────────────────────────────────────┐
│            Pass (Management Layer)       │
│  - Directory structure management        │
│  - Git integration                       │
│  - Command-line interface               │
└────────────────┬────────────────────────┘
                 │ Encryption/Decryption requests
                 ↓
┌─────────────────────────────────────────┐
│           GPG (Encryption Layer)         │
│  - Actual encryption/decryption process  │
│  - Key management                        │
│  - Security guarantee                    │
└─────────────────────────────────────────┘

Detailed Interaction

  1. Password Storage Flow ```bash pass insert github.com/personal

    ↓ Pass receives input

    ↓ Requests GPG to encrypt

    ↓ GPG encrypts with public key

    ↓ Pass saves as .gpg file

    ```

  2. Password Retrieval Flow ```bash pass show github.com/personal

    ↓ Pass reads .gpg file

    ↓ Requests GPG to decrypt

    ↓ GPG decrypts with private key (passphrase required)

    ↓ Pass displays plaintext

    ```

Why Choose Pass?

Pass Features

  • Unix philosophy: Each password as an individual GPG-encrypted file
  • Git integration: Built-in version control
  • Simple: No unnecessary features, robust
  • Standard: Available in many Linux distributions

Comparison with Other Options

  • KeePass: GUI-based and feature-rich, but limited CLI operations
  • Bitwarden: Cloud sync is convenient, but not locally self-contained
  • 1Password: Paid and feature-rich, but overkill

System Architecture

Architecture Diagram

Windows Host
│
├─ C:\gpg-keys-backup\
│  └─ wsl-personal-pass.git/ (Bare Repository)
│     ├─ GPG key backups
│     └─ Encrypted passwords
│
└─ WSL Ubuntu
   └─ ~/secure/pass-with-gpg/
      ├─ .git/ (Auto-push configured)
      ├─ gpg-keys/
      │  ├─ pass-secret-key.asc
      │  ├─ pass-public-key.asc
      │  └─ key-info.txt
      └─ password-store/
         └─ *.gpg (Encrypted passwords)

Data Flow

1. pass insert/generate
   ↓
2. GPG encryption
   ↓
3. Git auto-commit
   ↓
4. Git Hooks (post-commit)
   ↓
5. Auto-push to Windows repository

Prerequisites

Environment Requirements

Complete Setup Procedure

Setting Environment Variables

First, set the following variables according to your environment:

# Windows-side backup directory (change according to your environment)
export BACKUP_DIR="/mnt/c/gpg-keys-backup"
export REPO_NAME="wsl-personal-pass.git"

# WSL-side working directory
export WORK_DIR="$HOME/secure/pass-with-gpg"

# GPG key settings (name and email for Pass)
export GPG_NAME="Pass Manager"
export GPG_EMAIL="pass@localhost"

1. Installing Required Tools

# System update
sudo apt update

# Install required tools
sudo apt install -y gnupg pass git tree

# Verify installation
gpg --version
pass --version
git --version

2. Creating Windows-side Git Repository

Execute in Windows Command Prompt or PowerShell:

# Create backup directory
mkdir C:\gpg-keys-backup
cd C:\gpg-keys-backup

# Initialize Git repository
git init --bare wsl-personal-pass.git

Or, execute from WSL:

# Create Windows-side directory from WSL
mkdir -p "$BACKUP_DIR"
cd "$BACKUP_DIR"

# Initialize Git repository
git init --bare "$REPO_NAME"

3. Creating GPG Key (Pass-specific)

# Generate GPG key
gpg --batch --generate-key <<EOF
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: $GPG_NAME
Name-Email: $GPG_EMAIL
Expire-Date: 2y
%no-protection
%commit
EOF

# Automatically retrieve generated key ID
export PASS_GPG_ID=$(gpg --list-secret-keys --keyid-format LONG | grep -A1 "^sec" | grep "$GPG_EMAIL" -B1 | head -1 | awk '{print $2}' | cut -d'/' -f2)

# Verify
echo "Generated GPG Key ID: $PASS_GPG_ID"
gpg --list-secret-keys --keyid-format LONG

4. Building Integrated Repository

# Create working directory
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"

# Initialize as Git repository
git init
git remote add origin "$BACKUP_DIR/$REPO_NAME"

# Create directory structure
mkdir -p gpg-keys
mkdir -p password-store

# Export GPG keys
cd gpg-keys
gpg --armor --export-secret-keys "$PASS_GPG_ID" > pass-secret-key.asc
gpg --armor --export "$PASS_GPG_ID" > pass-public-key.asc
gpg --list-keys --fingerprint "$PASS_GPG_ID" > key-info.txt
cd ..

# Create README
cat << EOF > README.md
# WSL Personal Pass Repository

This repository contains:
- \`gpg-keys/\`: GPG keys for Pass
- \`password-store/\`: Passwords managed by Pass

## Configuration
- GPG Key ID: $PASS_GPG_ID
- Created: $(date +%Y-%m-%d)
EOF

# Initial commit
git add .
git commit -m "Initial setup: GPG keys for Pass"
git branch -M master
git push -u origin master

5. Initializing Pass

cd "$WORK_DIR"

# Use password-store directory as Pass store
export PASSWORD_STORE_DIR="$WORK_DIR/password-store"

# Initialize Pass
pass init "$PASS_GPG_ID"

# Create symbolic link (for access from usual location)
ln -sf "$WORK_DIR/password-store" ~/.password-store

6. Setting Up Auto-commit & Push

# Create post-commit hook
# Note: This hook is in the .git directory and not under Git control
# Must be recreated during restoration
cat << 'EOF' > "$WORK_DIR/.git/hooks/post-commit"
#!/bin/bash
echo "Auto-pushing to backup repository..."
git push origin master
EOF
chmod +x "$WORK_DIR/.git/hooks/post-commit"

# Script to detect Pass changes and auto-commit
cat << 'SCRIPT' > "$WORK_DIR/auto-commit.sh"
#!/bin/bash
cd "$(dirname "$0")"

if [ -n "$(git status --porcelain)" ]; then
    git add .
    git commit -m "Auto-commit: $(date +%Y-%m-%d\ %H:%M:%S)"
fi
SCRIPT
chmod +x "$WORK_DIR/auto-commit.sh"

7. Adding bashrc Configuration

# Add configuration to ~/.bashrc
cat << 'BASHRC' >> ~/.bashrc

# Pass configuration
export PASS_GPG_ID="$(gpg --list-secret-keys --keyid-format LONG | grep -A1 "^sec" | grep "pass@localhost" -B1 | head -1 | awk '{print $2}' | cut -d'/' -f2)"
export PASSWORD_STORE_DIR="$HOME/secure/pass-with-gpg/password-store"

# Auto-commit after Pass operations
pass() {
    command pass "$@"
    local exit_code=$?
    
    if [ $exit_code -eq 0 ]; then
        case "$1" in
            init|insert|add|generate|rm|remove|mv|cp|copy|edit)
                (cd "$HOME/secure/pass-with-gpg" && ./auto-commit.sh)
                ;;
        esac
    fi
    
    return $exit_code
}

# Backup GPG keys on update
backup-gpg-keys() {
    local work_dir="$HOME/secure/pass-with-gpg"
    cd "$work_dir/gpg-keys" || return 1
    
    local gpg_id="$PASS_GPG_ID"
    gpg --armor --export-secret-keys "$gpg_id" > pass-secret-key.asc
    gpg --armor --export "$gpg_id" > pass-public-key.asc
    gpg --list-keys --fingerprint "$gpg_id" > key-info.txt
    
    cd "$work_dir"
    if [ -n "$(git status --porcelain)" ]; then
        git add .
        git commit -m "GPG key update: $(date +%Y-%m-%d\ %H:%M:%S)"
    fi
}

# Utility aliases
alias pass-status='cd "$HOME/secure/pass-with-gpg" && git status -s && echo "=== Recent commits ===" && git log --oneline -5'
alias pass-tree='tree -a "$HOME/secure/pass-with-gpg" -I ".git"'
alias pass-sync='cd "$HOME/secure/pass-with-gpg" && git pull && git push'
BASHRC

# Apply configuration
source ~/.bashrc

8. Creating Restoration Documentation

# Create restoration documentation
cat << 'RESTORE' > "$WORK_DIR/RESTORE.md"
# Restoration Procedure

## 1. Clone Repository

\`\`\`bash
git clone /mnt/c/gpg-keys-backup/wsl-personal-pass.git ~/secure/pass-with-gpg
ln -sf ~/secure/pass-with-gpg/password-store ~/.password-store
\`\`\`

## 2. Restore GPG Keys

\`\`\`bash
cd ~/secure/pass-with-gpg/gpg-keys
gpg --import pass-secret-key.asc
gpg --import pass-public-key.asc

# Get imported key ID
export IMPORTED_KEY_ID=\$(gpg --list-secret-keys --keyid-format LONG | grep -A1 "^sec" | tail -1 | awk '{print \$1}' | cut -d'/' -f2)

# Set trust level
gpg --edit-key \$IMPORTED_KEY_ID trust quit
# Select 5 for ultimate trust
\`\`\`

## 3. Configure Environment

Add the Pass configuration above to ~/.bashrc and run source ~/.bashrc

## 4. Verify Operation

\`\`\`bash
pass list
\`\`\`
RESTORE

# Commit
cd "$WORK_DIR"
git add RESTORE.md
git commit -m "Add restore documentation"
git push

9. Security Settings

# Set directory permissions
chmod 700 "$WORK_DIR"
chmod 700 "$WORK_DIR/gpg-keys"
chmod 600 "$WORK_DIR/gpg-keys/"*
chmod 700 "$WORK_DIR/.git/hooks/post-commit"
chmod 700 "$WORK_DIR/auto-commit.sh"

10. Verification and Testing

# Verify GPG key
echo "=== GPG Key Info ==="
gpg --list-secret-keys --keyid-format LONG

# Create initial test entry
echo "=== Creating test entry ==="
pass generate test/initial-setup 16

# Check status
echo "=== Repository status ==="
pass-status

# Display tree structure
echo "=== Directory structure ==="
pass-tree

# Test sync
echo "=== Testing sync ==="
pass-sync

Usage

Basic Operations

# Add password
pass insert github.com/personal

# Generate password (32 characters)
pass generate aws/prod/api-key 32

# Show password
pass show github.com/personal

# Copy password to clipboard (auto-clear after 45 seconds)
pass -c github.com/personal

# List passwords
pass list

# Search passwords
pass find github

Management Commands

# Check backup status
pass-status

# Display directory structure
pass-tree

# Manual sync
pass-sync

# After updating GPG key
backup-gpg-keys

Troubleshooting

Common Issues and Solutions

GPG Errors

# Reset GPG agent
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent

Git Push Errors

# Verify and fix remote
cd "$WORK_DIR"
git remote -v
git remote set-url origin "$BACKUP_DIR/$REPO_NAME"

Pass Not Working

# Check environment variables
echo $PASS_GPG_ID
echo $PASSWORD_STORE_DIR

# Manually reset
export PASS_GPG_ID=$(gpg --list-secret-keys --keyid-format LONG | grep -A1 "^sec" | tail -1 | awk '{print $1}' | cut -d'/' -f2)
source ~/.bashrc

Security Best Practices

1. GPG Key Protection

  • Regularly change GPG key passphrase
  • Always backup after key updates with backup-gpg-keys
  • Use dedicated keys for Pass, don't mix with other purposes

2. Access Restrictions

  • Restrict access to Windows-side backup directory
  • Maintain WSL working directory permissions at 700
  • Always set private key file permissions to 600

3. Operational Considerations

  • Perform restoration tests quarterly
  • Regularly check backup status with pass-status
  • Delete passwords when no longer needed

4. Passphrase Policy

  • Recommend 20+ characters for GPG key passphrase
  • Use combinations of non-dictionary words
  • Include numbers and symbols

Summary

This setup achieves the following:

  • ✅ Secure password management in WSL environment
  • ✅ Automatic backup to Windows side
  • ✅ Change tracking via Git history
  • ✅ Reliable disaster recovery procedures
  • ✅ Fast command-line access

Credential management is an unavoidable challenge in WSL development environments. By combining Pass and GPG, you can build an environment that balances security and convenience.

References




以上の内容はhttps://rubyu.hatenablog.com/entry/2025/07/11/171948より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14