Kushal Das

FOSS and life. Kushal Das talks here.

kushal76uaid62oup5774umh654scnu5dwzh4u2534qxhcbi4wbab3ad.onion

PrivChat with Tor: 2020-12-11 Tor advancing human rights

Tomorrow, on 11th December, 2020 at 18:00UTC, Tor will host the third edition of the PrivChat event, to discuss with some real life Tor users and talk about how Tor helps them to defend human rights. You can watch it live on Youtube.

image of snowden

The event will be hosted by Edward Snowden, President, Freedom of the Press Foundation. We have Alison Macrina (Founder, Library Freedom Project), Berhan Taye ( Africa Policy Manager and Global Internet Shutdowns Lead, Access Now) and Ramy Raoof (Security Labs Technologist, Amnesty International) as participants in the discussion.

High load average while package building on Fedora 33

Enabling Link time optimization (LTO) with rpmbuild is one of the new features of Fedora 33. I read the changeset page once and went back only after I did the Tor package builds locally.

While building the package, I noticed that suddenly there are many processes with /usr/libexec/gcc/x86_64-redhat-linux/10/lto1 and my load average reached 55+. Here is a screenshot I managed to take in between.

high load average

Using Stem and PySocks to access network over Tor

I previously wrote about using the standard SOCKS proxy provided by the Tor Project on your system using Python, in particular using the requests module.

But, what about if you want to start a Tor SOCKS proxy only for your project (while the code is running), and use some existing code/module to do network calls (using sockets) over it?

Stem module to control the tor process

We can use Stem module to control the tor process in the system. In our example below, we will use PySocks module along with so that we can use urllib module to fetch some data. The code is based on one of the tutorial at the stem project. You will also notice that we are asking to use any exitnode from the Russia while creating the tor process.

Starting the tor process with a given SOCKS proxy port is super simple. And then we replace socket.socket with socks.socksocket (after the right configuration), and socket.getaddrinfo with our own implementation to make sure that we don't leak DNS information.

import io
import socket
import urllib.request

import socks
import stem.process
from stem.util import term

SOCKS_PORT = 7000


def query(url):
    """
    Uses urllib to fetch a site using the proxy on the SOCKS_PORT.
    """
    return urllib.request.urlopen(url).read()


def print_bootstrap_lines(line):
    if "Bootstrapped " in line:
        print(term.format(line, term.Color.BLUE))


def getaddrinfo(*args):
    "Let us do the actual DNS resolution in the SOCKS5 proxy"
    return [(socket.AF_INET, socket.SOCK_STREAM, 6, "", (args[0], args[1]))]


def main():
    # Start an instance of Tor configured to only exit through Russia. This prints
    # Tor's bootstrap information as it starts. Note that this likely will not
    # work if you have another Tor instance running.
    print(term.format("Starting Tor:\n", term.Attr.BOLD))

    tor_process = stem.process.launch_tor_with_config(
        config={
            "SocksPort": str(SOCKS_PORT),
            "ExitNodes": "{ru}",
        },
        init_msg_handler=print_bootstrap_lines,
    )

    print(term.format("\nChecking our endpoint:\n", term.Attr.BOLD))
    socks.set_default_proxy(
        socks.PROXY_TYPE_SOCKS5, "localhost", 7000, True, None, None
    )
    socket.socket = socks.socksocket
    socket.getaddrinfo = getaddrinfo
    try:
        print(term.format(query("https://icanhazip.com"), term.Color.BLUE))
    finally:
        tor_process.kill()  # stops tor


if __name__ == "__main__":
    main()

demo code running

If you are surprised about the getaddrinfo function above, it is just returning the same domain name it received (instead of an IP address). The actual DNS resolution happens over Tor at the proxy level.

PrivChat with Tor: 2020-08-28

Tomorrow at 17:00UTC, Tor Project is hosting the next session of PrivChat, titled "The Good, the Bad, and the Ugly of Censorship Circumvention". You can watch it live on Youtube.

PrivChat tomorrow 17:00UTC on youtube

This 2nd edition of PrivChat is about the Good, the Bad and the Ugly that is happening in the front lines of censorship circumvention. Cory Doctorow will be the host for the evening, and the following people will be participating:

  • Felicia Anthonio (Access Now),
  • Vrinda Bhandari (Internet Freedom Foundation ),
  • Cecylia Bocovich (Tor Project ),
  • Arturo Filastò (OONI )

Don't miss your chance to listen to them. You can ask questions via the Youtube chat.

Use DoH over Tor for your Qubes system

I was using my dns-tor-proxy tool in the AppVMs in my QubesOS system. But, at the same time I was trying to figure out how to make it the default DNS system for the whole Qubes.

ahf provided me a shell script showing how he is forwarding the DNS requests to a VPN interface. I modified the same so that all of standard DNS queries become DoH queries over the Tor network.

Setting up sys-firewall

In the following example, I am setting up the sys-firewall service VM. All other AppVMs connected to this VM as netvm will be use dns-tor-proxy without any modification.

Make sure that the template for sys-firewall has the latest Tor installed. You can get it from the official Tor repository.

Download (or build) the latest dns-tor-proxy 0.3.0 release, and put the file (as executable) in /rw/config/ directory.

Next, modify the /rw/config/rc.local file & add the following lines.

systemctl start tor
sh /rw/config/dns.sh
/rw/config/dns-tor-proxy --doh &

As you can see, we are executing another script at /rw/config/dns.sh, which has the following content. Remember to modify the DNS value to the right IP for your sys-firewall vm.


#!/bin/sh

QUBES_DNS_SERVERS="10.139.1.1 10.139.1.2"
DNS=10.137.0.x

# accept DNS requests from the other vms

iptables -I INPUT -i vif+ -p udp --dport 53 -j ACCEPT
iptables -I INPUT -i vif+ -p tcp --dport 53 -j ACCEPT

# Clean up our NAT firewall rules.
iptables --flush PR-QBS --table nat

# We take incoming traffic on TCP and UDP port 53 and forward to
# our DNS server.
for QUBES_DNS_SERVER in ${QUBES_DNS_SERVERS} ; do
    iptables --append PR-QBS --table nat --in-interface vif+ --protocol tcp --destination "${QUBES_DNS_SERVER}" --dport 53 --jump DNAT --to-destination "${DNS}":53
    iptables --append PR-QBS --table nat --in-interface vif+ --protocol udp --destination "${QUBES_DNS_SERVER}" --dport 53 --jump DNAT --to-destination "${DNS}":53
done

# Log *other* DNS service connections. This part is optional, but ensures that
# you can monitor if one of your VM's is making any traffic on port 53 with
# either TCP or UDP. If you want to log *every* DNS "connection", including the
# ones to QUBES_DNS_SERVERS, you can either move these commands up before the
# for-loop in this file or change the --apend option to be an --insert instead.
iptables --append PR-QBS --table nat --in-interface vif+ --protocol tcp --dport 53 --jump LOG --log-level 1 --log-prefix 'DNS Query: '
iptables --append PR-QBS --table nat --in-interface vif+ --protocol udp --dport 53 --jump LOG --log-level 1 --log-prefix 'DNS Query: '

Now, restart your sys-firewall vm. And you are all set for your DNS queries.

dns-tor-proxy 0.2.0 aka DoH release

I just now released 0.2.0 of the dns-tor-proxy tool. The main feature of this release is DNS over HTTPS support. At first I started writing it from scratch, and then decided to use modified code from the amazing dns-over-https project instead.

Demo

demo of the DoH support in the tool

✦ ❯ ./dns-tor-proxy -h
Usage of ./dns-tor-proxy:
      --doh                 Use DoH servers as upstream.
      --dohaddress string   The DoH server address. (default "https://mozilla.cloudflare-dns.com/dns-query")
  -h, --help                Prints the help message and exists.
      --port int            Port on which the tool will listen. (default 53)
      --proxy string        The Tor SOCKS5 proxy to connect locally, IP:PORT format. (default "127.0.0.1:9050")
      --server string       The DNS server to connect IP:PORT format. (default "1.1.1.1:53")
  -v, --version             Prints the version and exists.
Make sure that your Tor process is running and has a SOCKS proxy enabled.

Now you can pass --doh flag to enable DoH server usage, by default it will use https://mozilla.cloudflare-dns.com/dns-query. But you can pass any server using --dohaddress flag. I found the following servers are working well over Tor.

  • https://doh.libredns.gr/dns-query
  • https://doh.powerdns.org
  • https://dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion/dns-query
  • https://dnsforge.de/dns-query

The release also has a binary executable for Linux x86_64. You can verify the executable using the signature file available in the release page.

Introducing dns-tor-proxy, a new way to do all of your DNS calls over Tor

dns-tor-proxy is a small DNS server which you can run in your local system along with the Tor process. It will use the SOCKS5 proxy provided from Tor, and route all of your DNS queries over encrypted connections via Tor.

By default the tool will use 1.1.1.1 (from Cloudflare) as the upstream server, but as the network calls will happen over Tor, this will provide you better privacy than using directly.

In this first release I am only providing source packages, maybe in future I will add binaries so that people can download and use them directly.

Demo

In the following demo I am building the tool, running it at port 5300, and then using dig to find the IP addresses for mirrors.fedoraproject.org and python.org.

demo of dns tor proxy

The -h flag will show you all the available configurable options.

./dns-tor-proxy -h

Usage of ./dns-tor-proxy:
  -h, --help            Prints the help message and exists.
      --port int        Port on which the tool will listen. (default 53)
      --proxy string    The Tor SOCKS5 proxy to connect locally,  IP:PORT format. (default "127.0.0.1:9050")
      --server string   The DNS server to connect IP:PORT format. (default "1.1.1.1:53")
  -v, --version         Prints the version and exists.
Make sure that your Tor process is running and has a SOCKS proxy enabled.

Access Riseup email over Onion service

Email service (📧) is another excellent example that can be accessed safely over Tor Onion services. This is in particular useful in places where people in power do not like their citizens accessing privacy-focused email providers. I know, you must be thinking about your own country, but no worries, we all are in the same place :)

In this post, I will explain how one can access their emails via IMAP, and send using SMTP over onion services. I am taking Riseup as an example because they provide this option to the users, and also because I personally use their service. This document assumes that you already have tor service running on your system.

Riseup Tor Onion services address

Riseup and Tor

Riseup has a page listing all the Onion service addresses they provide. You can also verify the signed address from the signed file in the same page. For the rest of this post, we will use 5gdvpfoh6kb2iqbizb37lzk2ddzrwa47m6rpdueg2m656fovmbhoptqd.onion as the address for both IMAP and SMTP services. In the normal Internet, those are imap.riseup.net and smtp.riseup.net.

Getting the SSL certificate for the service for verification

Riseup uses Let's Encrypt for the SSL certificates. We have to pin them for the above-mentioned onion address so that we can use them in our system.

mkdir -p ~/.cert
torify openssl s_client -connect 5gdvpfoh6kb2iqbizb37lzk2ddzrwa47m6rpdueg2m656fovmbhoptqd.onion:993 -showcerts 2>&1 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sed -ne '1,/-END CERTIFICATE-/p' > ~/.cert/riseuponion.pem

openssl x509 -in .cert/riseuponion.pem -noout -sha256 -fingerprint
SHA256 Fingerprint=C6:BB:7B:04:97:54:05:65:76:81:4D:56:22:CE:50:6C:91:53:D3:3E:27:95:CC:C9:B8:B7:19:A5:E9:31:7D:15

The first command fetches the SSL certification from the given onion addresses, and stores it in the ~/.cert/riseuponion.pem file. The second command gives us the fingerprint for the same. You can verify these values by running the command against imap.riseup.net:993 and comparing the values.

By the way, remember that these values will change every 3 months (like any other Let's Encrypt certificate).

Setting up mbsync for IMAP access of the emails

I prefer to use the mbsync command from the imap package. The following the configuration for the same.

IMAPAccount riseup
# Address to connect to
Host 5gdvpfoh6kb2iqbizb37lzk2ddzrwa47m6rpdueg2m656fovmbhoptqd.onion
Port 993
User <my full email address without angle brakets>
PassCmd "/usr/bin/pass riseup"
# Use SSL
AuthMechs PLAIN
SSLType IMAPS
SSLVersions TLSv1 TLSv1.1 TLSv1.2
CertificateFile /home/kdas/.cert/riseuponion.pem

IMAPStore riseup-remote
Account riseup

MaildirStore riseup-local
# The trailing "/" is important
Path ~/.imap-mail/riseup/
Inbox ~/.imap-mail/riseup/Inbox

Channel riseup
Master :riseup-remote:
Slave :riseup-local:
# Exclude certain things
# Or include everything
Patterns *
# Automatically create missing mailboxes, both locally and on the server
Create Both
# Save the synchronization state files in the relevant directory
SyncState *

You can notice that I am using the CertificateFile key to point to the certificate we downloaded previously.

Now, I can sync the emails using the torify along with the regular mbsync command.

torify mbsync -a riseup 

Setting up msmtp to send emails

The following is my msmtp configuration

# riseup
account riseup
host 5gdvpfoh6kb2iqbizb37lzk2ddzrwa47m6rpdueg2m656fovmbhoptqd.onion
port 587
auth on
proxy_host 127.0.0.1
proxy_port 9050
tls on
tls_fingerprint C6:BB:7B:04:97:54:05:65:76:81:4D:56:22:CE:50:6C:91:53:D3:3E:27:95:CC:C9:B8:B7:19:A5:E9:31:7D:15
user <my full email address without angle brakets>
passwordeval "/usr/bin/pass riseup"
maildomain riseup.net
from <my full email address without angle brakets>

One thing to notice that msmtp actually allows us to directly mention the tor socks proxy details in the configuration file. And then in my mutt configuration, I mentioned

set sendmail="/usr/bin/msmtp -a riseup"

Onion service v2 deprecation timeline

On Monday June 15, the developers of the Tor Project announced the initial plan for the deprecation of Onion services v2. You can identify v2 addresses easily as they are only 16 character long, where as the v3 addresses are 56 character long.

Why?

The v2 services used RSA1024, where as v3 uses ed25519, means better cryptography. We can also have offline keys for the onion service. You can read all other benefits in the v3 spec.

Timeline

According to the email to the list, the following the current timeline:

  • On 2020-09-15 with 0.4.4.x release Tor will start informing v2 onion service operators that v2 is deprecated.
  • On 2021-07-15 with 0.4.6.x release Tor will stop supporting v2 onion addresses, and all related source code will be removed.
  • On 2021-10-15 there will be a new stable version release which will disable using v2 onion services on the Tor network.

How can you prepare as an Onion service provider?

If you are using/providing any v2 onion service, you should enable v3 service for the same service. This will help you to test your v3 configuration while keeping the v2 on, and then you can retire your v2 address. If you need help in setting authenticated v3 service, you can follow this blog post. I wrote another post which explains how can you generate the keys using Python cryptography module.

Read the full announcement in the list archive.

Onion location and Onion names in Tor Browser 9.5

Yesterday the Tor Browser 9.5 was released. I am excited about this release for some user-focused updates.

Onion-Location header

If your webserver provides this one extra header Onion-Location, the Tor Browser will ask the user if they want to visit the onion site itself. The user can even mark to visit every such onion site by default. See it in action here.

To enable this, in Apache, you need a configuration line like below for your website’s configuration.

Onion location demo

Header set Onion-Location "http://your-onion-address.onion%{REQUEST_URI}s"

Remember to enable rewrite module.

For nginx, add the following in your server configuration.

add_header Onion-Location http://<your-onion-address>.onion$request_uri;

URL which we can remember aka onion names

This is the first proof of concept built along with Freedom of the Press Foundation (yes, my team) and HTTPS Everywhere to help people to use simple names for onion addresses. For example, below, you can see that I typed theintercept.securedrop.tor.onion on the browser, and that took us to The Intercept’s SecureDrop address.

Onion name