Updates to the x86_64 image creation.
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
# Stormux Assistance System - Client Configuration
|
||||||
|
|
||||||
|
[server]
|
||||||
|
host = assistance.stormux.org
|
||||||
|
ssh_port = 22
|
||||||
|
ssh_user = stormux-assist
|
||||||
|
tunnel_port = 2222
|
||||||
|
|
||||||
|
[session]
|
||||||
|
# Session timeout in seconds (14400 = 4 hours)
|
||||||
|
timeout = 14400
|
||||||
|
|
||||||
|
[client]
|
||||||
|
log_file = /var/log/sas.log
|
||||||
|
log_dir = ~/stormux-assist-logs/
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../ssh-login-monitor.service
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Fenrir SSH Login Monitor
|
||||||
|
After=sshd.service
|
||||||
|
Wants=sshd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=false
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -850,7 +850,7 @@ install_base_system() {
|
|||||||
# Add desktop-specific packages
|
# Add desktop-specific packages
|
||||||
case "$desktopEnvironment" in
|
case "$desktopEnvironment" in
|
||||||
i3)
|
i3)
|
||||||
allPackages+=(i3-wm orca lxterminal pluma)
|
allPackages+=(i3-wm orca python-psutil lxterminal pluma)
|
||||||
allPackages+=(discount jq libnotify xfce4-notifyd pamixer playerctl)
|
allPackages+=(discount jq libnotify xfce4-notifyd pamixer playerctl)
|
||||||
allPackages+=(python-i3ipc python-wxpython sox yad)
|
allPackages+=(python-i3ipc python-wxpython sox yad)
|
||||||
allPackages+=(lxsession magic-wormhole pcmanfm)
|
allPackages+=(lxsession magic-wormhole pcmanfm)
|
||||||
@@ -860,7 +860,7 @@ install_base_system() {
|
|||||||
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
|
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
|
||||||
;;
|
;;
|
||||||
mate)
|
mate)
|
||||||
allPackages+=(mate mate-extra orca)
|
allPackages+=(mate mate-extra orca python-psutil)
|
||||||
# Add Stormux-specific MATE packages
|
# Add Stormux-specific MATE packages
|
||||||
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
|
stormuxPackages+=(xlibre-xserver xlibre-input-libinput nodm-dgw brave-bin)
|
||||||
;;
|
;;
|
||||||
@@ -1017,6 +1017,37 @@ EOF
|
|||||||
log_info "Audio configuration installed"
|
log_info "Audio configuration installed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# SSH login monitor installation (script + service)
|
||||||
|
#
|
||||||
|
|
||||||
|
install_ssh_login_monitor() {
|
||||||
|
log_info "=== Installing SSH Login Monitor ==="
|
||||||
|
|
||||||
|
local srcScript="/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
|
||||||
|
local srcService="/etc/systemd/system/ssh-login-monitor.service"
|
||||||
|
|
||||||
|
if [[ ! -f "$srcScript" ]]; then
|
||||||
|
log_error "Source script not found: $srcScript"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$srcService" ]]; then
|
||||||
|
log_error "Source service not found: $srcService"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$mountPoint/usr/share/fenrirscreenreader/scripts"
|
||||||
|
mkdir -p "$mountPoint/etc/systemd/system"
|
||||||
|
|
||||||
|
cp "$srcScript" "$mountPoint/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
|
||||||
|
chmod 755 "$mountPoint/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"
|
||||||
|
|
||||||
|
cp "$srcService" "$mountPoint/etc/systemd/system/ssh-login-monitor.service"
|
||||||
|
chmod 644 "$mountPoint/etc/systemd/system/ssh-login-monitor.service"
|
||||||
|
|
||||||
|
log_info "SSH login monitor installed to target system"
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# System configuration in chroot
|
# System configuration in chroot
|
||||||
#
|
#
|
||||||
@@ -1156,6 +1187,7 @@ systemctl enable NetworkManager.service
|
|||||||
systemctl enable brltty.path
|
systemctl enable brltty.path
|
||||||
systemctl enable fenrirscreenreader.service
|
systemctl enable fenrirscreenreader.service
|
||||||
systemctl enable cronie.service
|
systemctl enable cronie.service
|
||||||
|
systemctl enable ssh-login-monitor.service
|
||||||
|
|
||||||
# Enable bluetooth if present
|
# Enable bluetooth if present
|
||||||
systemctl enable bluetooth.service 2>/dev/null || true
|
systemctl enable bluetooth.service 2>/dev/null || true
|
||||||
@@ -1588,6 +1620,13 @@ if ! install_audio_configs; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Install SSH login monitor files (script + service)
|
||||||
|
if ! install_ssh_login_monitor; then
|
||||||
|
log_error "SSH login monitor installation failed"
|
||||||
|
cleanup_and_unmount
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Configure system
|
# Configure system
|
||||||
if ! configure_system; then
|
if ! configure_system; then
|
||||||
log_error "System configuration failed"
|
log_error "System configuration failed"
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
sas.sh
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Stormux Assistance System (SAS) - Client
|
||||||
|
# Simple command for users to request remote assistance
|
||||||
|
# Usage: sas
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
serverHost="assistance.stormux.org"
|
||||||
|
serverPort=22
|
||||||
|
serverUser="stormux-assist"
|
||||||
|
tunnelPort=2222
|
||||||
|
configFile="/etc/stormux-assist/client.conf"
|
||||||
|
logFile="/var/log/sas.log"
|
||||||
|
logDir="${HOME}/stormux-assist-logs"
|
||||||
|
sessionTimeout=14400 # 4 hours
|
||||||
|
|
||||||
|
# Session variables
|
||||||
|
sessionId=""
|
||||||
|
tunnelPid=""
|
||||||
|
|
||||||
|
# Speech feedback function
|
||||||
|
speak() {
|
||||||
|
spd-say -w "$1" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging function (format: "Message [timestamp]")
|
||||||
|
logMessage() {
|
||||||
|
local message="$1"
|
||||||
|
local timestamp
|
||||||
|
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
echo "${message} [${timestamp}]" >> "${logFile}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Error handler with speech
|
||||||
|
errorExit() {
|
||||||
|
local message="$1"
|
||||||
|
speak "Error: ${message}"
|
||||||
|
logMessage "ERROR: ${message}"
|
||||||
|
cleanup
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load configuration if it exists
|
||||||
|
loadConfig() {
|
||||||
|
if [[ -f "${configFile}" ]]; then
|
||||||
|
# Source config file values (simple INI parsing)
|
||||||
|
while IFS='=' read -r key value; do
|
||||||
|
# Skip comments and empty lines
|
||||||
|
[[ "${key}" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
[[ -z "${key}" ]] && continue
|
||||||
|
|
||||||
|
# Trim whitespace
|
||||||
|
key=$(echo "${key}" | xargs)
|
||||||
|
value=$(echo "${value}" | xargs)
|
||||||
|
|
||||||
|
case "${key}" in
|
||||||
|
host) serverHost="${value}" ;;
|
||||||
|
ssh_port) serverPort="${value}" ;;
|
||||||
|
ssh_user) serverUser="${value}" ;;
|
||||||
|
tunnel_port) tunnelPort="${value}" ;;
|
||||||
|
timeout) sessionTimeout="${value}" ;;
|
||||||
|
log_file) logFile="${value}" ;;
|
||||||
|
log_dir) logDir="${value}" ;;
|
||||||
|
esac
|
||||||
|
done < "${configFile}"
|
||||||
|
logMessage "Configuration loaded from ${configFile}"
|
||||||
|
else
|
||||||
|
logMessage "No config file found, using defaults"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check network connectivity
|
||||||
|
checkNetwork() {
|
||||||
|
speak "Checking network connection"
|
||||||
|
logMessage "Checking network connectivity to ${serverHost}"
|
||||||
|
|
||||||
|
if ! ping -c 1 -W 5 "${serverHost}" &>/dev/null; then
|
||||||
|
errorExit "No network connection detected. Please connect to the internet and try again."
|
||||||
|
fi
|
||||||
|
|
||||||
|
logMessage "Network connectivity verified"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check SSH client is installed
|
||||||
|
checkSsh() {
|
||||||
|
if ! command -v ssh &>/dev/null; then
|
||||||
|
errorExit "SSH client not found. Please install openssh."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v autossh &>/dev/null; then
|
||||||
|
errorExit "autossh not found. Please install autossh package."
|
||||||
|
fi
|
||||||
|
|
||||||
|
logMessage "SSH and autossh verified"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create log directory
|
||||||
|
createLogDir() {
|
||||||
|
if [[ ! -d "${logDir}" ]]; then
|
||||||
|
mkdir -p "${logDir}" || errorExit "Failed to create log directory ${logDir}"
|
||||||
|
logMessage "Created log directory ${logDir}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate session ID
|
||||||
|
generateSessionId() {
|
||||||
|
sessionId=$(date '+%Y%m%d-%H%M%S')-$(hostname -s)
|
||||||
|
logMessage "Generated session ID: ${sessionId}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Establish SSH reverse tunnel
|
||||||
|
establishTunnel() {
|
||||||
|
speak "Establishing connection to assistance server"
|
||||||
|
logMessage "Establishing SSH reverse tunnel to ${serverHost}:${serverPort}"
|
||||||
|
|
||||||
|
# Use autossh for auto-reconnection
|
||||||
|
# -M 0: disable autossh monitoring port (use ServerAliveInterval instead)
|
||||||
|
# -N: no remote command
|
||||||
|
# -R 2222:localhost:22: reverse tunnel from server port 2222 to local port 22
|
||||||
|
# ServerAliveInterval: keep connection alive
|
||||||
|
# ServerAliveCountMax: max failed keepalives before disconnect
|
||||||
|
# ExitOnForwardFailure: exit if tunnel cannot be established
|
||||||
|
|
||||||
|
autossh -M 0 \
|
||||||
|
-o "ServerAliveInterval=30" \
|
||||||
|
-o "ServerAliveCountMax=3" \
|
||||||
|
-o "ExitOnForwardFailure=yes" \
|
||||||
|
-o "StrictHostKeyChecking=accept-new" \
|
||||||
|
-N \
|
||||||
|
-R "${tunnelPort}:localhost:22" \
|
||||||
|
-p "${serverPort}" \
|
||||||
|
"${serverUser}@${serverHost}" &
|
||||||
|
|
||||||
|
tunnelPid=$!
|
||||||
|
|
||||||
|
# Wait a moment for tunnel to establish
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# Check if tunnel is still running
|
||||||
|
if ! kill -0 "${tunnelPid}" 2>/dev/null; then
|
||||||
|
errorExit "Failed to establish SSH tunnel. Please check your SSH keys and server accessibility."
|
||||||
|
fi
|
||||||
|
|
||||||
|
logMessage "SSH tunnel established (PID: ${tunnelPid})"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for user to quit or timeout
|
||||||
|
waitForQuit() {
|
||||||
|
speak "Connection established. Support staff have been notified via IRC. Press Q to quit or wait for support to connect."
|
||||||
|
logMessage "Session active, waiting for Q keypress or timeout"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "════════════════════════════════════════════════"
|
||||||
|
echo " Stormux Assistance System - Session Active"
|
||||||
|
echo "════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
echo "Support staff have been notified via IRC."
|
||||||
|
echo "They will connect shortly to help you."
|
||||||
|
echo ""
|
||||||
|
echo "Session ID: ${sessionId}"
|
||||||
|
echo "Session timeout: 4 hours"
|
||||||
|
echo ""
|
||||||
|
echo "Press 'Q' to end the session early"
|
||||||
|
echo ""
|
||||||
|
echo "════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local startTime
|
||||||
|
startTime=$(date +%s)
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# Check for timeout
|
||||||
|
local currentTime
|
||||||
|
currentTime=$(date +%s)
|
||||||
|
local elapsed=$((currentTime - startTime))
|
||||||
|
|
||||||
|
if [[ ${elapsed} -ge ${sessionTimeout} ]]; then
|
||||||
|
speak "Session has timed out after 4 hours"
|
||||||
|
logMessage "Session timed out after ${sessionTimeout} seconds"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for Q keypress (with timeout)
|
||||||
|
if read -r -t 1 -n 1 key; then
|
||||||
|
if [[ "${key}" == "q" ]] || [[ "${key}" == "Q" ]]; then
|
||||||
|
speak "Ending assistance session"
|
||||||
|
logMessage "User requested session termination"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if tunnel is still alive
|
||||||
|
if ! kill -0 "${tunnelPid}" 2>/dev/null; then
|
||||||
|
speak "Connection lost. Session ended."
|
||||||
|
logMessage "Tunnel process died unexpectedly"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup and exit
|
||||||
|
cleanup() {
|
||||||
|
logMessage "Starting cleanup"
|
||||||
|
|
||||||
|
# Kill tunnel if running
|
||||||
|
if [[ -n "${tunnelPid}" ]] && kill -0 "${tunnelPid}" 2>/dev/null; then
|
||||||
|
kill "${tunnelPid}" 2>/dev/null || true
|
||||||
|
logMessage "Tunnel process terminated"
|
||||||
|
fi
|
||||||
|
|
||||||
|
logMessage "Cleanup complete"
|
||||||
|
}
|
||||||
|
|
||||||
|
# End-of-session patronage message
|
||||||
|
patronageMessage() {
|
||||||
|
speak "Assistance session ended. Thank you for using Stormux Live Assistance."
|
||||||
|
sleep 2
|
||||||
|
speak "This service is made possible by supporters like you. Consider becoming a patron at patreon dot com slash stormux to help keep this service running."
|
||||||
|
|
||||||
|
logMessage "Session ended, patronage message delivered"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
speak "Starting Stormux assistance request"
|
||||||
|
logMessage "=== SAS Client Started ==="
|
||||||
|
|
||||||
|
# Ensure we clean up on exit
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
loadConfig
|
||||||
|
|
||||||
|
# Create log directory
|
||||||
|
createLogDir
|
||||||
|
|
||||||
|
# Pre-flight checks
|
||||||
|
checkNetwork
|
||||||
|
checkSsh
|
||||||
|
|
||||||
|
# Generate session ID
|
||||||
|
generateSessionId
|
||||||
|
|
||||||
|
# Establish tunnel
|
||||||
|
establishTunnel
|
||||||
|
|
||||||
|
# Wait for quit or timeout
|
||||||
|
waitForQuit
|
||||||
|
|
||||||
|
# End session
|
||||||
|
patronageMessage
|
||||||
|
|
||||||
|
logMessage "=== SAS Client Ended ==="
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main
|
||||||
|
main "$@"
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# SSH Login Monitor for Fenrir Screen Reader
|
||||||
|
# Monitors SSH logins and announces them via Fenrir's speech system
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
fenrirSocket="/tmp/fenrirscreenreader-deamon.sock"
|
||||||
|
logFile="/var/log/auth.log"
|
||||||
|
stateFile="/tmp/fenrir-ssh-monitor.state"
|
||||||
|
checkInterval=2 # seconds between checks
|
||||||
|
|
||||||
|
# Voice settings
|
||||||
|
announceUser=true
|
||||||
|
announceIp=true
|
||||||
|
announceHostname=true
|
||||||
|
announceLogout=false # Announce SSH disconnections (disabled by default - may not work reliably on all systems)
|
||||||
|
|
||||||
|
# Function to send message to Fenrir
|
||||||
|
fenrirSay() {
|
||||||
|
local message="$1"
|
||||||
|
# Only announce if Fenrir socket exists (silently skip if not)
|
||||||
|
if [[ -S "$fenrirSocket" ]]; then
|
||||||
|
echo "command say ${message}" | socat - UNIX-CLIENT:"${fenrirSocket}" 2>/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to get last processed line number
|
||||||
|
getLastLine() {
|
||||||
|
if [[ -f "$stateFile" ]]; then
|
||||||
|
cat "$stateFile"
|
||||||
|
else
|
||||||
|
echo "0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to save last processed line number
|
||||||
|
saveLastLine() {
|
||||||
|
echo "$1" > "$stateFile"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to parse SSH login and announce
|
||||||
|
processLogin() {
|
||||||
|
local logLine="$1"
|
||||||
|
local user=""
|
||||||
|
local ip=""
|
||||||
|
local hostname=""
|
||||||
|
|
||||||
|
# Parse different SSH login patterns
|
||||||
|
# Pattern 1: "Accepted publickey for USER from IP"
|
||||||
|
# Pattern 2: "Accepted password for USER from IP"
|
||||||
|
if [[ "$logLine" =~ Accepted\ (publickey|password|keyboard-interactive/pam)\ for\ ([^[:space:]]+)\ from\ ([^[:space:]]+) ]]; then
|
||||||
|
user="${BASH_REMATCH[2]}"
|
||||||
|
ip="${BASH_REMATCH[3]}"
|
||||||
|
|
||||||
|
# Try to resolve hostname
|
||||||
|
if command -v host &> /dev/null && [[ "$announceHostname" == "true" ]]; then
|
||||||
|
hostname="$(host "$ip" 2>/dev/null | grep -oP 'domain name pointer \K[^.]+' | head -1)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build announcement message (concise format)
|
||||||
|
local message=""
|
||||||
|
|
||||||
|
if [[ "$announceUser" == "true" ]]; then
|
||||||
|
message+="${user} "
|
||||||
|
fi
|
||||||
|
|
||||||
|
message+="S S H login"
|
||||||
|
|
||||||
|
if [[ "$announceIp" == "true" ]]; then
|
||||||
|
message+=" from ${ip}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$hostname" ]] && [[ "$announceHostname" == "true" ]]; then
|
||||||
|
message+=" ${hostname}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fenrirSay "$message"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to parse SSH logout and announce
|
||||||
|
processLogout() {
|
||||||
|
local logLine="$1"
|
||||||
|
local user=""
|
||||||
|
|
||||||
|
# Parse SSH disconnect patterns
|
||||||
|
# Pattern: "pam_unix(sshd:session): session closed for user USER"
|
||||||
|
if [[ "$logLine" =~ session\ closed\ for\ user\ ([^[:space:]]+) ]]; then
|
||||||
|
user="${BASH_REMATCH[1]}"
|
||||||
|
|
||||||
|
if [[ "$announceLogout" == "true" ]]; then
|
||||||
|
local message=""
|
||||||
|
|
||||||
|
if [[ "$announceUser" == "true" ]]; then
|
||||||
|
message+="${user} "
|
||||||
|
fi
|
||||||
|
|
||||||
|
message+="disconnected from S S H"
|
||||||
|
|
||||||
|
fenrirSay "$message"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to monitor auth.log
|
||||||
|
monitorAuthLog() {
|
||||||
|
local lastLine
|
||||||
|
lastLine=$(getLastLine)
|
||||||
|
|
||||||
|
# Get total lines in log
|
||||||
|
local totalLines
|
||||||
|
totalLines=$(wc -l < "$logFile" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
# If log was rotated, reset
|
||||||
|
if [[ $totalLines -lt $lastLine ]]; then
|
||||||
|
lastLine=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process new lines
|
||||||
|
if [[ $totalLines -gt $lastLine ]]; then
|
||||||
|
local newLines=$((totalLines - lastLine))
|
||||||
|
|
||||||
|
# Read only new lines
|
||||||
|
tail -n "$newLines" "$logFile" 2>/dev/null | while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ sshd.*Accepted ]]; then
|
||||||
|
processLogin "$line"
|
||||||
|
elif [[ "$line" =~ sshd.*session\ closed ]]; then
|
||||||
|
processLogout "$line"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveLastLine "$totalLines"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to monitor journalctl (alternative for systemd systems)
|
||||||
|
monitorJournalctl() {
|
||||||
|
# Follow journalctl for SSH logins and logouts
|
||||||
|
journalctl -u sshd -u ssh -f -n 0 --no-pager 2>/dev/null | while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ Accepted ]]; then
|
||||||
|
processLogin "$line"
|
||||||
|
elif [[ "$line" =~ session\ closed ]]; then
|
||||||
|
processLogout "$line"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [[ "$(id -u)" -ne 0 ]]; then
|
||||||
|
echo "Error: This script must be run with sudo privileges to access system logs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Note: We don't require Fenrir to be running at startup
|
||||||
|
# The script will silently skip announcements when Fenrir socket doesn't exist
|
||||||
|
|
||||||
|
# Determine monitoring method
|
||||||
|
if command -v journalctl &> /dev/null && systemctl is-active --quiet sshd 2>/dev/null; then
|
||||||
|
echo "Starting SSH login monitor (using journalctl)..."
|
||||||
|
fenrirSay "SSH login monitor started."
|
||||||
|
|
||||||
|
# Use journalctl for real-time monitoring
|
||||||
|
trap 'fenrirSay "SSH login monitor stopped."; exit 0' INT TERM
|
||||||
|
monitorJournalctl
|
||||||
|
elif [[ -f "$logFile" ]]; then
|
||||||
|
echo "Starting SSH login monitor (using auth.log)..."
|
||||||
|
fenrirSay "SSH login monitor started."
|
||||||
|
|
||||||
|
# Use auth.log polling
|
||||||
|
trap 'fenrirSay "SSH login monitor stopped."; rm -f "$stateFile"; exit 0' INT TERM
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
monitorAuthLog
|
||||||
|
sleep "$checkInterval"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Error: Cannot find SSH logs. Neither journalctl nor ${logFile} is available."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -3,6 +3,7 @@ alsa-utils
|
|||||||
amd-ucode
|
amd-ucode
|
||||||
arch-install-scripts
|
arch-install-scripts
|
||||||
archinstall
|
archinstall
|
||||||
|
autossh
|
||||||
base
|
base
|
||||||
base-devel
|
base-devel
|
||||||
bash-completion
|
bash-completion
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ file_permissions=(
|
|||||||
["/usr/local/bin/install-stormux"]="0:0:755"
|
["/usr/local/bin/install-stormux"]="0:0:755"
|
||||||
["/usr/local/bin/stormux-setup.sh"]="0:0:755"
|
["/usr/local/bin/stormux-setup.sh"]="0:0:755"
|
||||||
["/usr/local/bin/init-pipewire-sound.sh"]="0:0:755"
|
["/usr/local/bin/init-pipewire-sound.sh"]="0:0:755"
|
||||||
|
["/usr/local/bin/sas.sh"]="0:0:755"
|
||||||
|
["/usr/local/bin/sas"]="0:0:755"
|
||||||
|
["/usr/share/fenrirscreenreader/scripts/ssh-login-monitor.sh"]="0:0:755"
|
||||||
|
["/etc/stormux-assist"]="0:0:755"
|
||||||
|
["/etc/stormux-assist/client.conf"]="0:0:644"
|
||||||
["/home/stormux"]="1000:1000:755"
|
["/home/stormux"]="1000:1000:755"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user