Knowledgebase / Self-hosting Guide / Create your own SFTP onion service over Tor

Create your own SFTP onion service over Tor

Tor, an acronym for The Onion Router, is an open-source software that is free to use and promotes anonymous interactions online. It routes internet traffic through a global volunteer-driven overlay network comprising over seven thousand relays. The use of Tor increases the challenge of tracing a user's online activities.

SFTP, which stands for SSH File Transfer Protocol, is a protocol for secure file transfer that operates on top of the SSH protocol. It fully utilizes the security and authentication features of SSH. SFTP has essentially supplanted the old FTP as a file transfer protocol, and is rapidly replacing FTP/S. It delivers the same functionality as these protocols, but with greater security and reliability, and simpler configuration. There is essentially no justification for continuing to use the outdated protocols. In addition, SFTP safeguards against password eavesdropping and man-in-the-middle attacks. It ensures the data's integrity through encryption and cryptographic hash functions, and it verifies both the server and the user.

We suggest installing Docker if you're planning to establish an Onion Service and host it yourself. Docker is a software platform designed to facilitate building, testing, and deploying applications with speed. It organizes software into uniform units known as containers, which incorporate all the necessary components for the software's operation, such as libraries, system tools, code, and runtime. Docker enables swift deployment and scaling of applications in any environment, ensuring the smooth running of your code.

Also We suggest utilizing Docker Compose once Docker has been installed. Docker Compose serves as a utility for formulating and executing applications that involve multiple containers. It is instrumental in facilitating a smooth and productive development and deployment process. Docker Compose makes it straightforward to handle your entire application stack, including services, networks, and volumes, through a single, easily understood YAML configuration file. Consequently, all the services from your configuration file can be created and initiated with just one command.

To use Docker Compose, you should define services in a Compose file. Create a file called
compose.yaml
in your project directory and paste the following:
services:
  sftp:
    image: atmoz/sftp
    volumes:
      - ./home:/home
      - ./configs/users.conf:/etc/sftp/users.conf:ro
  tor:
    image: osminogin/tor-simple
    volumes:
      - ./configs/torrc:/etc/tor/torrc
      - ./hidden_service:/var/lib/tor/hidden_service
This Compose file defines two services:
sftp
and
tor
.
The
sftp
service uses a public SFTP image pulled from the Docker Hub registry. Two bind mounts are defined for this service. The first bind mount enables you to save the content uploaded by your SFTP users. The second bind mount allows you to configure the SFTP software, to enable how many users can use the SFTP.
The
tor
service uses a public Tor image pulled from the Docker Hub registry. Two bind mounts are defined for this service. The first bind mount enables you to configure the Tor software to use Tor as an onion service. The second bind mount allows you to check your hidden service address, and persist your onion service public and private keys on your host server. In the event that your container is removed, your onion service keys are retained.
Create a directory called
configs
in your project directory, and create a file called
torrc
inside the
configs
directory and paste the following:
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 22 sftp:22

This is a Tor config file which configure Tor instance to run an onion hidden service. Your onion service listens the port 22, and redirect the request to the address sftp:22.

Create a file called
users.conf
inside the
configs
directory and paste the following:
foo:123:1001:100
bar:abc:1002:100
baz:xyz:1003:100

This is a SFTP users config file, which defines three users with its password, user id and group id.

Create a directory called
hidden_service
in your project directory and update the permission:
# This command ensure that the hidden_service folder is owned by user tor, and owned by group nogroup in terms of container
chown 100:65533 hidden_service
# This command ensure that the hidden_service folder is not too permissive, and ensure the folder is accessed by tor user owner
chmod 700 hidden_service
Create directories called
home/foo
,
home/bar
, and
home/baz
in your project directory and update the permission:
chown 1001:100 home/foo
chown 1002:100 home/bar
chown 1003:100 home/baz

This is the final directory structure looks like:

├── compose.yaml                  Docker Compose File
├── configs                       Configuration files
│   ├── torrc
│   └── users.conf
├── home                          Home directories
│   ├── foo
│   ├── bar
│   └── baz
└── hidden_service                Tor hidden service file
From your project directory, start up your application by running
docker compose up
.
$ docker compose up

[+] Running 2/0
 ✔ Container onion-service-sftp-1  Created                                                                                            0.0s 
 ✔ Container onion-service-tor-1   Created                                                                                            0.0s 
Attaching to onion-service-sftp-1, onion-service-tor-1
onion-service-tor-1   | Apr 02 12:42:52.426 [notice] Tor 0.4.8.10 running on Linux with Libevent 2.1.12-stable, OpenSSL 3.1.2, Zlib 1.3, Liblzma 5.4.5, Libzstd 1.5.5 and Unknown N/A as libc.
onion-service-tor-1   | Apr 02 12:42:52.426 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://support.torproject.org/faq/staying-anonymous/
onion-service-tor-1   | Apr 02 12:42:52.426 [notice] Read configuration file "/etc/tor/torrc".
onion-service-tor-1   | Apr 02 12:42:52.430 [notice] Opening Socks listener on 127.0.0.1:9050
onion-service-tor-1   | Apr 02 12:42:52.430 [notice] Opened Socks listener connection (ready) on 127.0.0.1:9050
onion-service-tor-1   | Apr 02 12:42:52.000 [notice] Parsing GEOIP IPv4 file /usr/share/tor/geoip.
onion-service-sftp-1  | [/usr/local/bin/create-sftp-user] Parsing user data: "foo:123:1001:100"
onion-service-tor-1   | Apr 02 12:42:52.000 [notice] Parsing GEOIP IPv6 file /usr/share/tor/geoip6.
onion-service-sftp-1  | [/usr/local/bin/create-sftp-user] Parsing user data: "bar:abc:1002:100"
onion-service-sftp-1  | [/usr/local/bin/create-sftp-user] Parsing user data: "baz:xyz:1003:100"
onion-service-sftp-1  | Generating public/private ed25519 key pair.
onion-service-sftp-1  | Your identification has been saved in /etc/ssh/ssh_host_ed25519_key
onion-service-sftp-1  | Your public key has been saved in /etc/ssh/ssh_host_ed25519_key.pub
onion-service-sftp-1  | The key fingerprint is:
onion-service-sftp-1  | SHA256:vZoZixBYuD4ZDnnHEvuAoUP7yHTwXV9GrfPhRFWsjg0 root@0c02d46045dc
onion-service-sftp-1  | The key's randomart image is:
onion-service-sftp-1  | +--[ED25519 256]--+
onion-service-sftp-1  | |           .. .oo|
onion-service-sftp-1  | |   .      .  o  .|
onion-service-sftp-1  | |.oo .  .   oo  . |
onion-service-sftp-1  | |o++B. . ..ooEo.  |
onion-service-sftp-1  | |*oOo+.  S.. ==.  |
onion-service-sftp-1  | |o*+B .     ..oo  |
onion-service-sftp-1  | | o=.o   . .      |
onion-service-sftp-1  | |   . . . *       |
onion-service-sftp-1  | |      . =        |
onion-service-sftp-1  | +----[SHA256]-----+
onion-service-tor-1   | Apr 02 12:42:52.000 [notice] Bootstrapped 0% (starting): Starting
onion-service-tor-1   | Apr 02 12:42:52.000 [notice] Starting with guard context "default"
onion-service-sftp-1  | Generating public/private rsa key pair.
onion-service-sftp-1  | Your identification has been saved in /etc/ssh/ssh_host_rsa_key
onion-service-sftp-1  | Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub
onion-service-sftp-1  | The key fingerprint is:
onion-service-sftp-1  | SHA256:PMx8f2hx+j7xsRqdSWNJivTvL/Wrn18yCXQUtN/04FA root@0c02d46045dc
onion-service-sftp-1  | The key's randomart image is:
onion-service-sftp-1  | +---[RSA 4096]----+
onion-service-sftp-1  | |             .E. |
onion-service-sftp-1  | |             o . |
onion-service-sftp-1  | |           .o +..|
onion-service-sftp-1  | |       =  ..o+o++|
onion-service-sftp-1  | |        S ..ooo=+|
onion-service-sftp-1  | |         o . **o=|
onion-service-sftp-1  | |            =.=O=|
onion-service-sftp-1  | |           . o=+=|
onion-service-sftp-1  | |             +*B*|
onion-service-sftp-1  | +----[SHA256]-----+
onion-service-sftp-1  | [/entrypoint] Executing sshd
onion-service-sftp-1  | Server listening on 0.0.0.0 port 22.
onion-service-sftp-1  | Server listening on :: port 22.
onion-service-tor-1   | Apr 02 12:42:53.000 [notice] Bootstrapped 5% (conn): Connecting to a relay
onion-service-tor-1   | Apr 02 12:42:53.000 [notice] Bootstrapped 10% (conn_done): Connected to a relay
onion-service-tor-1   | Apr 02 12:42:53.000 [notice] Bootstrapped 14% (handshake): Handshaking with a relay
onion-service-tor-1   | Apr 02 12:42:54.000 [notice] Bootstrapped 15% (handshake_done): Handshake with a relay done
onion-service-tor-1   | Apr 02 12:42:54.000 [notice] Bootstrapped 20% (onehop_create): Establishing an encrypted directory connection
onion-service-tor-1   | Apr 02 12:42:54.000 [notice] Bootstrapped 25% (requesting_status): Asking for networkstatus consensus
onion-service-tor-1   | Apr 02 12:42:54.000 [notice] Bootstrapped 30% (loading_status): Loading networkstatus consensus
onion-service-tor-1   | Apr 02 12:42:55.000 [notice] I learned some more directory information, but not enough to build a circuit: We have no usable consensus.
onion-service-tor-1   | Apr 02 12:42:56.000 [notice] Bootstrapped 40% (loading_keys): Loading authority key certs
onion-service-tor-1   | Apr 02 12:42:56.000 [notice] The current consensus has no exit nodes. Tor can only build internal paths, such as paths to onion services.
onion-service-tor-1   | Apr 02 12:42:56.000 [notice] Bootstrapped 45% (requesting_descriptors): Asking for relay descriptors
onion-service-tor-1   | Apr 02 12:42:56.000 [notice] I learned some more directory information, but not enough to build a circuit: We need more microdescriptors: we have 0/7630, and can only build 0% of likely paths. (We have 0% of guards bw, 0% of midpoint bw, and 0% of end bw (no exits in consensus, using mid) = 0% of path bw.)
onion-service-tor-1   | Apr 02 12:42:57.000 [notice] Bootstrapped 50% (loading_descriptors): Loading relay descriptors
onion-service-tor-1   | Apr 02 12:43:00.000 [notice] The current consensus contains exit nodes. Tor can build exit and internal paths.
onion-service-tor-1   | Apr 02 12:43:00.000 [notice] Bootstrapped 55% (loading_descriptors): Loading relay descriptors
onion-service-tor-1   | Apr 02 12:44:03.000 [notice] Bootstrapped 62% (loading_descriptors): Loading relay descriptors
onion-service-tor-1   | Apr 02 12:44:11.000 [notice] Bootstrapped 70% (loading_descriptors): Loading relay descriptors
onion-service-tor-1   | Apr 02 12:44:15.000 [notice] Bootstrapped 75% (enough_dirinfo): Loaded enough directory info to build circuits
onion-service-tor-1   | Apr 02 12:44:15.000 [notice] Bootstrapped 90% (ap_handshake_done): Handshake finished with a relay to build circuits
onion-service-tor-1   | Apr 02 12:44:15.000 [notice] Bootstrapped 95% (circuit_create): Establishing a Tor circuit
onion-service-tor-1   | Apr 02 12:44:16.000 [notice] Bootstrapped 100% (done): Done
To check the V3 Onion Address of your onion service, open the file
hidden_service/hostname
.

This is a basic example of how to host your own SFTP onion service over Tor network. Using Docker and Docker Compose, setting up an onion service becomes very easy. For more information on Docker and Docker Compose, we recommend visiting the official site to explore and learn more.

Link to Tor Project

Link to Docker

Link to Docker Compose

Tags:
  • Onion Service
  • Docker
  • Docker Compose
  • SFTP

24/7 Expert Support

Our experts are always on hand to help answer your questions, get you started, and grow your presence online. You can email us any time