Files
mw-pfeddersheim-workstation/docs/workflows/security.workstation.md
T
jaandJunie e0c2997ee4 docs(security): add workstation hardening workflow for Arch Linux
Daily/weekly/monthly security checks covering systemd health,
network C2 detection, package audit, SBOM scanning, Unicode IOC
sweep, kernel hardening, and firewall status. References
supply-chain-security-2026-03.md for detailed threat context.

Co-authored-by: Junie <junie@jetbrains.com>
2026-03-24 04:34:31 +01:00

8.5 KiB

description, tags, last_updated, priority
description tags last_updated priority
Arch Linux workstation hardening workflow with daily, weekly, and monthly security checks based on March 2026 supply chain threat landscape.
arch-linux
hardening
security
supply-chain
workflow
2026-03-24 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

# 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

# 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

# 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

# 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

# List orphans (no longer required)
pacman -Qdt

# Remove orphans (review first)
pacman -Rns $(pacman -Qdtq)

2. npm/pnpm Audit

# 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

# 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

# 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)

# 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)

# 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

# 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

# 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

# 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)

# 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)

# 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)

# 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:

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:

{
  "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