-
Notifications
You must be signed in to change notification settings - Fork 4
/
snare.conf.5
361 lines (355 loc) · 9 KB
/
snare.conf.5
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
.Dd 2020-02-10
.Dt SNARE.CONF 5
.Os
.Sh NAME
.Nm snare.conf
.Nd snare configuration file
.Sh DESCRIPTION
.Nm
is the configuration file for
.Xr snare 1 .
It consists of one or more top-level options and one GitHub block.
.Pp
The top-level options are:
.Bl -tag -width Ds
.It Sy listen = Qq Em address ;
is a mandatory address and port number to listen on.
The format of
.Em address
is either:
.Bl -tag -width -Ds
.It x.x.x.x:port
an IPv4 address and port.
For example,
.Ql 0.0.0.0:8765
will listen on port 8765 on for all IPv4 addresses.
.It [x:x:x]:port
an IPv6 address and port.
For example,
.Ql [::]:8765
will listen on port 8765 for all IPv4 and IPv6 addresses.
.El
.It Sy maxjobs = Em int ;
is an optional non-zero positive integer specifying the maximum number of
jobs to run in parallel.
Defaults to the number of CPUs in the machine.
.It Sy user = Qq Em user-name ;
is an optional username that
.Nm
will try and change into after it has bound to a network port.
Note that
.Nm
will refuse to run as root unless
.Sy user
is specified.
As part of changing user,
.Nm :
.Bl -bullet
.It
changes its uid, euid, suid to the UID of
.Em user-name .
.It
changes its gid, egid, sgid to the primary GID of
.Em user-name .
.It
sets the $HOME environment variable to the home directory of
.Em user-name .
.It
sets the $USER environment variable to
.Em user-name .
.El
.Pp
All other environment variables are passed through to commands unchanged.
.It Sy github { ... }
specifies GitHub specific options.
.El
.Pp
A
.Sq github
block supports the following options:
.Bl -tag -width Ds
.It Sy match Qo Em regex Qc { Em match-options }
where
.Em regex
is a regular expression in
.Lk https://docs.rs/regex/ Rust regex format
that must match against a
.Qq owner/repo
full repository name.
If it matches, then
.Em match-options
are applied.
.Qq regex
must match against the full repository name: in other words, it is equivalent
to
.Em ^regex$ .
Thus the regex
.Qq a/b
does not match against the full repository name
.Qq a/bc ,
but the regex
.Qq a/b.*
does match against
.Qo a/bc Qc .
.El
.Pp
A
.Sq match
block supports the following options:
.Bl -tag -width Ds
.It Sy cmd = Qq Em shell-cmd ;
optionally specifies a command to be run.
.Em shell-cmd
will be executed via
.Ql $SHELL -c .
The following escape sequences are recognised and replaced before execution:
.Bl -tag -width Ds
.It Sy %e
the GitHub event type (e.g.
.Ql pull_request ) .
.It Sy %j
the path to the GitHub JSON.
.It Sy %o
the repository owner.
.It Sy %r
the repository.
.It Sy %%
a literal
.Ql % .
.El
.Pp
Note that
.Ql %
may not be followed by any character other than those above.
.Pp
The escape sequences are guaranteed to satisfy the regular expression
.Qq [a-zA-Z0-9._-]+
and not to be the strings
.Qq \&.
or
.Qq .. .
This means that they are safe to pass as shell arguments and/or to be included
in file system paths.
.It Sy errorcmd = Qq Em shell-cmd ;
optionally specifies a command to be run when a job exits unsuccessfully.
.Em shell-cmd
will be executed via
.Ql $SHELL -c .
The following escape sequences are recognised and replaced before execution:
.Bl -tag -width Ds
.It Sy %e
the GitHub event type (e.g.
.Ql pull_request ) .
.It Sy %j
the path to the GitHub JSON.
.It Sy %o
the repository owner.
.It Sy %r
the repository.
.It Sy %s
the path to the file containing the job's combined stderr / stdout.
.It Sy %x
the exit type:
.Qq status
(i.e. normal exit);
.Qq signal ;
or
.Qq unknown .
.It Sy %?
the exit status / signal number (either an integer or the literal string
.Qq unknown )
that
.Em cmd
failed with.
.It Sy %%
a literal
.Ql % .
.El
.Pp
Note that
.Ql %
may not be followed by any character other than those above.
.Pp
The escape sequences are guaranteed to satisfy the regular expression
.Qq [a-zA-Z0-9._-]+
and not to be the strings
.Qq \&.
or
.Qq .. .
This means that they are safe to pass as shell arguments and/or to be included
in file system paths.
.It Sy queue = Po evict | parallel | sequential Pc ;
specifies what to do when multiple requests for the same repository
are queued at once:
.Bl -tag -width Ds
.It Sy evict
only run one job for this repository at a time.
Additional jobs will stay on the queue: if a new job comes in for that
repository, it evicts any previously queued jobs for that repository.
In other words, for this repository there can be at most one running job and
one queued job at any point.
.It Sy parallel
run as many jobs for this repository in parallel as possible.
.It Sy sequential
only run one job for this repository at a time.
Additional jobs will stay on the queue and be executed in FIFO order.
.El
.Pp
The default
.Sy match
block sets this to
.Sy sequential ,
which is always safe, though at the possible expense of lower job throughput
for any given repository.
.It Sy secret = Qq Em secret ;
is the optional GitHub secret used to sign the webhook request.
This allows
.Nm
to tell the difference between genuine webhook requests and those from
malfeasants.
Although this is optional, we
.Em highly
recommend setting it in all cases.
Note also that if a GitHub request is signed, but you have not specified a
secret, then snare will return the request as
.Dq unauthorised
to remind you to use the secret at both ends.
.It Sy timeout = Em period ;
specifies the elapsed time, as a positive integer, in seconds that a
process can run before being sent SIGTERM.
The default
.Sy match
block sets this to one hour (3600 seconds).
.El
.Pp
.Sy match
blocks are evaluated in order from top to bottom with each successful
match overriding previous settings.
A default
.Sy match
block is inserted before any user
.Sy match
blocks:
.Bd -literal -offset 4n
match ".*" {
queue = sequential;
timeout = 3600;
}
.Ed
.Sh EXAMPLES
The minimal recommended
.Nm
file is as follows:
.Bd -literal -offset 4n
listen = "<address>:<port>";
github {
match ".*" {
cmd = "/path/to/prps/%o/%r %e %j";
errorcmd = "cat %s | mailx -s \\"snare error: github.com/%o/%r\\" [email protected]";
secret = "<secret>";
}
}
.Ed
.Pp
where
.Qq /path/to/prps
is a path to a directory where per-repo programs are stored.
Each repository then has a unique program
.Qq %o/%r
which will be executed with two arguments: the GitHub event; and the path to
the GitHub JSON.
If a job exits unsuccessfully then an email will be sent to [email protected]
containing the job's comined stderr and stdout output (assuming that a suitable
sendmail clone has been installed and activated).
.Pp
The top-to-bottom evaluation of match blocks allow users to specify defaults
which are only overridden for specific repositories.
For example, for the following configuration file:
.Bd -literal -offset 4n
listen = "<address>:<port>";
github {
match ".*" {
cmd = "/path/to/prps/%o/%r %e %j";
errorcmd = "cat %s | mailx -s \\"snare error: github.com/%o/%r\\" [email protected]";
secret = "sec";
}
match "a/b" {
errorcmd = "lpr %s";
}
}
.Ed
.Pp
the following repositories will have these settings:
.Bd -literal -offset 4n
a/b:
queue = sequential
timeout = 3600
cmd = "/path/to/prps/%o/%r %e %j";
errorcmd = "lpr %s";
secret = "sec"
c/d:
queue = sequential
timeout = 3600
cmd = "/path/to/prps/%o/%r %e %j";
errorcmd = "cat %s | mailx -s \\"snare error: github.com/%o/%r\\" [email protected]";
secret = "sec"
.Ed
.Pp
The following program expects to be called with an event and a JSON path (i.e.
.Qq %e %j )
and uses shell script to send a list of commits and diffs to the address
specified in $EMAIL on each
.Dq push
to master.
It works for any public GitHub repository:
.Bd -literal -offset 4n
#! /bin/sh
set -euf
# A list of email addresses separated by spaces.
EMAILS="[email protected] [email protected]"
# A GitHub URL either https or git.
REPO_URL="[email protected]:owner/repo.git"
if [ "$1" != "push" ]; then
exit 0
fi
ref=`jq .ref "$2" | tr -d '\"'`
if [ "$ref" != "refs/heads/master" ]; then
exit 0
fi
repo_fullname=`jq .repository.full_name "$2" | tr -d '\"'`
repo_url=`jq .repository.html_url "$2" | tr -d '\"'`
before_hash=`jq .before "$2" | tr -d '\"'`
after_hash=`jq .after "$2" | tr -d '\"'`
echo "$before_hash" | grep -E "^[a-fA-F0-9]+$" 2>&1 > /dev/null
echo "$after_hash" | grep -E "^[a-fA-F0-9]+$" 2>&1 > /dev/null
git clone "$REPO_URL" repo
cd repo
for email in `echo "$EMAILS"`; do
git log --reverse -p "$before_hash..$after_hash" \\
| mail -s "Push to $repo_fullname" "$email"
done
.Ed
.Pp
where
.Lk https://stedolan.github.io/jq/ jq
is a command-line JSON processor.
Depending on your needs, you can make this type of script arbitrarily more
complex and powerful (for example, not cloning afresh on each pull).
.Pp
Note that this program is deliberately untrusting of external input: it is
careful to quote all arguments obtained from JSON; and it uses a fixed
directory name
.Pf ( Dq repo )
rather than a file name from JSON that might
include characters (such as
.Dq ../.. )
that would cause the script to leak data about other parts of the file system.
.Sh SEE ALSO
.Xr snare 1
.Pp
.Lk https://developer.github.com/webhooks/ GitHub's webhooks documentation .
.Sh AUTHORS
.An -nosplit
.Xr snare 1
was written by
.An Laurence Tratt Lk https://tratt.net/laurie/