What's new

TOR for all traffic from a MAC?

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

JoeTheDownloader

Occasional Visitor
Hi,

I would like a single MAC address in my network to always push *everything* via TOR. I have enabled the TOR feature in Merlin 380.63_2 and set the target MAC address, leaving all other settings at their defaults, but in testing I notice the following behaviour:

* If I SSH to the test box and run "wget http://ipinfo.io/ip -qO -" I *do* see a TOR exit node IP, so everything looks good.
* However other traffic from the box seems to go out as normal - not via TOR. Additionally, performance is unaffected and way too fast for TOR (as in I am not getting the slow performance that I would expect if I was being TORed properly).
* Traceroute shows normal exit through my ISP.

So it seems like TOR is only half working for the MAC address?

Here are the relevant bits from "iptables -t nat -L -nv --line"

Chain PREROUTING (policy ACCEPT 7598 packets, 527K bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:1194
2 2563 186K VSERVER all -- * * 0.0.0.0/0 <MYPUBIPSNIPPEDOUT>
3 0 0 VSERVER all -- * * 0.0.0.0/0 <SOMEAPIPAIPSNIPPEDOUT>
4 93 6486 REDIRECT udp -- br0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 MAC <TARGETMACSNIPPEDOUT> redir ports 9053
5 75 4500 REDIRECT tcp -- br0 * 0.0.0.0/0 !10.99.101.0/24 tcpflags: 0x17/0x02 MAC <TARGETMACSNIPPEDOUT> multiport dports 80,443 redir ports 9040

Thanks for any comments.
 
Last edited:
To use TOR safely, the firewall must be configured to not reveal your true IP address. So, in its current state it doesn't work at all, in my opinion. I think Asus is giving its customers a false sense of security by advertising the TOR feature and thus allowing people to believe that they're protected. It should probably be fixed, OR removed from the WebUI. Otherwise, if you use it as is, the FBI will come. :eek:
 
Last edited:
EDIT: corrected syntax error in firewall-start
EDIT: added script variable for TOR users to configure the firewall
EDIT: added my TOR config and dnsmasq.conf.add

Here's my scripts to use TOR safely. I have TOR disabled in the WebUI. If you need clock synchronization for your protected TOR devices, then you need an NTP server somewhere on your local network since the UDP protocol doesn't route through the TOR network. DNS lookups are the only exception.

/jffs/scripts/firewall-start
Code:
#!/bin/sh
# TODO: replace with your list of TOR users here
TOR_CLIENTS="222 223"

IPADDR=$(/usr/sbin/nvram get lan_ipaddr)
NETWORK=${IPADDR%.*}
## for these TOR users, block direct Internet access for everything else that can't be routed through the TOR network (i.e. UDP and ICMP ping)
for TOR_CLIENT in $TOR_CLIENTS ; do
  /usr/sbin/iptables -I FORWARD -s ${NETWORK}.${TOR_CLIENT} -j DROP
  #/usr/sbin/iptables -I FORWARD -i br0 -s ${NETWORK}.${TOR_CLIENT} -p udp --dport 123 -j ACCEPT # Internet time requests
done


/jffs/scripts/nat-start
Code:
#!/bin/sh
# TODO: replace with your list of TOR users here
TOR_CLIENTS="222 223"

IPADDR=$(/usr/sbin/nvram get lan_ipaddr)
NETWORK=${IPADDR%.*}
## for these TOR users, route all TCP packets through the TOR network
for TOR_CLIENT in $TOR_CLIENTS ; do
  /usr/sbin/iptables -t nat -I PREROUTING -i br0 -p tcp --syn -s ${NETWORK}.${TOR_CLIENT} ! -d ${NETWORK}.0/24 -j REDIRECT --to-ports 9040
  /usr/sbin/iptables -t nat -I PREROUTING -i br0 -s ${NETWORK}.${TOR_CLIENT} -p udp --dport 53 -j REDIRECT --to-ports 9053
  #/usr/sbin/iptables -t nat -I PREROUTING -i br0 -s ${NETWORK}.${TOR_CLIENT} -p udp --dport 123 -j REDIRECT --to-ports 123 # requires an NTP server
done


/jffs/home/torrc
Code:
GeoIPFile /rom/tor/geoip
GeoIPv6File /rom/tor/geoip6
StrictNodes 1
VirtualAddrNetwork 10.192.0.0/10
#VirtualAddrNetworkIPv6 [FC00]/7
AutomapHostsOnResolve 1
#AvoidDiskWrites 1
SocksPort localhost:9050
SocksPort 192.168.1.1:9050
DNSPort localhost:9053
DNSPort 192.168.1.1:9053
TransPort localhost:9040
TransPort 192.168.1.1:9040
DataDirectory /var/lib/tor
Log notice file /var/log/tor/notices.log
RunAsDaemon 1
ExitPolicy reject *:* # no exits allowed
User tor


/jffs/configs/dnsmasq.conf.add
Code:
# ...
#address=/.pool.ntp.org/ntp.ubuntu.com/time.nist.gov/time-nw.nist.gov/time-a.nist.gov/time-b.nist.gov/time.windows.com/192.168.1.1
# ...


/jffs/home/tor-start
Code:
#!/bin/sh
TOR_CMD="/usr/sbin/Tor -f /jffs/home/torrc"
TOR_PID=$(/bin/echo $(/bin/ps ww | /bin/grep -F "$TOR_CMD" | /bin/grep -v grep) | /usr/bin/cut -f1 -d' ')

append_line () {
  local filepath="$1"
  local textline="$2"
  /bin/grep -q "$textline" "$filepath" || /bin/echo "$textline" >> "$filepath"
}

if [ -z "$TOR_PID" ]; then
  /usr/bin/killall Tor tor
  /bin/sleep 1
  [ -d /var/lib/tor ] && /bin/rm -rf /var/lib/tor
  [ -d /jffs/tor ] && /bin/cp -a /jffs/tor /var/lib/.
  /bin/mkdir -p /var/log/tor
  /bin/mkdir -p /var/lib/tor
  /bin/mkdir -p /var/lib/tor/hidden_service
  /bin/mkdir -p /var/lib/tor/other_hidden_service
  append_line "/etc/p-a-s-s-w-d" "tor:x:333:333:tor:/dev/null:/dev/null"
  append_line "/etc/s-h-a-d-o-w" "tor::0:0:99999:7:0:0:"
  append_line "/etc/g-r-o-u-p" "tor:x:333:"
  /bin/chown -R tor:tor /var/log/tor /var/lib/tor
  /bin/chmod -R u=rwx,g-rwx,o-rwx /var/log/tor /var/lib/tor
  $TOR_CMD
fi


/jffs/home/tor-stop
Code:
#!/bin/sh
TOR_CMD="/usr/sbin/Tor -f /jffs/home/torrc"
TOR_PID=$(/bin/echo $(/bin/ps ww | /bin/grep -i "$TOR_CMD" | /bin/grep -v grep) | /usr/bin/cut -f1 -d' ')

if [ -n "$TOR_PID" ]; then
  /usr/bin/killall Tor tor
  /bin/sleep 1
  source /jffs/home/tor-save
fi


/jffs/home/tor-restart
Code:
#!/bin/sh
/jffs/home/tor-stop && /jffs/home/tor-start


/jffs/home/tor-save
Code:
#!/bin/sh
if [ -d /var/lib/tor ]; then
  if [ -f /entware/bin/rsync ]; then
    /entware/bin/rsync -axvi --checksum --no-W --no-times --inplace --stats --temp-dir=/tmp --log-file=/tmp/rsync.log /var/lib/tor /jffs/
  else
    /bin/cp -a /var/lib/tor /jffs/.
  fi
fi
 
Last edited:
I presume in the first 2 scripts the * is replaced with the ip you want to use tor, keeping the period before it?
 
No, I think you replace "222" with the IP you're interested in (could be wrong though).

The only bit I don't understand is why we don't simply make an exception for NTP so that it goes out as normal, not via TOR, instead of needing a local server? I'm going to try to make that work and see how I get on. I will share results.
 
Last edited:
I presume in the first 2 scripts the * is replaced with the ip you want to use tor, keeping the period before it?
The scripts now have a variable and loop to configure the firewall.
 
No, I think you replace "222" with the IP you're interested in (could be wrong though).

The only bit I don't understand is why we don't simply make an exception for NTP so that it goes out as normal, not via TOR, instead of needing a local server? I'm going to try to make that work and see how I get on. I will share results.
The scripts now have a variable and loop to configure the firewall. The "222" means "192.168.1.222", which is the IP address of my laptop computer on my local network.

I also changed the script so TOR users can make Internet time requests direct to the Internet. However, you must un-comment that line in /jffs/home/firewall-start.
Code:
#/usr/sbin/iptables -I FORWARD -s ${NETWORK}.${TOR_CLIENT} -p udp --dport 123 -j ALLOW # Internet time requests

My Asus router has GPS-backed clock synchronization for the local network. However, this firmware mod is not for the faint of heart.
 
Last edited:
A word about running TOR as a non-root user. My scripts create a "tor" user to do this. Not sure how meaningful it is to do this on a router where everything runs as root. Cloudflare will not allow me to type the names of the three /etc files that must be updated when adding a new user in Linux. Therefore, in my scripts you must edit the names of the three /etc files by removing the dash characters in between the letters.
 
Last edited:
LOL! I did wonder about that, but I just assumed it was some customisation that I was unaware of. I was wondering why it wasn't working. Thanks!
 
EDIT: fixed bug in address_checker

Alternatively, here's command line tool to configure the firewall for TOR clients. I suppose you'd run this from /jffs/scripts/firewall-start, passing the list of network devices to be redirected through the TOR network.

/jffs/home/tor-firewall
Code:
#!/bin/sh
############################################################################################################
# Configuration
#
ALLOW_CLIENT_TIME_SYNC=1  # 0=None, 1=Allow Internet time sync, 2=Redirect to router's NTP server
IPADDR=$(/usr/sbin/nvram get lan_ipaddr)
NETWORK=${IPADDR%.*}
IPTABLES_BLOCK_INTERNET="/usr/sbin/iptables %s FORWARD %s -j DROP"
IPTABLES_ALLOW_NTP="/usr/sbin/iptables %s FORWARD -i %s %s -p udp --dport 123 -j ACCEPT"
IPTABLES_ROUTE_TCP="/usr/sbin/iptables -t nat %s PREROUTING -i %s -p tcp --syn %s ! -d ${NETWORK}.0/24 -j REDIRECT --to-ports 9040"
IPTABLES_ROUTE_DNS="/usr/sbin/iptables -t nat %s PREROUTING -i %s %s -p udp --dport 53 -j REDIRECT --to-ports 9053"
IPTABLES_ROUTE_NTP="/usr/sbin/iptables -t nat %s PREROUTING -i %s %s -p udp --dport 123 -j REDIRECT --to-ports 123"
DEMO_MODE=0

############################################################################################################
# Startup
#
if [ $# -lt 2 ]; then
  /bin/echo
  /bin/echo "Usage: tor-firewall {-I | -D} CLIENT [CLIENT]..."
  /bin/echo
  /bin/echo "Insert or delete firewall rules for TOR clients"
  /bin/echo
  /bin/echo "        I        Insert firewall rules"
  /bin/echo "        D        Delete firewall rules"
  /bin/echo "        CLIENT   Client address to redirect"
  /bin/echo
  /bin/echo "Examples"
  /bin/echo
  /bin/echo "tor-firewall -I 192.168.1.222                       # redirect one client IP address"
  /bin/echo "tor-firewall -I .222                                # same, but use the router's default network"
  /bin/echo "tor-firewall -I 192.168.1.222 192.168.1.223         # redirect two clients"
  /bin/echo "tor-firewall -I 192.168.1.222-223                   # redirect an IP range"
  /bin/echo "tor-firewall -I .222-223                            # same, but use the router's default network"
  /bin/echo "tor-firewall -I .222-223 .120-130 .175-200          # redirect multiple IP ranges"
  /bin/echo "tor-firewall -I AA:BB:CC:DD:EE:FF                   # redirect one MAC address"
  /bin/echo "tor-firewall -I AA:BB:CC:DD:EE:FF 11:22:33:44:55:66 # redirect two MAC addresses"
  /bin/echo
  if [ "$ALLOW_CLIENT_TIME_SYNC" == "0" ]; then
    /bin/echo "TOR clients are blocked from Internet time synchronization.  To change this behavior, edit the script."
  elif [ "$ALLOW_CLIENT_TIME_SYNC" == "1" ]; then
    /bin/echo "TOR clients are allowed to access the Internet directly to sychronize their clocks.  To change this behavior, edit the script."
  elif [ "$ALLOW_CLIENT_TIME_SYNC" == "2" ]; then
    /bin/echo "Your router is expected to have an NTP server running for TOR clients to use.  To change this behavior, edit the script."
  fi
  /bin/echo
  /bin/echo
  exit 0
else
  local ACTION="$(/bin/echo $1 | /usr/bin/tr '[a-z]' '[A-Z]')"
  local ACTION="${ACTION:1:1}"
  shift
  local TOR_CLIENTS="$@"
fi

############################################################################################################
# address_checker
#   returns the address type (0=IP address, 1=MAC address, 2=IP address range) and the reformatted address
#
address_checker() {
  TYPE_IP=0
  TYPE_MAC=1
  TYPE_IPRANGE=2
  local ref_addr_type="$1"
  local addr_old="$(eval /bin/echo \$$2)"
  local ref_addr_new="$3"

  eval $ref_addr_type=$TYPE_NONE
  eval $ref_addr_new=""

  local second=$(/usr/bin/expr index $addr_old "-")
  if [ $second -ne 0 ]; then
    eval $ref_addr_type=$TYPE_IPRANGE
    local second_str=${addr_old:$second}
    local second_str_dot=$(/usr/bin/expr index $second_str ".")
    if [ $second_str_dot -ne 0 ]; then
      # long notation
      eval $ref_addr_new=$addr_old
    else
      # short notation
      local a="${addr_old%.*}"
      local len_to_minus=$second
      local len_to_dot=$(( ${#a} + 1 ))
      eval $ref_addr_new="${addr_old:0:$len_to_minus}${addr_old:0:$len_to_dot}${second_str}"
    fi
  else
    if [ ${#addr_old} -eq 17 ]; then
      eval $ref_addr_type=$TYPE_MAC
    else
      eval $ref_addr_type=$TYPE_IP
    fi
    eval $ref_addr_new=$addr_old
  fi
}

############################################################################################################
# insert_firewall_rule
#   inserts an iptables rule when it does not exist
#
insert_firewall_rule() {
  local cmd="$1" ; shift ; local args="$@"
  if [ "$DEMO_MODE" == "1" ]; then
    echo $(/usr/bin/printf "$cmd" "-I" "$args")
  else
    $(/usr/bin/printf "$cmd" "-C" "$args") > /dev/null 2>&1 || $(/usr/bin/printf "$cmd" "-I" "$args")
  fi
}

############################################################################################################
# delete_firewall_rule
#   deletes an iptables rule
#
delete_firewall_rule() {
  local cmd="$1" ; shift ; local args="$@"
  if [ "$DEMO_MODE" == "1" ]; then
    echo $(/usr/bin/printf "$cmd" "-D" "$args")
  else
    $(/usr/bin/printf "$cmd" "-C" "$args") > /dev/null 2>&1
    if [ $? -eq 0 ]; then
      $(/usr/bin/printf "$cmd" "-D" "$args")
    else
      echo "NOTFOUND: "$(/usr/bin/printf "$cmd" "-D" "$args")
    fi
  fi
}

############################################################################################################
# apply_firewall_rule
#   inserts or deletes a firewall rule
#
apply_firewall_rule() {
  if [ "$ACTION" == "I" ]; then
    insert_firewall_rule "$@"
  elif [ "$ACTION" == "D" ]; then
    delete_firewall_rule "$@"
  fi
}

############################################################################################################
# apply_tor_firewall_rules
#   configures the Iptables Filter and NAT tables for one TOR source address
#
apply_tor_firewall_rules() {
  local interface="$1"
  local match="$2"

  # Filter rules
  apply_firewall_rule "$IPTABLES_BLOCK_INTERNET" "$match"
  [ "$ALLOW_CLIENT_TIME_SYNC" == "1" ] && apply_firewall_rule "$IPTABLES_ALLOW_NTP" "$interface" "$match"

  # NAT rules
  apply_firewall_rule "$IPTABLES_ROUTE_TCP" "$interface" "$match"
  apply_firewall_rule "$IPTABLES_ROUTE_DNS" "$interface" "$match"
  [ "$ALLOW_CLIENT_TIME_SYNC" == "2" ] && apply_firewall_rule "$IPTABLES_ROUTE_NTP" "$interface" "$match" # requires an NTP server
}

############################################################################################################
# for each TOR client, route all TCP packets through the TOR network AND block direct Internet access for
# everything else that can't be routed through the TOR network (i.e. UDP and ICMP pig)
#
if [ "$TOR_CLIENTS" == "br0" ]; then

  apply_tor_firewall_rules "br0"

else
  for tor_source in $TOR_CLIENTS ; do

    if [ "${tor_source:0:1}" == "." ]; then
      tor_source=${NETWORK}${tor_source}
    fi

    address_checker tor_source_type tor_source tor_source_new

    if [ $tor_source_type -eq $TYPE_IP ]; then

      apply_tor_firewall_rules "br0" "-s $tor_source_new"

    elif [ $tor_source_type -eq $TYPE_MAC ]; then

      apply_tor_firewall_rules "br0" "-m mac --mac-source $tor_source_new"

    elif [ $tor_source_type -eq $TYPE_IPRANGE ]; then

      apply_tor_firewall_rules "br0" "-m iprange --src-range $tor_source_new"

    fi
  done
fi



How to make TOR safe, if using the Asus WebUI settings for TOR VPN. Example for how to pass the Asus WebUI settings to the tor-firewall command-line tool, listed above. This is probably the quickest way to fix the issue.

/jffs/scripts/firewall-start
Code:
#!/bin/sh
if "$(/usr/sbin/nvram get Tor_enable)" == "1" ]; then
  Tor_redir_list="$(/usr/sbin/nvram get Tor_redir_list)"
  [ -z "$Tor_redir_list" ] && Tor_redir_list="br0"
  source /jffs/home/tor-firewall -I "$(/bin/echo ${Tor_redir_list//\</ })"
fi
 
Last edited:
Thanks for all your help with this. I got things set up last night. It is partially working but I think it needs some tweaking. I'm busy for a few days now but will come back to it.
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top