#!/bin/bash set -e project_name="torvirt" img_name=$project_name container_name=$project_name docker_folder="gateway" network_file="network.xml" network=$project_name tor_trans_port="9040" tor_dns_port="5353" tor_virt_addr="10.192.0.0/10" gtw_ip="10.152.152.10/18" veth_host="$project_name-host" veth_gw="$project_name-gw" ERROR_INVALID_ACTION=1 ERROR_ALREADY_CONFIGURED=2 ERROR_NOT_CONFIGURED=3 ERROR_ALREADY_RUNNING=4 print_help() { echo -e "Usage: $0 ACTIONS: c, configure Install dependencies, configure network and build gateway docker image s, start Start the gateway " } exit_with() { echo $2 >&2 exit $1 } virsh_get_field() { virsh net-info $network |awk "/^$1:/{print \$2}" } if [ "$#" -eq 0 ]; then print_help exit fi case $1 in "s" | "start") # check whether network and gateway have been configured if [ -z "$(virsh net-list --all | grep $network)" ]; then exit_with $ERROR_NOT_CONFIGURED "Error: network $network not found. Did you run \"$project_name configure\" ?" fi output=$(docker images ls -q -f reference=$img_name) if [ -z "$output" ]; then exit_with $ERROR_NOT_CONFIGURED "Error: docker image $img_name not found. Did you run \"$project_name configure\" first ?" fi output=$(docker ps -q -f name=$container_name) if [ "$output" ]; then exit_with $ERROR_ALREADY_RUNNING "Error: conatiner $container_name is already running" fi output=$(docker ps -aq -f status=exited -f name=$container_name) if [ "$output" ]; then docker rm $container_name fi # start $network network_started=$(virsh_get_field "Active") if [ $network_started = "no" ]; then virsh net-start $network fi brif=$(virsh_get_field "Bridge") # configure veth interfaces if ip link show $veth_host >/dev/null 2>/dev/null; then ip link del $veth_host fi ip link add $veth_gw type veth peer name $veth_host brctl addif $brif $veth_host ip link set $veth_host up # start gateway on wait.sh docker run --rm -itd --cap-drop=ALL --name $container_name $img_name >/dev/null pid=$(docker inspect -f '{{.State.Pid}}' $container_name) # setup gateway networing inside $network ip link set netns $pid dev $veth_gw nsenter -t $pid -n ip link set $veth_gw up nsenter -t $pid -n ip addr add $gtw_ip dev $veth_gw # allow *.onion nsenter -t $pid -n iptables -t nat -A PREROUTING -i $veth_gw -p tcp -d $tor_virt_addr --syn -j REDIRECT --to-ports $tor_trans_port # redirect DNS to tor nsenter -t $pid -n iptables -t nat -A PREROUTING -i $veth_gw -p udp --dport 53 -j REDIRECT --to-ports $tor_dns_port nsenter -t $pid -n iptables -t nat -A PREROUTING -i $veth_gw -p udp --dport $tor_dns_port -j REDIRECT --to-ports $tor_dns_port # redirect TCP to tor nsenter -t $pid -n iptables -t nat -A PREROUTING -i $veth_gw -p tcp --syn -j REDIRECT --to-ports $tor_trans_port # start tor docker kill -s USR1 $container_name >/dev/null docker attach $container_name ;; "c" | "configure") if virsh net-info $network >/dev/null 2>/dev/null; then exit_with $ERROR_ALREADY_CONFIGURED "Error: network $network already exists." fi output=$(docker images ls -q -f reference=$img_name) if [ "$output" ]; then exit_with $ERROR_ALREADY_CONFIGURED "Error: image $img_name already exists" fi virsh net-define $network_file cd $docker_folder && docker build -t $img_name . ;; *) print_help exit_with $ERROR_INVALID_ACTION "Unkown action: $1" ;; esac