#!/bin/bash
# Project Floodgate v0.0.2
# http://dc949.org/projects/floodgate/
# Jeffball@dc949.org && cp@dc949.org
#
#Arguments:
# $1 = the number of tor instances you want
# $2 = (random/nth) Specifies whether we want random tor nodes for each connection (default) or to rotate them
# $3 = a semicolon separated list of comma separated lists for exit nodes that you want each tor instance to use
#      Example: "{us},{gb};{fr};{ru}" Would tell the first tor to use exit nodes in USA/Great Britian, the second
#                                         instance to use exit nodes in france, and the third instance in russia
# $4 = A semicolon separated list of comma separated lists for entry nodes that you want each tor instance to use (same format as entry nodes)
#           The current tor does not allow you to use ip addresses or country codes though, only finger prints for entry nodes
#
# To specify entry nodes without exit nodes, use "" for $2

if [ "$1" == "-h" ]; then
    echo '
sudo bash multiTor.sh numberOfInstances [distributionMethod] [exitNodes] [entryNodes]

 numberOfInstances = the number of tor instances you want
 distributionMethod = (random/nth) Specifies whether we want random tor nodes for each connection (default) or to rotate them
 exitNodes = A semicolon separated list of comma separated lists for exit nodes that you want each tor instance to use
      Example: "{us},{gb};{fr};{ru}" Would tell the first tor to use exit nodes in USA/Great Britian, the second
                                         instance to use exit nodes in france, and the third instance in russia
 entryNodes = A semicolon separated list of comma separated lists for entry nodes that you want each tor instance to use (same format as entry nodes)
           The current tor does not allow you to use ip addresses or country codes though, only finger prints for entry nodes
 To specify entry nodes without exit nodes, use "" for exitNodes
 
 See the tor documentation on ExitNodes and EntryNodes for help specifying exit/entry nodes
'
    exit
fi

#############################################################################################################################################
##CONFIG SECTION#############################################################################################################################
#############################################################################################################################################

CONFIG_DIRECTORY=/home/jeff/Desktop/tor #the config directory for the tor configs

INITIAL_PORT='9050' #The first port for tor to run on

# destinations you don't want routed through Tor
NON_TOR="206.225.102.0/24"

#The ip address that tor should run on
MYIP="206.225.102.67"

# your internal interface
INT_IF="wlan0"

#############################################################################################################################################
##WRITE TOR CONFIG###########################################################################################################################
#############################################################################################################################################

START_TOR_INSTANCE='0' #The beginning instance of tor
END_TOR_INSTANCES=$1 #The last instnace of tor

for ((i=$START_TOR_INSTANCE ; i < $END_TOR_INSTANCES; i++ ))
do
    PORT=$(($INITIAL_PORT + $i - $START_TOR_INSTANCE));
    EXIT_NODE=$(echo $3 | cut -d\; -f$(($i+1)));
    EXITS=""
    if [ "$EXIT_NODE" != "" ]; then
        EXITS="ExitNodes $EXIT_NODE
                StrictExitNodes 1"
    fi

    ENTRIES=""    
    ENTRY_NODE=$(echo $4 | cut -d\; -f$(($i+1)));
    if [ "$ENTRY_NODE" != "" ]; then
        ENTRIES="EntryNodes $ENTRY_NODE
                StrictEntryNodes 1"
    fi

    DNS=""; 
    if [ $i -eq $START_TOR_INSTANCE ]; then 
        DNS="DNSPort 53
             DNSListenAddress $MYIP"
    fi
    
    mkdir $CONFIG_DIRECTORY/tor$i
    chown debian-tor $CONFIG_DIRECTORY/tor$i
    echo "#Tor Config for anonymizing middlebox
VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort $PORT
TransListenAddress $MYIP
$DNS

#Other options
DataDirectory ${CONFIG_DIRECTORY}/tor${i} #the data directory for this instance of tor
#RunAsDaemon 0 #Uncomment to run in non-daemon mode
SocksPort $PORT # what port to open for local application connections
#Log debug file ${CONFIG_DIRECTORY}/debug$i.log #uncomment to enable debugging

#Exit/Entry Nodes (if any):
$EXITS
$ENTRIES

######################################################################
#########The Default Config File Follows:#############################
######################################################################

## Configuration file for a typical Tor user
## Last updated 12 April 2009 for Tor 0.2.1.14-rc.
## (May or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with '## ' try to explain whats going on. Lines
## that begin with just '#' are disabled commands: you can enable them
## by removing the '#' symbol.
##
## See 'man tor', or https://www.torproject.org/tor-manual.html,
## for more options you can use in this file.
##
## Tor will look for this file in various places based on your platform:
## https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#torrc


## Replace this with 'SocksPort 0' if you plan to run Tor only as a
## relay, and not make any local application connections yourself.
#SocksPort 9050 # what port to open for local application connections
SocksListenAddress 127.0.0.1 # accept connections only from localhost
#SocksListenAddress 192.168.0.1:9100 # listen on this IP:port also

## Entry policies to allow/deny SOCKS requests based on IP address.
## First entry that matches wins. If no SocksPolicy is set, we accept
## all (and only) requests from SocksListenAddress.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy reject *

## Logs go to stdout at level 'notice' unless redirected by something
## else, like one of the below lines. You can have as many Log lines as
## you want.
##
## We advise using 'notice' in most cases, since anything more verbose
## may provide sensitive information to an attacker who obtains the logs.
##
## Send all messages of level 'notice' or higher to @LOCALSTATEDIR@/log/tor/notices.log
#Log notice file @LOCALSTATEDIR@/log/tor/notices.log
## Send every possible message to @LOCALSTATEDIR@/log/tor/debug.log
#Log debug file @LOCALSTATEDIR@/log/tor/debug.log
## Use the system log instead of Tors logfiles
#Log notice syslog
## To send all messages to stderr:
#Log debug stderr

## Uncomment this to start the process in the background... or use
## --runasdaemon 1 on the command line. This is ignored on Windows;
## see the FAQ entry if you want Tor to run as an NT service.
#RunAsDaemon 1

## The directory for keeping all the keys/etc. By default, we store
## things in HOME/.tor on Unix, and in Application Data\tor on Windows.
#DataDirectory @LOCALSTATEDIR@/lib/tor

## The port on which Tor will listen for local connections from Tor
## controller applications, as documented in control-spec.txt.
#ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
#CookieAuthentication 1

############### This section is just for location-hidden services ###

## Once you have configured a hidden service, you can look at the
## contents of the file '.../hidden_service/hostname' for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.

#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
#HiddenServicePort 80 127.0.0.1:80

#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22

################ This section is just for relays #####################
#
## See https://www.torproject.org/docs/tor-doc-relay for details.

## Required: what port to advertise for incoming Tor connections.
#ORPort 9001
## If you want to listen on a port other than the one advertised
## in ORPort (e.g. to advertise 443 but bind to 9090), uncomment the
## line below too. You will need to do ipchains or other port forwarding
## yourself to make this work.
#ORListenAddress 0.0.0.0:9090

## A handle for your relay, so people do not have to refer to it by key.
#Nickname ididnteditheconfig

## The IP address or full DNS name for your relay. Leave commented out
## and Tor will guess.
#Address noname.example.com

## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
## be at least 20 KBytes.
#RelayBandwidthRate 100 KBytes  # Throttle traffic to 100KB/s (800Kbps)
#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB/s (1600Kbps)

## Contact info to be published in the directory, so we can contact you
## if your relay is misconfigured or something else goes wrong. Google
## indexes this, so spammers might also collect it.
#ContactInfo Random Person <nobody AT example dot com>
## You might also include your PGP or GPG fingerprint if you have one:
#ContactInfo 1234D/FFFFFFFF Random Person <nobody AT example dot com>

## Uncomment this to mirror directory information for others. Please do
## if you have enough bandwidth.
#DirPort 9030 # what port to advertise for directory connections
## If you want to listen on a port other than the one advertised
## in DirPort (e.g. to advertise 80 but bind to 9091), uncomment the line
## below too. You'll need to do ipchains or other port forwarding yourself
## to make this work.
#DirListenAddress 0.0.0.0:9091
## Uncomment to return an arbitrary blob of html on your DirPort. Now you
## can explain what Tor is if anybody wonders why your IP address is
## contacting them. See contrib/tor-exit-notice.html for a sample.
#DirPortFrontPage /etc/tor/exit-notice.html

## A comma-separated list of exit policies. They're considered first
## to last, and the first match wins. If you want to _replace_
## the default exit policy, end this with either a reject *:* or an
## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
## default exit policy. Leave commented to just use the default, which is
## described in the man page or at
## https://www.torproject.org/documentation.html
##
## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
## for issues you might encounter if you use the default exit policy.
##
## If certain IPs and ports are blocked externally, e.g. by your firewall,
## you should update your exit policy to reflect this -- otherwise Tor
## users will be told that those destinations are down.
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
#
## Bridge relays (or 'bridges') are Tor relays that aren't listed in the
## main directory. Since there is no complete public list of them, even if an
## ISP is filtering connections to all the known Tor relays, they probably
## won't be able to block all the bridges. Also, websites won't treat you
## differently because they won't know you're running Tor. If you can
## be a real relay, please do; but if not, be a bridge!
#BridgeRelay 1
#ExitPolicy reject *:*
" > $CONFIG_DIRECTORY/torrc$i
    
done

#############################################################################################################################################
###Update Iptable############################################################################################################################
#############################################################################################################################################

TRANS_PORT=$INITIAL_PORT
END_PORT=$(($TRANS_PORT+$1-1))
if [ $1 != 1 ]; then 
    TRANS_PORT="$TRANS_PORT-$END_PORT"
fi

#Flush tables
iptables -F
iptables -t nat -F

#Exclude local destinations
for NET in $NON_TOR; do
    iptables -t nat -A PREROUTING -i $INT_IF -d $NET -j RETURN
done

#Setup dns routing
iptables -t nat -A PREROUTING -i $INT_IF -p udp --dport 53 -j REDIRECT --to-ports 53 

#Setup the tcp redirect rules
if [ "$2" == "nth" ]; then #if they want to rotate the instances
    for ((j=0 ; j < $1; j++ ))
    do
        if [ $j -lt $(($1-1)) ]; then
            iptables -A PREROUTING -t nat -i $INT_IF -p tcp --syn -j REDIRECT --to-ports $(($INITIAL_PORT+$j)) -m statistic --mode nth --every $(($1-$j))
        else #last time through, don't need nth module, catch all remaining packets     
            iptables -A PREROUTING -t nat -i $INT_IF -p tcp --syn -j REDIRECT --to-ports $(($INITIAL_PORT+$j))
        fi
    done
else
    iptables -t nat -A PREROUTING -i $INT_IF -p tcp --syn -j REDIRECT --to-ports $TRANS_PORT --random 
fi

#############################################################################################################################################
###Start Tor#################################################################################################################################
#############################################################################################################################################

killall tor #kill all current instances of tor, so we don't run into problems binding certain addresses
sleep 1s #give tor time to be killed

for ((i=$START_TOR_INSTANCE ; i < $END_TOR_INSTANCES; i++ ))
do
    tor -f $CONFIG_DIRECTORY/torrc$i
    echo "Started Tor $i"
done



