Version 9 (modified by trac, 9 years ago) (diff)



It is useful for a variety of reasons to determine if a connection is coming from a Tor node. Early attempts to determine if a given IP address was a Tor exit used the directory to match IP addresses and exit policies. This approach had a number of drawbacks, including false negatives when a Tor router exits traffic from a different IP address than its OR port listens on. The Tor DNS-based Exit List was designed to overcome these problems and provide a simple interface for answering the question: is this a Tor exit?


An implementation of the Tor DNS Exit List has been completed at DNS queries are answered via this host in the manner described in the design document. The exit nodes are tested regularly to avoid the false negatives when inspecting the directory entries alone.


The following examples describe how to utilize this service in various ways. Please add to this list if you have implemented hooks for a language or framework not provided below.

PHP Pear Net_DNS

You will need the Pear Net_DNS module for this to work properly:


// torel_check ($ip, $port, $destip) queries the Tor DNS Exit List server.
//   The result of the query is one of the following:
//   -1 : DNS lookup failed to get a response, or other error occurred.
//    0 : $ip does not appear to be a Tor exit.
//    1 : $ip is a known Tor exit for the provided destination IP / port.

function revaddr ($ip) {
  list($a, $b, $c, $d) = split ("[.]", $ip);
  return ("${d}.${c}.${b}.${a}");

function torel_qh ($ip, $port, $destip) {
  $rsrcip = revaddr ($ip);
  $rdstip = revaddr ($destip);

function torel_check ($ip, $port, $destip) {
  $ndr = new Net_DNS_Resolver(); 
  $qh = torel_qh ($ip, $port, $destip);

  // uncomment these two lines to query the server directly...
  //$ns = "";
  //$ndr->nameservers( array($ns) );

  // tune DNS params accordingly.  this is just my preference.
  $ndr->retrans = 2;
  $ndr->retry = 3;
  $ndr->usevc = 0;

  // perform DNS query
  if (! $pkt = $ndr->search ($qh)) {
    if (strcmp($ndr->errorstring, "NXDOMAIN") == 0) {
      // response but no answer.  does not appear to be Tor exit.
      return (0);
    // search failed: no response or other problem...
    return (-1);
  if (! isset ($pkt->answer[0])) {
    // response but no answer section.  does not appear to be Tor exit.
    // (this should only happen when authority sections are provided without answer)
    return (0);
  // is Tor exit
  return (1);

// get client request parameters from Apache or equiv server:
$ip = $myip = $myport = 0;
if (isset ($_SERVER["REMOTE_ADDR"])) { $ip = $_SERVER["REMOTE_ADDR"]; }
if (isset ($_SERVER["SERVER_ADDR"])) { $myip = $_SERVER["SERVER_ADDR"]; }
if (isset ($_SERVER["SERVER_PORT"])) { $myport = $_SERVER["SERVER_PORT"]; }

$istor = torel_check ($ip, $myport, $myip);

// use $istor as needed for altering page behavior:
if ($istor < 0) {
  // DNS query failed to get an answer
elseif ($istor) {
  // Endpoint is a known Tor exit
else {
  // Endpoint does not appear to be a Tor exit

An example implementation of this interface is available at

Dig command line

The DNS query tool "dig" can also be used to make manual queries as described on the torel page. Remember to reverse the IP address octets in the query sent:


In the response below, the address in the answer section means this endpoint,, is indeed a Tor exit to port 80:

; <<>> DiG 9.3.2 <<>>
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56277
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;        IN A


;; Query time: 31 msec
;; WHEN: Sun Jun 17 21:57:12 2007
;; MSG SIZE  rcvd: 96