How to make tiny tiny RSS connect through tor?

How to make tiny tiny RSS connect through tor? (french bellow)

Hello everyone,

I’m looking for some help : I have installed Yunohost RSS feed reader (tiny tiny
RSS) on my internet cube and I would like that its connexions go through tor
network so that my ip is masked for RSS feeds servers. Has anyone ever done
this?

Feeds are updated every 30 minutes from a crontab :
*/30 * * * * www-data cd /var/www/ttrss && /usr/bin/php /var/www/ttrss/update.php --feeds >/dev/null 2>&1

I modified it to use tor wrapper but I’m not sure my ip is properly masked :
## torify the app :
0,30 * * * * www-data cd /var/www/ttrss && /usr/bin/torify /usr/bin/php /var/www/ttrss/update.php --feeds >/dev/null 2>&1
## restart tor to change the ip address :
15,45 * * * * root /etc/init.d/tor restart

I wanted to checked that it was working but :
# all that I see here is that my internet traffic goes to my non-profit ISP (my
# VPN works like a charm) :
tcpdump -i eth0
# here, I see connexions to tor relays all the time (not only when the crontab
# is executed) and no direct connexion to any RSS feeds server :
netstat --tcp --udp --continuous –programs

So, basically, I have two questions :

  • is this enough to mask my ip to RSS feeds servers?
  • how can I be sure?

Thank you for your help,


Comment configurer tiny tiny RSS pour utiliser tor?

Salut tout le monde,

Je suis à la recherche d’un peu d’aide : j’ai installé l’agrégateur de flux RSS
(tiny tiny RSS) de yunohost sur ma brique internet et j’aimerais que ses
connexions passent par tor pour que mon ip soit masquée auprès des serveur qui
fournissent les flux. Quelqu’un a déjà fait ça?

L’update des flux se fait toutes les 30 min via une crontab :
*/30 * * * * www-data cd /var/www/ttrss && /usr/bin/php /var/www/ttrss/update.php --feeds >/dev/null 2>&1

Je l’ai modifiée pour utiliser le wrapper tor mais je ne suis pas sûr que cela
masque bien mon ip :
## torify the app :
0,30 * * * * www-data cd /var/www/ttrss && /usr/bin/torify /usr/bin/php /var/www/ttrss/update.php --feeds >/dev/null 2>&1
## restart tor to change the ip address :
15,45 * * * * root /etc/init.d/tor restart

J’ai voulu vérifier que cela fonctionnait, mais :
# tout ce que je vois ici, c’est que mon trafic est redirigé chez mon FAI
# associatif (mon VPN fonctionne bien) :
tcpdump -i eth0
# ici, je vois des connexions vers des relais tor en permanence (pas seulement
# lors de l’exécution de la crontab) et pas de connexion directe vers un des
# serveur fournissant les flux :
netstat --tcp --udp --continuous –programs

J’ai donc deux questions :

  • est-ce que vous pensez que cela suffise à masquer mon ip?
  • comment puis-je le vérifier?

Merci pour votre aide,

alb

Hello everyone,

It’s been a while I stopped working on this issue. Now I had the time to take a closer look at it and I think I solved it. Here I post my solution, feel free to tell me if I missed anything.

The previous updates I did on my internet cube moved Tiny Tiny RSS updates from a crontab to a systemd deamon which is now executed from file :

/etc/systemd/system/ttrss.service

But this does not change anything since I do not have to edit the crontab or the service.

First of all, here is how I can tell that I connect through TOR. The following command will show network connections for the /usr/bin/php program :

netstat --tcp --numeric-ports --programs --continuous 2>&1 | grep php

When /usr/bin/php program establishes a connection (i.e. when Tiny Tiny RSS fetches feeds), its destination and port is printed in the standard output.

In an other terminal, we can force Tiny Tiny RSS to fetch feeds with the following command :

/usr/bin/php /var/www/ttrss/update.php --force-update --feeds

This will print the connections in the terminal running netstat and will show the IP addresses of the servers where the feeds are fetched from (note that at least one user must have one RSS feed in his/her list).

Then, the first step is to configure TOR to make it controllable through command line interface, I used this tutorial to do so. A summary is as follows :

The first step is to install TOR from the repositories and make it possible to be controlled through a socket on port 9051 :

sudo apt-get install tor

Then edit file /etc/tor/torrc to uncomment the directive :

ControlPort 9051

Then set a password to control TOR by typing :

tor --hash-password "passwordhere"

And copy the hash in file /etc/tor/torrc on the line (which must be uncommented) starting with :

HashedControlPassword

Restart TOR (sudo /etc/init.d/tor restart) and it can now be controlled by sending commands to localhost on port 9051. See this tutorial to test it. Also, a socket listens on port 9050 to redirect the connections through TORSOCKS (see man torsocks for more informations).

The second step is to edit the PHP code of Tiny Tiny RSS to connect through TOR when fetching the content of RSS feeds.

Edit function fetch_file_contents in file /var/www/ttrss/include/functions.php to add the following content :

// connect through TOR :
curl_setopt($ch, CURLOPT_PROXY, 'localhost:9050');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);

after the lines :

if (defined('_CURL_HTTP_PROXY')) {
  curl_setopt($ch, CURLOPT_PROXY, _CURL_HTTP_PROXY);
}

(Note : in my installation, these are lines 416, 417 and 418)

Then, PHP command @curl_exec($ch); will be fetching data through the TOR socket. See this post for more informations.

Now, running netstat and forcing Tiny Tiny RSS to fetch the feeds will show connections to 127.0.0.1:9050, not to the IP server.

The last step is to control TORSOCKS from the same function to change the relays so that our IP address changes for each feed.

Edit function fetch_file_contents in file /var/www/ttrss/include/functions.php to add the following content at its beginning :

// connect to the TOR daemon to restart it :
$client = stream_socket_client( "localhost:9051", $errno, $errorMessage );
if ( $client === false ) {
  throw new UnexpectedValueException( "Failed to connect: $errorMessage" );
} else {
  fwrite( $client,
          "AUTHENTICATE \"passwordhere\"\r\nsignal NEWNYM\r\nQUIT\n" );
  fclose($client);
}

Now a different IP is used to fetch the RSS feeds. Note that the previously selected password must be set after the AUTHENTICATE keyword.

This can be tested with a simple PHP program. Just write the following text in a /tmp/test.php file :

<?php
// connect to the TOR daemon to restart it :
$client = stream_socket_client( "localhost:9051", $errno, $errorMessage );
if ( $client === false ) {
  throw new UnexpectedValueException( "Failed to connect: $errorMessage" );
} else {
  fwrite( $client,
          "AUTHENTICATE \"passwordhere\"\r\nsignal NEWNYM\r\nQUIT\n" );
  fclose($client);
}

$ch = curl_init('http://ipecho.net/plain');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);

// SOCKS5
curl_setopt($ch, CURLOPT_PROXY, 'localhost:9050');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);

curl_exec($ch);
curl_close($ch);
echo "\n";
?>

And run the following command several times to see your IP change :

/usr/bin/php /tmp/test.php

In the end, restart Tiny Tiny RSS deamon, just to be sure :

sudo systemctl status ttrss.service

That’s it, Tiny Tiny RSS now fetches feeds through the TOR network. Hope this helps.

alb

Ps: feel free to tell me if I missed anything.

1 Like

Hey alb1,

I am very much interested in having my Tiny Tiny RSS connect through Tor too. I tried to follow your guide but got some errors and got lost.

So, before asking anything else,
Is your guide still valid? or does it need any update?
Could it somehow be simplified?
Your two posts have many things, I am not an expert and get easily scared…

Cheers!

Hello @peer,

Note that installing some programs that are not supported by Yunohost can break your server (I know what I’m talking about). I highly recommend to create a backup and to try it in a virtual machine first (even if it does not guarantee that it will be durable).
Also, I’m not an expert in computer science and beware that what I say might not be accurate.

I tried to follow my post into configuring TTRSS to make it connecting through TOR. This method is still working on Yunohost 3.3.1 but my post might need to be more detailed.

I configured it in a brand new virtual machine that I installed on purpose. Here I describe what I did step by step. Just try to reproduce it and tell me if you face any problem.

I hope this post helps more than the previous one. Feel free to tell me if I missed anything.

@alb1

BEFORE WE START

First, install the virtual machine and configure its network as a bridged adapter (https://yunohost.org/#/install_on_virtualbox).

On the host: call “sudo arp-scan -local” to have the list of devices that are connected to your network.

Boot the virtual machine.

On the host: call “sudo arp-scan -local” again to see the IP of the virtual machine.
On the host, edit file /etc/hosts and add a line with the IP and our test domain so that this domain can be accessed by the host. Note, I chose “test.nohost.me”. No registration is performed so any domain will do.

Then, access the virtual machine through ssh:
ssh root@test.nohost.me

FIRST STEP: INSTALLATION AND CONFIGURATION OF TTRSS

yunohost tools postinstall --ignore-dyndns
# note: the --ignore-dyndns option avoids the domain registration
# domain: test.nohost.me
# enter a password and confirm it

yunohost user create alb1
# first name: alb
# last name: one
# e-mail: alb1@test.nohost.me

yunohost app install ttrss
# everything set to its default value

/usr/bin/php /var/www/ttrss/update.php --force-update --feeds
# this command cannot be run as root.

adduser yolo
# password: yolo

/usr/bin/php /var/www/ttrss/update.php --force-update --feeds
# you get some errors because ttrss directories are not writable. You must add
# writing rights:
(as root:) chmod -R 777 /var/www/ttrss/
(as yolo:) /usr/bin/php /var/www/ttrss/update.php --force-update --feeds
# this now forces ttrss to update the feeds

Using your web browser from the host, connect to test.nohost.me, login as alb1 and open Tiny Tiny RSS. Then add a RSS feed so that we can see that it is fetched by the previous command.

# Back in the terminal, as yolo:
/usr/bin/php /var/www/ttrss/update.php --force-update --feeds
# the previously added feed is fetched

SECOND STEP: SEE THE CONNECTION OF TTRSS USING NETSTAT

# Open a second terminal (without closing the first one) and ssh in the virtual
# machine again:
ssh root@test.nohost.me

# Run the following commands:
apt-get install net-tools
netstat --tcp --numeric-ports --programs --continuous 2>&1 | grep php

# Now, back in the first terminal, as yolo, fetch the feeds again:
/usr/bin/php /var/www/ttrss/update.php --force-update --feeds

# In the terminal running netstat, a line appears showing the destination for
# the RSS feed. Something like:
tcp 0 0 test.nohost.me:44430 <the_destination>:443 ESTABLISHED 4531/php

# This destination is an IP or domain, this means that the RSS agregator does
# not connect through tor, its connects directly to its target.

THIRD STEP: INSTALLATION AND CONFIGURATION OF TOR

# Now, as root:
apt-get install tor
tor --hash-password "passwordhere"
# copy the password hash

vim /etc/tor/torrc
# uncomment the '#' at the beginning of line: "ControlPort 9051"
# uncomment the '#' at the beginning of line: "HashedControlPassword (a hash)"
# and replace the hash by the one you just copied

# restart tor:
/etc/init.d/tor restart

FOURTH STEP: TESTING TOR USING PHP

Now write a file named /tmp/test.php with the following content:

<?php
// connect to the TOR daemon to restart it :
$client = stream_socket_client( "localhost:9051", $errno, $errorMessage );
if ( $client === false ) {
  throw new UnexpectedValueException( "Failed to connect: $errorMessage" );
} else {
  fwrite( $client,
          "AUTHENTICATE \"passwordhere\"\r\nsignal NEWNYM\r\nQUIT\n" );
  fclose($client);
}

$ch = curl_init('http://ipecho.net/plain');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);

// SOCKS5
curl_setopt($ch, CURLOPT_PROXY, 'localhost:9050');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);

curl_exec($ch);
curl_close($ch);
echo "\n";
?>

Execute this script with the following command:

/usr/bin/php /tmp/test.php

The last line represents your IP address. Execute this script several times to see it change (note: TOR does not change your exit node at each path modification, you might have to execute it 4 or 5 times to see it change).

FIFTH STEP: MODIFYING TTRSS TO MAKE IT CONNECT THROUGH TOR

Edit function fetch_file_contents in file /var/www/ttrss/include/functions.php to add the following content at its beginning:

// connect to the TOR daemon to restart it :
$client = stream_socket_client( "localhost:9051", $errno, $errorMessage );
if ( $client === false ) {
  throw new UnexpectedValueException( "Failed to connect: $errorMessage" );
} else {
  fwrite( $client,
          "AUTHENTICATE \"passwordhere\"\r\nsignal NEWNYM\r\nQUIT\n" );
  fclose($client);
}

and add the following content:

// connect through TOR :
curl_setopt($ch, CURLOPT_PROXY, 'localhost:9050');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);

after the lines:

if (defined('_CURL_HTTP_PROXY')) {
  curl_setopt($ch, CURLOPT_PROXY, _CURL_HTTP_PROXY);
}

Now, back in the first terminal, as yolo, fetch the feeds again:

/usr/bin/php /var/www/ttrss/update.php --force-update --feeds

In the terminal running netstat, a line appears showing the destination for the RSS feed. Something like:

tcp 0 0 test.nohost.me:44430 localhost:9050 ESTABLISHED 7511/php

This destination is now localhost on port 9050, this means that the RSS aggregator now connects through tor.

NOT WORKING WITH IPv6

Note, in my case, this does not work because I have native IPv6 and TOR is only
compatible with IPv4. So, to make it work I had to totally deactivate IPv6. I’m
sure a better solution exists and it’s worth looking into it. I just have not
the time right now.

# Here is a quick fix (totally disabling IPv6):
echo "# IPv6 disabled" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
sysctl -p
2 Likes

Wow, that’s a really nice tutorial. Thank you @alb1