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
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
Tutorials
+8.5k Android Studio : Import third-party library or package into Gradle Scripts
+16.5k Golang : Generate QR codes for Google Authenticator App and fix "Cannot interpret QR code" error
+8.5k Python : Fix SyntaxError: Non-ASCII character in file, but no encoding declared
+12.5k Golang : Get absolute path to binary for os.Exec function with exec.LookPath
+6k nginx : force all pages to be SSL
+11.5k CodeIgniter : Import Linkedin data
+8k Golang : How To Use Panic and Recover
+14k Golang : Reverse IP address for reverse DNS lookup example
+14.8k Golang : Basic authentication with .htpasswd file
+13.7k Golang : Gin framework accept query string by post request example
+18.7k Unmarshal/Load CSV record into struct in Go
+15.9k Golang : Get file permission