diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/hourly.py | 20 | ||||
-rwxr-xr-x | src/hourly.sh | 3 | ||||
-rwxr-xr-x | src/netns-script | 38 | ||||
-rwxr-xr-x | src/perform_queries.py | 39 | ||||
-rwxr-xr-x | src/vpn_wrapper.sh | 68 |
5 files changed, 168 insertions, 0 deletions
diff --git a/src/hourly.py b/src/hourly.py new file mode 100755 index 0000000..543ed20 --- /dev/null +++ b/src/hourly.py @@ -0,0 +1,20 @@ +#!/bin/python3 + +from sys import argv +import subprocess + +wrapper = '/var/lib/0tdns/vpn_wrapper.sh' +perform_queries = '/var/lib/0tdns/perform_queries.py' + +def get_vpn_connections(hour): + # TODO query database for the necessary information, + # for now, return some sample though-up data + return ( + # vpn_id | config_path + (14, "./vpngate_178.254.251.12_udp_1195.ovpn"), + (13, "./vpngate_public-vpn-229.opengw.net_tcp_443.ovpn") + ) + +hour = argv[1] +for vpn_id, config_path in get_vpn_connections(hour): + subprocess.run([wrapper, config_path, perform_queries, hour]) diff --git a/src/hourly.sh b/src/hourly.sh new file mode 100755 index 0000000..be1c52a --- /dev/null +++ b/src/hourly.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +hourly.py "`date '+%Y-%m-%d %H:00'`" diff --git a/src/netns-script b/src/netns-script new file mode 100755 index 0000000..ba2d226 --- /dev/null +++ b/src/netns-script @@ -0,0 +1,38 @@ +#!/bin/sh + +# adapted from +# https://unix.stackexchange.com/questions/149293/feed-all-traffic-through-openvpn-for-a-specific-network-namespace-only + +# vpn_wrapper.sh creates another script of name helper_script<timestamp>.sh, +# which gets called by openvpn process, exports NAMESPACE_NAME and WRAPPER_PID +# variables and then runs this script + +case $script_type in + up) + env + ip netns add $NAMESPACE_NAME + ip netns exec $NAMESPACE_NAME ip link set dev lo up + ip link set dev "$1" up netns $NAMESPACE_NAME mtu "$2" + ip netns exec $NAMESPACE_NAME ip addr add dev "$1" \ + "$4/${ifconfig_netmask:-30}" \ + ${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"} + if [ -n "$ifconfig_ipv6_local" ]; then + ip netns exec $NAMESPACE_NAME ip addr add dev "$1" \ + "$ifconfig_ipv6_local"/112 + fi + ;; + route-up) + ip netns exec $NAMESPACE_NAME ip route add default via "$ifconfig_remote" + + if [ -n "$ifconfig_ipv6_remote" ]; then + ip netns exec $NAMESPACE_NAME ip route add default via \ + "$ifconfig_ipv6_remote" + fi + + # notify our sh process, that openvpn finished initializing + kill -usr1 $WRAPPER_PID + ;; + down) + ip netns delete $NAMESPACE_NAME + ;; +esac diff --git a/src/perform_queries.py b/src/perform_queries.py new file mode 100755 index 0000000..4762e14 --- /dev/null +++ b/src/perform_queries.py @@ -0,0 +1,39 @@ +#!/bin/python3 + +import unbound + +def query_planned_queries(hour, vpn_id): + # TODO query database + # for now, return some sample thought-up data + return ( + # dns server IP | dns server id | service_id | service_name + ("195.98.79.117", 23, ((89, "devuan.org"), + (44, "gry.pl"), + (112, "invidio.us"))), + ("192.71.245.208", 33, ((77, "debian.org"), + (22, "nie.ma.takiej.domeny"), + (100, "onet.pl"))) + ) + +def resolve_call_back(mydata, status, result): + dns_id, service_id = mydata + # TODO write to database + print("callback called for {}".format(result.qname)) + if status==0 and result.havedata: + print("Result:",result.data.address_list) + +# hour from argv | vpn_id in database +contexts = [] +for dns_addr, dns_id, services in query_planned_queries("1999-01-08 04:00", 11): + ctx = unbound.ub_ctx() + ctx.set_fwd(dns_addr) + for service_id, service_name in services: + print(service_name) + print("starting resolution: {} through {}".format(service_name, dns_addr)) + ctx.resolve_async(service_name, (dns_id, service_id), + resolve_call_back, + unbound.RR_TYPE_A, unbound.RR_CLASS_IN) + contexts.append(ctx) + +for ctx in contexts: + ctx.wait() diff --git a/src/vpn_wrapper.sh b/src/vpn_wrapper.sh new file mode 100755 index 0000000..b4b9350 --- /dev/null +++ b/src/vpn_wrapper.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +OPENVPN_CONFIG="$1" +# rest of args is the command to run in network namespace +shift + +# just in case something causes more instances of this script +# to run simultaneously, we timestamp some names +SECONDS=`date '+%s'` + +HELPER_SCRIPT=/var/lib/0tdns/helper_script$SECONDS.sh +NAMESPACE_NAME=0tdns$SECONDS + +# we create another script as a way of passing variables +# to netns-script +cat > $HELPER_SCRIPT <<EOF +#!/bin/sh + +export NAMESPACE_NAME=$NAMESPACE_NAME +export WRAPPER_PID=$$ + +/var/lib/0tdns/netns-script "\$@" +EOF + +chmod u+x $HELPER_SCRIPT + +# in case we want some process in the namespace to be able +# to resolve domain names via libc we put some random public +# dns in namespace sepcific's resolv.conf; +# note, that while libunbound we're using will probably have +# dns addresses provided by us, it is still possible to pass +# a domain name as forwarder address to unbound, in which case +# it will try to resolve it first using libc +mkdir -p /etc/netns/$NAMESPACE_NAME/ +echo nameserver 23.253.163.53 > /etc/netns/$NAMESPACE_NAME/resolv.conf + +# starts openvpn with our just-created helper script, which calls +# the netns-script, which creates tun inside network namespace +# of name $NAMESPACE_NAME +# we could consider using --daemon option instead of & +openvpn --ifconfig-noexec --route-noexec --up $HELPER_SCRIPT \ + --route-up $HELPER_SCRIPT --down $HELPER_SCRIPT \ + --config "$OPENVPN_CONFIG" --script-security 2 & + +OPENVPN_PID=$! + +# waiting for signal from our netns script +# https://stackoverflow.com/questions/9052847/implementing-infinite-wait-in-shell-scripting +trap true usr1 + +# wait on openvpn process; +# if we get a signal - wait will terminate; +# if openvpn process dies - wait will also terminate +wait $OPENVPN_PID + +# TODO check which of 2 above mention situations occured and +# return from script with error code if openvpn process died + +# run the provided command inside newly created namespace +# under '0tdns' user; +sudo ip netns exec $NAMESPACE_NAME sudo -u 0tdns "$@" + +# close the connection +kill $OPENVPN_PID +wait $OPENVPN_PID + +# we no longer need those +rm -r $HELPER_SCRIPT /etc/netns/$NAMESPACE_NAME/ |