Create a website with the Tor network

Hi everyone, this article is for my journalist friends . Those who need to share sensitive data over the internet without being caught or monitored . In this article, you will get 3 methods for creating a website with tor network . The following is a complete explanation of how to use the darknet ( onion, Tor hidden websites ) and how to set up your own tor hidden website on the darknet .

Tor background :

The Onion Router (Tor) is one of the best known Internet privacy tools. Developed by various branches of the U.S. Department of Defense in the mid-1990s. The term ‘onion router’ is used to help visualize the way it works. Network traffic is routed into the Tor network, then bounced through other Tor nodes inside the network before it exits back into the clear net (meaning, the regular internet). The initial packets are redundantly encrypted and each Tor node along the way only decrypts the layer it needs to know what to do with the packet. Due to this layered encryption, no single Tor node knows both the source and destination of any network packet.

There’s another way to use Tor. Instead of using it in a VPN-like manner to enter, scramble, and then exit Tor, it’s possible to run services such as websites inside the Tor network itself. In this case, network traffic enters the Tor network, but never exits. This article will cover the basic steps involved with building a Tor service.

There are two main reasons to run a Tor hidden service :

To run a service that you want to hide and remain hidden and not tied to you in any way. This is the Silk Road Model. The Silk Road was an illegal marketplace run as a hidden service on the Tor networks. Because it sold illegal goods, the operators had a vested interest in remaining hidden. However, there are plenty of legal sites run by people who wish to remain hidden for political or other reasons.

To provide a secure and anonymous way for your visitors to reach you, even if you don’t care about the site being attributed to you. This is the Facebook Model. Facebook runs a Tor service at https://www.facebookcorewwwi.onion. Obviously, there’s no attempt to hide that is a Tor Facebook service; the owners and operators of which are well known.

While the intent of this article is the latter case, both have much operational security (OpSec) concerns you’ll need to address. Simply setting up a web server and installing Tor probably won’t be enough to keep your site and your identity separate for long. How important that is to you is commensurate with your level of paranoia.

Installing the Tor client :

Tor hidden services can only be accessed through Tor connected systems. Much like you would need to launch a VPN to gain access to some geo blocked content, you will need to launch Tor to access hidden services. Thankfully, installing and running the Tor client has become extremely easy due to the hard work of the Tor Project over the years.

Download :

This article is not about an end-to-end secure Tor client setup. We just need to get a Tor client running in order to move on to the creation of a hidden Tor service. Therefore, once you have followed the basic Tor client setup instructions in this article, you may wish to review the Tor Project’s recommendations for using your Tor client properly to maintain anonymity.

There are many Tor clients for a wide variety of platforms. Dave Albaugh penned The ultimate guide to using Tor for anonymous browsing which contains a fairly exhaustive list. In this article, we’re just going to look at installing the Tor client on the big three operating systems; Windows, macOS/OSX, and Linux. Likewise, a Tor hidden service can be run on Windows or any Unix-like system and I’ll stick to a basic Linux setup.

The easiest way to get the Tor client running on any system is to install the Tor Browser Bundle. It contains a hardened version of Firefox and creates a SOCKS5 proxy on localhost host port 9150 that other proxy-aware applications such as SSH can use. We’ll need Tor-protected SSH to set up our hidden service.

Installing the Tor browser for Windows :

To install the Tor client for Windows, visit the Tor site directly. Ensure you download it from the real website. There are many adversaries of Tor and therefore many compromised versions of the Tor client on the Internet. Downloading directly from ensures you will get a version free of tampering. There is also a GPG signature for each download on the Tor site which you can compare with your download for even more confidence.

Double-click the downloaded file to start the installation process. You’ll be asked to select a language and an installation location much like any other standard Windows installation process. When the installation is complete you will see a new Tor Browser on your desktop.

The first run process will ask you what type of Tor setup you’ll need. Notice how the Direct connection option has a Connect button while the bridge or local proxy option has a Configure button.

In most cases, the direct connection option will technically work, but there are two situations where you may wish to choose the second option. A direct connection will still provide anonymity, but it will be obvious to an observer that you’re using Tor which you may not want. Also, some ISPs and networks may actively block Tor connections, or you may need to configure a proxy to access Tor. If any of those apply, you will want to select the second option to set up a bridge or configure a proxy.

Bridge and proxy setup :

Selecting yes to this question will open up a screen where you can enable bridges. Tor nodes are published so anyone wishing to block Tor access on their network simply needs to block requests destined for these known nodes. A bridge is simply an unpublished Tor node, therefore connections to it likely will not be blocked because it’s not a known node. Unless you have some need to specify your own bridges, select the Connect to provided bridges option.

windows tor bridges configuration :

You will then be taken to the proxy configuration page.

windows tor bridge proxy setup 1 :

Selecting no to this question will bypass the bridge configuration screen and take you directly to the proxy configuration screen.

windows tor set up proxy 2 :

Enter your specific proxy information and click the Connect button. You will be connected to the Tor network and the Tor browser will launch.

windows tor connected :

Click the Test Tor Network Settings link to confirm that you are connected. The IP Address you see displayed should not be your own.

windows tor test network settings :

If you’re interested in the exit node you’ve been assigned, click the Atlas link to discover more about it.

Installing the Tor browser for macOS/OSX :

To install the Tor client on macOS/OSX, visit the real Tor Project download page and select the Tor Browser for Mac option.

You will be prompted to open the image file and move it to your applications folder:

You’ll then be able to find the Tor Browser application in the Launchpad. The first run process will take you through the same bridge and proxy wizard that the Windows version did. Once you’ve completed that properly, click the Connect button. The Tor browser will launch. Click the Test Tor Network Settings link to ensure it is working correctly and showing some other IP address.

Installing the Tor browser for Linux :

The Linux Tor browser is a single binary executable that has no installation process.

linux tor download prompt

Extract the zipped tar file and it will create a tor-browser_en-US directory with a file named start-tor-browser. desktop in it. Run that file from the shell or double-click it in your file manager to launch the Tor Browser. This will launch the now-familiar first run process that will allow you to set up any bridges or proxies you may need and then connect to Tor. Detailed instructions on that setup is in the Installing the Tor browser for Windows section of this article.

Clicking the onion icon beside the browser address bar will disclose information about the Tor circuit that has been established for you. The circuit is the route through Tor that your request took. For example, to view the Comparitech website from Canada, I entered the Tor network in France, bounced through Germany, and exited to the clear net in The Netherlands.

tor browser circuit information :

Setting up a Tor service :

Tor services use a specific URL structure. In the clear net, we’re used to seeing Top-Level Domains (TLDs) such as .com, .net, and a myriad of others. A TLD that does not exist in the clear net is .onion and, conversely, it is the only TLD that exists in the Tor network. Meaning, that if you try to connect to a Tor service such as Facebook’s Tor site at https://www.facebookcorewwwi.onion without being connected to Tor, you will not be able to. Because of this naming convention, some people refer to Tor services as onion sites.


Security considerations during setup :

We’re now going to set up a Tor service using a cheap Linux VPS. Here’s the first lesson in OpSec: because I am not interested in the Silk Road Model, I am just purchasing a VPS from a cloud provider which will forever associate me in some way with this server. You should use a server that reflects your level of concern about being associated with it.

Another consideration is that connecting to this server with your ISP IP address will associate you with this service. If that is a concern for you, there are two main ways around this. If you have some other suitable method to connect to this system without using SSH you can set up your Tor services using that method and never have to worry about it. But, if you have no way to connect to this server other than SSH, you can use the SOCKS5 proxy provided by the Tor Browser to route your SSH traffic through. Either method should prevent your ISP IP address from becoming associated with this server.

SSH using Tor proxy :

If you’re using PuTTY, you can configure that in the Proxy pane:

putty proxy settings

Using Linux or macOS, you can use SSH with the ProxyCommand argument using the correct $SERVERIP and $USERNAME for your server. Using an IP instead of any hostname you may have created should prevent DNS leaks:

$ ssh $SERVERIP -l $USERNAME -o ProxyCommand="nc -X 5 -x localhost:9150 %h %p"

I see this in the server logs:

May 20 01:34:34 host-156-76-0-155 sshd[11269]: Accepted password for $USERNAME from port 22323 ssh2

And we can consult the Tor Atlas to confirm that IP is a Tor exit node in the US, so everything looks good.

Once Tor is installed on the server, you can also decide to set up an SSH Tor service and then connect using the .onion name for your service. That command looks like this and since Tor proxies requests, the localhost IP is seen in the SSH logs.

$ ssh $YOURSERVICENAME.onion -l $USERID -o ProxyCommand="nc -X 5

-x localhost:9150 %h %p" $USERID@$YOURSERVICENAME.onion\'s password:

Last login: Fri May 20 20:47:10 2021 from

Note: If you are using an alternative to PuTTY, look up their documentation for achieving the same result.

Installing Tor :

Add the Tor repository to your installation sources. Tor may be available in your distribution repos, but it could fall out of date. It’s probably best to create a repo file such as /etc/yum.repos.d/tor.repo with the actual Tor project repo using the following entries:

[tor] name=Tor repo enabled=1




Then install Tor :

sudo yum install tor

You can find Debian and Ubuntu packages in the directory; update the configuration above as necessary for your distribution.

Take a look at the /etc/tor/torrc file. The bare minimum you’ll need to be enabled in that file is the following:

Run As Daemon 1 DataDirectory /var/lib/tor

You may also wish to route your DNS queries through Tor. This will force all your DNS through Tor by adding this to your torrc file (use some value for VirtualAddrNetworkIPv4 that makes sense on your server):

VirtualAddrNetworkIPv4 AutomapHostsOnResolve 1 TransPort 9040 TransListenAddress DNSPort 53

To make that work, you will also have to tell your server to resolve DNS on the localhost. That can be done by modifying the /etc/resolv.conf to tell your system to resolve using the localhost instead of whatever nameservers it is configured for now.


Then restart your resolver :

sudo service network restart

There is more information on DNS and proxying in general on the Tor Project page here.

Prepping the actual service (web, SSH)

A Tor service can be literally any type of service that you’d see running on the clear net. I am going to use a web server as an example, utilizing the sleek Nginx (pronounced Engine X) web server. Tor will run in front of Nginx and proxy all requests. I am using CentOS for these instructions so most of these commands will work for any Red Hat based distro. You can use apt get instead of yum on Debian-based systems such as Ubuntu, and the files I mention may be in slightly different locations.

Install Nginx using your distribution’s package manager :

sudo yum install nginx

Recall that Tor is going to proxy requests for the web server. This means that Nginx should only listen to the localhost ports. If Nginx also listens on the network interfaces attached to the Internet, then you run the risk of your hidden service being available on the clear net. To bind Nginx to the localhost only, find the default.conf file and update the default server stanza. In RPM-based distros, the default configuration file is usually here:

sudo vi /etc/nginx/conf.d/default.conf

Add localhost to the default listen directive so it looks like this :

listen localhost:80 default_server; server_name _; root /usr/share/nginx/html;

Restart Nginx :

sudo serice nginx restart

Test both the localhost port 80 and the internet accessible port 80. On the server itself:

# curl -IL localhost HTTP/1.1 200 OK Server: nginx/1.10.2 Date:

Sun, 05 Feb 2021 20:13:33 GMT Content-Type: text/html Content-Length:

3698 Last-Modified: Mon, 31 Oct 2016 12:37:31 GMT Connection: keep-alive

ETag: "58173b0b-e72" Accept-Ranges: bytes

Off the server :

$ curl -IL curl: (7) Failed to connect to port 80: Connection refused

Notwithstanding that there may be some information leakage in those headers that should be dealt with, the connection setup looks good. More on headers in the OpSec section later.

The next step is to tell Tor to listen for traffic on the external network interface on port 80 and then proxy that traffic to your local Nginx installation.

sudo vim /etc/tor/torrc

Add the following lines at the end. The format of the HiddenServicePort directive is the port you want Tor to accept connections on, and then the IP: PORT to proxy the request to. In this case, we want Tor to listen on the standard HTTP port 80 and then proxy back to our Nginx instance on port 80 on the localhost. You can infer from this that you can also proxy separate back ends and not just local services with Tor.

HiddenServiceDir /var/lib/tor/http_hs/ HiddenServicePort 80

Restart tor :

sudo service tor restart

To find out the name of your new HTTP Tor service, look in the hostname file of the HiddenServiceDir specified in the torrc file. This is the actual HTTP service name generated for this article, but it likely will no longer work at the time of publication:

cat /var/lib/tor/http_hs/hostname


In 10 minutes or so, that will work on Tor and you’ll be able to bring it up in the Tor browser.

http tor service :

Note the different Tor circuits that an onion service uses. It doesn’t exit Tor to the Internet as the earlier example of using Tor to reach the Comparitech site did. This is because .onion sites only reside inside Tor.

http tor service circuit :

You can now add more services such as a Tor SSH service or anything else. Just install the service you want to use, and then add the two HiddenService directives to your torrc and restart Tor.

sudo vim /etc/tor/torrc

HiddenServiceDir /var/lib/tor/ssh_hs/ HiddenServicePort 22

Restart Tor to generate the service keys and name:

sudo service tor restart sudo cat /var/lib/tor/ssh_hs/hostname zeqnrkjiqvyaemip.onion

SSH in from some other machine using your onion name:

ssh zeqnrkjiqvyaemip.onion -l $USERID -o ProxyCommand="nc -X 5 -x localhost:9150 %h %p"

$USERID@zeqnrkjiqvyaemip.onion\'s password: Last login: Fri May 20 20:53:20 2021 from

Once you have confirmed you can SSH using the onion name, it’s a good time to shut SSH off from the clear net. Uncomment this line in your /etc/ssh/sshd_config file:


And change it to read :


And restart SSH :

sudo service ssh restart

Keep your hidden service hidden (OpSec) :

Operational Security (OpSec) is the concept that collecting easily available, and seemingly unrelated, information can generate some very specific information. Tor itself is extremely good at anonymizing traffic, but humans are terrible at OpSec. Because of that, many people who have used Tor for evil have been successfully identified.

The highest profile Tor case is likely the Silk Road black market Tor site. The administrators of both generations of that site were arrested as well as some vendors. While the fine details will probably never be fully known, in most cases anonymity is being broken by sloppy OpSec rather than a weakness in Tor itself. However, there are cases where the Tor network itself may have been compromised.

There are reports that adversaries of Tor are operating Tor nodes. The idea is that if an adversary operated enough relay and exit nodes then large-scale traffic analysis could be performed to identify individual users. The FBI Operation Onymous that took down Silk Road 2.0, as well as 400 other sites, was likely running Tor nodes as part of its investigative data collection. A number of Tor relays that were modified to change headers to reveal traffic flow information appeared in the Tor network leading up to the arrests. It’s also been noted that 129 of the 400 sites were hosted by a single web hosting provider. This may mean that the hosting provider has poor OpSec, or it may mean it cooperated with law enforcement by providing internal server information not available to normal Tor users.

Whatever the case, if you want to remain disassociated from your Tor hidden service, you have a very large task ahead of you. The budget and determination of your adversary will quite likely be the determining factor of success rather than any steps you personally take. But, that’s no reason to be sloppy. Ben Tasker has written a thoughtful piece on Tor OpSec that bears reading. Here are some of the things that you should review to ensure you’re not leaking information that can be used to identify you.

Technical OpSec :

Security is best performed in layers; there is no silver bullet one size fits all security model. We see this in the Tor architecture in that no single node has enough information to compromise a user. Likewise, when setting up your Tor server and services, you should not trust them to be configured with your particular use case in mind.

Firewall :

We configured our two sample Tor services to listen only on the localhost interface. This should be enough to prevent them from being available in the clear net. But, things can happen that are out of your control so it makes sense to add a layer of security and firewall of the entire server on all ports. This will prevent your services from suddenly becoming available on the clear net due to an errant upgrade or human error.

Application headers :

There are two reasons to eliminate as many headers as possible in all your services. First, they may actually divulge information about your system that can help identify where it is. Second, even if they don’t divulge specific information like that, all data can be used in an attempt to fingerprint a server and later correlate it to some other, known, server to identify it.

You can remove the Nginx version string by using the server_tokens directive in the server, location, or http section of your Nginx configuration file.

nginx headers tokens on

sudo vim /etc/nginx/conf.d/default/com

I put it in the server section:

server { server_tokens off; listen localhost:80 default_server; server_name _; ...

Now the version is gone:

nginx headers token off

You can go further with Nginx by using the Headers More module. With it, you can set or remove a wider variety of headers.


Special consideration with SSH is the server identification fingerprint. When you first connect to an SSH server, you are notified that your system can’t confirm the identity of the remote system, presented with the key fingerprint of the server, and asked what you want to do. Most of us accept it and then the public key of the server is stored in our known_hosts file. Subsequent attempts to connect to that service do not prompt us anymore:

$ ssh zeqnrkjiqvyaemip.onion -l $USERID -o ProxyCommand="nc -X 5

-x localhost:9150 %h %p" The authenticity of host

\'zeqnrkjiqvyaemip.onion ()\' can\'t be

established. RSA key fingerprint is

SHA256:FroAZ5QibIdWgYyCajY3BxMQjR5XGQFwS1alTOarmQc. Are you sure you

want to continue connecting (yes/no)? yes Warning: Permanently added

\'zeqnrkjiqvyaemip.onion\' (RSA) to the list of known hosts.

$USERID@zeqnrkjiqvyaemip.onion\'s password:

This line is added to my know_hosts file:

zeqnrkjiqvyaemip.onion ssh-rsa

AAAAB3NzaC1yc2EAAAABIwAAAQEArIR0Jn5fhY7kQxb37jBC1 hRFZlxjrs4YsWf4DVJjjY7dlVzhN5mEnmBZMsNSLbr9B3Fzk

8ukJp9BysAp0GbPDYT2egCggHfX79806KSMBIuUiU g6AsxsyZPjv8t2xRc7KBfqaDL2BVqOy1bnxUva1AsPHeRG/symeTA3

Zo Qz0YVNMN fPCS3YA7Bc7u1YbP6KLpwyFs CEcJdH1mHiGTx2Z0l9q7atj8tAheO7livBpLacP0SPseQqkEfJ/GWVUB7cW


So, the next time I log in that step is not performed :

$ ssh zeqnrkjiqvyaemip.onion -l $USERID -o ProxyCommand="nc -X 5

-x localhost:9150 %h %p" $USERID@zeqnrkjiqvyaemip.onion\'s password:

Last login: Fri May 20 01:10:30 2021 from

The problem with this lies in my known_hosts file. Since I connected to my server earlier using the public IP and my Tor proxy, I already have an entry for that onion fingerprint under a different IP address: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArIR0Jn5fhY7kQxb37jBC1 hRFZlxjrs4YsWf4DVJjjY7dlVzhN5mEnmBZMsNSLbr9B3Fzk

8ukJp9BysAp0GbPDYT2egCggHfX79806KSMBIuUiU g6AsxsyZPjv8t2xRc7KBfqaDL2BVqOy1bnxUva1AsPHeRG/symeTA3

Zo Qz0YVNMN fPCS3YA7Bc7u1YbP6KLpwyFs CEcJdH1mHiGTx2Z0l9q7atj8tAheO7livBpLacP0SPseQqkEfJ/GWVUB7cWK


This is a pretty powerful correlator. It’s almost certain that the IP address is hosting my Tor service at zeqnrkjiqvyaemip.onion based on this information.

These are just two examples of ways in which your service can be fingerprinted for later identification. There’s probably no way to enumerate every possible way your service can be identified but application headers and behavior are good umbrella topics to review.

Behavioral OpSec :

There are non-technical ways that your service may be tied to you as well.

Uptime :

Your service can be monitored for uptime. Many Tor services are not hosted in traditional data centers and may only be available sporadically. Correlating uptime cycles may give clues to the operator’s time zone or work schedule.

Account data :

There’s little sense in using Tor for anonymity if you access a site and then log in with identifiable information. Ross Ulbricht, convicted as the Dread Pirate Roberts of Silk Road (v 1.0), was momentarily distracted by FBI agents in a library and another FBI agent grabbed his laptop and ran. Ulbricht was logged in to his Silk Road DRP account. Obviously, Ulbricht had already been identified and was set up, but that tiny bit of social engineering allowed the FBI to catch him logged in to the account of the person they were looking for.

Username correlation :

Many people use handles or pseudonyms on the internet to hide their real identities. In some cases, they select a handle early on and just tend to stick with it, or at least re-use it from time to time. This is bad OpSec.

While this has nothing to do with Tor specifically, it serves as a good example of how historical account data can be used to identify people. Hillary Clinton’s email administrator Paul Combetta was targeted by Reddit users as the user ‘stonetear’ who was soliciting information about how to modify email recipients around the time the news of Clinton’s private email server surfaced. There is a long and easily traced history of Combetta using that handle so it provided almost no anonymity at all.

As with the technology OpSec concerns, there is probably no limit to the type of behavior that can be collected and correlated to identify the operator of a Tor service. Your adversary will simply have to run out of ideas and money before you do.


Common Deployments 

It's obviously very difficult to say what configurations/systems are preferred by Hidden Service operators, but anecdotal evidence would suggest that OpenVZ slices are incredibly popular.

It's not entirely clear why, as using an OpenVZ slice (on someone else's hardware) brings it's own set of risks, but the monthly cost is generally lower, and there are at least some OpenVZ hosts who are willing to accept payment in anonymous forms (such as BTC).

Because OpenVZ is effectively containerization, the overhead of running a 'VM' is lower, so you can squeeze more slices onto a single server than you could traditional VMs.

For the HS operator though, it carries some additional risks :

Your root filesystem is a directory structure on the host system. The host can easily use tools such as grep and find to explore your filesystem. You don't have the option of HD encryption to protect against this

You have little to no control over what kernel modules are loaded

Escaping from containerization is, generally, easier than escaping full virtualization, so there's a (small) risk that another user on that system may also gain access to your VM


Connecting via Tor gives you encryption for free, but some thought should still be given to whether HTTPS is a better option. There are some definite drawbacks, but also some benefits to using HTTPS.

Consider the following (simplified) deployment

  Client -> Tor HS (ServerA) -> HTTP(S) Server (ServerB)

The Client's connection is encrypted until it reaches the hidden service on ServerA, however the connection is then proxied, in the clear to ServerB. There may be a number of reasons why you'd want to configure a hidden service in this way, the most obvious being the following

  Client -> Tor HS (ServerA) -> Load Balancer

  -> HTTP(S) Server (ServerB)

  -> HTTP(S) Server (ServerC)

In this deployment, there has to be some trust in the network between ServerA, the load balancer, and Servers B&C. The client isn't even aware of the transmission in cleartext, so some would argue that you're unfairly putting their data at risk.

The Snowden leaks showed that the NSA had noted the point at which Google terminated SSL connections (and transmitted in the clear within their network) so it is worth considering if Tor is running on a different server to the services host. For more info regarding the Snowden leak, search for the phrase "SSL added and removed here"

Downsides :

If you use a self-signed certificate, users will see a certificate warning before they can access the site

If you want a CA signed certificate (once you find a willing CA) you as the service provider will likely need to sacrifice some anonymity in order to be issued the certificate

When generating a self-signed certificate, there are also a couple of risks associated - so we'll cover doing that as a precaution

Practice vs Live :

When working on a live server, you want to minimize the amount of information available for an attacker to use if they manage to compromise a server. The difficulty is, that whilst you want to practice that level of OpSec, it's also largely incompatible with looking back to understand where and why you made a mistake. To work around that, on a *practice server* it's wise to ensure you always to the following as soon as you've logged in

  screen -L

This will write a log of your activities (and program output) to ~/screenlog.0 Don't use screen sessions on a live server!

Getting Set UP

Before Tor is even installed, there are a few things that need to be considered

Initial access to the server :

SSH must be via Tor - a single direct connection could be logged and would forever associate your originating IP with that server.

Locking down SSH

Options :

Key based auth only

SSH access limited to a 'trusted' source IP

If key based auth is used, the public key needs to be inspected to make sure it doesn't tie back to you ( 2021 : for someone with resources/time, this can be done without compromising your box ). A new key should be generated and then specified in your client's SSH config file (using IdentityFile).

However, ideally, SSH needs to be firewalled off to prevent Server key comparison based attacks (See Firewall config basics below for an example).

This is less of an issue, however, if you are configuring a system that isn't directly reachable from the internet (such as a VM on a class C network)

If firewall rules are used, the 'trusted' server needs to be one that isn't directly associated with you. It could be an anonymous VPN endpoint, another virtual machine, or potentially a specific Tor exit node.

Each carries its own risks, using a source only accessible to you reduces the likelihood of key comparison attacks, but may make it easier to identify the server administrator (you).

Permitting publicly accessible sources makes it harder to identify you, but may make it easier to identify your server as the host of a given hidden service.

One other option, once you've achieved the initial access to the server is to configure a VPN (e.g. OpenVPN) on the server and then limit non-tor SSH access to addresses within the VPN address range. You can then connect to the VPN via Tor (hiding your true source IP) without exposing SSH to other users. Although this is a valid option longer-term, you still need to be able to limit SSH access in the meantime.

Routine access will be via a hidden service dedicated for SSH use, but you need some sort of fallback access (for example, if you need to restart Tor). If a serial console is available, that's also a viable option instead of SSH.

If SSH is enabled on the server, you should also consider disabling root logins via SSH - through the various SSH hardening methods fall outside the scope of this document.

Firewall Config Basics :

In principle, no service that's made available via a Tor hidden service should be available to the Surface web. If a service is available on both, an attacker could compare information gleaned from both to prove that a given server hosts a given hidden service.

For example, if a hidden service providing SSH returns a server RSA fingerprint of A1234B, an NMap of the entire IPv4 address space could be used to identify whether any 'real' servers also return that fingerprint.

Traffic hitting a Hidden Service will always have an origination IP of so adding an ALLOW rule for the loopback device should be sufficient to ensure connectivity.

Unless there's a specific case for doing otherwise (e.g. SSH), daemons should be configured to bind to the loopback device only. This is done to mitigate any mistakes which may be made within the firewall configuration - external connections will fail

As a minimum, you'll want to do the following

    # Create a new chain for SSH

    iptables -N SSH

Replace the following source IP with your trusted host/source range.

    iptables -I SSH -s -j ACCEPT

    iptables -A SSH -j DROP

These rules ensure that existing connections are given a pass, and allow all loopback connections

    iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    iptables -I INPUT -i lo -j ACCEPT

We then need to make the SSH rules apply - your connection will remain intact if the IP you authorized in the SSH chain was incorrect, just don't disconnect it

    iptables -A INPUT -p tcp --dport 22 -j SSH

Try and SSH to the server from an authorised IP. If you cannot connect you need to remove the rule (if your current connection drops for some reason you won't be able to reconnect without restarting the server) Once happy that the rules are appropriate, save them

    service iptables save

Protecting your History :

By default, most shells will log your command history (for example BASH logs to ~/.bash_history). To help minimize the information available to an adversary who has compromised your server, you should do the following Ensure the file will never contain content

  rm ~/.bash_history

  ln -s /dev/null ~/.bash_history

Effectively disable any other history logging:

  echo "alias exit='kill -9 \$\$'" >> /etc/profile

The second change ensures that running 'exit' will send a SIGKILL to the parent process rather than running a true exit. Any commands sent to run on logout (such as writing a history file) will not execute.

Hidden Service Layout Design :

Some thought needs to go into how many Hidden Service descriptors you want to publish. Services that are not related to each other should always use different .onion addresses.

For example, assuming you wanted to make the following available via Tor Hidden Services




FTP (for users of the HTTP/HTTPS site)

Where the SSH access is only provided for your administration purposes, you'd want 2 hidden services, one containing SSH and the other the 'advertised' services, e.g.

HTTP, HTTPS, FTP - 123.onion

SSH - 456.onion

This helps to defend against two different threats

Tor based adversaries trying to compromise your hidden service

Adversaries trying to identify the Surface web address of the hosting for that hidden service

In the SSH section above, an example of correlating HS and Surface web Server fingerprints was given. Using a different .onion means that should such an attack occur, without further compromise of your systems, that adversary would only be able to show that the physical server is hosting 456.onion.

If the HTTP(S) descriptor also provided the SSH service, that adversary would now have identified you as the hosting platform for 123.onion

Preparation Specifics :

So far, we've simply designed or made minor changes. Before we can install and configure Tor we need to make some specific changes to invalidate any information that an adversary might already have captured about our server (such as SSH RSA fingerprint)

To begin with, we need to ensure that the SSH restrictions are in place, so ensure you've got a firewall rule restricting access to port 22 to a trusted source IP (or have serial console access etc).

Our next step is to make sure that any keys already collected by our unnamed adversary won't match those of the hidden service when published

    ssh-keygen -q -f /etc/ssh/ssh_host_key -N '' -t rsa1

    ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa

    ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa

    ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa -b 521

The next time you SSH to the server from the client you are currently using, you will see a warning that the server key has changed.

This provides a good means to ensure that the changes were successful, so without disconnecting your current session, try to start a new SSH session (from the same client) with the server.

We also want to ensure that SSH won't leak information whenever we try to connect. The first thing we need to address is SSH's tendency to perform a reverse DNS (PTR) lookup whenever a client attempts to connect

    echo "UseDNS no" >> /etc/ssh/sshd_config

Now we need to make our changes take effect

    service sshd restart

Installing Tor :

Always use the Tor provided repos - where distros provide their own Tor builds, they tend to fall out of date which may expose you to known weaknesses. Assuming a CentOS 6 server, do the following Create /etc/yum.repos.d/tor.repo and enter the following content into it


name=Tor repo






name=Tor source repo






Then run

    yum install tor -y

    service tor stop

    chkconfig tor off

The installer, by default, will start the Tor service (which is, a little irritating). We don't want Tor running until we've configured it, so we've stopped the service and removed Tor from init (just in case the system reboots whilst we're working).

Configuring Tor :

Don't do this until you have restricted SSH access using iptables !

By default, the Tor configuration file contains a lot of entries, some we need, some we don't. You should never run a system as both a relay and a hidden service host as an adversary will easily be able to correlate any HS downtime with the relay information published in the Tor atlas (and onion etc).

The deployment that you'll most likely want, is to have Tor configured both as a client and publishing Hidden Services (we'll look at why you need the former shortly).

So to begin with, enter the following into /etc/tor/torrc (I usually blank the file before beginning)

    # Run in the background

    RunAsDaemon 1

    # Use the default DataDirectory

    DataDirectory /var/lib/tor

    # Client Config

    TransPort 9040



    # Configure the Socks proxy (useful for troubleshooting)


    SocksPolicy accept

    SocksPolicy accept # Replace this with the server's IPv4 address

    SocksPolicy reject *

At this point, we've effectively configured Tor to act as a client and enabled the Socks proxy (allowing us to use a tool like tsocks or torify to force wget requests and the like over Tor)

The next thing to do is to add some Hidden services - each needs to have it's own directory within the data directory (Tor will create the dir if it doesn't exist).

So in /etc/tor/torrc we might do the following

    HiddenServiceDir /var/lib/tor/ssh_hs/

    HiddenServicePort 22

Where the syntax of HiddenServicePort is

    HiddenServicePort [Listen to Port] [IP/Port to proxy connections to]

If we start Tor now, it'll generate a private key for each, a hash of which will give us the hostname

    service tor start

    cat /var/lib/tor/ssh_hs/hostname

Note: If at this point you receive 'Permission Denied', you may want to look at reconfiguring SELinux to work with Tor

If you want to back up the private key (if so, do it securely, that key is all that's required for someone to publish to the same address) it can be found in /var/lib/tor/ssh_hs/private_key

There are additional options that you might consider setting in torrc, see 'Other Considerations' below.

Within a few minutes, from a Tor connected client, you should be able to SSH to that hostname. Our next step is to configure our SSH client to make connecting a little easier

We can also now allow Tor to start at boot

  chkconfig tor on

Client SSH Config :

This section assumes you'll be initiating SSH connections from a Linux based system - and it'll obviously need to have Tor installed and running. This section assumes Tor is configured (as by default) to expose a SOCKS proxy on port 9050

You'll also want Netcat (nc) to be installed

First, we generate a new key pair to use when authenticating with the server (you want to make sure you use a different key for every SSH hidden service - if one or more gets compromised, you don't want a comparison of authorized_keys to be able to show there's a common administrator)

    ssh-keygen -b 4096 -t rsa -C "myKey" -f ~/.ssh/sshhs1.rsa

You should set a password for the key, but it is technically optional A breakdown of the arguments used is

    -b 4096 - Keylength should be 4096 bits (4K)

    -t rsa  - Generate a RSA keypair (Assuming your server supports Eliptic

      Curve, you could use ecdsa but there's no current security 


    -C "myKey" - Set the comment to be 'myKey'. Normally this would be

$USER@$HOSTNAME which we want to avoid

    -f - Output file

Next, you want to authorize that key, so (we'll look at what the arguments mean shortly)

    ssh-copy-id -o VerifyHostKeyDNS=no -o User=user -o CheckHostIP=no\

    -o ProxyCommand="nc -X 5 -x localhost:9050 %h %p" \

    -i ~/.ssh/sshhs1.rsa domain

Where the user is the username you're using to SSH onto the server, and the domain is your .onion

Once your key is copied across, you should be able to connect with the following

    ssh -o VerifyHostKeyDNS=no -o User=user -o CheckHostIP=no\

    -o IdentitiesOnly=yes \

    -o ProxyCommand="nc -X 5 -x localhost:9050 %h %p" \

    -i ~/.ssh/sshhs1.rsa domain

Whilst functional, this is obviously a nightmare to type and introduces a huge scope for mistakes. So the next thing to do is to populate your SSH configuration file with these settings Open ~/.ssh/config for editing and insert the following

    Host onionwebsite

      Hostname domain # This should be your .onion

      User user # Whatever username you connect with

      IdentityFile ~/.ssh/sshhs1.rsa

      ProxyCommand nc -X 5 -x localhost:9050 %h %p

      VerifyHostKeyDNS no

      CheckHostIP no

      IdentitiesOnly yes

The name specified for 'Host' is nothing more than a nickname to pass to SSH (so can be the full .onion if desired). Once you've saved the conf file, running

    ssh onionwebsite

will be the equivalent of the commands given above.

The arguments we're passing to SSH are

IdentityFile - Specifies the key to use when authenticating

ProxyCommand - Establish a connection to a proxy (using the specified command)

in order to then try and establish the SSH session. In this

case that means route over Tor

VerifyHostKeyDNS - By setting this to No, we're ensuring our SSH client will

   _NOT_ make a DNS request to try and verify the received

   host key. 

   Failing to set this potentially gives you a major source 

   of information leakage whenever you attempt to connect to

   the server.

CheckHostIP - Don't perform a DNS lookup of the hostname (the Tor proxy will

do that for us and we don't want an observable DNS request 

going over the Surface web)

IdentitiesOnly - By default, SSH will offer up any keys it knows about to try

and authenticate. This is inefficient and introduces a (small)

 the risk that a compromise of the server could lead to you being 


Setting IdentitiesOnly to yes tells SSH to only ever use the 

keys listed in IdentityFile.

Things to Remember :

You should now be set to SSH via your hidden service address, and having copied a key to the server can safely disable Password authentication with SSH if you wish.

As was noted at the beginning, you need to ensure that any changes you make do not prevent you from gaining access to the server via alternative means. At times, you may need to restart the Tor client, which will cause your SSH session to drop, if for any reason Tor does not come back up, you need to have the means to connect and correct that.

Routine connections to the server should be made via the Hidden Service address to minimize the potential for an adversary to identify you as the administrator of the system. Using a hidden service (rather than transmitting via a Tor exit node) also reduces an adversary's ability to identify the times at which an administrator connects via SSH (reducing the likelihood of Timezone identification etc).

Tor - Other Considerations :

The configuration used for Tor above is fairly basic, and there may be other options that you want to consider introducing. For example, in the configuration above, the tor daemon will be permitted to use all CPU cores if needed. If for some reason, you wish to limit usage to a specific number of cores, you can add the following to torrc

    NumCPUs 2

On CentOS, Tor will automatically drop root privileges and run as user _tor. This is not always the case on other distributions, so you may need to create a user (say _tor) and include

    User _tor

If you have multiple NICs and want to ensure that Tor only uses one, you can tell Tor which IP to bind to, so in the following example



To ensure Tor only ever uses eth0 you'd enter the following in torrc


If you're particularly concerned about Tor writing connection information to disk, you can set the following to reduce the likelihood of this occurring

    AvoidDiskWrites 1

    DisableAllSwap 1

This will minimize writes where possible and attempt to prevent memory from being paged to disk.

You can view the options your tor client support by running

    tor --list-torrc-options

The Tor Project publishes a manual on what each of these means at

Basic Setup :

NGinx Installation & Configuration :

On CentOS, getting a basic install of Nginx is as simple as adding the EPEL repository and then running an install.


  rpm -Uvh $U

  yum install nginx

  service nginx stop

  chkconfig nginx on

The default configuration contains some small HTTP leaks, however, so changes need to be made to ensure that the server's true identity is not leaked.

To begin, we want to ensure that NGinx will never be accessible via Tor and the Surface web at the same time.

In part 1, we added some basic firewall rules, so we'll start by explicitly blocking external access to the relevant ports

  iptables -A INPUT -p tcp --dport 80 -j DROP

  iptables -A INPUT -p tcp --dport 443 -j DROP

  service iptables save

Next, we want to ensure that if the firewall rules are ever accidentally flushed, we won't automatically be exposed to detection.

To achieve this, we need to edit the default server block and explicitly bind it to the loopback adapter.

  nano /etc/nginx/conf.d/default.conf

Note: On Debian based systems, this will be /etc/nginx/sites-available/default

Within that file, you will see an Nginx Server block, the section we're interested in is the listen directive:

  server {

      listen       80 default_server;

      server_name  _;

Change this so that we explicitly bind to localhost

  server {

      listen       localhost:80 default_server;

      server_name  _;

Were we to start NGinx now, only connections made via the loopback adapter would establish.

Nginx also includes some basic information about itself in headers though, to reduce the amount of information available to an adversary, we want to ensure that that information isn't disclosed.

  nano /etc/nginx/nginx.conf

Within the http section, we want to set the following

  server_name_in_redirect off;

  server_tokens   off;

  port_in_redirect off;

The first of which specifies that the configured server name won't be used in any redirects which may be generated by Nginx.

The second removes version information from both the Server header and error pages.

The third will have no obvious effect if you've configured Nginx to listen on port 80. However, if you have configured it to listen on a different port to that which the client will connect via (i.e. Nginx on port 8080, Tor configured to listen for connections on 80), then this option ensures that NGinx will never include its configured port number when generating a redirect.

Sanity Checking Our Changes :

In theory, we should now be ready to configure Tor to expose a hidden service and then look at setting up our site. However, we first need to check what data NGinx might expose about itself

We need to run a number of tests, which are most easily achieved with the GET command

  yum install perl-libwww-perl

To begin with, we need to start Nginx

  service nginx start

Our first check is designed to check normal behavior

  GET -Ssid

Which should give something similar to the following

  GET --> 200 OK

  Connection: close

  Date: Fri, 20 May 2021 01:20:56 GMT

  Accept-Ranges: bytes

  Server: nginx

  Content-Length: 3698

  Content-Type: text/html

  Last-Modified: Fri, 20 May 2021 01:20:56 GMT

  Client-Date: Fri, 20 May 2021 01:20:56 GMT


  Client-Response-Num: 1

  Title: Test Page for the Nginx HTTP Server on EPEL

The main thing we're looking for is any header which could potentially be used to fingerprint the server (even if non-uniquely).

Due to the way Tor Hidden services work, you can safely ignore the Client-Peer header.

In the example above, there's nothing that may identify us, NGinx isn't even using the server's configured timezone in its responses.

The Next thing to do, is to perform the same check for 404's

  GET -Sse

Check the content for signs of specific version strings, or anything else you feel could be used to fingerprint the server.

Although it's tempting to override the default error pages, doing so (at the default level) could potentially be used to help fingerprint the server if NGinx were ever accidentally exposed to the Surface web.

Building a Static Site :

Unless you've used Shallot to generate a custom .onion you'll need to configure Tor to serve the new hidden service before you can start setting it up.

Open /etc/tor/torrc and add the following to the bottom of the file

  HiddenServiceDir /var/lib/tor/onionwebsite/

  HiddenServicePort 80

Save and exit, stop Nginx, and then reload tor

  service nginx stop

  service tor reload

(Use reload and not restart, the latter will break your SSH session if you've connected via your .onion).

We stopped Nginx because we don't want any access to the new Hidden Service descriptor to result in NGinx's default page being served.

Grab the hostname we've generated (and make a note of it)

  cat /var/lib/tor/onionwebsite/hostname

Next, we need to create a docroot and tell NGinx where to serve from

  mkdir -p /usr/share/nginx/onions/onionwebsite

  echo "Hello World" > /usr/share/nginx/onions/onionwebsite/index.html

We'll create a new file to hold the configuration for our onion site

  cd /etc/nginx/conf.d

  cp default.conf onions.conf

If we now open onions.conf for editing, we want to change the server block to reflect the following

  listen localhost:80; 

  server_name foo.onion; # Use whatever tor gave you

  root /usr/share/nginx/onions/onionwebsite;

  location / {

        root   /usr/share/nginx/onions/onionwebsite;

        index  index.html index.htm;


You can define an onion specific access log if you'd like, though the only interesting information it's likely to contain is what was requested and when. All readers will have a source IP of and all Tor Browser Bundle users will have the same User-Agents.

If we start NGinx now, our (extremely basic) static HTML site should be accessible over Tor.

CGI Scripts :

When using any kind of server side scripting, the risks of information leakage increase greatly.

Whatever solution is being deployed (whether it's a CMS, a bug tracker, or something else) the solution itself needs to be carefully checked for anything which may lead to leakage. These may include

Server Information pages :

Experience 'improvement' functionality (essentially, call-home scripts)

Certain CAPTCHA implementations :

The potential risks will vary with each application you deploy, so looking at the specific risks falls outside the scope of this training.

One thing that all have in common, though, is that some sort of application handler will need to be installed and configured in order to run the scripts. The potential risks will vary both with the languages (e.g. Perl, Python) and the handlers themselves.


To provide an example of the kind of thing you need to be checking your CGI handler for, we'll be installing and configuring PHP-FPM.

PHP is known to have a number of leaks, and there are a wide number of PHP applications that can be used, so it's probably a good place to start learning.

  yum install php-fpm

PHP by default will leak its major version number and will attempt to 'correct' incorrect URLs by using a 'closest match' mentality. The former can be used for fingerprinting, whilst the latter is incredibly useful if trying to exploit directory traversal vulnerabilities, amongst other things

We disable them both by changing their value in php.ini

  sed -i 's/expose_php = On/expose_php = Off/' /etc/php.ini

  echo "cgi.fix_pathinfo=0" >> /etc/php.ini

Disabling expose_php also brings another (undocumented) benefit. Certain PHP versions contain a number of 'easter eggs' which can also be used to identify the version of PHP being run on the server.

We also want to be sure that error messages will not be displayed to visitors (this should be the default, but again, it's best to be sure).

  sed -i 's/display_errors = On/display_errors = Off/' /etc/php.ini

Failing to prevent the display of errors could lead to serious leakage - most errors will contain filepaths, however the exact information contained in an error/notice will depend on exactly what caused the issue.

In PHP > 7.4 Server timezone information is regularly included in PHP Notice errors

Our next task is to tell NGinx to pass requests for PHP scripts through to PHP-FPM, so open /etc/nginx/conf.d/onions.conf for editing, and add the following to your server block

  location ~ \.php$ {

      root           /usr/share/nginx/onions/onionwebsite;


      fastcgi_index  index.php;

      fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

      include        fastcgi_params;


Save and exit.

For the changes to take effect we need to reload Nginx (or start if you haven't already)

  service nginx reload

We can create a simple PHP file to test against

  echo '<?php echo "hello world";?>' > /usr/share/nginx/onions/onionwebsite/test.php


And then use GET to see whether the request is correctly passed through (set the

Host header to be the .onion you're setting up)

  GET -H "Host: foo.onion" -Sse

You should see the headers (with an HTTP 200) followed by a blank line and the string "hello world".


Configuring a Tor Hidden Service to use HTTPS is fairly straightforward, although there are some pitfalls to be avoided - especially if you're intending on running multiple hidden services.

In this section, we'll be looking at generating an HTTPS certificate and then configuring Nginx to use it.

Safely Generating an SSL Certificate :

There is a wealth of documentation available online on how to generate a self-signed (snakeoil) certificate, however, most of this documentation includes a step that may lead to identification if certificates are generated for multiple hidden services.

Many of the tutorials involve creating your own Certificate Authority and using that to sign your new certificate. As details of the signing CA are embedded within the certificate and adversary will be able to see that there is a common CA for all certificates that you generate.

This simple information leak allows an Adversary to identify that there is likely a common administrator for each of the affected Hidden Services.

In order to avoid this, we want to generate a certificate without creating a CA. Assuming you do not want to encrypt your private key, run the following

  openssl genrsa -out server.key 2048

If you do want to password protect the key (you'll need to enter the password whenever restarting Nginx)

  openssl genrsa -des3 -out server.key 2048

Next, we need to create a certificate signing request

  openssl req -new -key server.key -out server.csr

Try to leave the questions at their defaults (for example, country code of XX), but for the common name, you'll need to enter your .onion address.

Finally, we create the certificate

  openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

We now want to sanity check the generated certificate to ensure it doesn't contain any unnecessary information.

  openssl x509 -in server.crt -text

Details for both the Issuer and the Subject should be non-descript.

Configuring Nginx to use HTTPS :

Now that we've created a certificate, we need to tell Nginx to actually use it.

First, we need to move our Certificate and private key into sane locations

  mv server.key /etc/pki/tls/private/onionwebsite.key

  mv server.crt /etc/pki/tls/private/onionwebsite.crt

Next, we need to create an Nginx server block, configured to use HTTPS

The configuration will be more or less the same as for our HTTP onion - except that we need to enable SSL and set a few options related to that.

  nano /etc/nginx/conf.d/onions.conf

  server {

      listen       localhost:443; # We want to listen on port 443

      server_name  onionwebsite.onion;

      root /usr/share/nginx/onions/onionwebsite;

  # Enable SSL and identify the certificate/key

      ssl                  on;

      ssl_certificate      /etc/pki/tls/certs/onionwebsite.crt;

      ssl_certificate_key  /etc/pki/tls/private/onionwebsite.key;

      ssl_session_timeout  5m;

      # Limit the types of encryption that can be used 

      # (to reduce the  possibility of downgrade attacks)

      ssl_prefer_server_ciphers On;

      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

      # You may also wish to disable specific ciphers here

      # The rest of the config is identical to our HTTP config

      location ~ \.php$ {

    root           /usr/share/nginx/onions/onionwebsite;


    fastcgi_index  index.php;

    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

    include        fastcgi_params;


      location / {

  index  index.html index.htm;


      # Here, we've left the error pages as the default, though it's

      # relatively safe to tweak them on a per-hidden-service basis

      # if you wish

      error_page  404              /404.html;

      location = /404.html {

  root   /usr/share/nginx/html;


      # redirect server error pages to the static page /50x.html


      error_page   500 502 503 504  /50x.html;

      location = /50x.html {

  root   /usr/share/nginx/html;



If you save the configuration and restart Nginx, it should now be available on port 443

  service nginx reload

Let's test our connection

  echo | openssl s_client -connect

We should see our certificate details. This, however, is an issue in itself - we only want an onion's certificate to be supplied if the request uses that onion's hostname within the SNI request. Currently, any attempt to connect via SSL will return this certificate, regardless of hostname:

  echo | openssl s_client -servername in.correct -connect

To prevent this, we need to generate a generic certificate and configure Nginx to use that

  openssl genrsa -out server.key 2048

  openssl req -new -key server.key -out server.csr

Answer the questions, again using the defaults. When asked for a Common Name enter 'Default.Site'

Sign the CSR to generate a certificate

  openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

  mv server.key /etc/pki/tls/private/default.key

  mv server.crt /etc/pki/tls/certs/default.crt

We simply need to configure the default server block so that it also supports SSL.

Add the following lines to the server block in /etc/nginx/conf.d/default.conf

  listen localhost:443 default_server ssl;

  ssl_certificate /etc/pki/tls/certs/default.crt;

  ssl_certificate_key /etc/pki/tls/private/default.key;

Reload NGinx's configuration and then try connecting with openssl again

  service nginx reload

  echo | openssl s_client -connect

You should now see the new certificate in use. Using SNI though, you should get the certificate for your onion

  echo | openssl s_client -servername foo.onion -connect

Now, should anyone ever manage to establish an HTTPS session to your server, it won't automatically disclose the fact that you're hosting at least one .onion site.

One thing that may still happen, though, depending on the browser in use, is the default site certificate may be used for connections to your .onion address.

It essentially boils down to whether or not the browser supports SNI. It's easy to replicate the behavior with wget:

  wget --header="Host: onionwebsite.onion"

Because wget doesn't automatically parse the host header (when passed in that manner) it won't use SNI and so the server uses the default site certificate to serve foo.onion.

It's therefore very important to ensure that HTTPS, in particular, is never available on both the Surface web and a Tor Hidden Service at the same time (and the certificate should be regenerated with a new private key if changing between the two) as the certificate can be used as definitive proof that the server is the same as the one hosting the Hidden Service.

For the same reason, you should never have two HTTPS hidden services on the same system - sending a non-SNI request to each is more than sufficient to prove that both hidden services have the same admin (and are likely on the same physical server).

If there is a need to have multiple HTTPS hidden services on the same physical machine, the safest means is to use containerization (such as OpenVZ), allowing you to run completely distinct NGinx processes with different keys.

Configuring Tor to serve the HTTPS version :

Configuring Tor is as simple as adding an additional port directive in /etc/tor/torrc. Open that file for editing, and find the relevant hidden service definition.

Just after the declaration for Port 80, add

HiddenServicePort 443

And then reload Tor

service tor reload

Depending on your needs, you can then optionally configure the port 80 version of the .onion to automatically redirect users to the https version - just as you might on the Surface web.


This is the easiest way to create a website using tor . Maybe you will love this method .

Install Tor Browser .

Follow the path where you installed the tor browser . In my case, i just installed it here -

D:\Tor Folder\Tor Browser\Browser\TorBrowser\Data\Tor 

Edit the file : torrc

Paste :

HiddenServiceDir D:\Tor Folder\Tor Browser\Tor website Name

HiddenServicePort 80

and save the file .

Configuring Tor to serve the HTTPS version :

Configuring Tor is as simple as adding an additional port directive in /etc/tor/torrc. Open that file for editing, and find the relevant hidden service definition.

Just after the declaration for Port 80, add

HiddenServicePort 443

And then reload Tor

service tor reload

Save and Restart tor browser .

Now you can see a folder named "Tor website Name" on the directory where you typed .

Also there will be a hostname file which include your tor url . now your computer is your website host .

Now make your computer a web server with XAMPP . Its not a big deal at all . Simply download xampp from and start the server along with database .

For sharing basic content using the tor website , this is the perfect and easiest method .

You can perform this method on cloud / VPS or a Dedicated Server .

For that purchase a server and install CentOS

First, configure the EPEL repository on your system.

sudo dnf install epel-release -y 

Now, create a new file /etc/yum.repos.d/tor.repo and edit in a text editor:

sudo nano /etc/yum.repos.d/tor-browser.repo 

Add one of the below configurations as per your Linux distribution.

On CentOS and RHEL systems:

name=Tor for Enterprise Linux $releasever - $basearch

Install Tor

yum install tor

Follow the path where you installed the tor browser . In my case, i just installed it here -

D:\Tor Folder\Tor Browser\Browser\TorBrowser\Data\Tor 

Edit the file : torrc

Paste :

HiddenServiceDir /var/www/hidden_service/

HiddenServicePort 80

and save the file .

Configuring Tor to serve the HTTPS version :

Configuring Tor is as simple as adding an additional port directive in /etc/tor/torrc. Open that file for editing, and find the relevant hidden service definition.

Just after the declaration for Port 80, add

HiddenServicePort 443

And then reload Tor

service tor reload

Save and Restart tor browser .

Now you can see a folder named "Tor website Name" on the directory where you typed .

Also there will be a hostname file which include your tor url . now your computer is your website host .

Install Nginx

yum install nginx

Let's configure `nginx.conf` with the following command:

nano /etc/nginx/nginx.conf

% Replace the `nginx.conf` file with the below configuration.

# For more information on configuration, see:

#   * Official English Documentation:

#   * Official Russian Documentation:

user nginx;

worker_processes auto;

error_log /var/log/nginx/error.log;

pid /run/;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.

include /usr/share/nginx/modules/*.conf;

events {

    worker_connections 1024;


http {

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;

    tcp_nopush          on;

    tcp_nodelay         on;

    keepalive_timeout   65;

    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;

    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.

    # See

    # for more information.

    include /etc/nginx/conf.d/*.conf;


Now, type in `Ctrl+O` and type `Ctrl+X` to save and exit the file.

% For SELinux enabled systems, Run the below command

setsebool -P httpd_can_network_connect 1

## Enable Port Forwarding to Domain

Create a new Nginx configuration file `athuljith.conf` for the domain with the following command:

vi /etc/nginx/conf.d/athuljith.conf

Add the following codes:

> Replace `athuljith.onion &` with `Your Domain Name & IP` and Change SSL Path according to your SSL Path.

upstream app {



server {

  listen 80 default_server;

  server_name athuljith.onion;

  return 301 https://$server_name$request_uri;


server {

    listen 443 ssl; # managed by Certbot

    # The host name to respond to

    server_name athuljith.onion;

    ssl_certificate /etc/letsencrypt/live/athuljith.onion/fullchain.pem; # managed by Certbot

    ssl_certificate_key /etc/letsencrypt/live/athuljith.onion/privkey.pem; # managed by Certbot

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {

        proxy_pass http://app;

        proxy_set_header X-Real-IP  $remote_addr;

        proxy_set_header X-Forwarded-For $remote_addr;

        proxy_set_header Host $host;

        proxy_set_header X-Real-Port $server_port;

        proxy_set_header X-Real-Scheme $scheme;



Now, press the `Esc` key, and type in `:wq!` and press the `Enter` key to save and exit the file.

% For SELinux enabled systems, Run the below command

setsebool -P httpd_can_network_connect 1

## Basic .conf file for Domain with SSL in CentOS / CentOS 8/ Rocky Linux 8 Servers

Create a new Nginx configuration file `athuljith.conf` for the domain with the following command:

vi /etc/nginx/conf.d/athuljith.conf

Add the following codes:

> Replace `athuljith.onion` with `Your Domain Name` and Change SSL Path according to your default Path.

> And also replace the root path, `/var/www/hidden_service/` with the actual path where your website's data are stored.

server {

listen 80;

server_name athuljith.onion;

root /var/www/hidden_service/;

index index.php index.html index.htm;

location / {

try_files $uri $uri/ /index.php?$args;


location = /favicon.ico {

log_not_found off;

access_log off;


location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

expires max;

log_not_found off;


location = /robots.txt {

allow all;

log_not_found off;

access_log off;


location ~ \.php$ {

include /etc/nginx/fastcgi_params;

fastcgi_pass unix:/run/php-fpm/www.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;


listen 443 http2 ssl; # managed by Certbot

    ssl_certificate /etc/athuljithencrypt/live/athuljith.onion/fullchain.pem; # managed by Certbot

    ssl_certificate_key /etc/athuljithencrypt/live/athuljith.onion/privkey.pem; # managed by Certbot

    include /etc/athuljithencrypt/options-ssl-nginx.conf; # managed by Certbot

    ssl_dhparam /etc/athuljithencrypt/ssl-dhparams.pem; # managed by Certbot


Now, press the `Esc` key, and type in `:wq!` and press the `Enter` key to save and exit the file.

For access, follow the below commands:

chmod -R 755 /var/www/hidden_service/

chown -R nginx:nginx /var/www/hidden_service/

% For SELinux enabled systems, Run the below command

setsebool -P httpd_can_network_connect 1

Now, restart & check the Nginx with the following commands:

        systemctl restart nginx

        systemctl status nginx

        systemctl restart tor

        cat /var/www/hidden_service/hostname

## Enable http and https ( 80/443 )

To enable http and https connection through the firewall, follow the commands:

firewall-cmd --permanent --zone=public --add-service=http

firewall-cmd --permanent --zone=public --add-service=https

firewall-cmd --reload

Thats it .

So , I have explained all 3 methods of how to create a website using the tor network .

Hidden Service Design Safety :

As we've seen, setting up a hidden service is straightforward, but avoiding a number of potential pitfalls requires a bit of forethought and planning.

It's important to adopt the mindset that both mistakes and compromises do happen from time to time so that you automatically put a failsafe in place as you go.

For example, you may have noted that the firewall rules we added at the beginning of this module have a very little affect - the Nginx server blocks are bound to the loopback interface, so even without those rules, NGinx shouldn't respond to connections from the Surface web.

The risk, of course, is that it's very easy to forget to include 'localhost' when writing a listen directive. The firewall rules are there to ensure that if that mistake is ever made, some protection remains in place.

Conversely, binding to the loopback interface ensures that if the firewall rules are ever accidentally flushed, NGinx still shouldn't be exposed to the wider world.

Particular care needs to be taken when using any kind of server side scripting.

If an adversary finds a way to execute arbitrary code on your system, they can very quickly identify the physical server that you're located on. Just as on the Surface web, there are mitigations you can put in place to reduce the attack surface, but the best defense is to ensure that server side scripting is used only where absolutely necessary.

As discussed in the previous module, in certain deployments, using HTTPS may provide your users with some additional security. However, it needs to be very carefully implemented to minimize the risk of information leakage.

When generating a default certificate, the values given need to be as generic as possible, to help ensure that a correlation cannot be found between multiple servers (as you may, one day, be running multiple services).

This section will cover how to implement various mechanisms which may be of use in protecting from Spam/bots and user account compromise.

Many of the approaches used on the Surface web are effective but may lead to a small loss of privacy. Most Hidden Service users use Tor precisely because they care about privacy and will expect that design decisions that you make will take that into consideration

In the previous module, it was stated that using server-side scripting should be avoided where possible. For some sites, though, it simply isn't possible - forums for example simply don't work without some form of scripting.

Credential phishing is particularly prevalent on the darknet, so you may wish to implement 2 Factor Authentication so that your users can choose to use an additional level of protection. Mechanisms such as Google Authenticator and the Yubikey obviously aren't going to be particularly welcome, as they require information to be disclosed to a third party.

Similarly, you may wish to send emails to users, but care needs to be taken in order to do so without revealing the identity of your server.

In this short module, we'll be looking at :

Bot/Compromise Protection


    2 Factor Authentication (2FA)


    MTA : Tor

    HS : Public Mailserver

Handling User Data in General

    Opsec is essential





Bot/Compromise Protection :


Traditional CAPTCHA services (such as ReCaptcha) require a request to go to a third party (such as Google) to generate (and often to verify) a Captcha. On Tor, this is generally considered to be unacceptable.

You may also, as seems to have been true in Ross Ulbricht's case, be risking your own anonymity by using such a service. It's alleged that Ulbricht misconfigured his Captcha in such a way that it was leaking his server's Surface web address, ultimately leading to the identification of the server.

Whether or not this is true, it highlights two major lessons which can be learned

Never use the Surface web IP/hostname in testing, use

Minimize use of third party services as far as possible

Although traditional CAPTCHA's are not a good fit for Tor hidden services, it is true that you may still have a need for the protection that they provide.

Essentially, there are two options

Roll your own (basic) CAPTCHA generator

Use a CAPTCHA generator designed for hidden services

The former is generally preferred - although it may be via a hidden service, the latter still requires that trust be placed in an unknown third party. Your captcha needn't be too complex to keep the most common bots out of a Tor Hidden Service.

2 Factor Authentication :

On the Surface web, there are a number of mechanisms commonly used to implement Two Factor Authentication:

User receives a text containing a one-time passphrase/string

User runs an app to generate a one-time passphrase/string

User has a hardware token that generates a one-time passphrase/string

Each of these has its own strengths and weaknesses, but none of the above are really suitable for a Tor environment as they either require the user to surrender identifying information (e.g. their mobile number), require a request to be made to an external service (e.g. such as Google Authenticator).

At a technical level, you could, theoretically, implement a Tor friendly 2FA solution using a Yubikey. The default configuration would require an API request to go to Yubico's servers, but it is possible to run your own. Most users, however, wouldn't be happy with having a yubikey configured to use a server specific to your site (or Tor in general) as it could constitute physical evidence in some states.

There is, however, a Tor friendly 2FA solution that can be implemented - PGP.

Some sites, after (or during) registration, will allow users to upload their PGP public key. Once the 2FA functionality is enabled for a user account, their login flow becomes something similar to the following

Enter username/password and submit

Server encrypts a random string using their public key

User is presented with the ASCII armored output

User uses their public key to decrypt the string

User enters string into the field supplied and submits

Server checks the string matches and grants access if so

There are a number of common traps to avoid though.

Firstly, you must warn users to use common sense regarding the key they upload. There's very little point in taking steps to keep users anonymous if they then upload a public key with their (publicly known) email address as the recipient. Users should always generate a new keypair using bogus data.

If an invalid password is entered for a user with 2FA enabled, a 2FA page should still be displayed. If an attacker is attempting to access an account, you don't want to admit that they've at least got the password correct (as it may be in use somewhere else). Internally, you can log in whether it was 2FA or the password that failed if you wish, but never tell the user trying to log in.

The string you generate doesn't need to be long, but it must be impossible to predict, otherwise, the protection that 2FA is supposed to offer is completely negated.

You also need to ensure that uploading a public key and actually enabling the 2FA are two distinct steps. Ideally, you should include a 'test' run within the enabling process so that the user can verify that they've uploaded the public key that they think they have - it's all too easy for a user to lock themselves out of their own account if 2FA is automatically enabled as soon as they've submitted their public key.

Email :

Having a Hidden Service send emails to users requires far more planning than on an equivalent Surface web service.

On the Surface web, you would simply install a Mail Transport Agent (MTA) such as Postfix or Exim and then configure your back-end to send mails via that.

However, a quick glance at the headers of any mail sent through this MTA will reveal your server's IP address - something which is obviously undesirable.

There are a number of options available, each with its own benefits and drawbacks, and it's important to assess which best fits your needs.

MTA : Tor

The simplest way to add email support to your hidden service is to install and configure an MTA, and then add a firewall rule to ensure any traffic your MTA generates is routed over Tor.

Depending on the MTA, you may also need to adjust the configuration to ensure that the server doesn't reveal anything about itself.

The major drawback with this approach, however, is that the receiving MTA may reject your mail (or mark it as spam) as the connection source (as it sees it) will be a Tor exit node and may well be included in DNSRBL's.

As your mail server isn't on the Surface web, you'll also be unable to receive emails sent in response - which may or may not be an issue for you.

You will also need to give careful thought to which MTA you use, and how your hidden service will access it. For example, in some circumstances, Exim may leak BCC addresses. On a Surface web service, this may just be embarrassing, but on a Hidden Service it constitutes a huge breach of user trust and depending on the content of your hidden service may put users in certain jurisdictions in danger.


Quick and relatively easy to implement


Mail may not actually be received by the users

You'll need to properly configure your MTA

Hidden Service : Public Mailserver

To reduce the likelihood of your mail being filed in the user's spam folder, you'll probably want to use a publicly accessible mail server. Running your own is an option, but will associate yourself with the hidden service.

As the mail server is routable on the Surface web, you'll also be able to receive any responses which may be sent (whether via manually logging in, or having your hidden service retrieve mails using IMAP).

Mail providers such as Google Mail or should be avoided as they have a tendency to require a mobile number for 'verification' when access is made from a known anonymous proxy (such as a Tor exit node).

You will need to be careful about how you access/set up the account, however. No matter how anonymous and friendly the mail provider may be, you should always assume that everyone has a price at which they'll sacrifice their principles. Never make a direct connection to their services, as it could potentially later be used to identify you.


Relatively quick and easy to set up

Replies can be sent/received

The likelihood of the mail being rejected is reduced


Service Reliance on an unknown third party

Care needs to be taken when accessing/setting up an account

Handling User Data in General :

When considering what user data you need to collect in order to run your service, it's incredibly important to ensure that things are kept minimal.

The only acceptable way to run a service (whether on the Surface web or Tor) is to assume that at some point you will be compromised, and in fact already may have been.

If an adversary manages to identify you as the administrator, you never want to be in a position of being coerced into releasing data on your users. The only way to ensure that is to never collect identifying data in the first place. For many services, a username and password is all that you will need to collect.

Any data that is collected, for whatever reason, should be encrypted to ensure that simple vulnerabilities (such as SQL Injection) do not lead to the full-scale release of user data. The decryption keys will need to be available to the service somewhere, so encryption doesn't give much protection against a full server compromise, but you should attempt to mitigate the effects of a compromise at any level.

When deciding whether the information is 'identifying', consider the various ways in which an adversary might use the data. Certain data points may not be identified on their own but can be correlated against data found elsewhere in order to build a profile of the user involved. Take the following as a simplistic example

Data recovered from you :


Zip Code

Data recovered from another service


House number ( without street or Zip )

On their own, neither data set is much used for establishing more than a general vicinity for the user, when combined, however, it becomes easy to reduce the number of potential candidates.

You have very little control over what data other services collect, but you can ensure that your systems do not require the user to part with more data than is absolutely necessary. Depending on how serious the consequences might be if an individual was identified as a user of your service, you may wish to encourage users to use a unique username (i.e. not one they've used elsewhere).

Opsec is Essential :

Although this module is aimed at protecting user privacy, many of the techniques we've looked at are nominally concerned with protecting the identity of our server.

The reality is, that however innocent (or otherwise) your services may be, as a Hidden Service operator you hold the keys to user data. As we've already discussed, seemingly meaningless data can be correlated against other data in order to establish a profile.

Your user's fortunes are, therefore, to some small extent, tied to your own. Quite aside from wanting to protect your own anonymity, a failure in Operational Security (OpSec) could allow an adversary to coerce you into revealing data or making changes in order to collect additional data.

For example, the (now defunct) secure email service - Lavabit - was famously targetted with a National Security Letter. Although the service could not view user emails, the US Government attempted to force the service to make changes and reveal data that would allow interception of these mails to occur. So whilst you can take steps to ensure you collect minimal data, be aware that a failure to protect your own identity could lead you to be coerced to make similar changes.

Backups :

There's obviously very little point in securing your server if you then push backups, in the clear, across the Surface web.

Having off-server backups is obviously desirable, but careful thought needs to be given to exactly how these are implemented.

Push Backups :

Backups using a 'push' method are fairly common and popular on the Surface web. Whether pushing up to Amazon's S3, or syncing to another server, there is a wide range of solutions available.

However, careful thought needs to be given to where you are pushing to. Should the server be compromised, you need to be able to ensure that examination of the backup method in use won't lead to your identification (as it might if pushing to an S3 account).

You'll also probably want to ensure that your backups are pushed out via Tor to ensure that the backup service cannot identify the server hosting your hidden services (in case unencrypted files are ever accidentally pushed).

Pull Backups :

A simple pull mechanism works around a number of the risks involved in using push backups but does also introduce some new risks.

A basic setup would be

Create a new HTTP(S) hidden service, protected by HTTP Basic or Digest authentication.

The document root for that service would be configured to be the directory that your backup archives are written into.

A script on a system with a Tor client downloads your backup archive at pre-configured intervals.

The advantage of running backups in this way is that neither the backup server nor the hidden service server needs to know the Surface web identity of each other. Your backup 'server' could be something as simple as a Raspberry Pi running on your Home Network, it doesn't need to be directly accessible from the Surface web at all.

However, push backups to have one clear advantage over Pull backups - timing. With a push backup, a backup will never be pushed to the backup server until it's complete. Without careful design, this may not be true for Pull backups - if your backup takes longer to run than expected, the pull may result in only part of the backup being pulled off-server.

You need to either design a mechanism to prevent this (such as a simple lock file that the client can check for) or ensure that the scheduled run times are staggered sufficiently. Whatever the mechanism, be sure that it works, otherwise you may find that the first time you know you've been capturing useless backups is when you need them.

Encrypting your Backups :

Whatever solution you opt to use, one constant exists - backups should be heavily encrypted as soon as they've been created. A key pair should be generated on another system, and only the public key should be available on the server hosting your Hidden Service. The private key should be stored somewhere very secure. Should you ever need to put the private key onto the server (for example to recover a backup) you should generate a new keypair and cease use of the old pair immediately after.

The type of encryption you use will generally depend on personal preference, but if using a pre-rolled backup script, be sure to carefully examine how it implements encryption.

For example, the 's3cmd' script can be used to push files to Amazon S3, and includes the ability to PGP encrypt files prior to uploading. When configuring s3cmd, the user is asked to enter a passphrase, and it's easily assumed that this is being used to protect the private key. In reality, however, the passphrase is used to generate a symmetric key which is then used for every single file you upload. When compared to how PGP behaves when using a keypair, this behavior is undesirable.

You may not be finished :

Although we've examined designing and implementing Tor Hidden Service in quite some depth, some users will likely find that there are still additional considerations that they need to make.

For example, whilst we discussed the risks of traffic leakage, we did very little to avoid it - one solution, assuming you have out-of-band access to the host system, is to add iptables rules to ensure that all TCP and DNS traffic is redirected to the ports operated by the Tor Daemon.

You'd still then need to look at filtering out other protocols (including UDP on all other ports) in case someone discovers a means to have your host system send arbitrary traffic.

Similarly, we haven't discussed the impact of your Guard being compromised, those with serious concerns may need to look at running their own guards to help reduce the effectiveness of common Hidden Service de-anonymization attacks

It's also important to remember that this documentation may not cover threats that have not been discovered yet, security is a continuous exercise.

Measure Twice, Cut Once :

Some of the changes we made in Part One may have seemed redundant - why rebind Nginx to the loopback interface if we're firewalling the port? We're all human and make mistakes, if there's a change that can be made to mitigate a potential future mistake, it's well worth considering.

Protect Your Users :

We live in a fairly unstable world, and you can be reasonably sure that however harmless your hidden service (or Surface web website is) there will be someone who will take issue with it. Taking proactive measures to keep the identity of your server hidden helps to limit your attack surface to only the elements that you're willingly to expose to the public.

The threat will not always be against you directly, but against your users. For example, Christians do not fare well in certain countries, a fact which may be important if you're providing a faith based hidden service. Failing to properly secure your server and protect it's identity could mean that you become the conduit via which aggressors identify your users.

Tor Hidden Services have the potential to allow your userbase a level of privacy that they cannot otherwise obtain on the Surface web, but the anonymous nature of Tor doesn't make you, as the site operator, any less responsible for taking measures to protect the data that your users entrust you with.

Now its time to give some security tips :

Always use a VPN with Tor. Don’t fall into a false sense of security by believing that Tor is enough to protect you. If you want the very best anonymity and privacy while on the Deep Web then you need to be using a VPN with Tor. It is an extremely valuable tool in your fight for anonymity.

Beware of big names :

Presume that large companies’ encryption systems and possibly even big name operating systems (proprietary software) have back doors that secret services in their country of origin (at least in the US and the UK) can access.

Always encrypt everything :

Security experts use simple math to make their point: as you raise the cost of decrypting your files (say, for intelligence agencies like the NSA), you automatically increase the degree of effort expended on following you. If you’re not Chelsea Manning, Julian Assange, or Edward Snowden, and if you weren’t involved in active surveillance around Trump Tower apartments, They may give up the effort even if your encrypted communications were stored. And should anyone decide to track you despite your efforts, it will be more of a headache if you use strong encryption like AES (Advanced Encryption Standard) and tools like PGP or openVPN, which are the strongest widely available encryption methods (VPN’s are used by the US government itself).

Perform full disk encryption :

This is done just in case someone gets their hands on your computer or phone. Full disk encryption can be done using FileVault, VeraCrypt or BitLocker. Putting a computer to “Sleep” (instead of Shutdown or Hibernate) may allow an attacker to bypass this defense. Here, Mika Lee gives a complete guide for encrypting your laptop.

Avoid chatting with sources on the phone :

All phone companies store data related to the caller and the receiver’s numbers, as well as the location of the devices at the time calls were made.  In the US and several other countries, they’re required by law to disclose information on registered calls in their possession. What can be done? You should use a secure call service, such as the one the Signal app – which was tested repeatedly for security – possesses. Although this may mean that both the source and the editor need to download the app as well, the process takes just a few minutes. Here is a guide on how to use it. Just for the hang of it, check out how many of your non-journalist friends are hanging out there. However you choose to communicate with your source, do not bring your mobile phone to sensitive meetings. Buy a disposable device and find a way to convey its number to the source in advance. The source needs to have a disposable safe device too. Authorities can track your movement through cellular network signals and it’s advised to make it harder for them to locate you retroactively in the exact same cafe where the source was sitting. If you fail to follow this rule, all local authorities will be required to do is ask (politely and legally) for the video filmed by the cafĂ©’s security camera at the time of your meeting.

Choose secure messengers :

your calls (cellular ones and via landlines) can be monitored by law enforcement agencies and each SMS is like a postcard – all text is fully visible to those who may intercept it. Therefore, use Messengers that allow for secure end to end calls: signal, which was already mentioned above, and Telegram are considered to be the safest (although Telegram, as well as WhatsApp’s web apps, were compromised once and then fixed). According to some experts, you can also consider using SMSSecure, Threema, and even Whatsapp. The Signal Protocol has been actually implemented into WhatsApp, Facebook Messenger, and Google Allo, making conversations using them encrypted. However, unlike Signal and WhatsApp, Google Allo and Facebook Messenger do not encrypt by default, nor notify users that conversations are unencrypted – but offer end-to-end encryption in an optional mode. You should also keep in mind that Facebook messenger and WhatsApp are both owned by Facebook. Adium and Pidgin are the most popular Mac and Windows instant messaging clients that support the OTR (Off the Record) encryption protocol and Tor – the web’s best encrypted browser, which we will get to in detail later (See how to enable Tor in Adium here and in Pidgin here). Naturally, you could also use Tor Messenger itself, which is probably the safest of them all. Two final notes on texting: A cyber security expert I’ve discussed this with, says you should also have a working hypothesis that text is encrypted but the fact that these specific two individuals are talking, at this present time, might not go unnoticed. The second note is you should also remember to delete the messages in your phone (although this may not be enough to withstand a forensic check), just in case your device falls in the wrong hands, to avoid exposing them.

Do not use organizational chats :

Slack, Campfire, Skype, and Google Hangouts should not be used for private conversations. They are easy to break in, and are exposed to disclosure requests for court use, to resolve legal issues at the workplace. Therefore, it’s best to avoid them, not only when it comes to conversations with sources, but also in conversations between colleagues, editors, etc., when you need to pass information received from your source, whose identity must be kept under cover. Many popular VoIP services like Jitsi have built-in chat features, and several of them are designed to offer most of Skype’s features, which makes them a great replacement.

In extreme cases, consider using a Blackphone :

This phone, which strives to provide perfect protection for web surfing, calls, text messages, and emails, is probably the best substitute for a regular phone if you are about to topple your government or getting ready to publish secret military files. An anti-bullet vest may also come in handy. Alternatively, try to do without a cell phone, Or opt for a cellular phone RFID signal-blocking bag. There’s always an option that even the Blackphone can be tracked using its IMEI (the mobile phone’s ID).

Avoid these mistakes :

Don’t access any site that requires a login but does not use encryption, especially if the user account on that site contains any personally identifiable information. An encrypted site will use “https:\\” at the beginning of the URL. Most browsers today will display a small padlock icon to the left of the address bar when the site is secure. There may also be a blue or green URL bar button in the Tor Browser.

Don’t log into Google, YouTube, Gmail, Hotmail, Yahoo! or any other secure site that has your personal information while using an anonymizer. All of those sites maintain logs of IP addresses that their users log in from. While this can’t be used to find you, it can be used after you’ve been found to further damage your, and everyone else’s, anonymity. The providers of all of these types of services keep their own logs relating to any user’s access. No matter what anonymous tool is used, after the user has been caught, these logs demonstrate what anonymous tool they used, and how that tool works on both ends, as they will invariably be in possession of the user’s computer. Also, those sites use auto-refresh to repopulate your browser with new content. Unfortunately, this also sends your information back to the web host with every refresh, adding to the information kept in the logs.

Stay away from forums, blogs, and microblogs that you normally visit as yourself when online. Don’t even quote any of them. Even creating an anonymous user account at those places can end up working against you. It’s far safer to just stay away from them until you are finished with your anonymous internet session.

Turn off or shut down any applications or programs that automatically sync with a server, or configure them to send all of their traffic through your anonymizer of choice. Things as email clients, Facebook, Twitter, instant messenger programs, streaming media, etc. Anything that cannot be configured to communicate anonymously should not be running while you are trying to be unrecognized. Ideally, the best option is to use a liveOS like Tails or any of the live Linux distributions that can be kept on a CD, DVD or even a thumb drive. When a computer is booted into one of these operating systems, especially one that is designed for anonymity, like Tails.

Develop a checklist of anonymous practices before you do anything online. Only you know what sorts of things you do online and it should stay that way. A checklist will help ensure that you don’t get careless.

If you must download something while using an anonymizer, don’t open it while your computer is still connected to the internet. Many innocuous seeming documents can contain links or even live streams of data that can and will give away your IP address when they connect to their remote data source. This is especially true of files ending in .doc and .pdf. Instead, either disconnect from the internet completely or open them in a virtual machine that does not have a network connection.

Do not torrent over Tor or any anonymous access tool that is not specifically designed to be used for torrenting. This is one of the most often ignored pieces of advice. All of the standard torrent clients use the IP address of the host computer to receive the torrent streams from other clients or seeders, and to source streams to others that are downloading that data, known as leeches. These programs embed the client computer’s actual IP address into the header of each packet of data transmitted. That way both the computer requesting the data and the computer sourcing the data can send and receive data without having to rely on any servers or “middlemen.” This is how the vast majority of torrent clients work. Using a standard torrent client is in no way anonymous. However, there are torrent clients that are designed to be anonymous. Look into GNUnet and Aqua for sharing large files anonymously over an anonymous file sharing network.

Do not modify the security settings or install any plugins in your browser or the browser provided as the anonymizer, unless specifically told to do so by the anonymous service provider of your choice. If you are not using the Tor Browser specifically, make sure you do not install any plugins in your web browser. This includes things like Adobe Flash Player, Apple QuickTime, Java, and others. Preferably, you will be using the Tor Browser, possibly even the hardened version, or one of its alternatives. That way, you will get the latest updates as soon as they are released.

If you don’t want your ISP to know that you are connecting to an anonymous network, like Tor, use a bridge instead of a regular entry node.

If you are engaged in any activity that is illegal in your home country, know that you will be actively hunted by your local law enforcement at the very least. In the United States, illegal activity is investigated by the FBI for any crimes that cross state lines, the DEA for any crimes involving narcotics, Homeland Security for anything they feel like investigating, the ATF when firearms are involved and the IRS when significant amounts of money is changing hands, regardless of what currency is used. These entities will all work together using a lot of different tools to find you. Any mistakes, no matter how small, will lead them right to you.

Ultimately, you will want to become familiar with and use several different anonymity tools. If you use a VPN, change servers often. Also, never use your anonymous access program without using a VPN, even if the VPN server you are connecting to is in your home city. You already should know that any logs kept by the VPN provider can point right to you, so make sure you choose a provider that does not keep any logs relating to you and your connection.

On the subject of VPNs specifically, not all are created equal. When shopping for one, you want to look for a provider that has, and keeps to, a strict “no logs” policy. You also want to make sure they use shared IP addresses. Just like with some websites, several VPN servers can exist on the same physical server as virtual machines. The physical server has only one IP address, so all of the virtual servers that it hosts all have to share that address. There can also be other servers being hosted like websites, email servers, databases and file sharers. The main benefit is that your VPN server can show up in the destination server logs as any of these, not necessarily a VPN.

Thanks & Regards .