generated from nhcarrigan/template
feat: reorganise bash scripts and add comprehensive documentation (#6)
CI / dependency-pin-check-typescript (push) Successful in 5s
CI / dependency-pin-check-python (push) Successful in 4s
CI / python (push) Successful in 9m28s
CI / typescript (push) Successful in 9m42s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m39s
CI / dependency-pin-check-typescript (push) Successful in 5s
CI / dependency-pin-check-python (push) Successful in 4s
CI / python (push) Successful in 9m28s
CI / typescript (push) Successful in 9m42s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m39s
## Summary This PR completes the bash script restructuring and adds comprehensive documentation across all script categories. ### Bash Restructuring - Moved cohort shell scripts (`remove_github_members.sh`, `update_github_teams.sh`) from `python/cohort/` into a new `bash/cohort/` directory - Moved existing bash utilities (`add-keys-to-git.sh`, `fix-yubikey-perms.sh`, `list-yubikey-ssh-keys.sh`) into a new `bash/yubikey/` subdirectory - Updated `run.sh` to support **Bash** as a third language option alongside TypeScript and Python - Bash scripts are run directly (no 1Password secret injection needed) - Category discovery and script listing works the same as for TS/Python - Removed dead "Root Scripts" logic that was no longer needed ### Documentation Added `README.md` files for all script categories that were missing them: - `bash/cohort/README.md` — cohort GitHub team management scripts - `bash/yubikey/README.md` — YubiKey SSH key and permission utilities - `typescript/src/crowdin/README.md` — Crowdin translation management scripts - `typescript/src/discord/README.md` — Discord bot utility scripts - `typescript/src/discourse/README.md` — Discourse forum management scripts - `typescript/src/gitea/README.md` — Gitea bulk repository operation scripts - `typescript/src/github/README.md` — GitHub API interaction scripts - `typescript/src/music/README.md` — Music file metadata tools - `typescript/src/s3/README.md` — S3-compatible object storage scripts - `typescript/src/security/README.md` — Security analysis and reporting scripts - `python/cohort/README.md` — Updated to remove moved shell scripts, fix usage commands Also updated project-level docs: - **`README.md`** — Corrected project structure, fixed running instructions (removed references to non-existent `make run-ts`/`make run-py` targets), added Bash prerequisites - **`CLAUDE.md`** — Updated project overview, structure, development standards, and script-adding guides to reflect the current state of the project ✨ This PR was created with help from Hikari~ 🌸 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Reviewed-on: #6 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #6.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# YubiKey Scripts
|
||||
|
||||
Shell scripts for managing YubiKey hardware security keys on WSL (Windows Subsystem for Linux). Covers SSH key extraction, Git signing key configuration, and fixing USB permission issues that commonly arise in WSL environments.
|
||||
|
||||
All scripts require a YubiKey to be attached and forwarded to WSL via `usbipd`. The `ykman` and `yubico-piv-tool` packages must be installed.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Run scripts via the interactive runner from the project root:
|
||||
|
||||
```bash
|
||||
make run
|
||||
# Select: Bash → yubikey → <script>
|
||||
```
|
||||
|
||||
Or run directly:
|
||||
|
||||
```bash
|
||||
bash bash/yubikey/<script-name>.sh
|
||||
```
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [add-keys-to-git.sh](#add-keys-to-gitsh)
|
||||
- [fix-yubikey-perms.sh](#fix-yubikey-permssh)
|
||||
- [list-yubikey-ssh-keys.sh](#list-yubikey-ssh-keyssh)
|
||||
|
||||
---
|
||||
|
||||
## add-keys-to-git.sh
|
||||
|
||||
Extracts the SSH public keys from three YubiKey PIV slots and writes them as Git commit signing keys to the corresponding per-context Git config files. Run this after replacing or re-provisioning a YubiKey.
|
||||
|
||||
| Slot | Context | Config file |
|
||||
|---|---|---|
|
||||
| 9a | Personal | `~/.git-naomi` |
|
||||
| 9c | Deepgram | `~/.git-dg` |
|
||||
| 9e | FreeCodeCamp | `~/.git-fcc` |
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
bash bash/yubikey/add-keys-to-git.sh
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
None.
|
||||
|
||||
### Notes
|
||||
|
||||
- After running, you must upload the new public keys to GitHub (and any other services that verify commit signatures) manually.
|
||||
- Requires `ykman` and `ssh-keygen` to be available in your PATH.
|
||||
|
||||
---
|
||||
|
||||
## fix-yubikey-perms.sh
|
||||
|
||||
Repairs YubiKey connectivity in WSL by fixing USB device permissions, restarting smart card services, and applying a polkit policy override that allows smart card access in WSL's "inactive" session context.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
bash bash/yubikey/fix-yubikey-perms.sh
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
None.
|
||||
|
||||
### Notes
|
||||
|
||||
- Run this script when `ykman` or `yubico-piv-tool` fail with "Failed to connect" or similar errors after attaching the YubiKey via `usbipd`.
|
||||
- The polkit fix modifies `/usr/share/polkit-1/actions/org.debian.pcsc-lite.policy` (a backup is created automatically on first run).
|
||||
- Requires `sudo` access. Several steps use `sudo` to modify system files and restart services.
|
||||
- Requires `lsusb`, `yubico-piv-tool`, `systemctl`, and `gpgconf` to be available.
|
||||
|
||||
---
|
||||
|
||||
## list-yubikey-ssh-keys.sh
|
||||
|
||||
Scans PIV slots 9a, 9c, 9d, and 9e on the connected YubiKey and prints any SSH public keys found, along with the certificate subject label if one is present.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
bash bash/yubikey/list-yubikey-ssh-keys.sh
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
None.
|
||||
|
||||
### Data Files
|
||||
|
||||
None.
|
||||
|
||||
### Notes
|
||||
|
||||
- Requires `ykman`, `ssh-keygen`, and `openssl` to be available.
|
||||
- Writes a temporary file to `/tmp/yubi_tmp.pem` during execution; it is cleaned up automatically after each slot is processed.
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "🔄 Extracting new keys from YubiKey and updating Git config..."
|
||||
|
||||
# 1. Update PERSONAL (Slot 9a) -> .git-naomi
|
||||
# ---------------------------------------------------------
|
||||
echo " -> Processing Slot 9a (Personal)..."
|
||||
KEY_9A=$(ykman piv keys export 9a - | ssh-keygen -i -m PKCS8 -f /dev/stdin)
|
||||
git config -f ~/.git-naomi user.signingkey "key::$KEY_9A"
|
||||
|
||||
# 2. Update DEEPGRAM (Slot 9c) -> .git-dg
|
||||
# ---------------------------------------------------------
|
||||
echo " -> Processing Slot 9c (Deepgram)..."
|
||||
KEY_9C=$(ykman piv keys export 9c - | ssh-keygen -i -m PKCS8 -f /dev/stdin)
|
||||
git config -f ~/.git-dg user.signingkey "key::$KEY_9C"
|
||||
|
||||
# 3. Update FREECODECAMP (Slot 9e) -> .git-fcc
|
||||
# ---------------------------------------------------------
|
||||
echo " -> Processing Slot 9e (FreeCodeCamp)..."
|
||||
KEY_9D=$(ykman piv keys export 9e - | ssh-keygen -i -m PKCS8 -f /dev/stdin)
|
||||
git config -f ~/.git-fcc user.signingkey "key::$KEY_9D"
|
||||
|
||||
echo "✅ Done! Your local Git is now synced with your new hardware keys."
|
||||
echo "⚠️ REMINDER: You must now upload these new public keys to GitHub and your 'prod' server!"
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Colors for pretty output
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${YELLOW}🔧 Starting YubiKey WSL Repair...${NC}"
|
||||
|
||||
# 1. CHECK: Is the key actually attached?
|
||||
if ! lsusb -d 1050: > /dev/null; then
|
||||
echo -e "${RED}❌ Error: No YubiKey detected in Linux!${NC}"
|
||||
echo " Please go to Windows PowerShell and run:"
|
||||
echo " usbipd attach --wsl --busid <YOUR_ID>"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✅ YubiKey Hardware detected.${NC}"
|
||||
|
||||
# 2. PERMISSIONS: The "Nuclear" Polkit Fix
|
||||
# This forces the smart card service to accept connections even if WSL looks "inactive"
|
||||
POLICY_FILE="/usr/share/polkit-1/actions/org.debian.pcsc-lite.policy"
|
||||
|
||||
if [ -f "$POLICY_FILE" ]; then
|
||||
echo " Applying 'Nuclear' permission fix to PC/SC Policy..."
|
||||
# Backup original if not exists
|
||||
if [ ! -f "$POLICY_FILE.bak" ]; then
|
||||
sudo cp "$POLICY_FILE" "$POLICY_FILE.bak"
|
||||
fi
|
||||
# Force permissions to 'yes'
|
||||
sudo sed -i 's/<allow_any>.*<\/allow_any>/<allow_any>yes<\/allow_any>/' "$POLICY_FILE"
|
||||
sudo sed -i 's/<allow_inactive>.*<\/allow_inactive>/<allow_inactive>yes<\/allow_inactive>/' "$POLICY_FILE"
|
||||
sudo sed -i 's/<allow_active>.*<\/allow_active>/<allow_active>yes<\/allow_active>/' "$POLICY_FILE"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Warning: Polkit policy file not found. Skipping nuclear fix.${NC}"
|
||||
fi
|
||||
|
||||
# 3. GROUP: Ensure user is in plugdev
|
||||
if ! groups $USER | grep -q "plugdev"; then
|
||||
echo " Adding $USER to plugdev group..."
|
||||
sudo usermod -aG plugdev $USER
|
||||
fi
|
||||
|
||||
# 4. USB NODE: Force read/write permissions on the raw USB device
|
||||
# This fixes the "Failed to connect" error from yubico-piv-tool
|
||||
echo " Forcing permissions on USB device node..."
|
||||
lsusb -d 1050: | while read -r line; do
|
||||
BUS=$(echo "$line" | awk '{print $2}')
|
||||
DEV=$(echo "$line" | awk '{print $4}' | tr -d :)
|
||||
PATH="/dev/bus/usb/$BUS/$DEV"
|
||||
echo " -> Unlocking $PATH"
|
||||
sudo chmod 666 "$PATH"
|
||||
done
|
||||
|
||||
# 5. SERVICES: Restart everything to pick up changes
|
||||
echo " Restarting Smart Card Services..."
|
||||
# Kill any stuck GPG agents that might hog the card
|
||||
gpgconf --kill gpg-agent 2>/dev/null || true
|
||||
# Restart the main daemon
|
||||
sudo systemctl restart polkit
|
||||
sudo systemctl restart pcscd
|
||||
|
||||
# 6. CONFIG CHECK: Warn if SSH config is bad
|
||||
if grep -q "IdentityFile.*yubi" ~/.ssh/config; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: Found 'IdentityFile' pointing to a YubiKey in ~/.ssh/config!${NC}"
|
||||
echo " You should remove that line so SSH doesn't throw 'libcrypto' errors."
|
||||
fi
|
||||
|
||||
# 7. FINAL TEST
|
||||
echo -e "${YELLOW}🔎 Verifying connection...${NC}"
|
||||
if yubico-piv-tool -a status > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}🎉 SUCCESS! Your YubiKey is ready.${NC}"
|
||||
yubico-piv-tool -a status | grep "Serial Number"
|
||||
else
|
||||
echo -e "${RED}❌ Status check failed.${NC}"
|
||||
echo " Try running: yubico-piv-tool -a status"
|
||||
fi
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
echo "Scanning YubiKey slots for SSH keys..."
|
||||
echo "---------------------------------------------------"
|
||||
|
||||
# Loop through the slots that support SSH keys
|
||||
for SLOT in 9a 9c 9d 9e; do
|
||||
# Try to export the key to a temp file
|
||||
if ykman piv keys export $SLOT /tmp/yubi_tmp.pem > /dev/null 2>&1; then
|
||||
echo -e "\033[0;32mFOUND KEY IN SLOT $SLOT:\033[0m"
|
||||
|
||||
# Check if there is a certificate label
|
||||
LABEL=$(ykman piv certificates export $SLOT - 2>/dev/null | openssl x509 -noout -subject 2>/dev/null)
|
||||
if [ ! -z "$LABEL" ]; then
|
||||
echo "Certificate Label: $LABEL"
|
||||
fi
|
||||
|
||||
# Convert to SSH format and print
|
||||
ssh-keygen -i -m PKCS8 -f /tmp/yubi_tmp.pem
|
||||
echo "---------------------------------------------------"
|
||||
rm /tmp/yubi_tmp.pem
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user