diff --git a/docs/workflows/security.workstation.md b/docs/workflows/security.workstation.md new file mode 100644 index 0000000..9c8a71c --- /dev/null +++ b/docs/workflows/security.workstation.md @@ -0,0 +1,325 @@ +--- +description: >- + Arch Linux workstation hardening workflow with daily, weekly, and monthly + security checks based on March 2026 supply chain threat landscape. +tags: + - arch-linux + - hardening + - security + - supply-chain + - workflow +last_updated: '2026-03-24' +priority: 8 +--- + +# Workstation Hardening Workflow (Arch Linux) + +**Source**: `docs/tech/supply-chain-security-2026-03.md` + +## Schedule Overview + +| Cadence | Duration | Focus | +|---------|----------|-------| +| Daily | 5 min | Service health, network, recent changes | +| Weekly | 15 min | Package audit, SBOM scan, journal review | +| Monthly | 30 min | IOC sweep, persistence audit, credential rotation | + +--- + +## Daily Checks (5 min) + +### 1. Systemd Service Health + +```bash +# Failed services +systemctl --failed + +# Unexpected user services (CanisterWorm pgmon detection) +systemctl --user list-units --type=service --all +``` + +**Alert if**: Unknown services present, especially short names like `pgmon`. + +### 2. Network Connections + +```bash +# Established outbound connections +ss -ntu state established + +# TeamPCP C2 check +ss -ntu | grep -E "45.148.10.212" + +# ICP C2 check (unexpected Dfinity connections) +ss -ntu | grep -E "icp0\.io|dfinity" +``` + +**Alert if**: Connections to unknown external IPs, especially C2 indicators. + +### 3. Boot Performance & Service Timing + +```bash +# Boot time +systemd-analyze + +# Slowest services (flag if >1s unexpected) +systemd-analyze blame | head -10 + +# Critical chain +systemd-analyze critical-chain +``` + +**Alert if**: New services in critical chain, unexpected boot time increase. + +### 4. Recent Package Changes + +```bash +# Packages changed in last 24h +pacman -Q --explicit | while read pkg ver; do + stat -c '%Y %n' /var/lib/pacman/local/$pkg-* 2>/dev/null +done | awk '$1 > '$(date -d 'yesterday' +%s)' {print}' +``` + +**Alert if**: Unexpected package installations or updates. + +--- + +## Weekly Audit (15 min) + +### 1. Package Orphan Cleanup + +```bash +# List orphans (no longer required) +pacman -Qdt + +# Remove orphans (review first) +pacman -Rns $(pacman -Qdtq) +``` + +### 2. npm/pnpm Audit + +```bash +# Verify scripts disabled +npm config get ignore-scripts # expect: true + +# Audit all active projects +fd -t f -e json -p 'package-lock' ~/internal ~/external 2>/dev/null | while read lock; do + dir=$(dirname "$lock") + echo "=== $dir ===" + (cd "$dir" && pnpm audit 2>&1 | head -20) +done +``` + +**Alert if**: `ignore-scripts` is not `true`, high/critical vulnerabilities. + +### 3. SBOM Vulnerability Scan + +```bash +# Generate and scan SBOM for active projects +fd -t d -p 'node_modules' ~/internal ~/external 2>/dev/null | while read dir; do + project=$(dirname "$dir") + echo "=== $project ===" + syft packages dir:"$project" -o cyclonedx-json 2>/dev/null | grype sbom:/dev/stdin --fail-on high 2>&1 | tail -5 +done +``` + +**Alert if**: High/critical CVEs in dependencies. + +### 4. Journal Suspicious Activity + +```bash +# Last 7 days: failed auth, suspicious exec, ptrace +journalctl --since "7 days ago" -p err --no-pager | grep -iE "denied|ptrace|segfault|oom" + +# Suspicious process starts from non-standard paths +journalctl --since "7 days ago" --no-pager | grep -E "ExecStart.*\.local" | grep -v "systemd" +``` + +**Alert if**: Repeated auth failures, ptrace from unexpected processes. + +--- + +## Monthly Deep Scan (30 min) + +### 1. Unicode Injection Scan (GlassWorm) + +```bash +# Scan all code repos for invisible Unicode +fd -t f -e js -e ts -e mjs -e py ~/internal ~/external 2>/dev/null | while read f; do + # Variation Selectors (U+FE00-FE0F) + grep -Pl "[\x{FE00}-\x{FE0F}]" "$f" 2>/dev/null && echo "VS_RANGE: $f" + # Ideographic Variation Selectors (U+E0100-E01EF) + grep -Pl "[\x{E0100}-\x{E01EF}]" "$f" 2>/dev/null && echo "IVS_RANGE: $f" + # Decoder pattern + grep -Pl "codePointAt.*0xFE00|codePointAt.*0xE0100|eval\(Buffer\.from" "$f" 2>/dev/null && echo "DECODER: $f" +done +``` + +**Alert if**: Any matches = immediate investigation, likely compromise. + +### 2. Systemd Persistence Audit (CanisterWorm) + +```bash +# List all user service files +ls -la ~/.config/systemd/user/ + +# Check for suspicious ExecStart paths (not /usr/bin or /usr/local) +grep -r "ExecStart" ~/.config/systemd/user/ 2>/dev/null | grep -v "/usr/bin\|/usr/local/bin" + +# Check for worm artifacts +find ~ -maxdepth 3 -name "pgmon*" -o -name "uv-proxy" -o -name "pglog" 2>/dev/null +``` + +**Alert if**: Unknown services, ExecStart pointing to dotfiles or temp dirs. + +### 3. IOC Sweep + +```bash +# TeamPCP exfil repos +gh repo list --limit 100 --json name 2>/dev/null | jq -r '.[].name' | grep -i "tpcp-docs" + +# DNS C2 resolution check +getent hosts scan.aquasecurtiy.org 2>/dev/null + +# Known malicious extension check +code --list-extensions 2>/dev/null | grep -i "quartz.quartz" +``` + +**Alert if**: Any IOC matches = incident response protocol. + +### 4. Credential Rotation Check + +```bash +# npm tokens older than 90 days +npm token list 2>/dev/null + +# GitHub tokens - check for long-lived PATs +gh auth status 2>/dev/null + +# SSH keys - check for keys without passphrase +ssh-add -l 2>/dev/null +``` + +**Action**: Rotate any token older than 90 days. Enforce GAT scoping. + +### 5. Full SBOM Regenerate + +```bash +# Regenerate SBOMs for all active projects +fd -t f -e json -p 'package-lock' ~/internal ~/external 2>/dev/null | while read lock; do + dir=$(dirname "$lock") + syft packages dir:"$dir" -o cyclonedx-json > "$dir/sbom.cyclonedx.json" 2>/dev/null + grype sbom:"$dir/sbom.cyclonedx.json" --fail-on high > "$dir/grype-report.txt" 2>&1 + echo "$dir: $(grep -c 'High\|Critical' "$dir/grype-report.txt" 2>/dev/null || echo 0) findings" +done +``` + +--- + +## Kernel Hardening Check (Monthly) + +```bash +# Verify kernel parameters +sysctl kernel.kptr_restrict # expect: 1 (hide kernel pointers) +sysctl kernel.dmesg_restrict # expect: 1 (restrict dmesg) +sysctl kernel.unprivileged_bpf_disabled # expect: 1 (restrict eBPF) +sysctl vm.mmap_min_addr # expect: 65536 (prevent null mapping) + +# Verify ASLR +cat /proc/sys/kernel/randomize_va_space # expect: 2 (full randomization) + +# Check loaded kernel modules for suspicious entries +lsmod | awk '{print $1}' | sort + +# Verify IOMMU enabled (hardware memory protection) +dmesg | grep -i "DMAR\|IOMMU" | head -3 +``` + +**Alert if**: Any parameter is 0/unset, unknown kernel modules loaded. + +## Firewall Status Check (Weekly) + +```bash +# Check nftables ruleset +sudo nft list ruleset 2>/dev/null | head -30 + +# If using ufw instead +sudo ufw status verbose 2>/dev/null + +# Verify default policies (should be DROP for input) +# nftables: look for "type filter hook input priority 0; policy drop" +# ufw: look for "Default: deny (incoming)" + +# Check for unexpected open ports +ss -tlnp | grep -E "LISTEN" +``` + +**Alert if**: Default input policy is ACCEPT, unexpected listening ports, no firewall active. + +## Tool Installation (One-Time) + +```bash +# SBOM and vulnerability scanning +pacman -S syft grype cosign yara + +# SAST with supply chain rules +uv tool install semgrep + +# Network template scanning +go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest + +# npm package risk scoring +npm install -g socket-cli +``` + +## Pre-commit Hook Setup (One-Time) + +Add to `.pre-commit-config.yaml` in each repo: + +```yaml +repos: + - repo: local + hooks: + - id: no-invisible-unicode + name: Block invisible Unicode (GlassWorm defense) + entry: python3 scripts/unicode-scanner.py + language: script + types: [text] +``` + +Place the Unicode scanner at `scripts/unicode-scanner.py` (see source doc for full script). + +## IDE Hardening (One-Time) + +VS Code `settings.json`: + +```json +{ + "editor.renderWhitespace": "all", + "editor.unicodeHighlight.ambiguousCharacters": true, + "editor.unicodeHighlight.invisibleCharacters": true +} +``` + +--- + +## Incident Response Quick Reference + +| Indicator | Action | +|-----------|--------| +| Unknown systemd service | Stop + investigate + remove | +| C2 IP in `ss` output | Kill connection, firewall block, full IOC sweep | +| Unicode IOC in code | Isolate repo, check git history, revert commit | +| Malicious extension | Uninstall immediately, clear extension cache | +| npm token compromise | Revoke token, rotate all tokens, audit publish log | + +## Threat Context (March 2026) + +| Threat | Vector | Detection | +|--------|--------|-----------| +| **TeamPCP** | Tag poisoning, `/proc/pid/mem` theft | SHA pinning, Falco eBPF | +| **CanisterWorm** | npm worm, systemd persistence | Service audit, npm script block | +| **GlassWorm** | Unicode steganography, invisible chars | grep VS ranges, pre-commit hook | + +## Full Reference + +Detailed technical background, Falco rules, Tetragon policies, Semgrep rules, YARA rules, and Python scanner: `docs/tech/supply-chain-security-2026-03.md`