I've spent the last couple of days looking for a solution to this problem, and though there are quite a few semi-relevant questions, none of the answers show a successful use case for sending a successful HTTP request over Tor to a hidden service using Ruby.
One thing that seems unclear in all the answers is how the Tor browser bundle acts as a proxy for requests.
I've tried multiple avenues of attack, the most recent being an attempt to adapt the PHP code here for sending curl requests to hidden services using Ruby CURL libraries.
This is my code using the Curb gem, which implements some of the libcurl bindings for Ruby:
require 'curb'
url = 'http://am4wuhz3zifexz5u.onion' #a known, functioning hidden service
c = Curl::Easy.new(url) do |curl|
curl.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0" #the user agent string from the most recent version of the tor browser
curl.verbose = true
end
c.perform
c.inspect
I then tried to run this through socksify, using the IP address and port specified by the Tor browser bundle's proxy settings:
$ socksify_ruby 127.0.0.1 9150 tor-test/tor-test.rb
This produced the following output:
* Adding handle: conn: 0x7fb1fe195e00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fb1fe195e00) send_pipe: 1, recv_pipe: 0
* Could not resolve host: jhiwjjlqpyawmpjx.onion
* Closing connection 0
Every approach I've tried has produced a similar result: the URI for the hidden service cannot be resolved
Can anyone help me out here or point me in the right direction? I feel that since the Tor browser can connect programmatically to hidden services, we all should be able to as well : )
Curl only uses a proxy if you set it up in your "curl"-block.
For example:
c = Curl::Easy.new() do |curl|
curl.proxy_tunnel = true
curl.proxy_type = Curl::CURLPROXY_SOCKS5 # also available and default Curl::CURLPROXY_HTTP
curl.proxy_url = '127.0.0.1:9050' # local tor client/proxy
curl.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0" #the user agent string from the most recent version of the tor browser
curl.verbose = true
curl.url = url # your example url
curl.perform
curl.inspect
end
Unfortunately curl does not use the proxy for hostname resolution. In other words, I did't find a way to force curl to use the proxy for hostname resolution.
But you can try
#enable socksify debug
Socksify::debug = true
#own try via direct use of socksify and Net::HTTP
uri = URI.parse('http://am4wuhz3zifexz5u.onion/') #a known, functioning hidden service
# some debug stuff - just ignore ;-)
puts uri
puts uri.host
puts uri.port
puts uri.path
res1 = Net::HTTP.SOCKSProxy('127.0.0.1', 9050).start(uri.host, uri.port) do |http|
http.get(uri.path)
end