Getting Started With tor Hidden Services on FreeBSD
At times I have wanted to demo the development version of a server that is running on my FreeBSD virtual machine. This is not a problem if the person I want to show it to is withing walking distance. The net being what it is, sometimes the other party is halfway around the world.
I figured tor would be a neat way to demo a server running on my laptop. This post covers serving content via tor on a FreeBSD machine. This does not cover securing a hidden service because it is non-trivial and that is not my use case.
Software Versions
$ date
February 6, 2016 at 08:59:26 AM JST
$ uname -vm
FreeBSD 11.0-CURRENT #0 r287598: Thu Sep 10 14:45:48 JST 2015 root@:/usr/obj/usr/src/sys/MIRAGE_KERNEL amd64
$ tor --version
Tor version 0.2.7.6.
$ curl --version
curl 7.47.0 (amd64-portbld-freebsd11.0) libcurl/7.47.0 OpenSSL/1.0.2e zlib/1.2.8
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets
Instructions
First, install security/tor. Consider enabling TOR2WEB if your service does not really need to be hidden.
portmaster security/tor
Serve content to a port on localhost. For example, add the following to server.sh for a simple date server that serves content to port 8080. This is not a robust server, but it is good enough for configuration testing.
#/bin/sh
HOST=127.0.0.1
PORT=8080
while true; do
BODY=$(cat <<EOF
{
"Date": "$(date)"
}
EOF
)
RESPONSE=$(cat <<EOF
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: $((${#BODY}+1))
Connection: close
${BODY}
EOF
)
echo "---$((X=X+1))---"
echo "$RESPONSE" | nc -N -l $HOST $PORT
done
If using the above, make the server script executable and run it.
chmod +x server.sh
./server.sh
Read the tor configuration instructions. Open /usr/local/etc/tor/torrc (see torrc instructions). Add the following lines to the section titled This section is just for location-hidden services
HiddenServiceDir /usr/home/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:8080
The following commands can be used to test the above server.
curl -v 127.0.0.1:8080
# log request date on the server and send EOF
date | nc 127.0.0.1 8080
Enable tor in /etc/rc.conf
tor_enable="YES"
Start tor.
service tor start
Get the hostname for your hidden service with the following command. Do not share the private_key, found in the same directory.
cat /usr/home/tor/hidden_service/hostname
The following command can be used to test the above nc server by supplying the tor proxy with -x and proxy protocol with -X. The -w 1 specifies a timeout. This is necessary because the nc server does not close the connection. The -v flag gives verbose output.
nc -w 1 -v -X5 -x localhost:9050 "$(cat /usr/home/tor/hidden_service/hostname)" 80
Test your hidden service with curl by supplying the tor proxy with the -x option.
curl -x socks5h://127.0.0.1:9050 -v "http://$(cat /usr/home/tor/hidden_service/hostname)/"
You alo can test your hidden service with Tor2web. For example, if your hidden service has a hostname of ABCDEFGHIJKLMNOP.onion, go to https://ABCDEFGHIJKLMNOP.onion.to to view it in a web browser. The nc server listed above might be a little flakey because it expects the client to close the connection.. You may need to restart the script if the server stops responding.
Test the hidden service with Tor2web from the command line with the following command. Note that Tor2web blocks the curl user agent, so the user agent is set to test instead.
curl -A test "https://$(cat /usr/home/tor/hidden_service/hostname).to"
To disable tor when you no longer need to use it, stop it with the service command.
service tor stop
Then disable it in /etc/rc.conf.
tor_enable="NO"
References:
- Tor Project
- Tor, Tor2web
- Tor, Configuring Hidden Services for Tor
- Tor, Edit torrc
- Tor, HTTP connection closed on: Excess found in a non pipelined read
- Tor, StackOverflow, curl an .onion url over an http proxy does not return expected source
- Tor, Using nc and ncat with tor without torify/torsocks
- FreeBSD, Man nc
- FreeBSD, Man curl
- FreeBSD Forums, nc Server Not Disconnecting
- Bash, How to assign a heredoc value to a variable in Bash?
- Bash, The while loop
- Bash, Length of string in bash
- Bash, Command Substitution
- UNIX, Simple command line http server
- UNIX, One command line web server on port 80 using nc (netcat)
- UNIX, Faking Services using Netcat (For Testing Nagios)
- Wikipedia, Netcat: Setting up a one-shot webserver on port 8080 to present the content of a file