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-15 09:56:37 +00:00
|
|
|
|
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
|
|
|
|
|
2017-02-15 09:56:37 +00:00
|
|
|
# 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
|
2017-02-04 10:39:01 +00:00
|
|
|
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
|
2017-02-04 10:39:01 +00:00
|
|
|
}
|
|
|
|
|
2017-02-15 09:56:37 +00:00
|
|
|
# push eotk directory to remote
|
|
|
|
DestructivePush() {
|
2017-02-14 23:29:19 +00:00
|
|
|
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 ::::
|
2017-02-15 09:56:37 +00:00
|
|
|
rsync $RSYNCFLAGS \
|
2017-02-14 23:00:04 +00:00
|
|
|
-av \
|
|
|
|
--delete \
|
2017-02-15 09:56:37 +00:00
|
|
|
--delete-excluded \
|
2017-02-15 10:56:58 +00:00
|
|
|
--exclude="*.log" \
|
2017-02-14 23:00:04 +00:00
|
|
|
--exclude="*~" \
|
|
|
|
--exclude=".git/" \
|
2017-02-15 09:56:37 +00:00
|
|
|
--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" \
|
2017-02-15 09:56:37 +00:00
|
|
|
--exclude="docs.d/" \
|
2017-02-14 23:00:04 +00:00
|
|
|
--exclude="hostname" \
|
2017-02-15 10:56:58 +00:00
|
|
|
--exclude="lock" \
|
2017-02-15 09:56:37 +00:00
|
|
|
--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
|
|
|
|
}
|
|
|
|
|
2017-02-15 09:56:37 +00:00
|
|
|
# mirror remote back for log review, backup, etc
|
|
|
|
Mirror() {
|
2017-02-14 23:29:19 +00:00
|
|
|
for host in `CloudHosts` ; do
|
2017-02-14 23:00:04 +00:00
|
|
|
test "$host" = "localhost" && continue # skip self
|
2017-02-14 23:29:19 +00:00
|
|
|
echo :::: host: $host ::::
|
2017-02-15 09:56:37 +00:00
|
|
|
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*" \
|
2017-02-15 09:56:37 +00:00
|
|
|
$host:${EOTK_HOME}/ $mirrors_dir/$host/
|
2017-02-14 23:00:04 +00:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoteAction() {
|
2017-02-14 23:29:19 +00:00
|
|
|
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 10:39:01 +00:00
|
|
|
|
2017-02-04 12:57:02 +00:00
|
|
|
verbose=false
|
2017-02-14 21:49:34 +00:00
|
|
|
|
2017-02-04 10:39:01 +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
|
2017-02-04 10:39:01 +00:00
|
|
|
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:39:01 +00:00
|
|
|
|
2017-02-04 10:06:42 +00:00
|
|
|
for project in $projects ; do
|
2017-02-14 23:29:19 +00:00
|
|
|
$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
|
2017-02-13 23:43:35 +00:00
|
|
|
dots=true
|
|
|
|
else
|
|
|
|
dots=false
|
|
|
|
fi
|
|
|
|
|
2017-02-07 13:57:12 +00:00
|
|
|
cat "$@" |
|
|
|
|
while read line ; do
|
|
|
|
case "$line" in
|
2017-02-13 23:43:35 +00:00
|
|
|
*%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!"
|
|
|
|
;;
|
2017-02-13 23:43:35 +00:00
|
|
|
*%NEW_HARD_ONION%*)
|
2017-02-14 23:58:51 +00:00
|
|
|
onion=secrets.d/`$self genkey`
|
2017-02-13 23:43:35 +00:00
|
|
|
echo "$line" | sed -e "s!%NEW_HARD_ONION%!$onion!"
|
|
|
|
;;
|
|
|
|
*%NEW_SOFT_ONION%*)
|
2017-02-14 23:58:51 +00:00
|
|
|
onion=`$self genkey`
|
2017-02-13 23:43:35 +00:00
|
|
|
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
|
|
|
|
2017-02-13 23:43:35 +00:00
|
|
|
if $dots ; then
|
|
|
|
echo ".\c" >/dev/tty
|
|
|
|
fi
|
2017-02-07 13:57:12 +00:00
|
|
|
done
|
2017-02-13 23:43:35 +00:00
|
|
|
|
|
|
|
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
|
2017-02-14 23:29:19 +00:00
|
|
|
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...
|
2017-02-13 23:43:35 +00:00
|
|
|
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"
|
2017-02-14 23:29:19 +00:00
|
|
|
|
|
|
|
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`
|
2017-02-15 09:56:37 +00:00
|
|
|
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
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +00:00
|
|
|
start) # project, or "-a"
|
2017-02-14 21:49:34 +00:00
|
|
|
LocalAction start "$@"
|
2017-02-04 10:06:42 +00:00
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +00:00
|
|
|
stop) # project, or "-a"
|
2017-02-14 21:49:34 +00:00
|
|
|
LocalAction stop "$@"
|
2017-02-04 10:06:42 +00:00
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +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
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +00:00
|
|
|
debugon) # project, or "-a"
|
2017-02-14 21:49:34 +00:00
|
|
|
LocalAction debugon "$@"
|
2017-02-04 10:06:42 +00:00
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +00:00
|
|
|
debugoff) # project, or "-a"
|
2017-02-14 21:49:34 +00:00
|
|
|
LocalAction debugoff "$@"
|
2017-02-04 10:06:42 +00:00
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +00:00
|
|
|
harvest|onions) # project, or "-a"
|
2017-02-14 21:49:34 +00:00
|
|
|
LocalAction harvest "$@"
|
2017-02-04 10:39:01 +00:00
|
|
|
;;
|
|
|
|
|
|
|
|
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)
|
2017-02-15 09:56:37 +00:00
|
|
|
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
|
|
|
;;
|
|
|
|
|
2017-02-04 10:39:01 +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
|
|
|
;;
|
|
|
|
|
2017-02-15 09:56:37 +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
|
|
|
;;
|
|
|
|
|
2017-02-15 09:56:37 +00:00
|
|
|
remote-test|test)
|
|
|
|
RemoteAction version
|
|
|
|
;;
|
|
|
|
|
2017-02-15 10:06:19 +00:00
|
|
|
freeze-mirrors|freeze-mirror|freeze|backup)
|
2017-02-15 09:56:37 +00:00
|
|
|
(
|
|
|
|
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?
|
2017-02-14 23:29:19 +00:00
|
|
|
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
|