summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ext/ovh/README (renamed from ovh/README)0
-rw-r--r--ext/ovh/soapi/Makefile (renamed from ovh/soapi/Makefile)0
-rw-r--r--ext/ovh/soapi/README (renamed from ovh/soapi/README)0
-rwxr-xr-xext/ovh/soapi/domainCapabilities (renamed from ovh/soapi/domainCapabilities)0
-rwxr-xr-xext/ovh/soapi/domainInfo (renamed from ovh/soapi/domainInfo)0
-rwxr-xr-xext/ovh/soapi/domainList (renamed from ovh/soapi/domainList)0
-rw-r--r--ext/ovh/soapi/soapi-re-1.24.wsdl (renamed from ovh/soapi/soapi-re-1.24.wsdl)0
-rwxr-xr-xext/ovh/soapi/zoneEntryAdd (renamed from ovh/soapi/zoneEntryAdd)0
-rwxr-xr-xext/ovh/soapi/zoneEntryDel (renamed from ovh/soapi/zoneEntryDel)0
-rwxr-xr-xext/ovh/soapi/zoneEntryList (renamed from ovh/soapi/zoneEntryList)0
-rwxr-xr-xext/ovh/soapi/zoneExport (renamed from ovh/soapi/zoneExport)0
-rwxr-xr-xext/ovh/soapi/zoneImport (renamed from ovh/soapi/zoneImport)0
-rwxr-xr-xext/solus/bin/client28
-rwxr-xr-xext/solus/lib/parse-return-data20
-rwxr-xr-xgold/mtgox/mtgox.ticker53
-rwxr-xr-xircbot/bot.py71
-rw-r--r--ircbot/feeds2
-rwxr-xr-xretiolum/Makefile2
-rwxr-xr-xretiolum/bin/apply-custom-hosts-patches8
-rwxr-xr-xretiolum/bin/list-known-public-addresses38
-rwxr-xr-xretiolum/bin/patch-retiolum-hosts13
-rwxr-xr-xretiolum/bin/update-retiolum-hosts6
-rwxr-xr-xretiolum/bin/update_tinc_hosts8
-rw-r--r--retiolum/hosts/Discordius11
-rw-r--r--retiolum/hosts/alphalabs3
-rw-r--r--retiolum/hosts/ire12
-rw-r--r--retiolum/hosts/nomic210
-rw-r--r--services/Makefile3
-rw-r--r--services/README.md25
-rwxr-xr-xservices/bin/services11
-rw-r--r--services/etc/conf.d/krebs-services-test-server3
-rw-r--r--services/etc/services/bootstrap9
-rw-r--r--services/etc/systemd/system/krebs-services-test-server.service14
-rw-r--r--services/services.txt4
-rwxr-xr-x[-rw-r--r--]services/test-server.py (renamed from services/test.py)10
-rw-r--r--util/README.markdown27
-rwxr-xr-xutil/bin/with6
-rw-r--r--util/lib/geo/Makefile15
-rw-r--r--util/lib/geo/index.js48
-rw-r--r--util/lib/geo/package.json7
40 files changed, 440 insertions, 27 deletions
diff --git a/ovh/README b/ext/ovh/README
index 90b34108..90b34108 100644
--- a/ovh/README
+++ b/ext/ovh/README
diff --git a/ovh/soapi/Makefile b/ext/ovh/soapi/Makefile
index 15ef8f3f..15ef8f3f 100644
--- a/ovh/soapi/Makefile
+++ b/ext/ovh/soapi/Makefile
diff --git a/ovh/soapi/README b/ext/ovh/soapi/README
index 42ad5ebf..42ad5ebf 100644
--- a/ovh/soapi/README
+++ b/ext/ovh/soapi/README
diff --git a/ovh/soapi/domainCapabilities b/ext/ovh/soapi/domainCapabilities
index a438e0b8..a438e0b8 100755
--- a/ovh/soapi/domainCapabilities
+++ b/ext/ovh/soapi/domainCapabilities
diff --git a/ovh/soapi/domainInfo b/ext/ovh/soapi/domainInfo
index 35459d06..35459d06 100755
--- a/ovh/soapi/domainInfo
+++ b/ext/ovh/soapi/domainInfo
diff --git a/ovh/soapi/domainList b/ext/ovh/soapi/domainList
index 342eec72..342eec72 100755
--- a/ovh/soapi/domainList
+++ b/ext/ovh/soapi/domainList
diff --git a/ovh/soapi/soapi-re-1.24.wsdl b/ext/ovh/soapi/soapi-re-1.24.wsdl
index c628c564..c628c564 100644
--- a/ovh/soapi/soapi-re-1.24.wsdl
+++ b/ext/ovh/soapi/soapi-re-1.24.wsdl
diff --git a/ovh/soapi/zoneEntryAdd b/ext/ovh/soapi/zoneEntryAdd
index 20ecd1fd..20ecd1fd 100755
--- a/ovh/soapi/zoneEntryAdd
+++ b/ext/ovh/soapi/zoneEntryAdd
diff --git a/ovh/soapi/zoneEntryDel b/ext/ovh/soapi/zoneEntryDel
index c8137fc1..c8137fc1 100755
--- a/ovh/soapi/zoneEntryDel
+++ b/ext/ovh/soapi/zoneEntryDel
diff --git a/ovh/soapi/zoneEntryList b/ext/ovh/soapi/zoneEntryList
index 63d0f1c6..63d0f1c6 100755
--- a/ovh/soapi/zoneEntryList
+++ b/ext/ovh/soapi/zoneEntryList
diff --git a/ovh/soapi/zoneExport b/ext/ovh/soapi/zoneExport
index 7747ded4..7747ded4 100755
--- a/ovh/soapi/zoneExport
+++ b/ext/ovh/soapi/zoneExport
diff --git a/ovh/soapi/zoneImport b/ext/ovh/soapi/zoneImport
index 42d46caf..42d46caf 100755
--- a/ovh/soapi/zoneImport
+++ b/ext/ovh/soapi/zoneImport
diff --git a/ext/solus/bin/client b/ext/solus/bin/client
new file mode 100755
index 00000000..60b720d6
--- /dev/null
+++ b/ext/solus/bin/client
@@ -0,0 +1,28 @@
+#! /bin/sh
+# usage: client ACTION
+# ACTION: boot, info, reboot, shutdown, or status
+# environment:
+# api_url URL to the client API like https://<MASTER IP>:5656/api/client
+# api_key
+# api_hash
+set -euf
+
+url="$api_url/command.php"
+key="$api_key"
+hash="$api_hash"
+
+action="${1-$ACTION}"
+
+case "$action" in
+ (info)
+ # get all the information
+ action="$action&ipaddr=true&hdd=true&mem=true&bw=true";;
+esac
+
+abspath="`readlink -f "$0"`"
+bindir="`dirname "$abspath"`"
+libdir="`dirname "$bindir"`/lib"
+export PATH="$libdir:$PATH"
+
+curl -sS -d key="$key" -d hash="$hash" -d action="$action" "$url" |
+ parse-return-data
diff --git a/ext/solus/lib/parse-return-data b/ext/solus/lib/parse-return-data
new file mode 100755
index 00000000..85219727
--- /dev/null
+++ b/ext/solus/lib/parse-return-data
@@ -0,0 +1,20 @@
+#! /bin/sh
+set -euf
+sed '
+ # transform "XML" into lines {key}<tab>{value}-lines
+ s|</[^>]*>|\n|g
+ s|<\([^>]*\)>|\1\t|g
+' |
+sed '
+ # transform ipaddr list into multiple ipaddr_[46]<tab>{ipaddr}-lines
+ /^ipaddr\t/{
+ s|,|\nipaddr\t|g
+ s/\t\([0-9]*[.]\)/_4&/g
+ s/\t\([0-9]*[:]\)/_6&/g
+ }
+ # parse CSVs into multiple lines with proper labels
+ s:^\(hdd\|mem\|bw\)\t\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$:\1_total\t\2\
+\1_used\t\3\
+\1_free\t\4\
+\1_percentused\t\5:
+'
diff --git a/gold/mtgox/mtgox.ticker b/gold/mtgox/mtgox.ticker
index b24dfb35..32ee53bf 100755
--- a/gold/mtgox/mtgox.ticker
+++ b/gold/mtgox/mtgox.ticker
@@ -1,4 +1,53 @@
#! /bin/sh
-# get mtgox ticker data
+# 2012-06-07 ~tv@iiso:bin/mtgox.ticker
set -euf
-curl -ksS https://mtgox.com/code/data/ticker.php
+
+Currency=${Currency-EUR}
+
+# continuous ticker
+## usage: mtgox.ticker -f [time] [json-path...]
+if test $# -ge 1 && test "$1" = -f; then
+ shift
+ time=`echo "$1" | grep '^[1-9][0-9]*[h]\?$'` && shift || time=60
+ echo -n "# sleep time: $time"
+ while echo -n "
+`date --rfc-3339=s` `"$0" "$@"`"; do
+ sleep $time
+ done
+ exit
+fi
+
+# 2012-11-17 tv /krebs/gold/mtgox/mtgox.ticker
+ticker() {
+ curl -ksS https://mtgox.com/code/data/ticker.php?Currency=$Currency
+}
+# 2012-11-17 tv ~mw*@iiso:Espresso-phonegap/package/bin/json-print
+print() {
+ node -e "
+// 2012-11-17 tv
+//filename = process.argv[2]
+filename = process.argv[1]
+jsonpath = []
+value = JSON.parse(require('fs').readFileSync(filename))
+// 2012-11-17 tv
+//process.argv.slice(3).forEach(function (key) {
+process.argv.slice(2).forEach(function (key) {
+ value = value[key]
+ jsonpath.push(key)
+ if (typeof value === 'undefined') {
+ console.error(filename + ':', jsonpath.join('.'), 'is', value)
+ process.exit(23)
+ }
+})
+
+console.log(JSON.stringify(value, null, 2))
+" "$@"
+}
+
+# ticker
+## usage: mtgox.ticker [json-path...] -> json
+# 2012-11-17 tv
+#/krebs/gold/mtgox/mtgox.ticker |
+# ~mw*@iiso:Espresso-phonegap/package/bin/json-print /dev/stdin ticker "$@"
+ticker |
+ print /dev/stdin ticker "$@"
diff --git a/ircbot/bot.py b/ircbot/bot.py
new file mode 100755
index 00000000..607e65c7
--- /dev/null
+++ b/ircbot/bot.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+import irc.bot
+import feedparser
+import _thread
+import math
+from time import sleep
+
+class TestBot(irc.bot.SingleServerIRCBot):
+ def __init__(self, rss, name, server='10.243.231.66', port=6667, chan='#news', timeout=60):
+ irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], name, name)
+ self.url = rss
+ self.feed = feedparser.parse(self.url)
+ self.name = name
+ self.server = server
+ self.port = port
+ self.chan = chan
+ self.to = timeout
+ self.oldnews = []
+ self.sendqueue = []
+ for entry in self.feed.entries:
+ self.sendqueue.append(entry.title + " " + entry.link)
+ self.oldnews.append(entry.link)
+
+ def start(self):
+ self.upd_thread = _thread.start_new_thread(self.updateloop, ())
+ self.bot = _thread.start_new_thread(irc.bot.SingleServerIRCBot.start, (self,))
+
+
+ def updateloop(self):
+ while True:
+ sleep(self.to)
+ self.feed = feedparser.parse(self.url)
+ for entry in self.feed.entries:
+ if not entry.link in self.oldnews:
+ self.send(entry.title + " " + entry.link)
+ self.oldnews.append(entry.link)
+
+ def sendall(self):
+ while len(self.sendqueue) > 0:
+ sleep(1)
+ self.send(self.sendqueue.pop())
+
+ def send(self, string):
+ if len(string) < 450:
+ self.connection.privmsg(self.chan, string)
+ else:
+ for x in range(math.ceil(len(string)/450)):
+ self.connection.privmsg(self.chan, string[x*450:(x+1)*450])
+ sleep(1)
+
+
+ def on_welcome(self, connection, event):
+ connection.join(self.chan)
+
+# def on_privmsg(self, connection, event):
+# print event.source().split('!')[0], event.arguments()
+
+F = open("feeds", "r")
+lines = F.readlines()
+F.close()
+
+botarray = []
+for line in lines:
+ lineArray = line.split('|')
+ bot = TestBot(lineArray[1], lineArray[0])
+ #bot.start()
+ botarray.append(bot)
+
+def startall():
+ for bot in botarray:
+ bot.start()
diff --git a/ircbot/feeds b/ircbot/feeds
new file mode 100644
index 00000000..50fe0667
--- /dev/null
+++ b/ircbot/feeds
@@ -0,0 +1,2 @@
+HN|http://news.ycombinator.com/rss
+Fefe|http://blog.fefe.de/rss.xml
diff --git a/retiolum/Makefile b/retiolum/Makefile
index f3424dea..b3a3c124 100755
--- a/retiolum/Makefile
+++ b/retiolum/Makefile
@@ -29,4 +29,4 @@ startup:
hosts:
bin/update-retiolum-hosts || :;
- sudo bin/apply-custom-hosts-patches
+ sudo bin/patch-retiolum-hosts
diff --git a/retiolum/bin/apply-custom-hosts-patches b/retiolum/bin/apply-custom-hosts-patches
deleted file mode 100755
index 2b2fda80..00000000
--- a/retiolum/bin/apply-custom-hosts-patches
+++ /dev/null
@@ -1,8 +0,0 @@
-#! /bin/sh
-set -euf
-
-patch=/etc/tinc/retiolum/hosts.patch
-
-if test -e $patch; then
- patch -N -d /etc/tinc/retiolum/hosts -r - < $patch
-fi
diff --git a/retiolum/bin/list-known-public-addresses b/retiolum/bin/list-known-public-addresses
new file mode 100755
index 00000000..21b1c389
--- /dev/null
+++ b/retiolum/bin/list-known-public-addresses
@@ -0,0 +1,38 @@
+#! /bin/sh
+#
+# printf '%s %s\n' hostname IP-address for each known public retiolum address
+#
+set -eu
+
+_list_hostname_address() {
+ cd /etc/tinc/retiolum/hosts
+ grep --with-filename '^Address' * |
+ sed -n '
+ s/: */ /
+ s/ *= */ /
+ s/ Address \([a-zA-Z0-9.:_]*\) \?.*/ \1/p'
+}
+_lookup_address() {
+ sed '
+ /:/!{/ [0-9.]*$/!{s/ / `dig +short /;s/$/` \&/}}
+ s/^/echo /
+ $s/$/\nwait/
+ ' | sh
+}
+_filter_public() {
+ sed '
+ # drop private IPv4 addresses
+ / 10\./d
+ / 172\.\(1[6-9]\|2[0-9]\|3[01]\)\./d
+ / 192\.168\./d
+ # TODO drop private IPv6 addresses
+ '
+}
+_filter_online() {
+ awk '
+ {print"nc -zw 2 "$2" 655 2>/dev/null && echo "$1" "$2" &"}
+ END {print"wait"}
+ ' | sh
+}
+
+_list_hostname_address | _lookup_address | _filter_public
diff --git a/retiolum/bin/patch-retiolum-hosts b/retiolum/bin/patch-retiolum-hosts
new file mode 100755
index 00000000..69d7b92c
--- /dev/null
+++ b/retiolum/bin/patch-retiolum-hosts
@@ -0,0 +1,13 @@
+#! /bin/sh
+#
+# Apply custom retiolum hosts patches, if any.
+#
+# usage: patch-retiolum-hosts [--reverse]
+#
+set -euf
+
+patch=/etc/tinc/retiolum/hosts.patch
+
+if test -e $patch; then
+ patch -N -d /etc/tinc/retiolum/hosts -r - "$@" < $patch
+fi
diff --git a/retiolum/bin/update-retiolum-hosts b/retiolum/bin/update-retiolum-hosts
index 2a379459..214ac205 100755
--- a/retiolum/bin/update-retiolum-hosts
+++ b/retiolum/bin/update-retiolum-hosts
@@ -1,5 +1,5 @@
#! /bin/sh
-set -eu
+set -euf
if test "${nosudo-false}" != true -a `id -u` != 0; then
echo "we're going sudo..." >&2
@@ -11,6 +11,4 @@ fi
cd $(dirname $(readlink -f $0))/..
mkdir -p /etc/tinc/retiolum/hosts
-cp -v -r hosts/* /etc/tinc/retiolum/hosts
-pkill -HUP tincd
-pkill -ALRM tincd
+rsync -va --delete hosts/ /etc/tinc/retiolum/hosts/
diff --git a/retiolum/bin/update_tinc_hosts b/retiolum/bin/update_tinc_hosts
index 7be30c2a..ce1be497 100755
--- a/retiolum/bin/update_tinc_hosts
+++ b/retiolum/bin/update_tinc_hosts
@@ -7,8 +7,12 @@ if test "${nosudo-false}" != true -a `id -u` != 0; then
exit 23 # go to hell
fi
-DIRNAME=`dirname $0`
-export PATH="`readlink -f $DIRNAME`:$PATH"
+list_hosts="$(
+ basename="`readlink -f "$0"`"
+ bindir="`dirname "$basename"`"
+ echo "$bindir/hosts"
+)"
+hosts() { "$list_hosts"; }
hosts="${hosts-/etc/hosts}"
diff --git a/retiolum/hosts/Discordius b/retiolum/hosts/Discordius
new file mode 100644
index 00000000..561b28ca
--- /dev/null
+++ b/retiolum/hosts/Discordius
@@ -0,0 +1,11 @@
+Subnet = 10.243.144.246
+Subnet = 42:017a:4584:17e1:685a:3991:6533:067b
+
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEAsOoWkyydyfW9ml7SBV8d+qXU8E1c4l0vEpdBnmOouZozo1bzzkH3
+bLn2DkZaOLCqVUC1twbeGi2a7tXHh4dLvkIcT38V3XbEwxHhMn7enpKr79GO/VFf
+Lu8t5dLbmPFFTOEeC54ke8X4MdlMrUMuXiGspnl/vc1NBSJIVECl6zdqvZt/UTWA
+vI7evk3F+Tf5dPATqSMdxE5506i2y/W6obwYwaXdPbyBsAQkgdTjfVUe2u0GKfld
+/THprmZYTwlBEZ3YAf12OdfO1aRsDpbogpZs/rcnebScDj7myzh7FkLHdH9nIfxg
+dfGxSBV7kRMwQmgfKjp/yETPjvRz0OMZoQIDAQAB
+-----END RSA PUBLIC KEY-----
diff --git a/retiolum/hosts/alphalabs b/retiolum/hosts/alphalabs
index e7265e67..a2e1032c 100644
--- a/retiolum/hosts/alphalabs
+++ b/retiolum/hosts/alphalabs
@@ -1,6 +1,5 @@
-Address = 10.9.0.10
Subnet = 42:0:0:0:0:0:0:a1fa/128
-Subnet = 10.243.0.10/32
+Subnet = 10.243.1.10/32
Compression = 9
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAvUAbMmmOFn+4kOvJAvmi0R/XCQa1YBlkjUvC6Pmt0Q8gV1DodXjB
diff --git a/retiolum/hosts/ire b/retiolum/hosts/ire
new file mode 100644
index 00000000..724158cb
--- /dev/null
+++ b/retiolum/hosts/ire
@@ -0,0 +1,12 @@
+Address = 198.147.23.143
+Subnet = 10.243.231.66
+Subnet = 42:b912:0f42:a82d:0d27:8610:e89b:490c
+
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEAwofjmP/XBf5pwsJlWklkSzI+Bo0I0B9ONc7/j+zpbmMRkwbWk4X7
+rVLt1cWvTY15ujg2u8l0o6OgEbIkc6rslkD603fv1sEAd0KOv7iKLgRpE9qfSvAt
+6YpiSv+mxEMTpH0g36OmBfOJ10uT+iHDB/FfxmgGJx//jdJADzLjjWC6ID+iGkGU
+1Sf+yHXF7HRmQ29Yak8LYVCJpGC5bQfWIMSL5lujLq4NchY2d+NZDkuvh42Ayr0K
+LPflnPBQ3XnKHKtSsnFR2vaP6q+d3Opsq/kzBnAkjL26jEuFK1v7P/HhNhJoPzwu
+nKKWj/W/k448ce374k5ycjvKm0c6baAC/wIDAQAB
+-----END RSA PUBLIC KEY-----
diff --git a/retiolum/hosts/nomic2 b/retiolum/hosts/nomic2
new file mode 100644
index 00000000..63d83ff5
--- /dev/null
+++ b/retiolum/hosts/nomic2
@@ -0,0 +1,10 @@
+Subnet = 10.243.0.111/32
+Subnet = 42:02d5:733f:d6da:c0f5:2bb7:2b18:09ed/128
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEA4RATrMG+MJyNq77+qUqoXkBIpUeytIvUNXT5OdvU5v91Xo2eGI23
+NXiFtILDb1nEPB+L4vVWkUKRuPAy+ThgqgTH1vyugT6jRoRhWWmGmSn2GjaF+UxK
+edTfGJqO0Iwn0kZsIFxXUibkmG5iRbJBoPXXz33VtNxOv2gZZ6klfv/pYWnrxmLm
+RZXkE1H3Y0U2ulQEXvpexzVscfYmlAw7h0Ew4aaY2LK4spLLPjx9RdDgfwZOZdS+
+gi5cmi/qM71/o67/4XippR9+7GQ8YecbeoR4bcZpDNoDy1ri7HPPu/t6CiqsYVyg
+jYGBm+IGbwI9hxGel2bXCVBGLE7gpN51TwIDAQAB
+-----END RSA PUBLIC KEY-----
diff --git a/services/Makefile b/services/Makefile
index 3ef670a3..37931f47 100644
--- a/services/Makefile
+++ b/services/Makefile
@@ -1,5 +1,6 @@
help:;@cat Makefile
export authorized_keys_file := authorized_keys
+export debug_log := true
export services_file := services.txt
export host_key_file := test.key
export services_home := /opt/services
@@ -32,7 +33,7 @@ test-client:
ssh localhost -p 1337 2>/dev/null
test-server:
- python test.py
+ ./test-server.py
$(host_key_file):
ssh-keygen -t rsa -P '' -f $@
diff --git a/services/README.md b/services/README.md
new file mode 100644
index 00000000..e0769bce
--- /dev/null
+++ b/services/README.md
@@ -0,0 +1,25 @@
+# //services
+
+## install and run test-server.py as systemd service
+
+### install dependencies
+
+ pacman -S python2-pyasn1 twisted
+
+### install systemd service and configuration
+
+ cp /krebs/services/etc/systemd/system/krebs-services-test-server.service \
+ /etc/systemd/system/
+ cp /krebs/services/etc/conf.d/krebs-services-test-server \
+ /etc/conf.d/
+
+### create services user and populate it's home
+
+ useradd -m -r -l -f -1 -d /opt/services -k /var/empty services
+ sudo -u services ssh-keygen -t rsa -P '' -f /opt/services/test.key
+ $EDITOR /opt/services/services.txt
+
+### run now and every reboot
+
+ systemctl start krebs-services-test-server
+ systemctl enable krebs-services-test-server
diff --git a/services/bin/services b/services/bin/services
index c142a363..e854cbcb 100755
--- a/services/bin/services
+++ b/services/bin/services
@@ -8,6 +8,8 @@ user=services
hostname=${1-localhost}
port=1337
+options="${options+$options }-o ControlMaster=no"
+
if test -n "${services_identity_file-}"; then
options="${options+$options }-i $services_identity_file"
fi
@@ -21,4 +23,11 @@ if echo $hostname | grep -q :; then
hostname=`echo $hostname | cut -d: -f1`
fi
-ssh $options $user@$hostname -p $port
+exec 3>&1
+{
+ ssh $options $user@$hostname -p $port
+} 2>&1 1>&3 | sed '
+ /^Connection to '$hostname' closed/d
+ /^Shared connection to '$hostname' closed/d
+'
+exec 3>&-
diff --git a/services/etc/conf.d/krebs-services-test-server b/services/etc/conf.d/krebs-services-test-server
new file mode 100644
index 00000000..243054f4
--- /dev/null
+++ b/services/etc/conf.d/krebs-services-test-server
@@ -0,0 +1,3 @@
+authorized_keys_file=/krebs/services/authorized_keys
+services_file=/opt/services/services.txt
+host_key_file=/opt/services/test.key
diff --git a/services/etc/services/bootstrap b/services/etc/services/bootstrap
new file mode 100644
index 00000000..8c848146
--- /dev/null
+++ b/services/etc/services/bootstrap
@@ -0,0 +1,9 @@
+services://destroy
+services://ire
+services://darth_serious:22
+services://pigstarter:22
+services://incept:22
+services://rage:22
+services://devstar:22
+services://heidi:22
+services://geisha:22
diff --git a/services/etc/systemd/system/krebs-services-test-server.service b/services/etc/systemd/system/krebs-services-test-server.service
new file mode 100644
index 00000000..99578cce
--- /dev/null
+++ b/services/etc/systemd/system/krebs-services-test-server.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=services: provider
+After=network.target
+
+[Service]
+EnvironmentFile=/etc/conf.d/krebs-services-test-server
+ExecStart=/krebs/services/test-server.py
+KillMode=process
+User=services
+Group=services
+Restart=no
+
+[Install]
+WantedBy=multi-user.target
diff --git a/services/services.txt b/services/services.txt
index dc88cbac..265e6d1c 100644
--- a/services/services.txt
+++ b/services/services.txt
@@ -3,5 +3,5 @@ type:
mail:
expires:
location:
-services://{{hostname}}:22/
-tinc://{{hostname}}/
+services://{{hostname}}:22
+tinc://{{hostname}}
diff --git a/services/test.py b/services/test-server.py
index 06340a54..7838e0af 100644..100755
--- a/services/test.py
+++ b/services/test-server.py
@@ -1,8 +1,9 @@
-#! /usr/bin/env python
+#! /usr/bin/env python2
from os import environ as env
authorized_keys_file = env.get('authorized_keys_file', '/dev/null')
+debug_log = env.get('debug_log', 'false')
services_file = env.get('services_file', '/dev/null')
host_key_file = env.get('host_key_file', '/dev/null')
host_key_pub_file = host_key_file + '.pub'
@@ -22,9 +23,10 @@ from twisted.internet.reactor import listenTCP, run
from twisted.python.components import registerAdapter
from zope.interface import implements
-from twisted.python.log import startLogging
-from sys import stderr
-startLogging(stderr)
+if debug_log == 'true':
+ from twisted.python.log import startLogging
+ from sys import stderr
+ startLogging(stderr)
class MyRealm:
diff --git a/util/README.markdown b/util/README.markdown
new file mode 100644
index 00000000..78b9b81a
--- /dev/null
+++ b/util/README.markdown
@@ -0,0 +1,27 @@
+# various utils
+
+## //util/bin/with
+
+ execute a command with an extended/modified environment
+
+### usage
+
+ with ENV COMMAND
+
+ where `ENV` is the name of the environment and
+ `COMMAND` your to-be-executed command (-line).
+
+### environment
+
+ `env_dir` defines the directory where environment files are searched
+ (default: `$HOME/.env.d`).
+
+### example
+
+ cat > ~/.env.d/frh-ire <<EOF
+ export api_url=...
+ export api_key=...
+ export api_hash=...
+ EOF
+
+ with frh-ire //ext/solus/bin/client info
diff --git a/util/bin/with b/util/bin/with
new file mode 100755
index 00000000..97893faf
--- /dev/null
+++ b/util/bin/with
@@ -0,0 +1,6 @@
+#! /bin/sh
+set -euf
+ENV="${env_dir-$HOME/.env.d}/$1"
+shift
+. "$ENV"
+exec "$@"
diff --git a/util/lib/geo/Makefile b/util/lib/geo/Makefile
new file mode 100644
index 00000000..d13cd471
--- /dev/null
+++ b/util/lib/geo/Makefile
@@ -0,0 +1,15 @@
+all: node_modules GeoLiteCity.dat
+
+node_modules: package.json
+ npm install
+ @touch -r $< $@
+
+GeoLiteCity.dat:
+ @test -e GeoLiteCity.dat && ln -s GeoLiteCity.dat $@ || { \
+ echo 'No GeoIP City database found.'; \
+ echo 'You can get one from http://dev.maxmind.com/geoip/geolite:'; \
+ echo ' wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz'; \
+ echo ' gunzip GeoLiteCity.dat.gz'; \
+ exit 23; \
+ }
+
diff --git a/util/lib/geo/index.js b/util/lib/geo/index.js
new file mode 100644
index 00000000..0763b1a4
--- /dev/null
+++ b/util/lib/geo/index.js
@@ -0,0 +1,48 @@
+function slurp (stream, callback) {
+ var data = []
+ stream.on('data', function (chunk) {
+ data.push(chunk)
+ })
+ stream.on('end', function () {
+ callback(null, Buffer.concat(data))
+ })
+ stream.resume()
+}
+
+
+var path = require('path')
+var city_dat = path.join(__dirname, 'GeoLiteCity.dat')
+
+var geoip = require('geoip')
+var city = new geoip.City(city_dat)
+
+slurp(process.stdin, function (err, data) {
+ var lines = data.toString().split('\n')
+ // remove last, empty element (caused by the [mandatory] final \n)
+ if (lines.length > 1 && lines[lines.length - 1] === '') {
+ lines.pop()
+ }
+ var name = 0, addr = 1
+ lines
+ .map(function (line) { return line.split(' ') })
+ .forEach(function (host) {
+ //city.lookup(host[addr], function (err, loc) {
+ // if (err) {
+ // console.error('#', host[name], err.message)
+ // } else {
+ // console.log(host[name] + ': ' + loc.longitude + ',' + loc.latitude)
+ // }
+ //})
+ var loc = city.lookupSync(host[addr])
+ //if (!loc) { console.error('#', host[name]) }
+ if (loc) {
+ var a = loc.latitude
+ var b = loc.longitude
+ //var c = loc.altitude
+ //var geo = 'geo:' + [a,b,c].join(',')
+ var geo = 'geo:' + [a,b].join(',')
+
+ console.log(host[name], geo)
+ }
+ })
+})
diff --git a/util/lib/geo/package.json b/util/lib/geo/package.json
new file mode 100644
index 00000000..ad449a62
--- /dev/null
+++ b/util/lib/geo/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "geo",
+ "version": "0.0.0",
+ "dependencies": {
+ "geoip": "*"
+ }
+}