Balaji's Blog https://blog.balaji-dutt.name One geek's misadventures in technology and life Sat, 27 Feb 2016 08:06:58 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 A simple upgrade to my home network https://blog.balaji-dutt.name/2015/696-a-simple-upgrade-to-my-home-network/ Mon, 27 Jul 2015 05:00:53 +0000 http://blog.balaji-dutt.name/?p=696 In case  you are wondering what is the thought process behind how someone winds up spending close to a 1000 SGD on just upgrades to a home network, wonder no more! “Ok. Clearly having a WiFi network that’s 2.4 GHz just isn’t working any more” “Since the Routerboard device I’m …

The post A simple upgrade to my home network appeared first on Balaji's Blog.

]]>
In case  you are wondering what is the thought process behind how someone winds up spending close to a 1000 SGD on just upgrades to a home network, wonder no more!

  • “Ok. Clearly having a WiFi network that’s 2.4 GHz just isn’t working any more”

That's a lot of Wifi points

  • “Since the Routerboard device I’m using doesn’t support 5 GHz WiFi, I’m going to need to pick up another WiFi router and make into an access point”
  • “If I’m going to be adding more access points, why not just make my Routerboard into an access point as well? I know I’m pretty annoyed by the fact that I can’t get a Speedtest result that shows me using anything more than 8% of my bandwidth allowance. Maybe 1 Gbps? Yeah, 1 Gbps sounds pretty good”
  • “Maybe I should pick up a EdgeRouter – that’s not too expensive right?”

Hours of reading forum posts and actually posting to forums yields a disappointing answer – some Firewall features I use on my Routerboard are only supported in “software-mode” by the EdgeRouter, which defeats the biggest USP of the device – hardware acceleration of firewall rules.

  • “Ok if I need to stick with Routerboard, what device can I get that handle my network config without maxing out its CPU”?

Turns out my ISP recommends that for the plan I’m subscribed to, I have to get a Mikrotik Cloud Core Router. More specifically, a CCR-1009-8G-1S-1S+PC1. Gulp

  • “Ok I’ve bitten the bullet and bought a router that can power a small ISP2. I’m guess I’m set now”
  • “Wait, if I want to have my current Routeboard act as an access point with a Guest WiFi network, I need to be able run VLAN’s?. What the hell is a VLAN?”
  • “Alright, so I need a switch that can support VLAN’s. Here’s hoping the dumb switch I bought 5 years ago supports passing VLAN’s”
  • “Guess that was too much to expect. Now I need a switch that can support tagging VLAN’s”

And that ladies and gentlemen, is how the idea of switching a home WiFi network from 2.4 GHz to 5 GHz turns out to require new WiFi access points, new switches and a router that’s massively overpowered for a home network. Coming in the future – a post about what my home network looks like after all these upgrades are done.

 


  1. You just gotta love these product names 

  2. Literally 

The post A simple upgrade to my home network appeared first on Balaji's Blog.

]]>
Fixing ruTorrent errors with nginx 1.6.1-2 https://blog.balaji-dutt.name/2014/677-fixing-rutorrent-errors-nginx-1-6-1-2/ Sat, 01 Nov 2014 03:53:45 +0000 http://blog.balaji-dutt.name/?p=677 The nginx 1.6.1-2 release on Debian Backports made a change to the default fastcgi configuration file with an almost casual reference in the release notes: [crayon-5b55deaa8fe0e038243640/] Talk about an understatement – that change broke every single PHP based site I manage (including this blog). Fixing the errors from this change …

The post Fixing ruTorrent errors with nginx 1.6.1-2 appeared first on Balaji's Blog.

]]>
The nginx 1.6.1-2 release on Debian Backports made a change to the default fastcgi configuration file with an almost casual reference in the release notes:

* debian/conf/fastcgi_params:
    + Sync with upstream and remove `SCRIPT_FILENAME` parameter.
      This change might break fastcgi sites. (Closes: #718639)

Talk about an understatement – that change broke every single PHP based site I manage (including this blog).

Fixing the errors from this change depends on how ruTorrent is setup – If ruTorrent is running as the only application on the site then the change is fairly straight forward, change the location handler for PHP files to include the SCRIPT_FILENAME parameter:

location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_pass  @phpfpm;
}

On the other hand, if ruTorrent is setup to run from a subfolder off the main site, i.e. http://site.com/rutorrent the parameter is quite different and figuring out what is the correct syntax proved to be surprisingly difficult. I could never get the ruTorrent debug log to work and the on-screen error messages are singularly unhelpful. The magic incantation for ruTorrent as a subfolder is to use REQUEST_FILENAME in the fastcgi_param config instead:

location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass  @phpfpm;
}

The post Fixing ruTorrent errors with nginx 1.6.1-2 appeared first on Balaji's Blog.

]]>
nginx + Apache + W3 Total Cache – a bad combination https://blog.balaji-dutt.name/2013/481-nginx-apache-w3-total-cache-a-bad-combination/ Sun, 13 Jan 2013 13:10:44 +0000 http://blog.balaji-dutt.name/?p=481 WordPress is notorious for buckling if a site sees a sudden spike in traffic (also known as the Digg Effect, slashdotted, fireballed etc. etc.). As a result, a number of plugins have emerged to replace the default “render-on-every-access” WordPress model with serving static files from disk (ala Drupal or Joomla). …

The post nginx + Apache + W3 Total Cache – a bad combination appeared first on Balaji's Blog.

]]>
WordPress is notorious for buckling if a site sees a sudden spike in traffic (also known as the Digg Effect, slashdotted, fireballed etc. etc.). As a result, a number of plugins have emerged to replace the default “render-on-every-access” WordPress model with serving static files from disk (ala Drupal or Joomla). The other option is to use nginx as a front-end proxy for Apache, letting nginx handle serving static files while Apache takes care of dynamic content. This is the setup I have in place for the wiki and my Gitweb installation as well.

One of the most popular plugins for content caching is W3 Total Cache. W3 Total Cache handles page caching (aka serving content from static HTML) but also does DB caching, browser caching and CDN redirection (if you’re so inclined). With a stock Apache or nginx (with PHP-CGI) install, getting W3 Total Cache working is fairly straightforward.

Unfortunately, once you decide to use the combination of nginx + Apache, the story gets a lot murkier.

Let’s look at the stock nginx configuration for WordPress when proxying to Apache:

server {
listen ip.add.re.ss:80;
server_name blog.domain.com;
error_log /var/log/nginx/blog-error.log;
access_log /var/log/nginx/blog-access.log combined;

## Your only path reference.
root /var/www/wordpress;
## This should be in your http block and if it is, it's not needed here.
index index.php;
#--snip--
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$uri&$args;
}

location ~ .php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
proxy_pass_header Set-Cookie;
proxy_pass_header Cache-Control;
proxy_pass http://127.0.0.1:80;
proxy_hide_header X-Powered-By;
}
}

In this configuration, page caching will simply not work:

W3 Total Cache - rejected URI

The reason for this is the URL that gets passed to Apache:

$ tail /var/log/apache2/blog-access.log
[13/Jan/2013:02:09:31 -0800] "GET /index.php?/2012/38-dummy-post-3/& HTTP/1.0" 200 5056 "-"

In contrast, look at the actual URL that’s being used to access the page:

The inclusion of the index.php in the URL is breaking the caching as W3 Total Cache is expecting the URL to match what nginx is seeing. The nginx configuration is the problem and needs to be fixed.

Let’s try a different nginx configuration:

server {
listen ip.add.re.ss:80;
server_name blog.domain.com;
error_log /var/log/nginx/blog-error.log;
access_log /var/log/nginx/blog-access.log combined;

## Your only path reference.
root /var/www/wordpress;
## This should be in your http block and if it is, it's not needed here.
index index.php;
#--snip--
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri/ @wordpress;
}

location @wordpress {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
proxy_pass_header Set-Cookie;
proxy_pass_header Cache-Control;
proxy_pass http://127.0.0.1:80;
proxy_hide_header X-Powered-By;
}

Success! W3 Total Cache is now seeing the URL the way nginx sees it and page caching is starting to work.

W3 Total Cache enabled

Except, the home page seems to be missing :(. The reason for this is that the default / URL looks for the directory file, i.e. index.php which isn’t currently handled by the nginx configuration.
So let’s add an handler for .php files in nginx:

location @wordpress {
#--snip--
}

location ~ .php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
proxy_pass_header Set-Cookie;
proxy_pass_header Cache-Control;
proxy_pass http://127.0.0.1:80;
proxy_hide_header X-Powered-By;
}

Let’s refresh the browser and check.. yup, the homepage is back. Looks it’s time to celebrate except..

W3 Total Cache - homepage

This happens because index.php is not normally cached by W3 Total Cache. Only the output from index.php needs to be cached by W3 Total Cache.

W3 Total Cache - page cache settings

Finally, remember the try_files directive that we used to get permalink caching working? That directive tells nginx to look for the file on disk first and only if not found, pass the request to Apache. This means that any static files in the wordpress directory will be served by nginx and W3 Total Cache doesn’t come into effect at all. This is mostly fine, since nginx can also handle the browser caching and content gzipping. Where this breaks down is if you intend to use a CDN as the files will not be redirected by nginx.

So that’s where things stand – You can either have caching on articles but a broken homepage or caching on articles, no caching on the homepage and no CDN capabilities. If anyone has suggestions on how to get W3 Total Cache working with nginx+Apache, let me know in the comments.

The post nginx + Apache + W3 Total Cache – a bad combination appeared first on Balaji's Blog.

]]>
Preventing version Leakage when using Dokuwiki https://blog.balaji-dutt.name/2010/469-preventing-version-leakage-when-using-dokuwiki/ Sun, 25 Jul 2010 09:15:37 +0000 http://blog.balaji-dutt.name/?p=469 As if not updating my blog for months at time wasn’t enough, I also maintain a wiki that gets even less attention 🙁 The software powering the wiki is Dokuwiki – a fantastic wiki software that’s very feature-rich (thanks to a plugin architecture) but very lightweight (everything is maintained in …

The post Preventing version Leakage when using Dokuwiki appeared first on Balaji's Blog.

]]>
As if not updating my blog for months at time wasn’t enough, I also maintain a wiki that gets even less attention 🙁

The software powering the wiki is Dokuwiki – a fantastic wiki software that’s very feature-rich (thanks to a plugin architecture) but very lightweight (everything is maintained in text files!)

There is however one mild annoyance – Dokuwiki insists on adding a Meta-header advertising the version number and there’s no direct way of turning this off:

dokuwiki-version

Luckily there’s a plugin that can help – the metaheaders plugin. Unfortunately, the plugin does not ship with a configuration UI and the documentation on the plugin page is sparse. In order to disable the “generator” meta that Dokuwiki adds, here’s what you need to do:

1. Create a file called metaheaders.conf.php in the Dokuwiki conf directory. If you are using the dokuwiki package in Debian, the metaheaders.conf.php needs to go into the /etc/dokuwiki directory.

2. Add the following lines to the metaheaders.conf.php file:

<?php
$clear[] = array ( 'name' => 'generator' );

3. Clear the dokuwiki cache – you can do this by issuing a touch command on each txt file in the pages directory under /path/to/dokuwiki/data/pages (or /var/lib/dokuwiki/data/pages in Debian). Or, you can take the nuclear option and remove the cache directory entirely (/var/lib/dokuwiki/data/cache in Debian). Either way, once you’ve done this – you can trigger a full refresh of the page in your browser and check the page headers:

dokuwiki-noversion

The post Preventing version Leakage when using Dokuwiki appeared first on Balaji's Blog.

]]>
Preventing Version Info Leakage with Dotdeb’s PHP 5.3.2 for Debian https://blog.balaji-dutt.name/2010/461-preventing-version-info-leakage-with-dotdebs-php-5-3-2-for-debian/ https://blog.balaji-dutt.name/2010/461-preventing-version-info-leakage-with-dotdebs-php-5-3-2-for-debian/#comments Sat, 24 Jul 2010 08:50:06 +0000 http://blog.balaji-dutt.name/2010/07/24/preventing-version-info-leakage-with-dotdebs-php-5-3-2-for-debian/ There are plenty of arguments for and against Security Through Obscurity – I’m of the opinion that while the benefit for doing it might be slim, actually implementing it doesn’t cause any problems, so why not? Moving On! The fastest way to upgrade the PHP version on Debian/Lenny “stable” without …

The post Preventing Version Info Leakage with Dotdeb’s PHP 5.3.2 for Debian appeared first on Balaji's Blog.

]]>
There are plenty of arguments for and against Security Through Obscurity – I’m of the opinion that while the benefit for doing it might be slim, actually implementing it doesn’t cause any problems, so why not?

Moving On! The fastest way to upgrade the PHP version on Debian/Lenny “stable” without running into dependency hell is through the dotdeb repositories. Not only does it allow you to upgrade to PHP 5.3.2, you also get the ability to install PHP-FPM through the Debian package manager, instead of having to re-compile PHP from source.

There is one small problem though – once you upgrade using the Dotdeb repository, all your PHP pages have an “X-Powered-By” header included:

header-versionleak

If you are serving PHP content using Apache/2 alone, fixing this is relatively simple. Enable mod_headers as follows:

a2enmod headers

Then add the following line to your Virtual Host definition:1

RequestHeader unset X-Powered-By

Now reload your Apache configuration and the header information should disappear when you do a full refresh of the page in your browser.

On the other hand, it becomes a little more complicated if you are using Nginx as your public web-server and proxying PHP requests to a backend Apache process. Depending on how your Nginx setup is configured to handle PHP requests, you may need to use one of two approaches:

Approach 1 – Nginx directly serves PHP content by proxying to a PHP/FastCGI server

If you have installed PHP-FPM, you will know that it runs as a service listening for any requests on Port 9000. Hence, you could have Nginx serve PHP content using the following directives:

location ~* ^.*.php$ {
fastcgi_pass   localhost:9000;
fastcgi_param  SCRIPT_FILENAME  /var/www/mywebsite/$fastcgi_script_name;}

To hide your PHP version, add the following directive to the Nginx configuration:

#Prevent version info leakage
fastcgi_hide_header X-Powered-By;

Approach 2 – Nginx serves PHP content by proxying to an Apache process:

In this approach, the Nginx configuration for serving PHP content looks very different from Approach 1:

location ~* ^.*.php$ {
proxy_pass http://127.0.0.1:80;
}

The directive for hiding the version information also changes as Nginx is now acting as reverse-proxy:

#Prevent version info leakage
proxy_hide_header X-Powered-By;

Reload your Nginx configuration and check that the changes have taken effect by triggering a full refresh of the page in your browser:

header-noversion


  1. Note: I don’t use Apache as my front-end web server anymore so this isn’t tested by me. That said, it should work  

The post Preventing Version Info Leakage with Dotdeb’s PHP 5.3.2 for Debian appeared first on Balaji's Blog.

]]>
https://blog.balaji-dutt.name/2010/461-preventing-version-info-leakage-with-dotdebs-php-5-3-2-for-debian/feed/ 1
Publish GitWeb with Nginx Reverse-Proxying for Apache https://blog.balaji-dutt.name/2010/11-publish-gitweb-with-nginx-reverse-proxying-for-apache/ Thu, 15 Jul 2010 14:52:55 +0000 http://blog.balaji-dutt.name/?p=11 Most installation guides for GitWeb assume that it will be hosted by a single web-server process (either Nginx or Apache). This article will show how to host GitWeb with Nginx acting as a front-end for Apache. Assumptions The Server OS is Debian/Lenny “stable” Nginx is setup to listen for incoming …

The post Publish GitWeb with Nginx Reverse-Proxying for Apache appeared first on Balaji's Blog.

]]>
Most installation guides for GitWeb assume that it will be hosted by a single web-server process (either Nginx or Apache). This article will show how to host GitWeb with Nginx acting as a front-end for Apache.

Assumptions

  • The Server OS is Debian/Lenny “stable”
  • Nginx is setup to listen for incoming connections on a publicly-accessible IP
  • Apache is configured to allow for multiple virtual hosts on the localhost IP

Nginx Compatability

For GitWeb to work correctly, the installed version of Nginx must support the try_files directive. Unfortuantely, the Debian “stable” version of Nginx (0.6.xx) does not. Hence, the Nginx install will need to be upgraded to 0.7.27 or higher. In Debian/Lenny, this can be easily accomplished with Backports – refer the Backports FAQ on adding backports to your sources.list file. Once that is done, the only command required is:

aptitude -t lenny-backports install nginx

Nginx Configuration

Add the following to your website configuration file under /etc/nginx/sites-available:

server {

listen my.ip.add.ress:80;
server_name gitweb.domain.com;
server_name_in_redirect off;

log_format domain_gitweb '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/gitweb-domain_access.log domain_gitweb;
error_log /var/log/nginx/gitweb-domain-error.log;

gzip on;
gzip_buffers 16 8k;
gzip_min_length 0;
gzip_proxied no-cache;
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript application/x-javascript;
gzip_disable "MSIE [1-6]\.";
gzip_comp_level 6;

## Only allow GET and HEAD request methods
if ($request_method !~ ^(GET|HEAD)$ ) {
return 444;
}

root /usr/share/gitweb;
#root has to be moved outside any location directives, otherwise adding expire headers
#will break

location / {
try_files $uri @gitweb;
}

location ~* ^.+\.(jpg|jpeg|gif|png|html)$ {
expires 30d;
}

location ~* ^.+\.(css|js)$ {
expires 30d;
gzip_vary on;
}

location @gitweb {
rewrite ([^/]+)/(.*) /gitweb.cgi/$1 break;
rewrite ^(/)$ /gitweb.cgi last;

}
#End Rewrites

#Pass to Apache
location ~* ^.*\.cgi(.*) {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:80;
}

}

Explaining the Nginx Configuration

Some of the core parameters that affect the setup are explained below:

Paramter Explanation
server_name gitweb.domain.com; The rest of the configuration assumes GitWeb is being served from a subdomain. If Gitweb is being hosted at domain.com/gitweb, then the ”/” and ”@gitweb” location directives will need to be modified accordingly
location / {try_files $uri @gitweb;}
This instructs Nginx to try and serve the requested resource from the path specified in the root directive, or else transfer processing to the “gitweb” location

Apache Configuration

Add The following to the site configuration file in /etc/apache2/sites-available:

ServerName gitweb.domain.com
ServerAdmin webmaster@domain.com
LogLevel warn
ErrorLog /var/log/apache2/gitweb-domain_com-error.log
DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote ratio_info
LogFormat '%h %t "%r" %{input_info}n/%{output_info}n (%{ratio_info}n%%)' compressed
CustomLog /var/log/apache2/gitweb-domain-access.log combined
CustomLog /var/log/apache2/gitweb-domain-deflate.log compressed
DocumentRoot /usr/lib/cgi-bin/
#Compression Directives
AddOutputFilterByType DEFLATE application/x-perl
#Additional Compression Directives
BrowserMatch \bMSIE\s(7|8) !no-gzip !gzip-only-text/html #This will need to be modified everytime a new IE version is released
#Following Directives ensure mod_deflate is not used for binary file types
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.avi$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mov$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp4$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.rm$ no-gzip dont-vary
AllowOverride AuthConfig
Order allow,deny
Allow from all
Options +ExecCGI +Indexes
DirectoryIndex gitweb.cgi
SetEnv GITWEB_CONFIG "/etc/gitweb.conf"
AddType application/x-perl .cgi
AddHandler cgi-script .cgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
</Directory>

Explaining the Apache Configuration

Much of the configuration here is directly from the GitWeb README. The only additional directives here pertains to gzip compression of the output, i.e.:

Paramter Explanation
AddType application/x-perl .cgi
The default mime.types file that Apache uses does not recognize cgi files. This adds a handle for the cgi files and activates gzip compression (all settings defaulted) for the output
AddHandler cgi-script .cgi
AddOutputFilterByType DEFLATE application/x-perl

Testing the configuration

Reload Nginx and Apache and then navigate to gitweb.domain.com. The familiar GitWeb page should come up.

The post Publish GitWeb with Nginx Reverse-Proxying for Apache appeared first on Balaji's Blog.

]]>
Installing rTorrent and hellanzb on CentOS5 64-bit VPS https://blog.balaji-dutt.name/2010/6-installing-rtorrent-and-hellanzb-on-centos5-64-bit-vps/ Thu, 15 Jul 2010 14:52:07 +0000 http://blog.balaji-dutt.name/?p=6 Overview The aim of this guide is to walk through the process of getting rTorrent and hellanzb working on a VPS running CentOS5 (64-bit version).1 In the interests of the author’s sanity, It is assumed that the reader has some familiarity with Unix command-line operations, and that the reader knows …

The post Installing rTorrent and hellanzb on CentOS5 64-bit VPS appeared first on Balaji's Blog.

]]>
Overview

The aim of this guide is to walk through the process of getting rTorrent and hellanzb working on a VPS running CentOS5 (64-bit version).1

In the interests of the author’s sanity, It is assumed that the reader has some familiarity with Unix command-line operations, and that the reader knows what the various permissions octals mean in Unix.

Please read the TODO to see what still needs fixing.

Assumptions

  • Operating System is CentOS5 64-bit, kernel 2.6.1x series 1)
  • CentOS5 is running on a OpenVZ VPS.
  • gcc, make, automake and autoconf installed
  • A text editor you are comfortable with (nano2 is recommended) but you can always use vi if you are hardcore
  • Working FTP Server (ProFTPD is highly recommended)
  • Installing software while logged in as root does not strike you as heresy.
  • Patience – lots of it.

Installing rTorrent

The Easy Way

rTorrent’s dependency tree is fairly long and very specific on the minimum versions required. The core dependency list is as follows:

  • pkg-config
  • libsigc++
  • curl 7.19.2 or higher
  • xmlrpc-c

Reminder: The rest of this section assumes you will be executing the commands as root

pkg-config

The current version of pkg-config (at the time of writing this guide) is 0.23. You can check the version information on the pkg-config website while the actual source tarballs are in the release directory.

The following set of commands will install pkg-config:

wget http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
tar zxf pkg-config-0.23.tar.gz
cd pkg-config-0.23
./configure
make
make install

libsigc++

Make sure you have rpmforge in your list of repositories. See this section for instructions if you are not sure how to proceed. If you have rpmforge already installed, you need to execute the following command:
yum install libsigc++20 libsigc++20-devel
Now to check if everything went ok with the libsigc++ install. Open the file ld.so.conf
nano -w /etc/ld.so.conf
and add the following lines:

/usr/local/lib/
/usr/include/
/usr/lib64/
/usr/lib
/usr/local/include/

Save and exit. Now run the following commands:

/sbin/ldconfig
pkg-config --cflags --libs sigc++-2.0

If everything went well, you should see something similar to the output below:

[root@centos]# pkg-config --cflags --libs sigc++-2.0
-I/usr/local/include/sigc++-2.0 -I/usr/local/lib/sigc++-2.0/include -L/usr/local/lib -lsigc-2.0

curl

Older versions of curl have bugs with some advanced features that libtorrent uses3 . Hence, rtorrent requires curl 7.19.2 or higher to be installed. However, CentOS 5 only ships with 7.15.5 and there are no updates available on the standard repositories.The current version of curl (at the time of writing this guide) is 7.19.3. You can check the version information on the curl website while the actual source tarballs are available on the download page.

Installing curl is fairly standard:

wget http://curl.haxx.se/download/curl-7.19.3.tar.gz
tar zxf curl-7.19.3.tar.gz
cd curl-7.19.3
./configure
make
make install

The curl make process can take a very long time, so this might be a good time to go get yourself a sandwich. Once the install process finishes, we need to check if the libraries are visible to pkg-config:

/sbin/ldconfig
pkg-config --cflags --libs libcurl
You should see the following output after the pkg-config command listed above:
[root@centos]# pkg-config --cflags --libs libcurl
-I/usr/local/include -L/usr/local/lib -lcurl

Now we move to the most important dependency for rtorrent, XMLRPC-C.

XMLRPC-C

XMLRPC-C comes in 3 flavours: Super-Stable, Stable and Advanced. While the Super-Stable version is available as a regular tarball, it seems like getting that version to work reliably is a hit-and-miss affair4. We are instead going to build the Advanced version for use with rtorrent.

To get the Advanced version source files, we need to install the subversion client:

yum install subversion

Next, we need to install a missing dependency for XMLRPC-C5:

yum install libxml2-devel

Now, we start the XMLRPC-C build process:

REPOS=http://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced
svn checkout $REPOS xmlrpc-c #This puts the source tree in a directory called xmlrpc-c in your current directory#
svn up
cd xmlrpc-c
./configure --disable-cplusplus
make
make install

The following command must execute without any errors:

[root@centos]# xmlrpc-c-config server-util --libs
-L/usr/local/lib -lxmlrpc_server -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok

Any errors at this stage means the rtorrent install will fail. Double-check that you have executed all the commands listed above starting from the section on installing curl.

Now that we have all the dependencies for rtorrent in place, it’s time to get started with installing rtorrent.

libtorrent/rTorrent

The latest build of rTorrent has a lot of functionality for managing torrents automatically. Plus, wTorrent relies on the latest build of rTorrent for much of it’s functionality.

Start by checking out the latest rTorrent build from the repository:

mkdir rtorrent-svn
cd rtorrent-svn
svn co svn://rakshasa.no/libtorrent/trunk
svn up
Next we install some dependencies for libtorrent to compile successfully:
yum install openssl-devel libidn-devel

Run the following commands to install libtorrent:

cd trunk
cd libtorrent
./autogen.sh
./configure
make
make install

Check if the libtorrent install took:

/sbin/ldconfig
pkg-config --cflags --libs libtorrent

You should see the following output after the pkg-config command listed above:
[root@centos]# pkg-config --cflags --libs libtorrent
-I/usr/local/include -L/usr/local/lib -ltorrent

If everything is in order, it's time to start the rTorrent install:

cd ../rtorrent
./autogen.sh
./configure --with-xmlrpc-c
make
make install

If everything executes without errors, congratulations! You have a working rTorrent install ready for use. Before you can start using rTorrent though, you need to setup the rTorrent configuration file.

Creating a basic .rtorrent.rc file

rTorrent looks a file called ”.rtorrent.rc” in the home directory of the user launching rTorrent. A sample .rtorrent.rc file is included below. A few things to note about this sample file:

  • Download/Upload speeds are set to unlimited (You may want to limit this to around 60-70% of your total VPS link speed)
  • Downloads are saved in ~/downloads
  • Make sure to point the session variable to a directory that exists.
  • rTorrent listens for XMLRPC connection on localhost, port 5000

# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.

# Maximum and minimum number of peers to connect to per torrent.
#min_peers = 40
#max_peers = 100

# Same as above but for seeding completed torrents (-1 = same as downloading)
# Don't set this too high, otherwise you will be seeding very slowly.
min_peers_seed = 5
max_peers_seed = 15

# Maximum number of simultanious uploads per torrent.
# Don't set this too high, otherwise you will be seeding very slowly.
max_uploads = 10

# Global upload and download rate in KiB. "0" for unlimited.
# Change this based on the total bandwidth available for your VPS
download_rate = 0
upload_rate = 0

# Default directory to save the downloaded torrents.
# make sure the path exists!
directory = ~/downloads

# Default session directory. Make sure you don't run multiple instance
# of rtorrent using the same session directory.
# Absolute path used here to enable "stop" functionality in the rtorrent init.d script
session = /home/rt/sessions/

#exec log
execute_log = ~/rtorrentexec.log

# Close torrents when diskspace is low.
#schedule = low_diskspace,5,60,close_low_diskspace=100M

# Stop torrents when reaching upload ratio in percent,
# when also reaching total upload in bytes, or when
# reaching final upload ratio in percent.

# Enable the default ratio group.
ratio.enable=

# Change the limits, the defaults should be sufficient.
ratio.min.set=100
ratio.max.set=200
ratio.upload.set=20M

# The ip address the listening socket and outgoing connections is
# bound to.
#bind = 127.0.0.1
#bind = rakshasa.no

# Port range to use for listening.
port_range = 6890-6999

# Start opening ports at a random position within the port range.
#port_random = no

# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
#check_hash = no

# Set whetever the client should try to connect to UDP trackers.
#use_udp_trackers = yes

# Alternative calls to bind and ip that should handle dynamic ip's.
#schedule = ip_tick,0,1800,ip=rakshasa
#schedule = bind_tick,0,1800,bind=rakshasa

# Encryption options, set to none (default) or any combination of the following:
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
#
# encryption = allow_incoming,enable_retry,prefer_plaintext
encryption = allow_incoming,try_outgoing,enable_retry

# Enable DHT support for trackerless torrents or when all trackers are down.
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
# The default is "off". For DHT to work, a session directory must be defined.
#
# dht = auto

# UDP port to use for DHT.
#
# dht_port = 6881

# Enable peer exchange (for torrents not marked private)
#
# peer_exchange = yes

#XMLRPC
scgi_port = localhost:5000

#umask
umask = 0022

#
# Do not modify the following parameters unless you know what you're doing.
#

# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10

# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100

# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10
Now that you have a .rtorrent.rc file setup, it's time to actually launch rTorrent.

Working with rTorrent

Launch rTorrent by running the following command:

/usr/local/bin/rtorrent

You should find yourself looking a fairly spartan window:

rtorrent-main

Let's start by loading a new torrent meta-file. Torrent meta-files can be loaded into rTorrent using the Backspace key. Auto-completion of directories using the Tab key and wildcards (example: *.torrent) is supported.

Once you have a torrent loaded, you can use the following list of commands to manage rTorrent:

Command Description
Ctrl+S Start download. Runs hash first unless already done.
Ctrl+D Stop an active download, or remove a stopped download.
Ctrl+Q Initiate shutdown
↑/ ↓ Select item
Go back to the previous screen.
Switch to Download View.
L View log. Exit by pressing Space.

There is one problem with launching rTorrent from a regular shell window. Once you type in Ctrl+Q to exit from rTorrent, it shuts down completely, stopping all your in-progress torrents. The next section will deal with how to keep rTorrent running in the background as well as how to launch rTorrent on startup.

Running rTorrent as a Service

We will be using dtach to keep rTorrent running in the background6. To install dtach, execute the following command:

yum install dtach

Now you can launch rtorrent using dtach:

dtach -c /tmp/dtach-rtorrent rtorrent

Once rTorrent launches, press Ctrl+\. You will get the following message at the shell:

[root@centos]# dtach -c /tmp/dtach-rtorrent rtorrent
[detached]

You can verify that rTorrent is still running by running the following command:

[root@centos]# ls -l /tmp/dtach*
srw------- 1 root root 0 Apr 2 01:33 /tmp/dtach-rtorrent

To reconnect the rTorrent session in the background, type

dtach -a /tmp/dtach-rtorrent

In order to launch rTorrent at startup, we need to create an entry in the init.d folder as well as a configuration file that the init.d script can read.

These commands need to be executed while logged in as root

The configuration file can be created as follows:

touch /etc/rtorrent.init.conf
nano -w /etc/rtorrent.init.conf

Now copy and paste the following text into your rtorrent.init.conf file:

##Start Configuration##
#Do not put a space on either side of the equal signs e.g.
# user = user
# will not work

# system user to run as
user="rt"

# the full path to the filename where you store your rtorrent configuration
config="/home/rt/.rtorrent.rc"

# set of options to run with
options=""

# file to log to (makes for easier debugging if something goes wrong)
logfile="/home/rt/rtorrentInit.log"
Save and exit. If you want, you can get the file directly on your server as follows:
cd /etc
wget http://wiki.theaveragegeek.com/samples/rtorrent.init.conf
Make sure to also create the logfile
touch /home/rt/rtorrentInit.log
The next step is to create the entry in the init.d folder:
touch /etc/init.d/rtorrent
nano -w /etc/init.d/rtorrent
Add the following text to your rtorrent file in the init.d folder:
#!/bin/sh
#
#
#############
######
#############
# This script depends on dtach.
# Based on the script created by lostnihilist at http://libtorrent.rakshasa.no/attachment/wiki/RTorrentCommonTasks/rtorrentInit.sh
# Licensed under the GPLv2 by average_geek: contact_at_theaveragegeek_dot_com
##############
######
##############
#/etc/rc.d/init.d/rtorrent
# chkconfig: 235 80 30
# description: Run rtorrent as a Daemon service using dtach
# processname: rtorrent
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
#VARIABLES#
. /etc/rtorrent.init.conf
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
DESC="rtorrent via dtach"
NAME=rtorrent
DAEMON=$NAME
SCRIPTNAME=/etc/init.d/$NAME
RETVAL=0
lockfile=${LOCKFILE-/var/lock/subsys/rtorrent}
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

#Functions
checkconfig() {
exists=0

for i in `echo "$PATH" | tr ':' '\n'` ; do
if [ -f $i/$NAME ] ; then
exists=1
appdir=$i
apppath=$i/$NAME
break
fi
done

if ! [ -x "$apppath" ] ; then
echo "cannot find executable rtorrent binary in PATH $appdir" | tee -a "$logfile" >&2
exit 3
fi

if [ $exists -eq 0 ] ; then
echo "cannot find rtorrent binary in PATH $PATH" | tee -a "$logfile" >&2
exit 3
fi

if ! [ -r "${config}" ] ; then
echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
exit 3
fi

session=`getsession "$config"`
if ! [ -d "${session}" ] ; then
echo "cannot find readable session directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2
exit 3
fi
}

getsession() {

session=`awk '/^[[:space:]]*session[[:space:]]*=[[:space:]]*/{print($3)}' "$config"`
echo $session
}

start() {

daemon `su -c "dtach -n /tmp/dtach-"${DAEMON}" rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2`

RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}

}

stop() {

killproc $NAME

RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f ${lockfile}

}
#End Functions
#Script

checkconfig

case "$1" in

start)
echo -n "Starting $DESC: $NAME"
start
;;

stop)
echo -n "Stopping $DESC: $NAME"
stop
;;

restart|force-reload)
echo -n "Restarting $DESC: $NAME"
stop
sleep 1
start
;;

*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;

esac

exit 0

Now we need to make the rtorrent file executable:

chmod 755 /etc/init.d/rtorrent

Next we add rTorrent to the list of startup services:

chkconfig --add rtorrent

Now you can start rTorrent using the following command:

/etc/init.d/rtorrent start

If there are no problems with your configuration file, you should see the following:

[root@centos]# /etc/init.d/rtorrent start
Starting rtorrent via dtach: rtorrent [ OK ]

Verify that rTorrent is running with the following command:

ls -l /tmp/dtach*

You should see the following:

[root@centos]# ls -l /tmp/dtach*
srw------- 1 root root 0 Apr 2 01:33 /tmp/dtach-rtorrent

Caveats

Unfortunately, launching rTorrent as a starup service this way comes with some limitations:

  • The startup script launches rTorrent through a couple of layers of redirection. This means that sometimes, rTorrent can fail to start but the startup script still says “Starting rtorrent via dtach: rtorrent [ OK ]”
  • Another problem is that if rTorrent finds any problems in the .rtorrent.rc file, it does not send the message to stderr but rather to stdout (i.e. on-screen)
  • So if you make a change to your .rtorrent.rc file you might want to check for any problems by launching rTorrent the usual way, i.e.,
    /usr/local/bin/rtorrent

    Installing hellanzb

    In case you are wondering what hellanzb is, it “is a Python application designed for *nix environments that retrieves nzb files and fully processes them. The goal being to make getting files from Usenet as hands-free as possible.”

    hellanzb's dependency list is deceptively simple:

    • Twisted
    • unrar/unzip
    • par2cmdline
    • pyOpenSSL (if you want to use SSL connections to your Usenet provider)

    The reality of course is a bit more complicated. Let's get started with Twisted.

    hellanzb dependencies

    hellanzb's core dependency is Twisted - a networking stack written in Python. Twisted in turn, relies on zope.interface and python headers. Let's start with the core python headers install:

    yum install python-devel

    While zope.interface is available as a simple tarball, I never managed to get the build to work. The only thing that did work was a default file that I located on a 3rd-party repository7 :

    wget ftp://ftp.pbone.net/mirror/ftp.pramberger.at/systems/linux/contrib/rhel5/x86_64/python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm
    rpm -ivh python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm

    Now we can get started with Twisted. The current version of Twisted (at the time of writing this article) is 8.2.0 . You can find the latest version info on the Twisted website, and a link to the source tarball is available on the home page as well. Installation is as follows:

    wget http://tmrc.mit.edu/mirror/twisted/Twisted/8.2/Twisted-8.2.0.tar.bz2#md5=c85f151999df3ecf04c49a781b4438d2
    tar jxf Twisted-8.2.0.tar.bz2
    cd Twisted-8.2.0/
    python setup.py install --install-lib /usr/lib/python2.4/site-packages

    The odd install path for Twisted is due to a bug in the way Python packages get installed on 64-bit OS'es. See this bug report.

    The next set of dependencies for hellanzb are for unrar/unzip. If you have been using the instructions listed in this article on how to install rTorrent, you should have the rpmforge repository installed. The only thing left to do is to execute the following command:

    yum install unrar unzip

    Now we move par2cmdline. In case you are wondering what this program does, you should read this article on PAR files. The latest version of the par2cmdline client for UNIX (at the time of writing this article) is 0.3. You can download the source tarball from the clients section of the parchive website.

    Unfortunately, a bug in gcc 4.x.x prevents par2cmdline from compiling properly unless a patch is applied8 . The complete process for building par2cmdline goes like this:

    wget http://prdownloads.sourceforge.net/parchive/par2cmdline-0.3.tar.gz?download
    tar zxf par2cmdline-0.3.tar.gz
    cd par2cmdline-0.3/
    wget http://slackbuilds.org/slackbuilds/12.2/system/par2cmdline/par2cmdline-0.4-gcc4.patch
    yum install patch
    patch reedsolomon.cpp par2cmdline-0.4-gcc4.patch
    ./configure
    make
    make install

    Optional:Finally, we install PyOpenSSL:

    yum install PyOpenSSL

    Building hellanzb

    At the time of writing this article, the latest version of hellanzb was 0.13. You can check the version info on hellanzb's website while the actual source tarballs are available in the distfiles folder. You could be adventurous and try the nightly builds in the distfiles folder, but the stable version works well enough.

    wget http://www.hellanzb.com/distfiles/hellanzb-0.13.tar.gz
    tar zxf hellanzb-0.13.tar.gz
    cd hellanzb-0.13
    python setup.py install

    If everything went well, you have a working hellanzb install. Now it's time to configure hellanzb.

    Creating a hellanzb.conf file

    hellanzb looks for a configuration file called “hellanzb.conf” in the /usr/etc folder. A sample hellanzb.conf file is given below. You should note the following about this sample conf file:

    • Download speeds are set to 150kB/s (You may want to limit this to around 30% of your total VPS link speed)9
    • Finished Downloads are saved in /home/nzb/downloads/completed_files
    • hellanzb listens for XMLRPC connection on localhost, port 8760

    #
    # hellanzb.conf - sample hellanzb configuration file
    #
    # To quickly get started, change the default defineServer() call and the
    # Hellanzb.PREFIX_DIR directory
    #
    # This is actually interpreted python code: strings must be surrounded by
    # quotes, numbers and the 'None' keyword should not
    #
    # $Id: hellanzb.conf.sample 1057 2007-03-27 04:13:53Z pjenvey $
    
    # Log output to this file, set to None (no single quotes) for no logging
    Hellanzb.LOG_FILE = '/var/tmp/hellanzb.log'
    
    # Uncomment this line to log DEBUG messages to the specified file
    #Hellanzb.DEBUG_MODE = '/var/tmp/hellanzb-debug.log'
    
    # Automatically roll over both log files when they reach LOG_FILE_MAX_BYTES
    # size
    Hellanzb.LOG_FILE_MAX_BYTES = 131072
    
    # Save LOG_FILE_BACKUP_COUNT of those rolled over log files
    Hellanzb.LOG_FILE_BACKUP_COUNT = 0
    
    # Define server connections. Servers can have multiple hosts, hellanzb will
    # persist the number of connections to each specified server. There may be
    # multiple defineServer lines.
    
    # Set both the username and password to 'None' (without the quotes) if your
    # usenet server does not require authorization
    
    #Following is an example of a standard Usenet server
    defineServer(id = 'ChangeMe',
    hosts = [ 'news.changeme.com:119' ],
    
    username = 'user',
    password = 'pass',
    #username = None, # no auth
    #password = None,
    
    connections = 4,
    antiIdle = 4.5 * 60, # 4 minutes, 30 seconds, 0 to disable
    #bindTo = '204.31.33.7', # connect FROM this ip address
    #enabled = False, # disable this server
    #skipGroupCmd = False, # skip sending nntp GROUP commands
    #fillserver = 0, # defaults to 0 (a main server).
    # fillservers must have values > 0
    # (priority)
    ssl = False
    )
    
    #Following is an example of a Secure Usenet server
    #defineServer(id = 'SecureMe',
    # hosts = [ 'secure.news.changeme.com:443' ],
    #
    # username = 'ssluser',
    # password = 'sslpass',
    # #username = None, # no auth
    # #password = None,
    #
    # connections = 4,
    # antiIdle = 4.5 * 60, # 4 minutes, 30 seconds, 0 to disable
    # #bindTo = '204.31.33.7', # connect FROM this ip address
    # #enabled = False, # disable this server
    # #skipGroupCmd = False, # skip sending nntp GROUP commands
    # #fillserver = 0, # defaults to 0 (a main server).
    # # fillservers must have values > 0
    # # (priority)
    # ssl = True
    # )
    
    # Uncomment this line to limit all server connections to the specified KB/s
    # bandwidth
    Hellanzb.MAX_RATE = 150 # limit to 150kB/s
    
    # Important locations
    # Make sure the path mentioned in Hellanzb.PREFIX_DIR exists!
    Hellanzb.PREFIX_DIR = '/home/nzb/downloads/'
    
    # Where to put queued .nzb files
    Hellanzb.QUEUE_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.queue/'
    
    # Where the fully processed archives go
    Hellanzb.DEST_DIR = Hellanzb.PREFIX_DIR + 'completed_files/'
    
    # The .nzb currently being downloaded is stored here
    Hellanzb.CURRENT_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.current/'
    
    # The archive currently being downloaded is stored here
    Hellanzb.WORKING_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.inprogress/'
    
    # Archives interrupted in the middle of downloading are stored here temporarily
    Hellanzb.POSTPONED_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.postponed/'
    
    # Archives currently being processed. May contains archive directories, or
    # symbolic links to archive directories
    Hellanzb.PROCESSING_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.processing/'
    
    # Temp storage
    Hellanzb.TEMP_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.temp/'
    
    # Filename to store hellanzb state in between CTRL-Cs. The state (includes the
    # order of the queue, and smart par recovery information) is intermittently
    # written out as XML to this file
    Hellanzb.STATE_XML_FILE = Hellanzb.PREFIX_DIR + 'nzb/hellanzbState.xml'
    
    # _Sub directory within the nzb archive dir_ to move processed files to
    Hellanzb.PROCESSED_SUBDIR = 'processed'
    
    # Remove the PROCESSED_SUBDIR if the archive was successfully post processed.
    # Warning: The normal Hellanzb.LOG_FILE should be enabled with this option --
    # for a record of what hellanzb deletes
    Hellanzb.DELETE_PROCESSED = True
    
    # Maximum amount of memory used to cache encoded Article data segments.
    # hellanzb will write article data to disk when this cache is exceeded
    # Available settings:
    # -1: Unlimited size
    # 0: Disable cache (only cache to disk)
    # >0: Limit cache to this size, in bytes, KB, MB, e.g.:
    # 1024 '1024KB' '100MB' '1GB'
    #Hellanzb.CACHE_LIMIT = '2048KB'
    
    # Save archives into a sub directory of DEST_DIR named after their newzbin.com
    # category (when queued using the enqueuenewzbin XMLRPC call); e.g. Apps,
    # Movies, Music
    Hellanzb.CATEGORIZE_DEST = False
    
    # Disable SMART_PAR (download all PAR files)
    #Hellanzb.SMART_PAR = False
    
    # Supply a path to the (un)rar command
    Hellanzb.UNRAR_CMD = '/usr/local/bin/unrar'
    
    # Supply a path to the par2 command
    Hellanzb.PAR2_CMD = '/usr/local/bin/par2'
    
    # Skip unraring during post processing
    #Hellanzb.SKIP_UNRAR = False
    
    # Supply a path to the optional macbinconv command (for converting MacBinary
    # files)
    #Hellanzb.MACBINCONV_CMD = None
    
    # hellanzb inherits the umask from the current user's environment (unless it's
    # running in daemon mode). The umask can be forced with this option
    #IMPT NOTE: Following mask works in CentOS. Default UMASK is 0022
    #Hellanzb.UMASK = 022
    
    # Supported music types (case insensitive) and optionally their decompression
    # executables
    # and the file type that executable will decompress to (case insensitive). The
    # exes must be in the PATH.
    #
    # will be replaced with the name of music file
    # optional is with the specified extension
    #
    # None means these files don't need to be decompressed
    defineMusicType('wav', None, None)
    defineMusicType('mp3', None, None)
    #defineMusicType('ape', 'mac -d', 'wav')
    #defineMusicType('flac', 'flac -d -- ', 'wav')
    #defineMusicType('shn', 'shorten -x < > ', 'wav')
    
    # Max files we should decompress at the same time
    Hellanzb.MAX_DECOMPRESSION_THREADS = 2
    
    # Enable Mac OS X Growl notifications
    Hellanzb.GROWL_NOTIFY = False
    
    # The growl notification server, in the format 'hostname'
    Hellanzb.GROWL_SERVER = 'IP'
    
    # The growl password
    Hellanzb.GROWL_PASSWORD = 'password'
    
    # Enable libNotify Daemon notifications
    Hellanzb.LIBNOTIFY_NOTIFY = False
    
    # Disable ANSI color codes in the main screen (preserves the in place scroller)
    #Hellanzb.DISABLE_COLORS = False
    
    # Disable ALL ANSI color codes in the main screen (for terminals that don't
    # support ANY ANSI codes
    #Hellanzb.DISABLE_ANSI = False
    
    # Hostname for the XMLRPC client to connect to. By default, localhost
    # Do not change this
    Hellanzb.XMLRPC_SERVER = 'localhost'
    
    # Port number the XML RPC server will listen on, and the client will connect to.
    # Set to 'None' (without the quotes!) for no XML RPC server
    # Following port is default for hellanzb. Change it to head off potential bot-attacks
    # hellanzb will listen on this port *ON ALL IPS* (incl. public facing ones)
    Hellanzb.XMLRPC_PORT = 8760
    
    # Password for the XML RPC server. You might probably never use this, but the
    # command line XML RPC calls do -- it should definitely be changed from its
    # default value. The XML RPC username is hardcoded as 'hellanzb' -- E.g. URL:
    # http://hellanzb:changeme@localhost:8760
    Hellanzb.XMLRPC_PASSWORD = 'changemenow'
    
    # Username/Password to http://www.newzbin.com for automatic NZB downloading
    Hellanzb.NEWZBIN_USERNAME = 'newzbin'
    Hellanzb.NEWZBIN_PASSWORD = 'password'
    
    # If any of the following file types are missing from the archive and cannot be
    # repaired, continue processing because they're unimportant (case insensitive)
    Hellanzb.NOT_REQUIRED_FILE_TYPES = [ 'log', 'm3u', 'nfo', 'nzb', 'sfv', 'txt' ]
    
    # Don't get rid of (move into the PROCESSED dir) the following file types when
    # finished post processing (case insensitive)
    #Hellanzb.KEEP_FILE_TYPES = [ 'log', 'm3u', 'nfo', 'nzb', 'sfv', 'txt' ]
    Hellanzb.KEEP_FILE_TYPES = [ 'nfo', 'txt' ]
    
    # List of alternative file extensions matched as NZB files in the QUEUE_DIR.
    # The 'nzb' file extension is always matched
    #Hellanzb.OTHER_NZB_FILE_TYPES = [ 'xml' ]
    
    # Support extracting NZBs from ZIP files with this suffix (case insensitive) in
    # QUEUE_DIR. Defaults to '.nzb.zip'. Set to False to disable.
    #Hellanzb.NZB_ZIPS = '.nzb.zip'
    
    # Support extracting NZBs from GZIP files with this suffix (case insensitive)
    # in QUEUE_DIR. Defaults to '.nzb.gz'. Set to False to disable.
    #Hellanzb.NZB_GZIPS = '.nzb.gz'
    
    # Delay enqueueing new, recently modified NZB files added to the QUEUE_DIR until
    # this many seconds have passed since the NZB's last modification time (defaults
    # to 10 seconds)
    #Hellanzb.NZBQUEUE_MDELAY = 10
    
    # Optional external handler script. hellanzb will run this script after post
    # processing an archive, with the following arguments:
    #
    # handler_script type archiveName destDir elapsedTime parMessage
    #
    # type: post processing result, either 'SUCCESS' or 'ERROR'
    # archiveName: name of the archive, e.g. 'Usenet_Post5'
    # destDir: where the archive ended up, e.g. '/ext2/usenet/Usenet_Post5'
    # elapsedTime: a pretty string showing how long post processing took, e.g.
    # '10m 37s'
    # parMessage: optional post processing message. e.g. '(No Pars)'
    # Hellanzb.EXTERNAL_HANDLER_SCRIPT = '~/bin/post_hellanzb.sh'

    Working with hellanzb

    It might not seem possible, but hellanzb boasts an interface even more spartan than rTorrent. hellanzb can be launched with the following command:
    /usr/bin/hellanzb.py
    Once hellanzb starts, you will see the following in your SSH session:

    hellanzb-main

    In order to have hellanzb process nzb files, you need to place them in the “Hellanzb.QUEUE_DIR” folder10 .

    Unlike rTorrent, hellanzb ships with a “daemon” mode built-in, so you can start it as a service very easily by issuing the following command:

    /usr/bin/hellanzb.py -D

    In order to see what hellanzb is currently doing, you can use the following command:

    /usr/bin/hellanzb.py status

    Let's now see how to add hellanzb to the list of services on startup.

    Running hellanzb as a Service

    In order to launch hellanzb at startup, we use a process identical to the one used for rTorrent. First, we create an entry in the init.d folder and then add a configuration file that the init.d script can read.

    These commands need to be executed while logged in as root

    The configuration file can be created as follows:

    touch /etc/hellanzb.init.conf
    nano -w /etc/hellanzb.init.conf

    Now copy and paste the following text into your hellanzb.init.conf file:

    ##Start Configuration##
    #Do not put a space on either side of the equal signs e.g.
    # user = user
    # will not work
    
    # system user to run as
    user="nzb"
    
    # the full path to the filename where you store your hellanzb configuration
    config="/usr/etc/hellanzb.conf"
    
    # file to log to (makes for easier debugging if something goes wrong)
    logfile="/home/nzb/hellanzbinit.log"
    Save and exit. If you want, you can get the file directly on your server as follows:
    cd /etc
    wget http://wiki.theaveragegeek.com/samples/hellanzb.init.conf
    Make sure to also create the logfile
    touch /home/nzb/hellanzbinit.log
    The next step is to create the entry in the init.d folder:
    touch /etc/init.d/hellanzb
    nano -w /etc/init.d/hellanzb
    Add the following text to your rtorrent file in the init.d folder:
    #!/bin/sh
    #
    #############
    ######
    #############
    # Licensed under the GPLv2 by average_geek: contact_at_theaveragegeek_dot_com
    ##############
    ######
    ##############
    #/etc/rc.d/init.d/hellanzb
    # chkconfig: 235 80 30
    # description: Run hellanzb as a Daemon service
    # processname: hellanzb
    # Source function library.
    . /etc/rc.d/init.d/functions
    # Source networking configuration.
    . /etc/sysconfig/network
    #VARIABLES#
    . /etc/hellanzb.init.conf
    PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
    DESC="hellanzb daemon"
    NAME=hellanzb.py
    DAEMON=$NAME
    SCRIPTNAME=/etc/init.d/$NAME
    RETVAL=0
    lockfile=${LOCKFILE-/var/lock/subsys/hellanzb}
    # Check that networking is up.
    [ ${NETWORKING} = "no" ] && exit 0
    
    #Functions
    checkconfig() {
    exists=0
    
    for i in `echo "$PATH" | tr ':' '\n'` ; do
    if [ -f $i/$NAME ] ; then
    exists=1
    appdir=$i
    apppath=$i/$NAME
    break
    fi
    done
    
    if ! [ -x "$apppath" ] ; then
    echo "cannot find executable hellanzb binary in PATH $appdir" | tee -a "$logfile" >&2
    exit 3
    fi
    
    if [ $exists -eq 0 ] ; then
    echo "cannot find hellanzb binary in PATH $PATH" | tee -a "$logfile" >&2
    exit 3
    fi
    
    if ! [ -r "${config}" ] ; then
    echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
    exit 3
    fi
    
    dlpath=`getsession "$config"`
    if ! [ -d "${dlpath}" ] ; then
    echo "cannot find the download directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2
    exit 3
    fi
    }
    
    getsession() {
    
    path=`awk '/^Hellanzb.PREFIX_DIR[[:space:]]*=[[:space:]]*/ { print $3 }' "$config"`
    trimpath=`echo $path | sed -e s/\'//g`
    echo $trimpath
    }
    
    start() {
    
    [ -d "${base}" ] && cd "${base}"
    
    daemon `su -c "/usr/bin/hellanzb.py -D 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2`
    
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch ${lockfile}
    
    }
    
    stop() {
    
    killproc $NAME
    
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f ${lockfile}
    
    }
    #End Functions
    #Script
    
    checkconfig
    
    case "$1" in
    
    start)
    echo -n "Starting $DESC: $NAME"
    start
    ;;
    
    stop)
    echo -n "Stopping $DESC: $NAME"
    stop
    ;;
    
    restart|force-reload)
    echo -n "Restarting $DESC: $NAME"
    stop
    sleep 1
    start
    ;;
    
    *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 1
    ;;
    
    esac
    
    exit 0

    Now we need to make the hellanzb file executable:

    chmod 755 /etc/init.d/hellanzb

    If you would like to skip copying and pasting text into your shell session, you can run the following commands instead:

    cd /etc/init.d/
    wget http://wiki.theaveragegeek.com/samples/hellanzb.sh
    mv hellanzb.sh hellanzb
    chmod 755 /etc/init.d/hellanzb

    Next we add hellanzb to the list of startup services:

    chkconfig --add hellanzb

    Now you can start hellanzb using the following command:

    /etc/init.d/hellanzb start

    If there are no problems with your configuration file, you should see the following:

    [root@centos]# /etc/init.d/hellanzb start
    Starting hellanzb daemon: hellanzb.py [ OK ]

    Verify that hellanzb is running with the following command:

    ps ax | grep hellanzb

    You should see the following:

    [root@centos]# ps ax | grep hellanzb
    10084 ? Sl 0:00 /usr/bin/python /usr/bin/hellanzb.py -D
    10236 pts/1 R+ 0:00 grep hellanzb

    Other Tips

    Download files via FTP reliably

    If you are using ProFTPD as your FTP server, you want to add the following line to your proftpd.conf file: (usually located in /etc)

    UseSendfile off

    This is recommended as there are some issues with VPS kernels that can cause timeouts on large transfers - See this article

    Fixing the sudo error

    By now you would be familiar with this annoying problem every time you issue the sudo command:

    [user@centos ~]$ sudo su -
    Password:
    audit_log_user_command(): Connection refused

    This is actually due to a bug in the version of sudo that ships with Red Hat. You can check out this blog post for instructions on how to upgrade your version of sudo which will fix this annoying error message.

    SAFE USAGE

    Copyright laws and laws pertaining to patents and inventions protect original works of authorship and inventions. Individuals who reproduce, distribute copies, receive copies, publicly perform or display works or inventions other than their own and without the consent of the owners or holders of rights, or their authorized agents, in original works of authorship or inventions, may be in violation of copyright, patent or other intellectual property infringement. The authors and contributors of this article do not encourage or condone the illegal copying of copyrighted material. This is not intended to be legal counsel or advice. If you have any questions, consult your attorney.11

    TODO

    1. Fix the inevitable spelling errors/bugs in this article?

  1. I’m guessing the guide will still work for higher kernel versions in the 2.6 series, but experience has taught me to hedge my bets 

  2. nano is not installed by default 

  3. http://libtorrent.rakshasa.no/wiki/LibTorrentKnownIssues#Inabilitytoconnecttotrackersorannouncestimeout  

  4. http://libtorrent.rakshasa.no/ticket/1028 

  5. http://fr.rpmfind.net/linux/RPM/fedora/updates/testing/7/i386/xmlrpc-c-1.06.25-1.fc7.i386.html 

  6. The other option is screen, which is a better screen-multiplexer program but requires a lot more privileges to run 

  7. http://rpm.pbone.net/index.php3/stat/4/idpl/10370620/com/python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm.html 

  8. http://slackbuilds.org/repository/12.2/system/par2cmdline/ 

  9. hellanzb 0.13 has a problem with speed limits due to a bug in the underlying twisted network stack 

  10. That would be /home/nzb/usenet/nzb/daemon.queue/ if you used the sample hellanzb.conf from this wiki 

  11. Taken directly from the hellanzb README at http://www.hellanzb.com/trac/hellanzb/browser/trunk/README  

The post Installing rTorrent and hellanzb on CentOS5 64-bit VPS appeared first on Balaji's Blog.

]]>
Fix Mouse Grabbing/Ungrabbing for a Debian VMWare Image https://blog.balaji-dutt.name/2010/452-fix-mouse-grabbingungrabbing-for-a-debian-vmware-image/ Mon, 12 Jul 2010 12:56:28 +0000 http://blog.balaji-dutt.name/?p=452 One of the more fully configured VMWare images for Debian on the VMWare Appliance Marketplace is the image provided by Visoracle. While it does work almost flawlessly out of the box, there is one small problem – the Guest OS doesn’t support Mouse grabbing/ungrabbing by default. To fix this, add …

The post Fix Mouse Grabbing/Ungrabbing for a Debian VMWare Image appeared first on Balaji's Blog.

]]>
One of the more fully configured VMWare images for Debian on the VMWare Appliance Marketplace is the image provided by Visoracle.

While it does work almost flawlessly out of the box, there is one small problem – the Guest OS doesn’t support Mouse grabbing/ungrabbing by default.

To fix this, add the following line to your /etc/X11/xorg.conf , in the “Section “InputDevice”” for the Identifier “VMware Mouse”:1

Option    CorePointer

Then hit CTRL+ATL+BACKSPACE to restart X-Windows. Now enjoy the awesomeness of seamless of mouse grabbing/ungrabbing.


  1. Credit where credit is due, this fix is courtesy of the VMWare Community Forums  

The post Fix Mouse Grabbing/Ungrabbing for a Debian VMWare Image appeared first on Balaji's Blog.

]]>
Using VMWare Workstation – a couple of Tips https://blog.balaji-dutt.name/2010/449-using-vmware-workstation-a-couple-of-tips/ https://blog.balaji-dutt.name/2010/449-using-vmware-workstation-a-couple-of-tips/#comments Sun, 04 Jul 2010 10:46:24 +0000 http://blog.balaji-dutt.name/?p=449 When trying to setup a new Virtual Machine, you could take the tough approach and do it from scratch. Or you could let someone else do the hard work for you and download a pre-built image. For VMWare, the place to do this is the VMWare Applicance Marketplace. This may …

The post Using VMWare Workstation – a couple of Tips appeared first on Balaji's Blog.

]]>
When trying to setup a new Virtual Machine, you could take the tough approach and do it from scratch. Or you could let someone else do the hard work for you and download a pre-built image. For VMWare, the place to do this is the VMWare Applicance Marketplace.

This may or may not work perfectly for you. Here’s how I fixed a couple of problems that I encountered:

  • I can’t connect to the Internet via Wi-Fi from the Virtual Machine

If your host machine connects to the Internet via Wi-Fi, you’ll find that the Virtual Machine cannot browse the net or download any packages. The reason for this is that by default, Wi-Fi adapters are excluded by the VMWare Workstation. You can fix in one of two ways:

1. Remove your Wi-Fi adapter from the Exclusion list – Go to Edit > Virtual Network Editor > Automatic Bridging:

vmware-network-editor

You should see your Wi-Fi adapter listed in the “Do not attempt to bridge” list. Select the adapter and hit Remove. Now try rebooting the Virtual Machine and see if Internet access has started working.

2. Map a specific VMNet Adapter to your Wi-Fi adapter – In the Virtual Network Editor, Choose the Host Virtual Network Mapping tab:

vmware-network-mapping

Pick a VMNet Adapter and map it your Wi-Fi adapter. Next go to your Virtual Machine settings and modify the Network option to point to the VMNet Adapter you had modified:

vmware-vm-settings

  • I’ve shared a folder from the Host PC, but the Linux Virtual Machine can’t see it.

The nice part of using images from the Appliance Marketplace is that VMware tools is typically installed, enabling the best features of the VMWare Workstation such as changing the resolution and Unity View. However, you might find that Shared folders aren’t working properly. To test whether you have a fully working VMware tools install, run the following command:

sudo lsmod | grep vmhgfs

You should something similar to the following output:

# lsmod | grep vmhgfs
vmhgfs                 51336  1

If the command exits without any output, you have an incomplete VMWare tools install. Run the following command:

sudo /usr/bin/vmware-config-tools.pl

Accept the default prompts and wait for the configuration to finish. Now try the following commands:

# modprobe vmhgfs
# lsmod | grep vmhgfs

If the lsmod command returns some output now, you’re all set to start copying-and-pasting files between the Host PC and your Virtual Machine.

The post Using VMWare Workstation – a couple of Tips appeared first on Balaji's Blog.

]]>
https://blog.balaji-dutt.name/2010/449-using-vmware-workstation-a-couple-of-tips/feed/ 2
Tips on working with FreeNX on a Debian/Ubuntu VPS https://blog.balaji-dutt.name/2010/441-tips-on-working-with-freenx-on-a-debianubuntu-vps/ https://blog.balaji-dutt.name/2010/441-tips-on-working-with-freenx-on-a-debianubuntu-vps/#comments Sun, 30 May 2010 10:14:29 +0000 http://blog.balaji-dutt.name/2010/05/30/tips-on-working-with-freenx-on-a-debianubuntu-vps/ The command-line is and will always be the fastest way to administer a remote Linux installation. But whether it’s running a speed test of the server or monitoring AWStats reports only accessible from the localhost, a GUI interface can often come in handy. The typical recommendation in such cases is …

The post Tips on working with FreeNX on a Debian/Ubuntu VPS appeared first on Balaji's Blog.

]]>
The command-line is and will always be the fastest way to administer a remote Linux installation. But whether it’s running a speed test of the server or monitoring AWStats reports only accessible from the localhost, a GUI interface can often come in handy.

The typical recommendation in such cases is to install VNC and a <Insert preferred desktop environment here>. There are a few problems with this:

1. VNC requires you to open an additional port (or two) at your firewall.

2. VNC relies on it’s own user-authentication database and doesn’t support long passwords.

3. Trying to get usable performance out of VNC is a black art in itself.

The smart answer is NX – a remote desktop solution that relies on SSH for authentication, scales to any sort of connection (all the way down to a 56kbps modem link) and supports multimedia and file-sharing support.

I’m not going to talk about how to install NX on Debian/Ubuntu – there are plenty of guides, including this one on the Ubuntu Wiki.

There are a few “gotchas” when it comes to installing FreeNX on a Debian/Ubuntu VPS and it took a while for me to work out the answers. For the reference of anyone else struggling with these problems then, here are my tips:

  • When I use the NoMachine NX Client and try to exit a session, the application seems to “hang”:

One of the best features of NX is robust suspend/resume support for sessions. On a default install of FreeNX however, trying to exit a FreeNX session from the NoMachine NX client doesn’t work. The problem is that a couple of dependencies aren’t included. To fix this, run the following commands:

On Ubuntu –

aptitude install x11-utils

On Debian 5 –

aptitude install x11-utils && aptitude install xterm

Now when you try to exit the session you should see the following dialog box:

xmessage-ubuntu

  • I was told that the NX Client could tunnel sound, but all I get is an error message on my VPS. I was lied to!

Actually the lack of sound is a problem of working with FreeNX on a VPS. You need to install a Sound Daemon – specifically the Gstreamer Sound Daemon. To fix this, run the following commands in Debian/Ubuntu:

aptitude install gstreamer0.10-esd

Once this done, go to System > Preferences > Sound and modify your settings as follows:

gstreamer-sound

Now when you click the Test button, you should hear the soothing sound of a test tone on your local speakers. Note that this isn’t guaranteed to get applications like rhythmbox working and I have no idea on how to go about fixing problems like those. Also keep in mind that the volume control applet will still complain about missing plugins and refuse to “unmute” itself.

  • I’m able to login via SSH, but trying to login via NX fails.

I’ll begin this section with a  big caveat – the fix for this problem does involve reducing the security of your SSH config. Another caveat – this problem appears to be isolated to Ubuntu.

Situation – you have disabled clear text passwords in your SSHD config (i.e PasswordAuthentication no) and only allow Public Key authentication.

Problem – The NX client fails when trying to connect to the Server. If you turn on debug-level logging for SSH, you see the following message in your auth.log:

(nx) Failed login for user=<someuser> from <so.me.I.P>

You know the password for <someuser> is correct and have typed in letter-by-letter 10 times now.

Diagnosis – Tracing the root of this problem is very hard for two reasons – 1) the error message is very generic and can occur in a number of scenarios and 2) It seems specific to Ubuntu. Debian does not require any changes to your SSHD config to get FreeNX working.

Solution – The only solution that I could find after multiple iterations with the SSHD Config is to enable clear text passwords. In other words, open the sshd_config file and change the line

PasswordAuthentication no

to

PasswordAuthentication yes

Reboot the SSH daemon and FreeNX will start working without a hitch.

It is worth noting that enabling PasswordAuthentication does not imply the passwords are sent unencrypted – they are still encrypted using the host key. In addition, you can lock down SSH access to specific users/groups using the AllowUsers or AllowGroups directives in your SSH config.

The post Tips on working with FreeNX on a Debian/Ubuntu VPS appeared first on Balaji's Blog.

]]>
https://blog.balaji-dutt.name/2010/441-tips-on-working-with-freenx-on-a-debianubuntu-vps/feed/ 1