ReqTor

A Req plugin for routing HTTP requests through a Tor SOCKS5 proxy.

Supports both clearnet sites and .onion hidden services.

Installation

Add req_tor to your list of dependencies in mix.exs:

def deps do
  [
    {:req_tor, "~> 0.1.0"}
  ]
end

Prerequisites

Ensure Tor is running locally:

# macOS
brew install tor
brew services start tor

# Linux
sudo apt install tor
sudo systemctl start tor

The default SOCKS5 proxy runs on port 9050. Tor Browser uses port 9150.

Usage

Req sends the request directly. ReqTor sends it through Tor.

Req.get!("https://example.com")

ReqTor.get!("https://check.torproject.org")

# .onion hidden services
ReqTor.get!("http://example.onion/")

# Reuse a client. `head!`, `post!`, `put!`, `patch!`, `delete!`, and `request!` match.
req = ReqTor.new(tor_port: 9150)
ReqTor.get!(req, url: "http://example.onion/")

# Tor Browser user-agent (helps avoid blocks)
req = ReqTor.new(tor_browser: true)

# Skip the proxy for one call
ReqTor.get!(req, url: "https://example.com", tor_enabled: false)

attached?/1 tells a Tor request from a plain Req request:

ReqTor.attached?(ReqTor.new())
#=> true

ReqTor.attached?(Req.new())
#=> false

To add Tor to a request that already has Req plugins, attach it and still call ReqTor:

req = Req.new(base_url: "http://example.onion") |> ReqTor.attach()
ReqTor.get!(req, url: "/")

Helper Functions

req = ReqTor.new()

# Check if connected through Tor
ReqTor.check_tor?(req)
#=> true

# Get your Tor exit node IP
ReqTor.exit_ip(req)
#=> {:ok, "185.220.101.42"}

# Or pass options straight through
ReqTor.exit_ip(tor_port: 9150)
#=> {:ok, "185.220.101.42"}

Options

Option Default Description
:tor_host "127.0.0.1" Tor SOCKS5 proxy host
:tor_port 9050 Tor SOCKS5 proxy port (use 9150 for Tor Browser)
:tor_enabled true Route this request through Tor. false skips the proxy for that call
:tor_insecure :auto :auto verifies clearnet TLS and skips it for .onion. true skips every host. false verifies every host
:tor_browser false Use Tor Browser's user-agent string. This replaces :user_agent
:receive_timeout 60000 Milliseconds to wait on the Tor socket. Req's option, with a longer Tor default
:user_agent ReqTor/<version> Sent unless you set this, a user-agent header, or :tor_browser

License

BSD 3-Clause. See LICENSE.