SNARE.CONF(5) | File Formats Manual | SNARE.CONF(5) |
snare.conf
— snare
configuration file
snare.conf
is the configuration file for
snare(1). It consists of one or more top-level options and
one GitHub block.
The top-level options are:
0.0.0.0:8765
’ will listen on
port 8765 on for all IPv4 addresses.[::]:8765
’ will listen on port
8765 for all IPv4 and IPv6 addresses.snare.conf
will try
and change into after it has bound to a network port. Note that
snare.conf
will refuse to run as root unless
user is specified. As part of changing user,
snare.conf
:
All other environment variables are passed through to commands unchanged.
A ‘github’ block supports the following options:
A ‘match’ block supports the following options:
$SHELL -c
’. The
following escape sequences are recognised and replaced before execution:
pull_request
’).%
’.Note that ‘%
’ may not be
followed by any character other than those above.
The escape sequences are guaranteed to satisfy the regular expression "[a-zA-Z0-9._-]+" and not to be the strings "." or "..". This means that they are safe to pass as shell arguments and/or to be included in file system paths.
$SHELL -c
’. The following escape
sequences are recognised and replaced before execution:
pull_request
’).%
’.Note that ‘%
’ may not be
followed by any character other than those above.
The escape sequences are guaranteed to satisfy the regular expression "[a-zA-Z0-9._-]+" and not to be the strings "." or "..". This means that they are safe to pass as shell arguments and/or to be included in file system paths.
The default match block sets this to sequential, which is always safe, though at the possible expense of lower job throughput for any given repository.
snare.conf
to tell the difference between
genuine webhook requests and those from malfeasants. Although this is
optional, we
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 “unauthorised” to remind you to use the secret at
both ends.match blocks are evaluated in order from top to bottom with each successful match overriding previous settings. A default match block is inserted before any user match blocks:
match ".*" { queue = sequential; timeout = 3600; }
The minimal recommended snare.conf
file is
as follows:
listen = "<address>:<port>"; github { match ".*" { cmd = "/path/to/prps/%o/%r %e %j"; errorcmd = "cat %s | mailx -s \"snare error: github.com/%o/%r\" someone@example.com"; secret = "<secret>"; } }
where "/path/to/prps" is a path to a directory where per-repo programs are stored. Each repository then has a unique program "%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 someone@example.com containing the job's comined stderr and stdout output (assuming that a suitable sendmail clone has been installed and activated).
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:
listen = "<address>:<port>"; github { match ".*" { cmd = "/path/to/prps/%o/%r %e %j"; errorcmd = "cat %s | mailx -s \"snare error: github.com/%o/%r\" abc@def.com"; secret = "sec"; } match "a/b" { errorcmd = "lpr %s"; } }
the following repositories will have these settings:
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\" abc@def.com"; secret = "sec"
The following program expects to be called with an event and a JSON path (i.e. "%e %j") and uses shell script to send a list of commits and diffs to the address specified in $EMAIL on each “push” to master. It works for any public GitHub repository:
#! /bin/sh set -euf # A list of email addresses separated by spaces. EMAILS="someone@example.com someone.else@example.com" # A GitHub URL either https or git. REPO_URL="git@github.com: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
where 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).
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 (“repo”) rather than a file name from JSON that might include characters (such as “../..”) that would cause the script to leak data about other parts of the file system.
snare(1) was written by Laurence Tratt https://tratt.net/laurie/
2020-02-10 | Debian |