Enterprise-Onion-Toolkit/eotk

380 wiersze
9.0 KiB
Plaintext
Czysty Zwykły widok Historia

2017-02-04 10:06:42 +00:00
#!/bin/sh
# Enterprise Onion Toolkit
2017-02-15 10:57:30 +00:00
#RSYNCFLAGS="-n" # safety/testing
2017-02-04 10:06:42 +00:00
cd `dirname $0` || exit 1
export EOTK_HOME=`pwd` # expected by tools
2017-02-04 16:28:16 +00:00
2017-02-14 23:58:51 +00:00
# for invoking myself
prog=`basename $0`
self=$EOTK_HOME/$prog
# meta
version=1.1alpha
2017-02-04 16:28:16 +00:00
# set project directory; this path is hard-replicated elsewhere
2017-02-04 10:06:42 +00:00
project_dir=$EOTK_HOME/projects.d
# mirror directory
mirrors_dir=$EOTK_HOME/mirrors.d
2017-02-04 16:28:16 +00:00
# set path
2017-02-05 13:14:47 +00:00
export PATH=$EOTK_HOME/opt.d:$EOTK_HOME/lib.d:$PATH
2017-02-04 16:28:16 +00:00
2017-02-14 21:49:34 +00:00
# print a formatted message to stdout
Print() {
echo "$prog:" "$@"
}
# print a formatted message to stderr
Warn() {
2017-02-14 21:49:34 +00:00
Print "$@" 1>&2
}
2017-02-14 23:00:04 +00:00
# essentially the projects.d folder is a little database
ListProjects() {
(
cd $project_dir || exit 1
for d in *.d/ ; do
echo `basename $d .d`
done
)
2017-02-14 21:49:34 +00:00
}
# what are the names of the remote workers?
CloudHosts() { # fake this up for the moment
2017-02-15 10:56:58 +00:00
echo "localhost" # this will be magic
2017-02-15 15:49:22 +00:00
for i in 1 2 3 4 5 6 ; do
: echo rig$i
done
}
# push eotk directory to remote
DestructivePush() {
for host in `CloudHosts` ; do
2017-02-14 23:00:04 +00:00
test "$host" = "localhost" && continue # skip self
2017-02-15 00:01:33 +00:00
echo :::: host: $host ::::
rsync $RSYNCFLAGS \
2017-02-14 23:00:04 +00:00
-av \
--delete \
--delete-excluded \
2017-02-15 10:56:58 +00:00
--exclude="*.log" \
2017-02-14 23:00:04 +00:00
--exclude="*~" \
--exclude=".git/" \
--exclude=".gitignore" \
2017-02-15 10:56:58 +00:00
--exclude="cached-certs" \
--exclude="cached-microdesc*" \
2017-02-14 23:00:04 +00:00
--exclude="configure*.log" \
--exclude="docs.d/" \
2017-02-14 23:00:04 +00:00
--exclude="hostname" \
2017-02-15 10:56:58 +00:00
--exclude="lock" \
--exclude="mirrors.d/" \
--exclude="ob*.yaml" \
2017-02-14 23:00:04 +00:00
--exclude="onion_service_non_anonymous" \
--exclude="private_key" \
--exclude="secrets.d/" \
2017-02-15 10:56:58 +00:00
--exclude="state" \
2017-02-14 23:00:04 +00:00
${EOTK_HOME}/ \
$host:${EOTK_HOME}/
done
}
# mirror remote back for log review, backup, etc
Mirror() {
for host in `CloudHosts` ; do
2017-02-14 23:00:04 +00:00
test "$host" = "localhost" && continue # skip self
echo :::: host: $host ::::
test -d $mirrors_dir || mkdir $mirrors_dir || exit 1
rsync $RSYNCFLAGS -av \
--delete \
--delete-excluded \
2017-02-15 10:56:58 +00:00
--exclude="cached-certs" \
--exclude="cached-microdesc*" \
$host:${EOTK_HOME}/ $mirrors_dir/$host/
2017-02-14 23:00:04 +00:00
done
}
RemoteAction() {
for host in `CloudHosts` ; do
echo :::: host: $host ::::
2017-02-15 10:56:58 +00:00
if [ "$host" = "localhost" ] ; then
$self "$@"
else
ssh "$host" "$self $*"
fi
2017-02-14 23:00:04 +00:00
done
2017-02-04 10:06:42 +00:00
}
2017-02-14 21:49:34 +00:00
# run a command in the context of the local projects directory
LocalAction() {
2017-02-04 10:06:42 +00:00
action=$1
shift
2017-02-04 12:57:02 +00:00
verbose=false
2017-02-14 21:49:34 +00:00
if [ "x$1" = "x" ] ; then
2017-02-14 23:00:04 +00:00
Print error: missing project name, try: $prog projects for a list, or -a for all
2017-02-14 21:49:34 +00:00
return 1
elif [ "x$1" = "x-a" ] ; then
2017-02-14 21:49:34 +00:00
projects=`ListProjects`
2017-02-04 12:57:02 +00:00
verbose=true
2017-02-04 10:06:42 +00:00
else
projects="$*"
fi
2017-02-04 10:06:42 +00:00
for project in $projects ; do
$verbose && echo :::: project: $project ::::
2017-02-04 16:28:16 +00:00
sh $project_dir/$project.d/$action.sh
2017-02-04 10:06:42 +00:00
done
}
2017-02-14 23:00:04 +00:00
# implement kludge to insert freshly-generated onions into a "*.tconf"
2017-02-14 21:49:34 +00:00
# template-configuration, so people don't have to type so much...
2017-02-07 13:57:12 +00:00
Populate() {
2017-02-14 21:49:34 +00:00
if [ -t 0 ] ; then # if stdin is a terminal, provide diags
dots=true
else
dots=false
fi
2017-02-07 13:57:12 +00:00
cat "$@" |
while read line ; do
case "$line" in
*%NEW_ONION%*) # legacy / shorter / more common
2017-02-14 23:58:51 +00:00
onion=secrets.d/`$self genkey`
2017-02-07 13:57:12 +00:00
echo "$line" | sed -e "s!%NEW_ONION%!$onion!"
;;
*%NEW_HARD_ONION%*)
2017-02-14 23:58:51 +00:00
onion=secrets.d/`$self genkey`
echo "$line" | sed -e "s!%NEW_HARD_ONION%!$onion!"
;;
*%NEW_SOFT_ONION%*)
2017-02-14 23:58:51 +00:00
onion=`$self genkey`
onion=`basename $onion .key`
echo "$line" | sed -e "s!%NEW_SOFT_ONION%!$onion!"
;;
2017-02-07 13:57:12 +00:00
*)
echo "$line"
;;
esac
2017-02-14 21:49:34 +00:00
if $dots ; then
echo ".\c" >/dev/tty
fi
2017-02-07 13:57:12 +00:00
done
if $dots ; then
echo "" >/dev/tty
fi
2017-02-07 13:57:12 +00:00
}
2017-02-14 21:49:34 +00:00
# get a config file and re/populate the projects directory with it
2017-02-07 10:05:53 +00:00
Configure() {
log=configure$$.log
for file in "$@" ; do
echo :::: file: $file ::::
2017-02-07 13:57:12 +00:00
case "$file" in
2017-02-14 21:49:34 +00:00
*.conf)
: happy bunnies
;;
2017-02-07 13:57:12 +00:00
*.tconf)
file2=`basename $file .tconf`.conf
if [ -s $file2 ] ; then
2017-02-14 21:49:34 +00:00
Print info: $file: using existing $file2
2017-02-07 13:57:12 +00:00
else
2017-02-14 21:49:34 +00:00
Print info: $file: populating $file2 with onions, please be patient...
Populate $file >$file2
2017-02-07 13:57:12 +00:00
fi
file="$file2"
;;
2017-02-14 21:49:34 +00:00
*)
Print error: bad config file suffix, was expecting: .conf, .tconf
exit 1
;;
esac
2017-02-07 13:57:12 +00:00
2017-02-07 10:05:53 +00:00
if ! $EOTK_HOME/lib.d/do-configure.pl "$file" ; then
2017-02-14 21:49:34 +00:00
Print error: failure processing $file: see $log
2017-02-07 10:05:53 +00:00
exit 1
fi
done 2>$log
2017-02-14 21:49:34 +00:00
Print info: done, logfile: $log
2017-02-07 10:05:53 +00:00
}
2017-02-14 21:49:34 +00:00
# argument 'parser' - ha!
2017-02-04 10:06:42 +00:00
cmd="$1"
shift # we may need the remaining args
2017-02-04 10:06:42 +00:00
case "$cmd" in
version)
2017-02-15 10:06:19 +00:00
Print $version $EOTK_HOME `uname -a`
if [ -d .git ] ; then
2017-02-04 10:06:42 +00:00
git show -s --oneline
fi
;;
projects|proj)
2017-02-14 21:49:34 +00:00
ListProjects
2017-02-04 10:06:42 +00:00
;;
2017-02-07 13:57:12 +00:00
populate|pop)
Populate "$@"
;;
2017-02-04 10:06:42 +00:00
configure|config|conf)
2017-02-07 10:05:53 +00:00
Configure "$@"
2017-02-04 10:06:42 +00:00
;;
start) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction start "$@"
2017-02-04 10:06:42 +00:00
;;
stop) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction stop "$@"
2017-02-04 10:06:42 +00:00
;;
bounce|restart|reload) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction bounce "$@"
2017-02-04 10:06:42 +00:00
;;
2017-02-11 20:29:48 +00:00
nxreload) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction nxreload "$@"
2017-02-11 20:29:48 +00:00
;;
debugon) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction debugon "$@"
2017-02-04 10:06:42 +00:00
;;
debugoff) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction debugoff "$@"
2017-02-04 10:06:42 +00:00
;;
harvest|onions) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction harvest "$@"
;;
status) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction status "$@"
2017-02-04 10:06:42 +00:00
;;
2017-02-05 14:55:05 +00:00
maps|map) # project, or "-a"
2017-02-14 21:49:34 +00:00
LocalAction maps "$@"
2017-02-04 11:19:47 +00:00
;;
2017-02-04 16:36:17 +00:00
ps)
ps auxww | egrep '\b(eotk)\b'
2017-02-04 16:36:17 +00:00
;;
2017-02-05 13:14:47 +00:00
genkey|gen)
secrets=secrets.d
test -d $secrets || mkdir $secrets || exit 1
2017-02-14 21:49:34 +00:00
(
cd $secrets
generate-onion-key.sh
)
2017-02-05 13:14:47 +00:00
;;
delete) # project, or "-a"
2017-02-15 10:06:19 +00:00
Print delete is tbd
;;
push)
Print push is destructive and has been renamed, see the documentation
2017-02-04 10:06:42 +00:00
;;
# this used to be called 'push' but got renamed because oops.
# DO NOT USE THIS CASUALLY, LEARN FROM MY MISTAKES
remote-nuke-and-push|rnap)
RemoteAction stop -a
DestructivePush
;;
remote-mirror|mirror|pull)
Mirror
2017-02-14 21:49:34 +00:00
;;
remote-test|test)
RemoteAction version
;;
2017-02-15 10:06:19 +00:00
freeze-mirrors|freeze-mirror|freeze|backup)
(
ds=`date "+%Y%m%d%H%M%S"`
cd $mirrors_dir || exit 1
for directory in */ ; do
test -d "$directory" || exit 1 # did */ expand?
dir=`basename $directory` # strip trailing /
echo :::: freeze: $dir ::::
tar cf - $dir | bzip2 > $dir-$ds.tar.bz2
done
)
2017-02-14 21:49:34 +00:00
;;
2017-02-15 15:49:22 +00:00
remote) # todo: wire this into all actions?
RemoteAction "$@"
2017-02-14 21:49:34 +00:00
;;
2017-02-14 23:58:51 +00:00
ob-config|obconfig)
if [ "x$1" = "x" ] ; then
Print error: missing project name, try: $prog projects for a list, or -a for all
exit 1
fi
2017-02-15 16:00:51 +00:00
# TODO: check if they are extant first, and if so, exit with error
# ob storage
ob_dir=$project_dir/onionbalance.run
test -d $ob_dir || mkdir $ob_dir || exit 1
# config files
ob_conf=$ob_dir/config.yaml
tor_conf=$ob_dir/tor.conf
tor_control=$ob_dir/tor-control.sock
# make tor conf
(
echo DataDirectory $ob_dir
echo ControlPort unix:$tor_control
echo PidFile $ob_dir/tor.pid
echo Log info file $ob_dir/tor.log
echo SafeLogging 1
echo HeartbeatPeriod 60 minutes
echo RunAsDaemon 1
echo "#" onionbalance
# echo SocksPort unix:$ob_dir/tor-socks.sock # curl 7.38 does not like this
echo SocksPort 127.0.0.1:9050 # meh
echo CookieAuthentication 1
echo MaxClientCircuitsPending 1024
) > $tor_conf
# make ob conf
$self remote map "$@" | grep -v "^::::" | do-obconfig.pl > $ob_conf
# to be done
# echo tor -f $tor_conf
# echo onionbalance -s $tor_control -c $ob_conf -v info
;;
ob-start|obstart)
;;
ob-stop|obstop)
2017-02-14 23:58:51 +00:00
;;
2017-02-04 10:06:42 +00:00
*)
2017-02-14 21:49:34 +00:00
Print usage: see README.md for documentation
2017-02-04 10:06:42 +00:00
exit 1
;;
esac
exit 0