Files

85 lines
3.9 KiB
Bash
Executable File

#!/bin/bash
# qdiag.sh — read-only Qubes dom0 diagnostics for SignerRpc qrexec issues.
# Run as root in dom0: sudo bash qdiag.sh
# Output: qdiag.txt in the current directory. No system changes are made.
OUT="qdiag.txt"
: >"$OUT"
sec() { printf '\n===== %s =====\n' "$1" >>"$OUT"; }
run() { printf '\n$ %s\n' "$*" >>"$OUT"; "$@" >>"$OUT" 2>&1 || true; }
runsh() { printf '\n$ %s\n' "$1" >>"$OUT"; bash -c "$1" >>"$OUT" 2>&1 || true; }
sec "1. Identity / versions"
run hostname
run id
run uname -a
run cat /etc/qubes-release
run qubesctl --version
run rpm -q qubes-core-admin-linux qubes-core-qrexec 2>/dev/null
sec "2. Qubes version detail"
run qvm-ls --raw-data --fields NAME,STATE,CLASS,TEMPLATE 2>/dev/null
run qvm-ls --running 2>/dev/null
sec "3. Policy directories inventory"
run ls -la /etc/qubes/policy.d/
run ls -la /etc/qubes-rpc/policy/ 2>/dev/null
run ls -la /usr/share/qubes/policy.d/ 2>/dev/null
run ls -la /etc/qubes-rpc/ 2>/dev/null
sec "4. Policy file ownership/permissions"
runsh 'find /etc/qubes/policy.d /etc/qubes-rpc/policy /usr/share/qubes/policy.d -maxdepth 1 -type f -printf "%M %u:%g %s %p\n" 2>/dev/null | sort'
sec "5. Symlinks in policy dirs"
runsh 'find /etc/qubes/policy.d /etc/qubes-rpc /etc/qubes-rpc/policy -maxdepth 2 -type l -printf "%p -> %l\n" 2>/dev/null'
sec "6. Search for SignerRpc / nsigner / signer policy files"
runsh 'find / -xdev \( -path /proc -o -path /sys -o -path /dev \) -prune -o -iname "*signer*" -print 2>/dev/null | grep -vi "^/home" | head -50'
runsh 'grep -RIl "SignerRpc\|NsignerRpc\|nsigner" /etc/qubes /usr/share/qubes 2>/dev/null | head -30'
sec "7. Policy contents (signer-related)"
runsh 'for f in $(grep -RIl "SignerRpc\|NsignerRpc\|nsigner\|signer" /etc/qubes/policy.d /etc/qubes-rpc/policy /usr/share/qubes/policy.d 2>/dev/null); do echo "--- $f ---"; cat "$f"; echo; done'
sec "8. Clipboard policy contents"
runsh 'for f in $(grep -RIl "ClipboardPaste" /etc/qubes/policy.d /etc/qubes-rpc/policy /usr/share/qubes/policy.d 2>/dev/null); do echo "--- $f ---"; cat "$f"; echo; done'
sec "9. Full policy.d listing with contents (all files)"
runsh 'for f in /etc/qubes/policy.d/*; do echo "--- $f ---"; cat "$f" 2>/dev/null; echo; done'
sec "10. Effective policy query (if tools exist)"
runsh 'command -v qrexec-policy-graph && qrexec-policy-graph --include-ask 2>&1 | grep -iE "signer|clipboard" | head -30'
runsh 'command -v qvm-tags && qvm-tags dom0 2>/dev/null | head -20'
sec "11. qrexec policy daemon status"
run systemctl status qrexec-policy-daemon --no-pager -l 2>&1
run systemctl is-active qrexec-policy-daemon 2>&1
sec "12. Target qube info (nostr_signer)"
run qvm-ls --raw-data --fields NAME,STATE,CLASS,TEMPLATE,NETVM nostr_signer 2>/dev/null
run qvm-features nostr_signer 2>/dev/null
run qvm-prefs nostr_signer 2>/dev/null
sec "13. Caller qube info (ai)"
run qvm-ls --raw-data --fields NAME,STATE,CLASS,TEMPLATE,NETVM ai 2>/dev/null
run qvm-features ai 2>/dev/null
sec "14. Recent qrexec/policy journal errors"
runsh 'journalctl -b --no-pager 2>/dev/null | grep -iE "qrexec|policy|SignerRpc|NsignerRpc|clipboard" | tail -80'
sec "15. qrexec service definitions in target qube (via qvm-run, read-only)"
runsh 'qvm-run -p nostr_signer "ls -la /etc/qubes-rpc/ 2>/dev/null; echo ---; ls -la /rw/config/qubes-rpc/ 2>/dev/null; echo ---; cat /rw/config/rc.local 2>/dev/null" 2>&1 | head -60'
sec "16. Test qrexec call to nostr_signer (read-only get_info)"
runsh 'echo "{\"id\":\"diag\",\"method\":\"get_info\",\"params\":[]}" | timeout 10 qrexec-client-vm nostr_signer qubes.SignerRpc 2>&1; echo "exit=$?"'
runsh 'echo "{\"id\":\"diag\",\"method\":\"get_info\",\"params\":[]}" | timeout 10 qrexec-client-vm nostr_signer qubes.NsignerRpc 2>&1; echo "exit=$?"'
sec "17. Qubes global config files"
runsh 'ls -la /etc/qubes/ | head -30'
runsh 'cat /etc/qubes/policy.d/50-config-input.policy 2>/dev/null'
runsh 'cat /etc/qubes/policy.d/50-config-updates.policy 2>/dev/null'
sec "DONE"
printf 'Diagnostics complete. Output saved to %s\n' "$OUT"
exit 0