TorVirt/torvirt
2023-05-25 22:12:53 +02:00

110 lines
3.3 KiB
Bash
Executable File

#!/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 <action>
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