Install the latest version of SABnzbd for multiple users on Debian 8

This article explains how to set up SABnzbd on Debian 8. I suppose it will also work on Ubuntu and other Linux flavours since there aren’t a whole lot of dependencies.

We’ll install SAB’s Python code in a central location so all users will use the same code. Each user will have their own download queue and locations, preferences, history files, etc. We’ll encrypt the webinterface with SSL certificates from Let’s Encrypt.

If you found this article useful please click some of the ads around here :)

Here’s what we’ll cover:

  • Why the Python code instead of the Debian package?
  • Install dependencies and extra tools
  • Download and extract SABnzbd’s Python code
  • Create an ini file
  • Webbased setup
  • Secure web interface with Let’s Encrypt SSL certificates
  • Add users
  • Managing the SAB processes
  • Upgrading and tweaks
  • Domain name
    I assume you have a registered domain name. If not: get one or skip the Let’s Encrypt part since Let’s Encrypt only works with registered domain names. Use self-signed certificates instead. In this article I use example.com. Substitute it by your own domain name.

    Port numbers
    By default the SABnzbd webinterface runs on port 8080. All port numbers I use in this article are arbitrairy. By convention don’t use lower port numbers (<1024). Make sure you get your port mapping right.

    Because SABnzbd will be running under the users' respective accounts it is important to distinguish between things done as root and as a regular user. My useraccount is called vorkbaard and I'll be using it as an example. Substitute your own.

    Commands executed as root are indicated by #. Use sudo to run them or just log in as root or do

    $ sudo su
    

    or

    $ su root
    

    to change user contexts.

    Commands executed as a regular user are indicated by $.

    Why the Python code instead of the Debian package?

    Because while stable the Debian package is rather outdated. At the moment of writing the Debian package is at version 0.7.18 while the current version is 1.0.1. Now to be fair the functionality is alright in the Debian ersion. I’m in it for the eye candy and SABnzbd is not the most critical part of my server so if it breaks there’s no urgency to fix it.

    Dependencies

    This page lists SAB’s dependencies: https://github.com/sabnzbd/sabnzbd
    To install them in Debian, run

    # aptitude install python2.7 python-cheetah python-openssl python-support python-yenc unzip p7zip-full par2
    

    On my server SABnzbd was complaining about a “problematic UNRAR” because I had installed unrar-free. The non-free version of unrar stopped the complaints:
    In /etc/apt/sources.list make sure you have non-free added to your repositories:

    deb http://ftp.nl.debian.org/debian/ jessie main contrib non-free
    deb-src http://ftp.nl.debian.org/debian/ jessie main contrib non-free
    
    deb http://security.debian.org/ jessie/updates main contrib non-free
    deb-src http://security.debian.org/ jessie/updates main contrib non-free
    
    # jessie-updates, previously known as 'volatile'
    deb http://ftp.nl.debian.org/debian/ jessie-updates main contrib non-free
    deb-src http://ftp.nl.debian.org/debian/ jessie-updates main contrib non-free
    

    Do

    # aptitude update
    

    to update the package cache.

    Then install unrar:

    # aptitude install unrar
    

    Download and extract SABnzbd’s Python code

    Head over to http://sabnzbd.org/download/ and copy the Python Source location. I’m installing in /opt on my server because I feel it should go there. But any location with the correct permissions will do.

    Go to /opt and download SABnzbd:

    # cd /opt
    # wget https://github.com/sabnzbd/sabnzbd/releases/download/1.0.1/SABnzbd-1.0.1-src.tar.gz
    

    Extract the tarball and rename the directory:

    # tar -xzf SABnzbd-1.0.1-src.tar.gz
    # mv SABnzbd-1.0.1 sabnzbd
    

    Create an ini file

    We should now create a stub ini file to tell SABnzbd it should a) not fire up your web browser when it starts and b) should be accessible from outside, not just the local server. The purpose of this is to start up SABnzbd on the server but continue the webbased setup from your workstation.

    Now the sabnzbd.ini file is distinct for each user. So it goes in the user directory. We’ll cover adding more users later; this is just the initial setup.

    As a user create a file called ~/sabnzbd.ini
    And add this to it:

    [misc]
    host = 0.0.0.0
    auto_browser = 0
    

    Later on you may prefer to use hidden ini file. In that case just name them ~/.sabnzbd.ini.

    Start SABnzbd

    Then fire up SABnzbd. The -f switch specifies which ini file you want to use. The -d switch tells SAB to go into daemon mode. Personally I like to run it interactively when setting it up (so no -d switch) in a separate terminal session so I can keep an eye on it.

    $ python /opt/sabnzbd/SABnzbd.py -f ~/sabnzbd.ini
    

    multisab_8

    Keep an eye on the process for warnings, errors and missing dependencies. Press Ctrl+C if you need stop the process – note that this will stop SABnzbd so it will no longer be available from its webinterface. If you stop SAB from the webinterface the process will stop as well.

    If all is well SAB will start up normally (if not: stop the process, fix what needs fixing and try again) and you will be able to access it on its default port number 8080. Follow the webbased wizard.

    multisab_7

    Secure web interface with Let’s Encrypt SSL certificates

    Here is a fun part. I’m not familiar with Let’s Encrypt on non-Debian systems but Let’s Encrypt keeps a fairly good documentation. Also because it is still under development so things may change.

    If you do not have a registered domain name you could use self-signed certificates (Let’s Encrypt will not work withou a registered domain name) but you’ll be forever dodging browser warnings.

    Install Let’s Encrypt
    If you haven’t done so install Apache. If you prefer a different web server that’s ok, check Let’s Encrypt’s website.

    # aptitude install apache2
    

    In /etc/apache2/sites-available/000-default.conf change

    # ServerName www.example.com
    

    to your own domain name:

    ServerName vorkbaard.nl <-- use your own domain
    

    Reload Apache:

    # service apache2 reload
    

    Make sure you can reach it from outside.

    Let’s Encrypt is easily installed from Debian Jessie’s backport repository: http://backports.debian.org/Instructions/

    # echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/backports.list
    # aptitude update
    # aptitude install letsencrypt python-letsencrypt-apache
    

    The installation had some dependency issues on my server and aptitude offered to resolve them. It offered a bunch of solutions and I chose the one that did not keep anything at their current version and/or uninstalled stuff.

    Start Let’s Encrypt:

    # letsencrypt run
    

    Afterwards verify your site is accessible over https.

    Set permissions
    If all is well your certificates will now reside in /etc/letsencrypt/live/example.com/. We must copy the certificates to /opt/sabnzbd/admin/ and set the correct permissions. Why /opt/sabnzbd/admin? Because sabnzbd/admin is the original certificate location for SAB. Keeping things in their expected locations makes it easier to troubleshoot.

    Unfortunately this involves compromising security a bit because your SAB-enabled users will be able to read your server’s private key. This is not optimal but we can reduce the risk to a minimum.

    Create the admin folder:

    # mkdir /opt/sabnzbd/admin
    

    Create a group called sab and add all users that should be able to use SAB (so as not to give anyone access):

    # groupadd sab
    

    For each user:

    # usermod -a -G sab vorkbaard
    

    Note that the -G parameter must be a capital G. The lowercase g would change the user’s primary group, not add an extra group.

    Give the sab group read permissions on /opt/sabnzbd/admin:

    # chown root:sab /opt/sabnzbd/admin
    

    Set traverse rights for the sab users (i.e. they should be able to open the folder):

    # chmod 610 /opt/sabnzbd/admin
    

    Renewing the certificates
    Now we’ll create a little script to renew the certificates and copy them over to the admin folder:

    Create a file /root/sabcerts.sh:

    #!/bin/bash
    
    # Renew the Let's Encrypt certificates
    /usr/bin/letsencrypt renew –-agree-tos
    
    # Copy the new certs to SABnzbs
    cp /etc/letsencrypt/live/www.example.com/*.pem /opt/sabnzbd/admin
    chmod 440 /opt/sabnzbd/admin/*.pem
    chown root:sab /opt/sabnzbd/admin/*.pem
    

    Schedule it with cron:

    # crontab -e
    

    Add this line:

    @daily /root/sabcerts.sh

    In cron make sure you end your last line with an end of line sign – just add a new, empty line. Otherwise the last line will not run, no error will get logged and you will spend countless hours troubleshooting. You are welcome.

    Run the script while you’re at it and all should be in order.

    # /root/sabcerts.sh
    

    If you screw this up the SABnzbd will throw an error at you when starting its Python script.

    multisab_2

    From the webinterface set the following options:
    [x] Enable HTTPS
    HTTPS Port: 8081 (note that this is arbitrary but it must be different from the HTTP port)
    HTTPS Certificate: /opt/sabnzbd/admin/cert.pem
    HTTPS Key: /opt/sabnzbd/admin/privkey.pem
    HTTPS Chain Certificates: /opt/sabnzbd/admin/chain.pem

    The chain certificate is not always necessary (depends on the browser and its support) but it does no harm.

    Save then restart SABnzbd. Keep an eye on the process for errors. If all went well you can now connect to the https version of your SABnzbd process!

    multisab_1

    Add users

    If you’re going to add users you must keep a couple of things in mind:
    – You do not want your users to interfere on each others setups. In other words: they must be separated. So we’ll use separate SAB processes for each users. To accomplish this we must use the –new parameter when starting SAB.
    – Because two processes cannot run on the same port number we must dedicate distinct port numbers for each user.
    – Each user must have her own sabnzbd.ini file.
    – SAB users must be members of the sab group in order to read the certificates.

    Set up your first account in a generic way, then close SABnzbd and copy your sabnzbd.ini file to /opt/sabnzbd/ for easy access. Keep this file as a template and copy it to all SAB-enabled users. Make sure to change the port and https_port values. Afterwards also change the API and NZB keys from the web interface and perhaps reset their password, e-mail address, and so on.

    Just for inspirational purposes I will describe how to add a user and enable SABnzbd for her/him.

    Copy the ini file:

    # cp /home/user/vorkbaard/sabnzbd.ini /opt/sabnzbd/sabbznd.ini.generic
    

    Clean out the password. In /opt/sabnzbd/sabnzbd.ini.generic set:

    password = ""
    

    Create a new user:

    # useradd -G sab -m tinus
    

    -G sab adds the new user to the sab group; -m creates the user’s home directory.

    Bestow unto Tinus a password:

    # passwd tinus
    

    Copy the generic ini file to Tinus’s home folder and set permissions:

    # cp /opt/sabnzbd/sabnzbd.ini.generic /home/tinus/sabnzbd.ini
    # chown tinus: /home/tinus/sabnzbd.ini
    # chmod 770 /home/tinus/sabnzbd.ini
    

    In /home/tinus/sabnzbd.ini change:

    https_port = 8082
    port = 8083
    

    The port numbers should be unique.

    After you start the new user’s SABnzbd process (see the next section) log in to her SAB webinterface and set a password and other personal options.

    Managing the SAB processes

    Create a file /etc/init.d/multisab.sh and add:

    #!/bin/bash
    ### BEGIN INIT INFO
    # Provides: multisab
    # Required-Start: $remote_fs $syslog
    # Required-Stop: $remote_fs $syslog
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-Description: Start sab at boot time
    # Description: Sabnzbdplus for multiple users
    ### END INIT INFO
    
    # userlist format: "username|port number|api key [space] username|port number|api key"
    userlist="tinus|8083|CsZ2HCbpHd5z7XvDlp7QPfViqnc4rfyC vorkbaard|8081|q89pYfUkvGgbQvW5SQYkwR1Lj2FQjIz2"
    
    case "$1" in
    start)
      for userstr in $userlist
      do
        name=$(cut -d'|' -f1 <<< $userstr)
        /usr/bin/sudo -u $name -H /usr/bin/python /opt/sabnzbd/SABnzbd.py -d -f /home/$name/sabnzbd.ini --new
      done
    ;;
    stop)
      for userstr in $userlist
      do
        name=$(cut -d'|' -f1 <<< $userstr)
        port=$(cut -d'|' -f2 <<< $userstr)
        akey=$(cut -d'|' -f3 <<< $userstr)
        shutdownurl="https://localhost:$port/sabnzbd/api?mode=shutdown&apikey=$akey"
        /usr/bin/wget --no-check-certificate --delete-after $shutdownurl
      done
    ;;
    *)
      echo "Usage: $0 {start|stop}"
      exit 1
    esac
    
    exit 0
    

    wget will complain about ‘localhost’ not being the in the cert’s name, hence the –no-check-certificate switch. Using localhost will prevent problems with non-functional internet connections, nat reflection and changing domain names. You could use http://localhost:<http port number> but that way you would need to keep the non-ssl port opened. Anyway, I use localhost.

    Change the userlist string so it contains your own users and their own API keys. It is ok to use incorrect API keys to start the SABnzbd processes but to stop them (gracefully) you need the right ones. If you’ve just added a user then use a fictional API key, start the multisab service, log in to the user’s SABnzbd webinterface, find the API key and paste the key in the script.

    Make the script executable:

    # chmod +x multisab.sh
    

    Register it as a service that should start at normal boots and stop at poweroffs and such:

    # update-rc.d multisab.sh defaults
    

    You can now also control it with

    # service multisab start
    

    and

    # service multisab stop
    

    Upgrading and tweaks

    When upgrading:
    – Make sure to read the release notes. You may very well be able to keep your old ini files but you never know.
    – Keep your /opt/sabnzbd/admin folder or recreate it.

    Stop the multisab service:

    # service multisab stop

    Change to the opt partition and download and extract the new version:

    # cd /opt
    # wget https://github.com/sabnzbd/sabnzbd/releases/download/1.0.2/SABnzbd-1.0.2-src.tar.gz
    # tar -xzf SABnzbd-1.0.2-src.tar.gz
    

    Rename the old directory

    # mv /opt/sabnzbd /opt/sabnzbd.old

    Rename the new directory

    # mv /opt/SABnzbd-1.0.2 /opt/sabnzbd

    Copy the admin directory, preserving al permissions

    # cp -rp /opt/sabnzbd.old/admin /opt/sabnzbd/
    
    Start the multisab service
    # service multisab start

    Reload SABnzbd in your browser and verify everthing works and the new version is active.

    Tweaks
    - Turn off http - once everything works I suggest you turn off unencrypted http access by enabling HTTPS, leaving the HTTPS Port field empty and entering the https value in the SABnzbd Port field.
    - Set a sensible caching: http://wiki.sabnzbd.org/highspeed-downloading. If you have enough memory set it to 500M or so.
    - There are a bunch of things you can do to make SABnzbd faster, have it play nicer and overall just behave better. Poke around in the settings and check the SABnzbd site.

    Enjoy :)

    5 Comments

    1. Jeff Lavoie

      I made what I think might be a better version of the start and stop script.

      #!/bin/bash
      ### BEGIN INIT INFO
      # Provides: multisab
      # Required-Start: $network $remote_fs $syslog
      # Required-Stop: $network $remote_fs $syslog
      # Default-Start: 2 3 4 5
      # Default-Stop: 0 1 6
      # Short-Description: Starts multiple SABnzbd+ at boot time
      # Description: This script will check for sabnzb.ini files
      # in any user folders under the /home directory and
      # start a sabnzbdplus instance for each one that exists.

      ### END INIT INFO

      getparam()
      {
      cat <<EOF | python
      import ConfigParser
      config = ConfigParser.ConfigParser()
      config.read('$1')
      print (config.get('$2','$3'))
      EOF
      }

      DAEMON="/usr/bin/sabnzbdplus"

      case "$1" in
      start)
      for file in $( find /home -type f -name sabnzbd.ini )
      do
      name=$(cut -d'/' -f3 <</dev/null
      tempfile=/tmp/multisab.ini
      port=$(getparam $tempfile “misc” “port”)
      rm -rf $tempfile
      echo “Starting SABnzbd+ for user $name on port $port.”
      /usr/bin/sudo -u $name -H /usr/bin/python $DAEMON -d -f $file –new
      done
      ;;
      stop)
      for file in $( find /home -type f -name sabnzbd.ini )
      do
      name=$(cut -d’/’ -f3 <</dev/null
      tempfile=/tmp/multisab.ini
      port=$(getparam $tempfile “misc” “port”)
      akey=$(getparam $tempfile “misc” “api_key”)
      rm -rf $tempfile
      shutdownurl=”https://localhost:$port/sabnzbd/api?mode=shutdown&apikey=$akey”
      echo “Shutting down SABnzbd+ for user $name on port $port.”
      /usr/bin/wget –no-check-certificate –delete-after $shutdownurl 1>/dev/null 2>/dev/null
      #echo “Name: $name”
      #echo “Port: $port”
      #echo “API Key: $akey”
      done
      ;;
      *)
      echo “Usage: $0 {start|stop}”
      exit 1
      esac

      exit 0

      • Jeff Lavoie

        Just a note, the reason I had to use tail to make a temp file was because there are two lines before the first “section” (misc) in the ini file and the config parser thought there were no headers because of it. Using the tail command and temp file skips the two lines. If there is a better way of doing this please let me know.

    2. Pingback: Plex Media Server From Scratch – Chris R Miller

    3. Pingback: Plex Media Server From Scratch – Chris R Miller

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.

    Back to Top