How to Create a Tor Onion Site: Ubuntu Setup Example
This guide provides a step-by-step example of setting up a Tor onion site on Ubuntu. Follow these instructions to ensure your site is secure and anonymous.
General Recommendations for Maintaining Anonymity
- Do not run any other services on this server.
- Use a freshly installed operating system.
- Do not use any other services from this hosting provider.
- Pay for hosting via PayPal or, preferably, Bitcoin.
- Do not provide any identifying information to your hosting provider.
- Do not run a Tor relay on this server, as its public address will be exposed.
- Do not send emails from this server.
- Use secure website software and strong passwords.
- Avoid software that uses scripts, such as JavaScript.
- Ensure your application does not display error information that could compromise anonymity.
- Make sure your siteβs code does not use elements from third-party sites (e.g., jquery.com, Google Fonts).
- Promptly install security updates on your server.
Main Steps
- Choose a hosting provider, considering your usersβ geographic distribution.
- Install and configure Ubuntu.
- Install and configure the Nginx web server.
- Install and configure Tor Hidden Services.
After completing these steps, your site will be accessible via its onion address on the Tor network.
Assumptions
We assume you have already chosen a hosting provider and installed Ubuntu.
Configuring Ubuntu
- Remove applications that may affect anonymity:
sudo apt-get remove --purge rsyslog exim postfix sendmail wget curl
- Optimize system settings for high-traffic sites:
sudo vi /etc/sysctl.d/100-nginx.conf
fs.file-max = 2097152 net.core.netdev_max_backlog = 65536 net.core.optmem_max = 25165824 net.core.rmem_default = 16777216 net.core.rmem_max = 31457280 net.core.somaxconn = 65536 net.core.wmem_default = 16777216 net.core.wmem_max= 31457280 net.ipv4.ip_local_port_range= 2000 65000 net.ipv4.tcp_congestion_control = cubic net.ipv4.tcp_fin_timeout= 7 net.ipv4.tcp_keepalive_intvl = 15 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_time = 90 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_max_syn_backlog = 65536 net.ipv4.tcp_max_tw_buckets = 1048576 net.ipv4.tcp_mem = 8388608 8388608 8388608 net.ipv4.tcp_orphan_retries = 0 net.ipv4.tcp_rfc1337 = 1 net.ipv4.tcp_rmem = 8192 87380 16777216 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_wmem = 8192 65536 16777216 vm.dirty_background_ratio = 2 vm.swappiness = 10 vm.dirty_ratio = 60
sudo sysctl -p /etc/sysctl.d/100-nginx.conf
sudo vi /etc/security/limits.conf
* soft nofile 1048576 * hard nofile 1048576 root soft nofile 1048576 root hard nofile 1048576
sudo vi /etc/pam.d/su
session required pam_limits.so
sudo vi /etc/pam.d/common-session
session required pam_limits.so
Installing and Configuring Nginx
- Install Nginx:
sudo apt-get install nginx
- Backup the original config:
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig
- Create a new config for high-traffic sites:
sudo vi /etc/nginx/nginx.conf
user www-data; worker_processes auto; pid /run/nginx.pid; worker_rlimit_nofile 2129952; events { worker_connections 81920; multi_accept on; use epoll; } http { open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 30; reset_timedout_connection on; send_timeout 2; client_max_body_size 32k; client_body_buffer_size 32k; client_body_in_single_buffer on; client_body_timeout 10s; client_header_timeout 10s; client_header_buffer_size 8k; large_client_header_buffers 4 32k; types_hash_max_size 2048; server_tokens off; include /etc/nginx/mime.types; default_type application/octet-stream; access_log off; error_log off; gzip on; gzip_disable "MSIE [1-6]\."; gzip_comp_level 6; gzip_buffers 16 8k; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m; limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=30r/s; server { listen 127.0.0.1:8080 default_server backlog=65536; server_name localhost _ ""; root /usr/share/nginx/html; index index.html; location / { expires 1h; allow 127.0.0.1; deny all; } } }
- Restart Nginx:
sudo service nginx restart
Installing and Configuring Tor
- Add the Tor repositories as listed on the Tor Project website:
sudo vi /etc/apt/sources.list
deb http://deb.torproject.org/torproject.org trusty main deb-src http://deb.torproject.org/torproject.org trusty main
gpg --keyserver keys.gnupg.net --recv 886DDD89 gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -
- Install Tor:
sudo apt-get update sudo apt-get install tor deb.torproject.org-keyring
- Configure Tor Hidden Service:
sudo vi /etc/tor/torrc
HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:8080
- Restart Tor:
sudo service tor restart
- Find your Tor onion address:
sudo cat /var/lib/tor/hidden_service/hostname
Your site is now accessible at the onion address listed in this file.
The private key for your onion address is stored in:
/var/lib/tor/hidden_service/private_key
Setting Up and Configuring the Firewall
- Install the firewall:
sudo apt-get install ufw
- Configure the firewall:
sudo ufw allow ssh
- Enable SSH access to the server:
sudo ufw enable
References
- How to create an ONION site
- Configuring Hidden Services for Tor
- How To Create A Hidden Service Tor Site
- How to Create a Tor .onion Site [Updated]
- 500 Million hits/day with Nginx + PHP-FPM + MySQL
- Tuning Nginx for Best Performance
- Optimizing Nginx for High Traffic Loads
- Tuning NGINX for Performance
- sysctl.conf
- The GNU/Linux Kernel
- Lessons learned tuning TCP and Nginx in EC2
- Increase “Open Files Limit”
- Setting up a hidden service with Nginx
For information about migrating from V2 to V3 onion services, see here.