aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:13 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:13 +0100
commit7ad6f474634f7c359264053bf0f8e93a9bdd37b1 (patch)
tree56b94c94a40a118e12ba5e4bedf975224e4754a0
parentaabcdc206246aa935790908f2ab7e7edcc88b3b9 (diff)
downloaddotfiles-7ad6f474634f7c359264053bf0f8e93a9bdd37b1.tar.gz
dotfiles-7ad6f474634f7c359264053bf0f8e93a9bdd37b1.tar.bz2
dotfiles-7ad6f474634f7c359264053bf0f8e93a9bdd37b1.zip
feat(suspend): bounce snx-rs around system sleep
snx-rs (Check Point VPN) doesn't notice that its tunnel died during suspend: the IKE keepalive is interrupted and the SAML cookie may expire, but the daemon happily sits on dead sockets after resume. `snxctl status` keeps reporting "Connected" while no traffic actually flows, so the user has to manually disconnect+reconnect. Install an /etc/systemd/system-sleep/ hook that stops the user-scope snx-rs.service before suspend and starts it on resume. The tunnel is left disconnected after resume; the waybar toggle (or any `snxctl connect`) re-establishes it, going through SAML only if the cached cookie has actually expired. The hook enumerates logged-in users via loginctl and skips any that don't have snx-rs.service enabled, so it's a no-op on machines that don't use the VPN. Also teach run_onchange_after_deploy-etc.sh.tmpl to install files under etc/systemd/system-sleep/ with mode 0755 (systemd ignores sleep hooks that aren't executable).
-rwxr-xr-xetc/systemd/system-sleep/50-snx-rs45
-rwxr-xr-xrun_onchange_after_deploy-etc.sh.tmpl3
2 files changed, 48 insertions, 0 deletions
diff --git a/etc/systemd/system-sleep/50-snx-rs b/etc/systemd/system-sleep/50-snx-rs
new file mode 100755
index 0000000..5241126
--- /dev/null
+++ b/etc/systemd/system-sleep/50-snx-rs
@@ -0,0 +1,45 @@
+#!/bin/sh
+# Bounce the user-scope snx-rs (Check Point) tunnel around suspend/hibernate.
+#
+# Problem: during suspend the IKE SA keepalive is interrupted and the SAML
+# session cookie may expire. snx-rs doesn't detect this — the daemon
+# happily sits on dead sockets after resume, so `snxctl status` reports
+# "Connected" while no traffic actually goes through. The user has to
+# manually disconnect+reconnect (which re-triggers the SAML browser flow).
+#
+# Fix: stop the daemon before suspend, start it after resume. The tunnel
+# is left disconnected on resume — user clicks the waybar toggle (or any
+# `snxctl connect`) to re-establish, which goes through SAML if and only
+# if the cached cookie has actually expired. Net result:
+# - waybar correctly shows "disconnected" immediately on resume
+# - one click reconnects (often without re-doing SAML)
+# - no stale "Connected"-but-dead state
+#
+# Invoked by systemd-suspend(8) / -hibernate / -hybrid-sleep with
+# $1 = pre|post $2 = suspend|hibernate|hybrid-sleep|suspend-then-hibernate
+set -eu
+
+case "$1" in
+ pre) action=stop ;;
+ post) action=start ;;
+ *) exit 0 ;;
+esac
+
+# Iterate over every logged-in user that has the snx-rs.service enabled.
+# loginctl list-users gives us "UID USER" pairs.
+loginctl list-users --no-legend 2>/dev/null |
+ awk '{print $1, $2}' |
+ while read -r uid user; do
+ [ -n "$uid" ] && [ -n "$user" ] || continue
+ runtime="/run/user/$uid"
+ [ -d "$runtime" ] || continue
+ # Skip users without snx-rs enabled to avoid spurious "Unit not found".
+ runuser -u "$user" -- env \
+ "XDG_RUNTIME_DIR=$runtime" \
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=$runtime/bus" \
+ systemctl --user is-enabled snx-rs.service >/dev/null 2>&1 || continue
+ runuser -u "$user" -- env \
+ "XDG_RUNTIME_DIR=$runtime" \
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=$runtime/bus" \
+ systemctl --user "$action" snx-rs.service || true
+ done
diff --git a/run_onchange_after_deploy-etc.sh.tmpl b/run_onchange_after_deploy-etc.sh.tmpl
index d08f989..743675a 100755
--- a/run_onchange_after_deploy-etc.sh.tmpl
+++ b/run_onchange_after_deploy-etc.sh.tmpl
@@ -18,6 +18,9 @@ find etc -type f ! -name .ignore | while IFS= read -r src; do
etc/sudoers-rs)
sudo install -D -m 0440 -o root -g root "$src" "/${src}"
;;
+ etc/systemd/system-sleep/*)
+ sudo install -D -m 0755 -o root -g root "$src" "/${src}"
+ ;;
*)
sudo install -D -m 0644 -o root -g root "$src" "/${src}"
;;