-
Notifications
You must be signed in to change notification settings - Fork 0
/
qidled.conf
176 lines (153 loc) · 7.79 KB
/
qidled.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/bin/bash
#
# Configuration file for qidled.
#
# Recommended location: /etc/qidled.conf (symlinks supported)
#
# This is a bash file allowing you to add your own code.
#Time in seconds after which to consider a VM idle, if it has no active X window.
#Set an empty map to disable all actions on VM idles.
#[index]: [VM name regex] --> [timeout]
#[index]: A number followed by a colon and a space to define the order in which regexes are executed (lower first).
#[VM name regex]: A Posix Extended Regular Expression (ERE) to match against VM names.
#[timeout]: Timeout in seconds after which to consider matching VMs idle.
declare -A VM_TIMEOUT=(
['50: .*']=600
)
#Number of checks to do for a VM before considering it idle.
#(E.g. with VM_TIMEOUT=180 and VM_CHECKS=2 a first idle check will be done after 90 seconds, then another after 180 seconds. Only if _both_ found the VM idle, the idle action will be triggered after 180s.)
VM_CHECKS=2
#Associative array with the actions to execute whenever a VM becomes idle.
#[index]: [VM name regex] --> [action]
#[index]: A number followed by a colon and a space to define the order in which regexes are executed (lower first).
#[VM name regex]: A Posix Extended Regular Expression (ERE) to match against VM names. Actions are only executed, if at least one regex matches _and_ none of regular expressions of `VM_IDLE_EXCLUDE` matches.
#[action]: Name of a bash function or command to execute when a matching VM becomes idle. The VM name is passed as first argument and the number of times that the VM idle event was seen since the last non-idle event as second argument. Actions are never called on shut down VMs.
declare -A VM_IDLE=(
['50: .*']='action_vm_epause_shutdown'
)
#Array of Posix ERE VM names for which never to execute any action on VM idle triggers (even if they match any regex in `VM_IDLE`).
declare -a VM_IDLE_EXCLUDE=(
'^.*-sys-.*$'
'^sys-.*$'
'^fedora-.*$'
'^debian-.*$'
'^disp-mgmt-.*$'
)
#Dimensions in pixels that windows must at least have to prevent a VM idle.
#Set this to a reasonable value to prevent VMs from using small, nearly invisible windows (e.g. 1x1) to avoid their idle.
#VMs may still attempt other attacks (e.g. 100% transparent windows, moving windows outside of the screen, no border or title bar, ...), but the combination of Qubes OS and a reasonable window manager _should_ prevent most of those. If in doubt, best test it yourself! Please report a bug if you find a working attack.
#Note that these kind of attacks cannot bypass user idle triggers (if enabled) anyway.
MIN_WINDOW_WIDTH=20
MIN_WINDOW_HEIGHT=20
#Time in seconds after which to consider the user idle.
#Set it to a negative number to disable all actions on user idles.
#User idles can still be triggered manually via `qidled triggerUserIdle`.
USER_TIMEOUT=900
#Associative array with the actions to execute whenever the user becomes idle.
#Actions are only executed against running VMs that match the regular expression.
#The syntax is identical to the `VM_IDLE` map.
declare -A USER_IDLE=(
#['30: ^dom0$']='action_dom0_shutdown 48' #shutdown after 48 times $USER_TIMEOUT (900s) = 12h
['50: .*']='action_vm_epause_shutdown'
)
#Array of Posix ERE VM names for which never to execute any action on user idle triggers (even if they match any regex in `USER_IDLE`).
declare -a USER_IDLE_EXCLUDE=(
"${VM_IDLE_EXCLUDE[@]}"
)
########################### actions ############################
#action_vm_epause [vm] [count]
#Pause the given VM.
#Paused VMs cannot attack other VMs via memory side channel attacks, but can fall victim to them. Unpausing is significantly faster than starting a VM though.
#**Warning**:
# - For e.g. non-Linux HVMs unpausing may fail after 10 minutes or so as the kernel may not be able to cope with "time jumps". Therefore it's called "emergency pause" (epause).
# - For Linux VMs, longer pauses usually work, but may result in Xorg crashes inside the VM. You can fix that by
# a) removing the line `WatchdogSec=3min` in `/usr/lib/systemd/system/systemd-logind.service` in your template VM.
# b) restarting `qubes-gui-agent` on unpause with e.g. `qvm-run -u root -n --nogui [vm] "qvm-sync-clock ; systemctl restart qubes-gui-agent"` (you'll notice if you don't get any window from that VM, but it's running).
# - See https://github.com/QubesOS/qubes-issues/issues/5988 for all the gory details.
#[vm]: Running VM to pause.
#[count]: How often an idle event was observed since the last non-idle event. Only a VM shutdown will cancel repetitive calls to this function.
#returns: Sets a non-zero exit code, if and only if the action failed.
function action_vm_epause {
local vm="$1"
local cnt="$2"
[[ "$vm" == "dom0" ]] && return 0 #ignore dom0
[ $cnt -eq 0 ] && qvm-pause "$vm"
return 0
}
#action_vm_shutdown [vm] [count]
#Halt the given VM.
#Currently only shut down VMs / VMs without active memory pages cannot fall victim to memory side channel attacks originating from running VMs.
#[vm]: Running VM to shut down.
#[count]: How often an idle event was observed since the last non-idle event. Only a VM shutdown will cancel repetitive calls to this function.
#returns: Sets a non-zero exit code, if and only if the action failed.
function action_vm_shutdown {
local vm="$1"
[[ "$vm" == "dom0" ]] && return 0 #ignore dom0
#NOTE:
# - the [count] can be ignored as we shut down the VM and thus won't be called again
# - it is security relevant to kill a VM that refuses to shut down (maybe because it wants to attack you via a side channel?!)
qvm-shutdown --wait --timeout 30 "$vm"
}
#action_vm_epause_shutdown [shutdown count] [vm] [count]
#First emergency pause the VM, then shut it down after the second timeout.
#Suitable for those who want quick recovery and some protection for a short while and maximum protection against memory side channel attacks after a longer while.
#[shutdown count]: Count after which to shut down (default: 1).
#[vm]: VM.
#[count]: How often an idle event was observed since the last non-idle event. Only a VM shutdown will cancel repetitive calls to this function.
#returns: Sets a non-zero exit code, if and only if the action failed.
function action_vm_epause_shutdown {
local scnt=1
if [ $# -gt 2 ] ; then
local scnt="${1:-1}"
shift
fi
local vm="$1"
local cnt="$2"
[[ "$vm" == "dom0" ]] && return 0 #ignore dom0
#unpause as workaround for https://github.com/QubesOS/qubes-issues/issues/5987
[ $cnt -lt $scnt ] && action_vm_epause "$@" || { qvm-unpause "$vm" &> /dev/null ; sleep 1 ; action_vm_shutdown "$@" ; }
}
#action_dom0_shutdown [shutdown count] [vm] [count]
#Shut down the entire machine.
#[shutdown count]: Count after which to shut down (default: 0).
#[vm]: VM.
#[count]: How often an idle event was observed since the last non-idle event. Only a VM shutdown will cancel repetitive calls to this function.
#returns: Sets a non-zero exit code, if and only if the action failed.
function action_dom0_shutdown {
local scnt=1
if [ $# -gt 2 ] ; then
local scnt="${1:-0}"
shift
fi
local vm="$1"
local cnt="$2"
if [[ "$vm" == "dom0" ]] && [ $cnt -ge $scnt ] ; then
logger -t "$B_SCRIPT_NAME" "Shutting dom0 down..."
#make sure the Xen shutdown happens, even if other commands hang
( sleep 60 ; sudo systemctl -i poweroff ) &
disown
#unpause paused VMs for proper shutdown
qvm-unpause --all &> /dev/null
sleep 1
#shutdown all VMs
qvm-shutdown --all --wait --timeout 30
#shutdown Xen
#NOTES:
# - poweroff, shutdown, halt, init, ... are all systemctl symlinks on systemd systems
# - -i is required to shut down even when there's an open tty
sudo systemctl -i poweroff
#if we get here, we failed
return 1
else
return 0
fi
}
#action_print [type] [vm] [count]
#Print the action calls to `qidle_exec.log` for debugging purposes.
#[type]: "user" or "vm"
function action_print {
local type="$1"
local vm="$2"
local cnt="$3"
echo "$(date) $type idle triggered for $vm (count: $cnt)." >> "$B_SCRIPT_DIR/qidle_exec.log"
}