From 7ad6f474634f7c359264053bf0f8e93a9bdd37b1 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Fri, 29 May 2026 11:18:13 +0100 Subject: 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). --- etc/systemd/system-sleep/50-snx-rs | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 etc/systemd/system-sleep/50-snx-rs (limited to 'etc/systemd/system-sleep') 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 -- cgit v1.3.1