Create Tor Onion Service with Nginx
Last modified: 2024-02-13
1. Setup Tor
1. Install Tor
# on Debian/Ubuntu
sudo apt install tor
# on Fedora
sudo dnf install tor
Then enable and start tor service.
sudo systemctl enable tor
sudo systemctl start tor
# Check status
sudo systemctl status tor
2. Configure Tor Onion Service
Edit /etc/tor/torrc
for adding the following lines (remove #
at the target lines and modify values):
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 unix:/var/run/tor/hidden_service.sock
3. Restart Tor Service
sudo systemctl restart tor
4. Check Your Onion Domain
Your onion domain is stored at /var/lib/tor/hidden_service/hostname
.
cat /var/lib/tor/hidden_service/hostname
2. Setup Nginx
1. Install Nginx
# on Debian/Ubuntu
sudo apt install nginx
# on Fedora
sudo dnf install nginx
2. Create Website Contents
Here we create a directory /var/www/onion
and put the contents here.
mkdir -p /var/www/onion
touch /var/www/onion/index.html
Then write contents for index.html
such as below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hidden Site</title>
</head>
<body>
<h1>Welcome to Hidden Site</h1>
</body>
</html>
After that change permission for allow nginx
to read files under /var/www/onion
.
chown -R nginx:nginx /var/www/onion
Remember to update permission of /var/www/onion
with above command every time you add new files/directories under /var/www/onion
.
3. Configure Nginx
Create /etc/nginx/conf.d/onion.conf
and add the following directive. Replace <your-onion-address>.onion
with your Onion domain stored at /var/lib/tor/hidden_service/hostname
.
server {
listen unix:/var/run/tor/hidden_service.sock;
server_name <your-onion-address>.onion;
access_log /var/log/nginx/hidden_service.log;
index index.html;
root /var/www/onion;
location / {
root /var/www/onion;
index index.html index.htm;
}
}
4. Start Nginx Server
Before starting the Nginx, if the SELinux is activated, temporarily disable the SELinux to give Nginx permission to process UNIX sockets (/var/run/tor/hidden_service.sock
).
# 0: Set `Permissive` mode temporarily
setenforce 0
# Check status (the `Permissive` mode is expected)
getenforce
Then start Nginx.
sudo systemctl enable nginx
sudo systemctl start nginx
# Check status
sudo systemctl status nginx
3. Access To You Onion Service
Using Tor Browser, you can access to the onion service by entering your .onion
domain. See the domain in /var/lib/tor/hidden_service/hostname
.
To monitor access log, use tail
command.
tail -f /var/log/nginx/hidden_service.log
4. Backup HiddenServiceDir
To keep your onion service available for a long time, make a backup copy of the /var/lib/tor/hidden_service
directory somewhere.
When starting Hidden Service using this directory, just simply copy it to /var/lib/tor/
as below:
cp -r /path/to/hidden_service /var/lib/tor/
Then modify /etc/tor/torrc
and start tor
service.
5. (Optional) Get Vanity Address
If you want to use a custom Onion domain with arbitrary prefix such as exampleabcdef....onion
, you can generate it using mkp224o.
1. Install Dependencies
# on Debian/Ubuntu
apt install gcc libc6-dev libsodium-dev make autoconf
# on Fedora
sudo dnf install -y gcc
sudo dnf install -y glibc-static
sudo dnf install -y libsodium-devel
sudo dnf install -y make
sudo dnf install -y autoconf
2. Build the mkp224o
Project
git clone https://github.com/cathugger/mkp224o.git
cd mkp224o
./autogen.sh
./configure
make
3. Generate Vanity Address
# -d: Specify output directory
# -n: The number of domains to generate
./mkp224o -d domains -n 5 mysite
# Result examples:
mysiteabcdef.....onion
mysite012334.....onion
mysiteef0123.....onion
mysite789abc.....onion
mysite345def.....onion
4. Copy the Key Files
After generating, the key files are saved under domains/mysite...onion
directory.
ls domains/mysiteabcdef....onion
hostname hs_ed25519_public_key hs_ed25519_secret_key
Choose one domain and copy these files to /var/lib/tor/hidden_service/
.
cd domains/mysiteabcdef....onion
cp domains/mysiteabcdef/* /var/lib/tor/hidden_service/
5. Update the Nginx Config
Replace the original onion domain to our vanity address in /etc/nginx/conf.d/onion.conf
server {
...
server_name mysiteabcdef....onion;
...
}
6. Restart Tor and Nginx
Now restart Tor and Nginx to apply the domain.
sudo systemctl restart tor
sudo systemctl restart nginx
Access to mysite...onion
in Tor Browser.
6. (Optional) Make Your Onion Service To Be More Secure
If you want your onion service to be more secure, add additional configurations.
Hide Nginx Version
Usually the Nginx version is displayed in the HTTP response header such as below:
Server: nginx/1.24.0
You may want to hide the version. To hide it, add the server_tokens off
in the /etc/nginx/nginx.conf
as follow:
http {
...
server_tokens off;
...
}
This hide the Nginx version from the Server
header such as below:
Server: nginx
Rate Limiting Requests
Reference: https://www.nginx.com/blog/rate-limiting-nginx/
By rate limiting requests per second (or millisecond), it may prevent DDoS attacks.
Add limit_req_zone
and limit_req
directives to /etc/nginx/conf.d/onion.conf
.
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
Server {
...
location / {
limit_req zone=mylimit burst=20 nodelay;
...
}
}