27 December 2015

SABnzbd in FreeBSD Jail

So today I installed and configured a usenet client, named SABnzbd. This software is perfect for downloading usenet binaries. For more information about the software, you'd better check out http://sabnzbd.org for a better understand about the features of SABnzbd. I'll start off with giving the information I used to create my jail:

Jail information

propertyvalue
Jailnamesabnzbdplus-prd
IPv4 address192.168.1.102
typestandard
vanillaFALSE (unchecked)

Getting shell access to the jail

First of all, ssh access should already be configured on the FreeNAS machine. If this is already the case, start an ssh session to the FreeNAS machine. on FreeBSD or Linux, this can be done via a terminal, on windows you will need something like putty.

Once the session is established, run jls to get a list of all the jails present on the server.


In order to get into the sabnzbdplus-PRD jail, you would want to run jexec 9 csh.

Installing the software

The software can be easily installed via the portstree. As this is a new jail, the portstree should first be fetched and extracted into the jail: portsnap fetch extract will do that for us. After the portstree is extracted, sabnzbd can be installed by navigating to the /usr/ports/news/sabnzbdplus folder and executing make install clean. The default config should be OK.

After the installation is finnished, the following will be displayed:



It is important to note the changes which are done by the port:
  • group '_sabnzbd' with gid '350'.
  • user '_sabnzbd' with uid '350'
  • rc script is located in /usr/local/etc/rc.d/sabnzbd (this script will be executed each time the jail boots up)
  • default port sabnzbd will listen on: '8080'
By having a quick look at the sabnzbd startup script ( cat /usr/local/etc/rc.d/sabnzbd ) we also get the following information:
  • default config dir = /usr/local/sabnzbd
  • default user sabnzbd will run as = '_sabnzbd'
  • default group sabnzbd will run as = '_sabnzbd'
  • python script which is the actual program = /usr/local/bin/SABnzbd.py

Config sabnzbd to start at boot

Add the following line into /etc/rc.conf:
enable_sabnzbd="YES"

Start the sabnzbd daemon

The software is installed, the configuration is done so that sabnzbd will start automatically at boot time. For now, sabnzbd should be started manually. To do this, execute service sabnzbd start.

Allowing other devices to have access to the Web UI

This shouldn't give any problems, Though, it is still necessary to modify the sabnzbd config file in order to allow other machines on the network to have access to the web interface as well. As said earlier, the config file is located in /usr/local/sabnzbd'.

cd /usr/local/sabnzbd
ee sabnzbd.ini

In this file search for "host = localhost" and modify that line so that it becomes "host = 0.0.0.0". Save the changes and restart the sabnzbd service: service sabnzbd restart. This will allow any device on the same subnet as the sabnzbd server to actually access the sabnzbd web UI, The sabnzbd quick-start will help you set up SABnzbd, like adding a usenet server, adding a username and password to prevent everyone on your LAN to access the web UI,...

Storage

All downloads (usenet as well as torrents) will be placed on a dedicated dataset.

All steps done to have this working setup will be shown here. In a future post on setting up transmission (torrent client), the very same dataset will be used for storing the completed downloads.

Creating a dataset

So first of all, a dataset should be created. This is done via the FreeNAS Web UI. Navigate to the storage tab, and select the zpool where the new dataset should be created and click on the create ZFS Datasetbutton:


After the dataset is created, modify the permissions to that they look like the following:


Now this dataset can be mounted inside the jail. To do this, open up the FreeNAS web UI and navigate to the jails tab. Select the sabnzbdplus jail and click on the 'Add storage' button.
Then, point the source to the newly created dataset 'Download'


Note: the value behind 'Source' is as how the FreeNAS box would see it in its filesystem. The value behind 'Destination' is path how the jail would see it!

Additionally, the permissions should also be set so that the _sabnzbd user (from inside the jail) actually has permissions on the mounted folder inside the jail. Since the dataset (in the FreeNAS web UI) has the user 'media' set as owner, and the group 'media' set as group owner, the _sabnzbd user should be added to the group 'media' inside the jail. In order to get to know the user ID and group ID of the media user in FreeNAS, check the 'Account' section in the FreeNAS web UI. In my case, those are '816'.

Now, inside the jail a new group called 'media' should be created with groupID '816' and the _sabnzbd user should be added to that group. This will allow the local _sabnzbd user to actually make use of the mounted dataset inside the jail:
pw add group -n media -g 816 -M _sabnzbd

Folder layout

In order to keep the downloads a little bit organised, the following commands were executed to create a simple folder layout:
mkdir -p /media/sabnzbd/to\ download
mkdir -p /media/sabnzbd/to\ download/nzedb
mkdir -p /media/sabnzbd/to\ download/couchpotato
mkdir -p /media/sabnzbd/to\ download/sickrage
mkdir -p /media/sabnzbd/to\ download/headphones

This should give the following structure (ignore the folder about transmission, they are used by the transmission jail):

Now, the correct permissions on the created folders should be applied so that the '_sabnzbd' user and 'media' group are owners on the folders and both have permission to read, write and execute:

chown -R _sabnzbd:media /media/sabnzbd
chmod -R 775 /media/sabnzbd

Verifying permissions

In order to see if the chown and chmod commands are applied well, a quick ls -alR /media/sabnzbd could be run:

SABnzbd configuration

Now that al permissions are set, the last step is to configure SABnzbd. Open up a webbrowser and navigate to http://192.168.1.102:8080/sabnzbd and click on Config (top right corner of the page). From here, the configuration can be done. It is advised to check all properties on the SABnzbd wiki as the information is very good in line with how the configuration appears in SABnzbd.

NOTE: Beware that all passwords are saved in plaintext in the SABnzbd config file located in /usr/local/sabnzbd/sabnzbd.ini

The most important thing to configure is the "Completed Download folder", "Permissions for completed downloads" and the "Watched Folder" (both can be found in the config > Folders > User Folders).
They should be set to /media/sabnzbd/downloaded, 775 and /media/sabnzbd/to download

Save the configuration and restart sabnzbd.

Final test

Now all configuration is done, SABnzbd should work:
  • It watches the folder /media/sabnzbd/to download, so if an .nzb file is placed on the dataset Download/sabnzbd/to download SABnzbd should notice this and import the nzb to be downloaded.
  • After the download is finished, SABnzbd will check the files with quickpar. If necessary, the damaged/corrupted files will be fixed automatically if sufficient par blocks are available.
  • The archives will also be extracted into the given "Completed Download folder", /media/sabnzbd/downloaded.
NOTE: The following commands should all be executing in the FreeNAS shell, and not inside the SABnzbd jail.

cp /mnt/testfile.nzb /mnt/Fritketel/Download/sabnzbd/to\ download


As shown above, after the copy of the nzb file, sabnzbd automatically started downloading.


And after the download is completed, it is placed nicely into /mnt/Fritketel/Download/sabnzbd/downloaded folder on FreeNAS.

Lock SABnzbd configuration

To prevent that others can read or modify the SABnzbd configuration via the web UI, modify the file located in /usr/local/sabnzbd/sabnzbd.ini and alter the following line: "config_lock = 0" to "config_lock = 1"

10 December 2015

TransIP DynamicDNS

A few weeks ago I spotted an interesting deal to have my own domain name (fritvet.be). I decided to register it and forward it to my external IP address.

Now the problem was that my isp doesn't assign static IP addresses, so I had to update my domain DNS settings regulary to keep it forwarded to my actual external IP address.

In order to do this, my DNS registrar ( TransIP ) provides an API built in PHP which allows to update the DNS settings for my domain.

Though my knowledge of PHP is next to nonexisting, I managed to get a setup running in a FreeNAS jail which will be explained in this blogpost.

Overview

  1. Creating a FreeNAS jail + general configuration
  2. install php & php-extensions
  3. script for execution + crontab
Maybe some additional information about my setup which might be relevant:
- This installation was done on FreeNAS 9.2.1.3-RELEAS-x64
- forumpost on transip which contains a working php script: click!

1. Creating a FreeNAS jail + general configuration

Start off by logging into the FreeNAS webinterface and navigate to jails and choose to add a jail.
Enter a suitable jailname, make sure to select standardjail as type, and fill in an IP address in the same range as the subnet where the FreeNAS server is located in.

property value
Jailname TransIP-PRD
IPv4 address 192.168.1.110
type standard
vanilla FALSE (unchecked)

Once the jail is created, open a terminal session on the newly created jail via the FreeNAS web interface so that SSH can be enabled.

Configure root password

The root password can be set by executing the following command
passwd root

Create technical user account

The technical user account will be used to run the script.
run the adduser command to create a new user:

Note that the user is also added to the group wheel so that during a session, the user can switch user as root if necessary. At the end of the configuration, the account will be removed from the group so that root access will be denied.

Enable SSH

modify the file /etc/rc.conf so that sshd_enable="NO" becomes sshd_enable="YES". This will make sure the sshd daemon will be start when the jail is started:
ee /etc/rc.conf

Now, the SSH daemon isn't running yet, execute the following command to start the sshd daemon:
service sshd start

Setting the hostname

Setting the hostname for the jail should be done so that it gets a nice name, issue this by executing the following command
hostname transip-prd.local

Portstree

Now that ssh is set up and a technical user account (transip) is created, further configuration can be done via a SSH session. Once logged in via ssh, run the following commands to pull and extract the portstree in the jail :
portsnap fetch extract



Note: Only the first time portsnap fetch extract should be used. If the portstree is already extracted, it can be updated in the future by executing portsnap fetch update

2. Install php and php-extensions

After the portstree is available inside the jail (default location is /usr/ports), the necessary software can be installed.
Since  the API is written in php, the php port should be installed inside the jail, this is done by executing the following commands as root:
cd /usr/ports/lang/php56
make install clean

After the sourcecode is downloaded and compiled, the program will be available: man php

The API also requires some php-extensions to be installed:
cd /usr/ports/lang/php56-extensions
make config


php56-extensions to be installed (1)
php56-extensions to be installed (2)

Moving the API to the jail

The API should be placed inside the jail so that it can actually be used. There are different ways of doing this, depending on your setup. I did this myself by downloading the API to my PC-BSD machine and with the help of the scp command the file could be copied to the jail (ssh should be running on the server for this method to work!)
Notice that the scp command was run on my PC-BSD machine.
scp transip.tar transip@192.168.1.110:/home/transip


after the file  was copied to the jail, it can be extracted with the following command:
tar -xf transip.tar

PHP script

In order to have a working php script, follow the instructions provided in the commented section of the php script - TransIP-updateDNS

3. script for execution + crontab

Fix group membership

Earlier on in this blog, the transip user was created and added to the wheel group, which allows the user to switch user to root. Now all configuration is done, the user can be removed from the 'wheel' group to improve the security
pw groupmod wheel -d transip

Shell script

A shell script provides the possibility of having multiple commands being run sequential. The following code will check if there is a directory called 'log'. If not, it will be created in /home/transip/updateDNS. Then, the current date and timestamp will be shown, and the actual php script which handles the DNS update is launched.
#!/bin/sh
cd /home/transip/updateDNS
if [ ! -d log ]; then
echo "creating log folder"
mkdir log
fi
date "+%d/%m/%Y - %H:%M"
/usr/local/bin/php /home/transip/updateDNS/update.php
printf "\n"
Make the script executable by executing chmod o+x shell.sh
If the script runs fine, you will see the following output (make sure to run this command as the transip to verify permissions are OK):


The shell script runs just fine, without any errors (permissions, php plugins missing,... ). The script should now be run on a fixed interval to keep the domain forwarded to my actual external IP.

Crontab

The crontab file allows us to configure scheduled tasks. In my case, I'll be running the 'update.sh' script each 15 minutes. The script should be run as the transip user, so make sure the following command is ran as the transip user.

crontab -e
and add the following line
*/15 * * * * /bin/sh /home/transip/updateDNS/update.sh >> /home/transip/updateDNS/log/updateDNS.log