-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevidencer.cfg
216 lines (171 loc) · 10 KB
/
evidencer.cfg
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# Pretty handy when you do not match anything to run, then evidencer gives you a warning.
WARNINGS=1
# If your finger slips and you run a script that matches too many serverfiles... abort
MAXMATCHES=2
# Also copy evidencer.cfg and evidencer when creating a new suit when running ./evidencer -Cs myNewSuit
SUIT_LINK=1
SUIT_CFG=1
# Defaults can be changed. Some people like single letter change directories. (the "s" clashes)
# Don't just stick with scripts/servers/results, change it a bit:
# checks/hosts/output tasks/clients/logs cheese/hamburgers/crumbs investigate/cases/clues
#SCRIPTS=scripts
#SERVERS=servers
#RESULTS=results
# Instead of polluting the directory where evidencer is in, why not put important files in a subdir?
# You can even put that directory in a git repo, so no changes are lost.
#CFGDIR=.
CFGDIR=CFG
# This is for big lists to run in less time by grouping, but be careful that the OUTPUTDIR can only be
# one, so this means that you mix output from another script into this single output.
# It might be what you want (for example: you do not have any pre/post scripts), it might not.
#GROUP=1
#FOLD=0
# Run a maximum of THROTTLE parallel ssh commands, to not overburden the server or the network
THROTTLE=10
# You can, instead of writing complex oneliners in this configuration file, actually run external scripts
# These scripts normally don't have the variables this configuration file has, but we can export these
# using a regexp and comma separation, it means you can do:
# EXPORT=BASEDIR,SILENCE,OUTPUTDIR,RUNSERVERFQ,RUNSCRIPTFQ,OUTPUTLOG
# or:
# /RUN/,BASEDIR
# which would export all variables that contain RUN, and also BASEDIR
# Conveniently we just export everything with /./
EXPORT=/./
# LightSalmon3 (137). Get more from: https://jonasjacek.github.io/colors/
# Unused colouring letters are (caps only): DEFHJMQSTVX_
C:S=\033[38;5;137m
# Colors. Get more from: https://gist.github.com/iamnewton/8754917
# BOLD=\033[1m # use: existing %{C:B} instead
# NORM=\033[0m # use: existing %{C:N} instead
# In fact, here is how to list what is available: grep C: ./evidencer |grep 033 |grep =
# If you don't like colors on your terminal, uncomment:
#NOCOLORS=2
# Executing scripts (if we use /v for verbose, we fill them)
RUN_START=[ %{VERBOSE} = 1 ] && %{_RUN_START}
RUN_BEGIN=
RUN_END=
RUN_FINISH=
# It does not matter if a variable is defined before or after, they are filled in later.
# All official variables are uppercase. You can define and use mixedcase variables.
# These echo colorfully if you use /v (see: ALIAS /v=)
_RUN_START=echo "%{C:B}1%{C:N} %{C:U}%{C:B}STARTING%{C:N} %{C:S}%{NOW}%{C:N} from ${PWD}"
_RUN_BEGIN=echo "%{C:B}2%{C:N} %{C:U}%{C:B}Begin with:%{C:N} %{C:B}${RUNNAMES}%{C:N} on %{RUNSERVER}"
_RUN_END=echo "%{C:B}3%{C:N} %{C:U}%{C:B}End with:%{C:N} %{C:B}%{RUNNAMES}%{C:N} on %{RUNSERVER} with exitcode ${ERRORCODE}"
_RUN_FINISH=echo "%{C:B}4%{C:N} %{C:U}%{C:B}FINISHED%{C:N} Total errors is ${TOTALERRORS} and we took ${TOTALTIME} seconds. %{C:S}%{NOW}%{C:} %{C:S}${HOME}%{C:N}"
# Try: ./evidencer /v get.a.spoon=VM-ET -d
# As you will see, RUN_START is never executed, because it already ran before we evaluated /v
# To see RUN_START, try: ./evidencer -r /v get.a.spoon=VM-ET -d
ALIAS /v=&RUN_START=%{_RUN_START}{,}&RUN_BEGIN=%{_RUN_BEGIN}{,}&RUN_END=%{_RUN_END}{,}&RUN_FINISH=%{_RUN_FINISH}{,}&SILENCE=
# These can be handy, unless you dislike too much information on your screen.
RUN_FAIL=echo "%{C:R}ERROR:%{C:N} %{C:B} RUN script did not exit correctly%{C:N}. ERRORCODE=(%{ERRORCODE})"
RUN_ABORT=echo "%{C:R}ABEND(%{ERRORCODE}):%{ABORTMSG}%{C:N}"
# These variables %{} will be evaluated and filled in BEFORE starting the script (they dont change)
YMDHHMM=%{YEAR}-%{MONTH}-%{DAY}_%{HH}%{MM}
# These variables ${} will be evaluated at running/printing time. (these change each RUN_*)
NOW=${YEAR}-${MONTH}-${DAY}_${HH}:${MM}:${SS}
# Add some structure to the scripts
# If you are running one script, then RUNNAME = RUNNAMES, however, if you group/bundle/fold then the resulting script names
# are concatenated with a + and that is your RUNNAMES.
# For example:
# ./evidencer os.show.+=localhost -f
# Results in the OUTPUTDIR ./results/os.show.boottime+os.show.cpu+os.show.free+os.show.uptime/
# RUNNAMES must be overriden with a !, like so:
# ./evidencer os.show.+=localhost -f -r RUNNAMES:=bundled
# This would then create ./results/bundled/
OUTPUTDIR=%{RUNRESULTSDIR}/${RUNNAMES}
# You can tail -f this to see how many servers are still pending
OUTPUTLOG=%{OUTPUTDIR}.log
# This file will be touched when starting, so you know when run last ran it.
STARTFILE=%{OUTPUTDIR}.run
# Note that none of the 3 above variables are official ones, they are used later in official variables.
# Define names of pre and post scripts (must be runnable)
PRE_PROCESS_SCRIPT=%{RUNSCRIPTSDIR}/%{RUNNAME}^pre
POST_PROCESS_SCRIPT=%{RUNSCRIPTSDIR}/%{RUNNAME}^post
# Define names for filter processes
FILTER_PROCESS_SCRIPT=%{RUNSCRIPTSDIR}/%{RUNNAME}^filter
FILTER_PROCESS=%{RUNSCRIPTSDIR}/PRE^filter
RUN_FILTER=if [ -x %{FILTER_PROCESS_SCRIPT} ];then %{FILTER_PROCESS_SCRIPT} "%{OUTPUTDIR}" "${SERVER}" ; else %{FILTER_PROCESS} "%{OUTPUTDIR}" "${SERVER}";fi
# MAXAGE in days
MAXAGE=1
# Days to seconds
MAXAGESECS=$((${MAXAGE}*24*60*60))
# instead of using date, we can also do: NOW=%{EPOCH}
FILTER_AGE= NOW=$(date +%s); AGE=$(stat -c %Y "%{OUTPUTDIR}/%{SERVER}"); DIFF=$(($AGE - $NOW + ${MAXAGESECS})); [ $DIFF -lt 0 ]
FILTER_AGE10= [ ! -f "%{OUTPUTDIR}/%{SERVER}" ] || test "$( find '%{OUTPUTDIR}/%{SERVER}' -mmin +10 )"
FILTER_EXISTS=[ ! -f "%{OUTPUTDIR}/%{SERVER}" ]
ALIAS /skipifnew =&RUN_FILTER:=%{FILTER_AGE}{,}XFILTER:=1
ALIAS /skipifexists=&RUN_FILTER:=%{FILTER_EXISTS}{,}XFILTER:=1
ALIAS /skipif10min=&RUN_FILTER:=%{FILTER_AGE10}{,}XFILTER:=1
# To manipulate the verbosity of ssh-batch
SILENCE=--quiet --no-info
# Rather than passing each SSH option like this:
OPTIONS=--ssh-option UserKnownHostsFile=%{CFGDIR}/kh --ssh-option HashKnownHosts=yes
# Why not define a separate configuration file and write them there?
OPTIONS=--fqdn-logname -F %{BASEDIR}/CFG/config
# For now, we default to ~/.ssh/config
OPTIONS=--fqdn-logname
# https://serverfault.com/questions/233855/why-should-i-use-hashknownhosts-yes-in-ssh-config
# https://unix.stackexchange.com/questions/234903/correct-ssh-config-file-settings-to-tunnel-to-a-3rd-machine
# This confirmation only activates for scripts that have #?: and a message in a line.
# Only the first letter (case insensitive) will be checked for an affirmation
# So this is also valid for localization: YN=j/n
# The default is: YN=Y/N (and does not accept colors)
YN=Yes or No
# First we run RUN_PRE. It will make sure the directories exist to save your data to
RUN_PRE= [ -d "%{OUTPUTDIR}" ] || mkdir "%{OUTPUTDIR}"; touch "%{STARTFILE}"; \
if [ -f "%{PRE_PROCESS_SCRIPT}" ];then "%{PRE_PROCESS_SCRIPT}" "%{RUNSERVERFQ}" "%{RUNSCRIPTSDIR}";fi
# Then, if we do not have an argument, we run RUN
RUN=%{BASEDIR}/bin/ssh-batch ${SILENCE} %{OPTIONS} --bg-log-dir "%{OUTPUTDIR}" %{RUNSERVERFQ} -- %{RUNSCRIPTFQ} > "%{OUTPUTLOG}"
# If we do have an argument, run this instead
RUN_ARG=%{BASEDIR}/bin/ssh-batch ${SILENCE} %{OPTIONS} --bg-log-dir "%{OUTPUTDIR}" %{RUNSERVERFQ} -- %{RUNSCRIPTFQ} --- %{ARG} > "%{OUTPUTLOG}"
POST_GENERIC=if [ -x "%{RUNSCRIPTSDIR}/POST" ];then "%{RUNSCRIPTSDIR}/POST" "%{OUTPUTLOG}" "%{RUNSERVERFQ}" "%{OUTPUTDIR}";fi
## Sample of a generic POST script: ./scripts/POST
# OUTPUTLOG=$1
# RUNSERVERFQ=$2
# OUTPUTDIR=$3
# export svr=""
# # We cleanup the server list (could contain comments, jumphosts, or usernames) and print the rest
# cat $RUNSERVERFQ | perl -pe 's/:.*|.*\^|.*\@//g' while read svr;do
# cat "$OUTPUTDIR/$svr"' | grep -v -e '<ssh_askpass>' |perl -pe 's/^/$ENV{svr}':/'
# done
#
# Run this after RUN finished
# Long entries can be split across multiple lines by using the \
RUN_POST= if [ -f "%{POST_PROCESS_SCRIPT}" ];then \
"%{POST_PROCESS_SCRIPT}" "%{OUTPUTLOG}" "%{RUNSERVERFQ}" "%{OUTPUTDIR}";else\
%{POST_GENERIC};fi
# some scripts do not like to be Grouped/Folded. Use the -r to redefine it, like so:
# ./evidencer -r SEPARATE script1=serverlist1 script2=serverlist2
# The ! means that once set, it can not be overriden
ALIAS SEPARATE=GROUP:=0{,}FOLD:=0
# If you want to just run the RUN_POST script (because that processes your script output), then this nests Aliases:
ALIAS NOARG=RUN_ARG=
ALIAS NOPRE=RUN_PRE=
ALIAS NORUN=RUN=
ALIAS ~showonly=NORUN{,}NOPRE{,}NOARG
# The four lines could have been replaced by:
ALIAS ~ShowOnly=RUN_ARG={,}RUN_PRE={,}RUN=
# Be careful with aliases, if your scripts contain a substring equal to the alias (case sensitive), then it's replaced!
# use a leading / or UPPERCASE for aliases and lowercase for scripts.
# From the commandline try: ./evidencer -r NOARG,NOPRE,NORUN ...
# From the commandline try: ./evidencer -r ~showonly ...
# From the commandline try: ./evidencer -r ~ShowOnly ...
# Example of an alias for the commandline (so it does not require the -r)
# This example runs test3 on VM-PR and then get.the.knife with the newest servers file (# is an alias to that)
ALIAS /go=&FOLD=0 &GROUP=0 &RUN= &ARG="SAD_SAD" test3=VM-PR &RUN= get.the.knife=#
ALIAS ~runseparate=&SEPARATE os.show.boottime=+ get.the.knife=+
ALIAS ~run=os.show.boottime=+ get.the.knife=+
# Let ssh-batch be less verbose when running.
# use as follows: ./evidencer /q get.the.knife=+ or as: ./evidencer -r /q get.the.knife=+
ALIAS /q=&SILENCE=--quiet
# use only as follows: ./evidencer -r /qq get.the.knife=+
ALIAS /qq=SILENCE=--quiet
# If you defined a task^post, then don't use that, instead use the ./scripts/POST
ALIAS /raw=&RUN_POST=%{POST_GENERIC}
# Undefine all actions except RUN_POST and RUN_END. This way, you can re-display the results
# without fetching the data.
# Use it like: ./evidencer /show test=serverlist (note that the order is important here)
# or like: ./evidencer test=serverlist -r /show (order is not important, -r is always first)
ALIAS /show=&RUN:={,}&RUN_ARG:={,}&RUN_PRE:={,}&RUN_START:={,}&RUN_FINISH:={,}
# For this to work, your post action should be configured to display something.
ALIAS /max=&MAXMATCHES=2000