Golang : Accessing content anonymously with Tor




There are times when we need to access content and do research anonymously. Using Tor(The Onion Router) can be useful in this case. What Tor does is to forward your requests in an encrypted manner from the beginning to the end of your request across a network of computers located worldwide.

Below is an example Golang program that emulates a wget command and to test if we can browse anonymously, we are going to execute a HTTP GET command to see if our IP address is masked by Tor or not.

goTOR.go


 package main

 import (
  "fmt"
  "golang.org/x/net/proxy"
  "io/ioutil"
  "net/http"
  "net/url"
  "os"
  "time"
 )

 func main() {
  if len(os.Args) != 2 {
 fmt.Printf("Usage : %s <URL to get> \n", os.Args[0])
 os.Exit(0)
  }

  webURL := os.Args[1]

  // Setup localhost TOR proxy
  torProxyUrl, err := url.Parse("socks5://127.0.0.1:9050") // port 9150 is for Tor Browser
  if err != nil {
 fmt.Println("Unable to parse URL:", err)
 os.Exit(-1)
  }

  // Setup a proxy dialer
  torDialer, err := proxy.FromURL(torProxyUrl, proxy.Direct)
  if err != nil {
 fmt.Println("Unable to setup Tor proxy:", err)
 os.Exit(-1)
  }

  torTransport := &http.Transport{Dial: torDialer.Dial}
  client := &http.Client{Transport: torTransport, Timeout: time.Second * 5}

  response, err := client.Get(webURL)
  if err != nil {
 fmt.Println("Unable to complete GET request:", err)
 os.Exit(-1)
  }

  defer response.Body.Close()

  // Read response body
  body, err := ioutil.ReadAll(response.Body)
  if err != nil {
 fmt.Println("Error reading body of response.", err)
 os.Exit(-1)
  }

  fmt.Println(string(body))
 }

Sample output:

Build the executable

>go build goTOR.go

and then run

>./goTOR https://check.torproject.org | grep "Your IP"

and

>./goTOR https://check.torproject.org | grep "Congratulation"

if your computer is on TOR network, you should see that the IP address is different from what is given on http://whatismyipaddress.com/ and also you should get this message as well Congratulations. This browser is configured to use Tor.


NOTE: In case you encounter this error message :

2016/10/06 16:10:05 Error making GET request.Get https://check.torproject.org: dial tcp 127.0.0.1:9050: getsockopt: connection refused

To fix this on Mac OS X:


Get the latest Homebrew

>ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

then

>brew install tor

follow by

brew install torsocks

and finally, run tor as a background process with :

>tor &

Once tor is running, you should see these messages:

Oct 06 16:15:13.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.

Oct 06 16:15:13.000 [notice] Bootstrapped 100%: Done

then you can run the code example again and this time, it should give you the IP address instead of getsockopt:connection refused error message.

Happy TOR-ring and Coding!

References:

https://www.socketloop.com/tutorials/golang-get-command-line-arguments

https://www.socketloop.com/references/golang-net-http-client-get-function-example

https://gist.github.com/Yawning/bac58e08a05fc378a8cc





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement