Ozan Tunca

Senior Software Developer, Music Producer

I’m Ozan, a Senior Software Developer working mainly with JavaScript (read TypeScript). I build scalable, maintainable, performant front-ends and back-ends. I'm also an electronic music enthusiast so don't forget to check out my SoundCloud.

How to Anonymize Node.js Applications Using Tor

Like every developer, I find myself writing many scripts, bots and cron jobs, that regularly hit certain servers. Occasionally, I need these scripts to appear to be in random remote locations. Sometimes I want to test how my new bot protection behaves, or view my website or application from abroad, or access a website that’s not accessible from the country I’m in (I used to live in Turkey), or simply mask who I am online. To achieve this seamlessly and reliably, I needed a trustworthy and anonymous VPN or proxy.

I set up my own VPN which was a pretty good solution for some of my use cases. But it was complicated to change the location of VPN, it wasn’t anonymous, and it was costly when I wasn’t actively using it. After some thinking and some research, I’ve realised that Tor is perfect for most of my use cases. It’s reliable, anonymous, and free!

In this article, I’m going to explain how you can set up your own code to work over Tor and use its advantages for free. Let’s start by understanding what Tor is.

What is Tor?

Tor, or as it used to be called “The Onion Router,” is a service that enables free anonymous communication over the Internet. It directs Internet traffic through free, worldwide, volunteer operated relays to mask the origin of requests. The Tor Project aims to help people protect themselves from companies, governments, or individuals who conduct traffic analysis or network surveillance.

They also developed Tor Browser to replace your usual browser for daily usage. For instance, if you’re worried about how companies like Facebook and Google monitor your every move to show you relevant ads, you might want to check out Tor Browser. It works like any other internet browser with some added features and options to increase anonymity. It uses Tor’s network to conceal who you are and what you do online. That’s why it’s also the most popular way to access the hidden part of the internet commonly known as the deep web. According to Tor Metrics, about two million people use Tor Browser every day.

What’s particularly interesting about Tor is how easy it is to set up a local Tor proxy and direct all our traffic through it. It’s also completely free.

Setting up a Tor Proxy

The most stable way of doing this is to run a Tor proxy ourselves and redirect our Node.js requests through it. Setting up your own proxy sounds complicated but it’s easy. I’ll explain an easy way and a not so easy way of doing this. Both are relatively simple so bear with me.

Usually, when you install software like a proxy, the process is different depending on which operating system you’re running. Installing and configuring on Mac server would be different from a Linux server, so doing both would require repetitive efforts. This is what I call the not so easy way and it will be explained later. Now, let’s explain the cross-platform way.

Easy way

As mentioned above, the easy way is to install and configure Tor cross-platform using Docker. Docker is a containerization solution that lets you run your software inside a virtual-machine-like environment to isolate it from external interference. It also allows you to run your software in a managed environment so that you can reliably and easily run it cross-platform.

If you don’t already have Docker, install the correct community edition for your operating system here. After installing and starting it, we’ll run the Docker version of Tor proxy in our machine. Thankfully, someone took the time to set it up inside a Docker container and open-sourced it. We just need to run the image they published. Run this command below on your favorite shell/terminal:

docker run -it -p 9050:9050 -d dperson/torproxy

This command downloads thedperson/torproxy image from the public Docker Hub and runs it locally on your Docker setup. It also exposes this proxy on port 9050 so you can connect your scripts to the proxy over this port.

Not so easy way

If you’ve already set up Tor on the previous step, you can skip this one. I’ll explain how to do it without using Docker.

To set up Tor without using Docker, we need to install it manually.

For Ubuntu/Debian

To install Tor on Ubuntu/Debian, we need to update the source list of apt and then install Tor with apt. There are slight differences depending on the version of the operating system you're using. Tor Project already has a document with the steps and the exact code you need to run based on your operating system. Instead of repeating that information here, I recommend you take a look at their document here.

For Mac OSX

It’s easier for OSX compared to Linux distributions. There are two popular package managers for Mac, Homebrew and Macports. Install one of them if you haven’t already. If you don’t know which one to choose, I can recommend Homebrew as I’m quite satisfied with it:

Depending on which package manager you chose to install, run either:

brew install tor

or

sudo port install tor

Running Tor without Docker

Luckily this part is very simple. Simply run:

tor

Or, to run it in the background:

tor &

This command starts the Tor proxy and exposes it over port 9050.

Testing Our Tor Connection

Now we have our very own Tor entry point up and running, let’s test that it does what we want it to do. An easy way to do this is to make an HTTP request through Tor to a website to see what they think our IP address is. You can use any HTTP client--curl, httpie or wget, for example — and make a request to any "What Is My IP Address Solution." Here’s an example command I invoked and the result:

original ip

(Berlin, Germany)

Now let’s use our local Tor Socks5 Proxy for the same request:

masked ip

(Roubaix, France)

ifconfig.me (or any website that I access through Tor) now thinks that I’m in France even though I’m in Germany.

It’s also possible to select the country you want to appear to be in. Simply provide the -l option to your Docker command with the ISO country code and Tor should use an exit node in that country. Example:

docker run -it -p 9050:9050 -d dperson/torproxy -l "US"

Keep in mind that, thanks to its complicated nature, Tor can be too slow for a reliable Netflix or similar streaming experience. It’s discouraged to use it for those purposes.

Connecting Node.js scripts to Tor

The next step is to configure our code so that all the requests generated from our Node.js code will go through this proxy. Most HTTP clients let you specify a proxy or an HTTP agent to be used. A popular Socks Proxy agent you can use in your scripts is socks-proxy-agent. Below is an implementation using Node’s built-in HTTP client https:

const https = require('https');
const { SocksProxyAgent } = require('socks-proxy-agent');
const agent = new SocksProxyAgent('socks5h://127.0.0.1:9050');
https.get('https://ifconfig.me', {
agent
}, res => {
res.pipe(process.stdout);
});

Here’s another example implementation, this time using the popular JavaScript HTTP client library, Axios:

const { SocksProxyAgent } = require('socks-proxy-agent');
const axios = require('axios');
const agent = new SocksProxyAgent('socks5h://127.0.0.1:9050');
axios({
url: 'https://ifconfig.me',
httpsAgent: agent,
})
.then(({
data
}) => {
console.log(data);
});

Final Words

Congratulations — your script just got a lot harder to track and identify. Use this ability wisely!

Let me know what you think about this article and what applications you have could benefit from this approach.

Resources

Footer Logo