Kushal Das

FOSS and life. Kushal Das talks here.


Using Python to access Onion network over SOCKS proxy

Tor provides a SOCKS proxy so that you can have any application using the same to connect the Onion network. The default port is 9050. 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.

Using Python requests module

I used pipenv to install the dependencies.

$ pipenv install
$ pipenv shell
$ pipenv install requests[socks]
Installing requests[socks]…
Collecting requests[socks]
  Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests[socks])
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests[socks])
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests[socks])
  Using cached idna-2.6-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests[socks])
  Using cached certifi-2018.1.18-py2.py3-none-any.whl
Collecting PySocks!=1.5.7,>=1.5.6; extra == "socks" (from requests[socks])
  Using cached PySocks-1.6.8.tar.gz
Building wheels for collected packages: PySocks
  Running setup.py bdist_wheel for PySocks: started
  Running setup.py bdist_wheel for PySocks: finished with status 'done'
  Stored in directory: /home/kdas/.cache/pip/wheels/77/f0/00/52f304b7dddcca8fca05ad1226382134ad50ba6c1662d7539e
Successfully built PySocks
Installing collected packages: chardet, urllib3, idna, certifi, PySocks, requests
Successfully installed PySocks-1.6.8 certifi-2018.1.18 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22

Adding requests[socks] to Pipfile's [packages]…
Pipfile.lock (711973) out of date, updating to (dcbf91)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (dcbf91)!
Installing dependencies from Pipfile.lock (dcbf91)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 6/6 — 00:00:01

After this, writing the actual code is very simple, we will be doing a GET request to https://httpbin.org to find out our IP address.

import requests

def main():
    proxies = {
            'http': 'socks5h://',
            'https': 'socks5h://'
    r = requests.get('https://httpbin.org/get', proxies=proxies)

if __name__ == '__main__':

If you see closely, you will find that I am using socks5h as the protocol, instead of socks5. The request documentation mentions that using socks5h will make sure that DNS resolution happens over the proxy instead of on the client side.

The output of the code looks like below:

$ python usesocks.py 
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.18.4"
  "origin": "", 
  "url": "https://httpbin.org/get"

$ python usesocks.py 
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.18.4"
  "origin": "", 
  "url": "https://httpbin.org/get"

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

How to delete your Facebook account?

I was planning to delete my Facebook account for some time, but, never took the actual steps to do it. The recent news on how the companies are using data from Facebook made me take that next step. And I know Snowden is talking about these issues for a long time (feel free to read a recent interview), I should have done that before. I was just lazy.

First download all the current information for archive

Login to Facebook, go to your settings page. Then you can see a link saying Download a copy of your Facebook data. Click on that. It will ask your password, and then take some time to generate an archive. You can download it after some time.

Let us ask Facebook to delete the account

Warning: Once you deleted your account, you can not get back your data. So, do the next steps after think clearly (personally, I can say it is a good first step to slowly gain back privacy).

Go to this link to see the following screen.

If you click on the blue Delete my account, it will open the next screen, where it will ask you to confirm your password, and also fill in the captcha text.

After this, you will see the final screen. It will take around 90 days to delete all of your information.

Remember to use long passphrases everywhere

Now, you have deleted your account. But, remember that it is just one single step to have privacy. There various other things you can do. I think the next step should be about all of your passwords. Read this blog post about how to generate long passphrases, and use those instead of short passwords. You should also use a proper password manager to save all of these passwords.


Running Tor relay inside a docker container

The latest Tor project release is But, that is not available on all the different versions of different Linux distributions. For example, CentOS 7 has tor-, and only Fedora 28 has the latest Tor.

This is where a container can help. The official builds from Tor Project are for Debian, means we can build and use a Debian based container.

The Dockerfile

FROM debian:stretch
LABEL MAINTAINER Kushal Das <mail@kushaldas.in>

RUN apt-get update
RUN apt install vim gpg -y

RUN echo "deb http://deb.torproject.org/torproject.org stretch main\ndeb-src http://deb.torproject.org/torproject.org stretch main" > /etc/apt/sources.list.d/tor.list

# Let us get the key for Tor
RUN gpg --keyserver keys.gnupg.net --recv A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
RUN gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 > tor.gpg
RUN apt-key add tor.gpg

# Finally install Tor
RUN apt update
RUN apt install tor deb.torproject.org-keyring -y
ADD ./torrc /etc/tor/torrc

# Add the tor user
RUN groupadd -g 1000 tor && useradd -m -d /home/tor -g 1000 tor

# Now drop to the actual user
USER tor
RUN mkdir -p /home/tor/.tor/keys

VOLUME ["/home/tor/.tor"]

EXPOSE 9001 9051


I have a configuration file named torrc, you can copy the sample configuration and edit as required. I have the following entries there.


ORPort 9001



ExitRelay 0

Next, we will create a directory in the host system to keep the keys, and other files. We want to restart the container and still have the same details, mounting a directory from the host system into the container will help us in that.

mkdir /mnt/tor
chcon -R -t svirt_sandbox_file_t /mnt/tor

Please also make sure that you have correct ownership of that directory.

Running the container

docker run -d -v /etc/localtime:/etc/localtime -v /mnt/tor:/home/tor/.tor --restart always -p 9001:9001 -name relay kushaldas/tor:

After starting the container, you can check the logs for any error. If you can see the following message in the log, then it means that you configured the relay properly.

# docker logs -f relay

Self-testing indicates your ORPort is reachable from the outside.

The official relay guide

Tor project recently published an updated relay guide for anyone new to running a relay. Please go through that document first. If you need help, there is a mailing list of Tor relay operators, and #tor channel on OFTC IRC server is also very welcoming.

Tor Mumbai meetup

On 20th January, we had a Tor meetup in Mumbai. Hasgeek organized the event, with OML providing the meeting space. I noticed the announcement over Twitter, and made sure that I registered for the event. Two contributors from the core team, Sukhbir Singh and Antonela Debiasi, were present at the event.

Getting there

Bhavin joined me on the trip. We started early in the morning to make sure that we skip all the traffic, and reach Mumbai with enough time on hand. The venue was surrounded by many excellent food places, which was really helpful.

The meetup

There were around 15 participants. Folks came from different cities. We started a small round of introductions, and both of the core contributors explained how they contribute to different parts of the project. Mentioning names (of the participants) were voluntary, and it was a no photograph event. Harish Pillai also joined us in the meetup.

Antonela described the work, the Tor UX team is doing. Only 2-3 days ago, I’d heard about their work in a discussion with Simply Secure. Antonela explained how they are doing user testing, and later, many participated in the same. We should also do similar kind of user testing in every conference/meetup.

We also tested the Tor network speed. Feel free to run the same test in your system using this link.

Next, Sukhbir gave a detailed talk on the Tor project. This was filled with many interesting facts and how-to(s). Discussions ranged from the Tor Browser itself to other parts of the Tor ecosystem. He also mentioned lot of dos/don’ts while using Tor. While talking about Tor Exit relays in India, Sukhbir mentioned that he never met any of the Exit relay operators in India before.

In the later half of the meetup, I demoed the SecureDrop project. We discussed about how the Freedom of the Press Foundation is helping journalists and whistleblowers worldwide. How to leak securely? was the next topic of discussion. Sukhbir had already mentioned most of the points. I made sure to repeat and refer back to those. I have a separate blog post on the topic. The discussion then moved to the Indian press and why we don’t have any SecureDrop instances running in India. People talked about their concerns and the current situation related to privacy in India.

In the end, we all moved to the microbrewery next door, and discussions continued.

While coming back, we were stuck in Mumbai traffic for a few hours, and reached home late.

Antonela has also shared her views about the meetup in the Tor Blog.

The Onion service to access my blog

I am happy to announce the availability of my website as an Onion hidden service at http://kushal76uaid62oup5774umh654scnu5dwzh4u2534qxhcbi4wbab3ad.onion/. This is a complete different instance than the regular https://kushaldas.in.

The .onion hidden service addresses are generated based on the hash of the public key. It means the Tor browser will take you to the right service which has access to the private key. The Onion services are always inside the Tor network, means you are not exiting the circuit/network. It is also end-to-end encrypted. These features together help to have confidentiality and integrity. If you want to read more about how the Tor hidden services work, read this document.

Things different on this site

  • This website has all the resources local to the server. Saptak helped to identify the external resources. Anwesha and I both wrote two different versions of the Python scripts to make things available locally. It was a fun programming problem.
  • No user-tracking JavaScript in the site.
  • No Disqus comments either. As it would require to load external Javascript, which in turn can be used to identify users.

Visiting the site using Tor Browser

Just in case you never encountered any .onion address before, you can visit these addresses using the Tor Browser. Download the latest version of the site. Remember to download Tor Browser only from the official website. Because my service is using version 3 of hidden service, you will need at least Tor Browser 7.5 to visit it.

Here are a few quick tips for using Tor Browser:

  • Do not install any plugin on the browser. They can be used to find your IP address.
  • Do not change the default browser window size. Browser window size can be used as metatdata to identify the users.
  • Use https versions of the websites you want to visit. The Tor Browser uses HTTPS Everywhere plugin to help you with that. As I mentioned earlier, the onion hidden services are already end-to-end encrypted, and you don’t get out of the Tor network, you can use them without the SSL certificates.

You can find more tips on the Tor project website.

Btw, DuckDuckGo also provides the search engine over a hidden service which you can use all the time.

How to configure Tor onion service on Fedora

You can set up a Tor onion service in a VM on your home desktop, or on a Raspberry Pi attached to your home network. You can serve any website, or ssh service using the same. For example, in India most of the time if an engineering student has to demo a web application, she has to demo on her laptop or on a college lab machine. If you set up your web application project as an onion service, you can actually make it available to all of your friends. You don’t need an external IP or special kind of Internet connection or pay for a domain name. Of course, it may be slower than all the fancy website you have, but you don’t have to spend any extra money for this.

In this post, I am going to talk about how can you set up your own service using a Fedora 26 VM. The similar steps can be taken in Raspberry Pi or any other Linux distribution.

Install the required packages

I will be using Nginx as my web server. The first step is to get the required packages installed.

$ sudo dnf install nginx tor
Fedora 26 - x86_64 - Updates                     10 MB/s |  20 MB     00:01
google-chrome                                    17 kB/s | 3.7 kB     00:00
Qubes OS Repository for VM (updates)             98 kB/s |  48 kB     00:00
Last metadata expiration check: 0:00:00 ago on Wed Jan 17 08:30:23 2018.
Dependencies resolved.
 Package                Arch         Version                Repository     Size
 nginx                  x86_64       1:1.12.1-1.fc26        updates       535 k
 tor                    x86_64         updates       2.6 M
Installing dependencies:
 gperftools-libs        x86_64       2.6.1-5.fc26           updates       281 k
 nginx-filesystem       noarch       1:1.12.1-1.fc26        updates        20 k
 nginx-mimetypes        noarch       2.1.48-1.fc26          fedora         26 k
 torsocks               x86_64       2.1.0-4.fc26           fedora         64 k

Transaction Summary
Install  6 Packages

Total download size: 3.6 M
Installed size: 15 M
Is this ok [y/N]:

Configuring Nginx

After installing the packages, the next step is to setup the web server. For a quick example, we will just show the default Nginx index page over this web service. We will have to change the web server port to a different one in /etc/nginx/nginx.conf file. Please read about Nginx to know more about how to configure Nginx with your web application.

listen 8090 default_server;

Here we have the web server running on port 8090.

Configuring Tor

Next, we will set up the Tor onion service. The configuration file is located at /etc/tor/torrc. We will add the following two lines.

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80

We are redirecting port 80 in the onion service to the port 8090 in the same system.

Starting the services

Remember to open up port 80 in the firewall before starting the services. I am going to keep it an exercise for the reader to find out how :)

We will start nginx and tor service as the next step, you can also watch the system logs to find out status of Tor.

$ sudo systemctl start nginx
$ sudo systemctl start tor
$ sudo journalctl -f -u tor
-- Logs begin at Thu 2017-12-07 07:13:58 IST. --
Jan 17 08:33:43 tortest Tor[2734]: Bootstrapped 0%: Starting
Jan 17 08:33:43 tortest Tor[2734]: Signaled readiness to systemd
Jan 17 08:33:43 tortest systemd[1]: Started Anonymizing overlay network for TCP.
Jan 17 08:33:43 tortest Tor[2734]: Starting with guard context "default"
Jan 17 08:33:43 tortest Tor[2734]: Opening Control listener on /run/tor/control
Jan 17 08:33:43 tortest Tor[2734]: Bootstrapped 5%: Connecting to directory server
Jan 17 08:33:44 tortest Tor[2734]: Bootstrapped 10%: Finishing handshake with directory server
Jan 17 08:33:44 tortest Tor[2734]: Bootstrapped 15%: Establishing an encrypted directory connection
Jan 17 08:33:45 tortest Tor[2734]: Bootstrapped 20%: Asking for networkstatus consensus
Jan 17 08:33:45 tortest Tor[2734]: Bootstrapped 25%: Loading networkstatus consensus
Jan 17 08:33:55 tortest Tor[2734]: I learned some more directory information, but not enough to build a circuit: We have no usable consensus.
Jan 17 08:33:55 tortest Tor[2734]: Bootstrapped 40%: Loading authority key certs
Jan 17 08:33:55 tortest Tor[2734]: Bootstrapped 45%: Asking for relay descriptors
Jan 17 08:33:55 tortest Tor[2734]: I learned some more directory information, but not enough to build a circuit: We need more microdescriptors: we have 0/6009, and can only build 0% of likely paths. (We have 0% of guards bw, 0% of midpoint bw, and 0% of exit bw = 0% of path bw.)
Jan 17 08:33:56 tortest Tor[2734]: Bootstrapped 50%: Loading relay descriptors
Jan 17 08:33:57 tortest Tor[2734]: Bootstrapped 56%: Loading relay descriptors
Jan 17 08:33:59 tortest Tor[2734]: Bootstrapped 65%: Loading relay descriptors
Jan 17 08:34:06 tortest Tor[2734]: Bootstrapped 72%: Loading relay descriptors
Jan 17 08:34:06 tortest Tor[2734]: Bootstrapped 80%: Connecting to the Tor network
Jan 17 08:34:07 tortest Tor[2734]: Bootstrapped 85%: Finishing handshake with first hop
Jan 17 08:34:07 tortest Tor[2734]: Bootstrapped 90%: Establishing a Tor circuit
Jan 17 08:34:08 tortest Tor[2734]: Tor has successfully opened a circuit. Looks like client functionality is working.
Jan 17 08:34:08 tortest Tor[2734]: Bootstrapped 100%: Done

There will be a private key and the hostname file for the onion service in the /var/lib/tor/hidden_service/ directory. Open up Tor browser, and visit the onion address. You should be able to see a page like below screenshot.

Remember to backup the private key file if you want to keep using the same onion address for a longer time.

What all things can we do with this onion service?

That actually depends on your imagination. Feel free to research about what all different services can be provided over Tor. You can start with writing a small Python Flask web application, and create an onion service for the same. Share the address with your friends.

Ask your friends to use Tor browser for daily web browsing. The more Tor traffic we can generate, the more difficult it will become for the nation-state actors to try to monitor traffics, that in turn will help the whole community.

WARNING on security and anonymous service

Remember that this tutorial is only for quick demo purpose. This will not make your web server details or IP or operating system details hidden. You will have to make sure of following proper operational security practices along with system administration skills. Riseup has a page describing best practices. But, please make sure that you do enough study and research before you start providing long-term services over the Tor.

Also please remember that Tor is developed and run by people all over the world and the project needs donation. Every little bit of help counts.

Do not limit yourself

This post is all about my personal experience in life. The random things I am going to write in this post, I’ve talked about in many 1x1 talks or chats. But, as many people asked for my view, or suggestions on the related topics, I feel I can just write all them down in one single place. If you already get the feeling that this post will be a boring one, please feel free to skip. There is no tl;dr version of it from me.

Why the title?

To explain the title of the post, I will go back a few years in my life. I grew up in a coal mine area of West Bengal, studied in the village’s Bengali medium school. During school days, I was very much interested in learning about Science, and kept doing random experiments in real life to learn things. They were fun. And I learned life lessons from those. Most of my friends, school teachers or folks I knew, kept telling me that those experiments were impossible, or they were beyond my reach. I was never a class topper, but once upon a time I wanted to participate in a science exam, but the school teacher in charge told me that I was not good enough for it. After I kept asking for hours, he finally said he will allow me, but I will have to get the fees within the next hour. Both of my parents were working, so no chance of getting any money from them at that moment. An uncle who used to run one of the local book stores then lent me the money so that I could pay the fees. The amount was very small, but the teacher knew that I didn’t get any pocket money. So, asking for even that much money within an hour was a difficult task. I didn’t get a high score in that examination, but I really enjoyed the process of going to a school far away and taking the exam (I generally don’t like taking written exams).

College days

During college days I spent most of my time in front of my computer at the hostel, or in the college computer labs. People kept laughing at me for the same, batchmates, juniors, seniors, or sometimes even professors. But, at the same time I found a few seniors and friends, and professors who kept encouraging whatever I did. The number of people laughing at me were always higher. Because of the experience during school days, I managed to ignore those.

Coming to the recent years

The trend continued through out my working life. There are always more people who kept laughing at everything I do. They kept telling me that the things I try to do, do not have any value and beyond my limit. I don’t see myself as one of those bright developers I meet out in the world. I kept trying to do things I love, tried to help the community whichever way possible. What ever I know, I learned because someone else took time to teach me, took time to explain it to me. Now, I keep hearing the similar stories from many young contributors, my friends, from India. Many times I saw how people kept laughing at my friends in the same way they do at me. They kept telling my friends that the things they are trying to achieve are beyond their limit. I somehow managed to meet many positive forces in my life, and I keep meeting the new ones. This helped me to put in my mind that we generally bound ourselves in some artificial limits. Most of the folks laughing at us, never tried anything in life. It is okay if we can not write or speak the perfect English like them, English is not our primary language anyway. We can communicate as required. The community out there welcomes everyone as they are. We don’t have to invent the next best programming language, or be the super rich startup person to have good friends in life. One can always push at personal level, to learn new things. To do things which makes sense to each of us. That maybe is totally crazy in other people’s life. But, it is okay to try things as you like. Once upon a time, during a 1x1 with my then manager (and lifelong mentor) Sankarshan Mukhopadhyay, he told me something which remained with me very strong to this day. We were talking about things I can do, or rather try to do. By taking another example of one of my good friends from Red Hat, he explained to me that I may think that my level is nowhere near to this friend. But, if I try to learn and do things like him, I may reach 70% level, or 5% or 50%. Who knows unless I try doing those new things. While talking about hiring for the team, he also told me about how we should always try to get people who are better than us, that way, we always will be in a position to learn from each other I guess those words together changed many things in my life. The world is too large, and we all can do things in our life at certain level. But, what we can do depends on where we draw those non-existing limits in our lives.

The Python community is one such example, when I went to PyCon US for the first time in 2013, the community welcomed me the way I am. Even though almost no one knew me, I never felt that while meeting and talking to my life time heroes. Funny that in the same conference, a certain senior person from India tried to explain that I should start behaving like a senior software engineer. I should stand in the corner with all the world’s ego, and do not talk to everyone the way I do. Later in life, the same person tried to convince me that I should stop doing anything related to community as that will not help me to make any money.

Sorry, but they are wrong in that point. I never saw any of my favorite human beings doing that. Does not matter how senior people are, age or experience wise, they always listen to others, talk nicely with everyone. Money is not everything in life. I kept jumping around in PyCon every year, kept clicking photos or talking with complete strangers about their favorite subjects. Those little conversations later become much stronger bonds, I made new friends whom I generally meet only once in a year. But, the community is still welcoming. No one cared to judge me based on how much money I make. We tried to follow the same in dgplug. The IRC channel #dgplug on Freenode is always filled with folks from all across the world. Some are very experienced contributors, some are just starting. But, it is a friendly place, we try to help each other. The motto of Learn yourself, teach others is still very strong among us. We try to break any such stupid limits others try to force on our lives. We dream, we try to enjoying talking about that book someone just finished. We discuss about our favorite food. I will end this post saying one thing again. Do not bound yourself in some non existing limits. Always remember, What a great teacher, failure is (I hope I quoted Master Yoda properly). Not everything we will try in life will be a super successful thing, but we can always try to learn from those incidents. You don’t have to bow down in front of anyone, you can do things you love in your life without asking for others’ permissions.