Using Ruby to access Onion network over SOCKS proxy

Source code lives here.

Vlad Dyachenko
2 min readMay 15, 2019

Tor provides a SOCKS proxy so that you can have any application using the same to connect the Onion network. The Tor Browser also provides the same service on port 9150. In this post, we will see how can we use the same SOCKS proxy to access the Internet.

Before the start, we need to install Tor to use it as a proxy.

# For Debian-like distros, you can find a guide over here.
#
brew install tor

Then launch Tor. The default port is 9050.

brew services start tor

Basically, Net::HTTP doesn’t support SOCKS proxy out-of-the-box (the same issue is actual for httparty, faraday, Curl::Easy), so the only way is to use socksify Gem:

gem install socksify
--Fetching socksify-1.7.1.gem
--Successfully installed socksify-1.7.1
--Parsing documentation for socksify-1.7.1
--Installing ri documentation for socksify-1.7.1
--Done installing documentation for socksify after 0 seconds
1 gem installed

First of all, let’s visit some onion site using the Tor browser to get real request headers.

Scraping headers from the “real” request

After this, writing the actual code is very simple, we will be doing a GET request to http://hydr@rzxpnΣw4@f.onion.

require 'socksify/http'
require 'net/http'
require 'uri'
# Socksify::debug = trueSOME_ONION_URI = URI.parse("http://hydr@rzxpnΣw4@f.onion/")query = Net::HTTP::Get.new(SOME_ONION_URI)
query["Host"] = "hydr@ruzxpnΣw4@f.onion"
query["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0"
query["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
query["Accept-Language"] = "en-US,en;q=0.5"
query["Referer"] = "http://hydr@ruzxpnΣw4@f.onion/shops"
query["Cookie"] = "pregate=1528672853.53f0db8f48fc195fc238a00d45a84ae4.598147be81d2cd4feb1047180cc96f95; gate=1528672884.28f0a6bc2d4368c96399a7c2d8f5b763.7fcc5bccc8fc7181eb15320d338a6f65"
response = Net::HTTP.SOCKSProxy('127.0.0.1', 9050).start(SOME_ONION_URI.host, SOME_ONION_URI.port) do |http|
http.request(query)
end

The output of the code looks like below:

irb(main): response
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main): puts response.body
=> ....
<div class="page">
<form action="/gate" method="post">
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEARwBHAAD/>
<form/>
</div>
....
We got the same result here!

Now, you can use the same code to access any standard webservice or access any Onion address.

--

--