DIY SNES Classic

Inspired by the recent NES Classic I made a DIY SNES Classic just in time for the Christmas holidays and it’s very portable!

To make one yourself you’ll need:

Both controllers use Bluetooth, so two player wire-free gaming is possible. The USB cables are just for charging, but if you’ve got no charge they can be used as wired controllers too. Retropie can be controlled via the controllers, no keyboard/mouse required.

Raspberry Pi 3 Nextcloud Box running on Ubuntu Core

I recently bought the Nextcloud Box. When it came to setting it up I ran into a problem, I only had Raspberry Pi 3 computers available and at the time of writting the microSDHC card provided with the Nextcloud Box only supports the Raspberry Pi 2. Bummer!


This guide outlines how to use Ubuntu Core on the Raspberry Pi 3 to run Nextcloud provided as a snap from the Ubuntu store.

If you’re not familiar with Ubuntu Core, here’s a quote:

Ubuntu Core is a tiny, transactional version of Ubuntu for IoT devices and large container deployments. It runs a new breed of super-secure, remotely upgradeable Linux app packages known as snaps

After following this guide Ubuntu Core and any installed snaps (and their data) will reside on the SD card and the 1TB hard disk in the Nextcloud box will be available for file storage. This guide explains how to:

  • Install and configure Ubuntu Core 16 for the Raspberry Pi 3
  • Format the 1TB hard disk in the Nextcloud Box and auto-mount it
  • Install the Nextcloud snap and connect the removable-media interface to allow access to the hard disk
  • Activate and configure the Nextcloud External Storage app so the hard disk can be used to store files
  • Optional configuration of Email and HTTPS for Nextcloud

Prepare a microSDHC card

I explained the main steps in this post but you really should read and follow the Get started with a Raspberry Pi 2 or 3 page as it fully explains how to use a desktop computer to download an Ubuntu Core image for your Raspberry Pi 2 or 3 and copy it to an SD card ready to boot.

Here’s how to create an Ubuntu Core microSDHC card for the Raspberry Pi 3 using an Ubuntu desktop:

  • Download Ubuntu Core 16 image for Raspberry Pi 3
  • Insert the microSDHC card into your PC
    • Use GNOME Disks and its Restore Disk Image… option, which natively supports XZ compressed images.
    • Select your SD card from the panel on the left
    • Click the “burger menu” on the right and Select Restore Disk Image…
    • Making sure the SD card is still selected, click the Power icon on the right.
  • Eject the SD card physically from your PC.
GNOME Disks - Restore Disk Image

Ubuntu Core first boot

An Ubuntu SSO account is required to setup the first user on Ubuntu Core:

Insert the Ubuntu Core microSHDC into the Raspberry Pi, which should be in the assembled Nextcloud Box with a keyboard and monitor connected. Plug in the power.

  • The system will boot then become ready to configure
  • The device will display the prompt “Press enter to configure”
  • Press enter then select “Start” to begin configuring your network and an administrator account. Follow the instructions on the screen, you will be asked to configure your network and enter your Ubuntu SSO credentials
  • At the end of the process, you will see your credentials to access your Ubuntu Core machine:
This device is registered to <Ubuntu SSO email address>.
Remote access was enabled via authentication with the SSO user <Ubuntu SSO user name>
Public SSH keys were added to the device for remote access.


Once setup is done, you can login to Ubuntu Core using ssh, from a computer on the same network, using the following command:

ssh <Ubuntu SSO user name>@<device IP address>

The user name is your Ubuntu SSO user name.

Reconfiguring network

Should you need to reconfigure the network at a later stage you can do so with:

sudo console-conf

Prepare 1TB hard disk

Log in to your Raspberry Pi 3 running Ubuntu Core via ssh.

ssh <Ubuntu SSO user name>@<device IP address>

Partition and format the Nextcloud Box hard disk

This will create a single partition formatted with the ext4 filesystem.

sudo fdisk /dev/sda

Do the following to create the partition:

Command (m for help): o
Created a new DOS disklabel with disk identifier 0x253fea38.

Command (m for help): n
Partition type
    p   primary (0 primary, 0 extended, 4 free)
    e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-1953458175, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-1953458175, default 1953458175):

Created a new partition 1 of type 'Linux' and of size 931.5 GiB.

Command (m for help): w

Now format the partition and give it the label data. This label will be used to reference it for mounting later:

sudo mkfs.ext4 -L data /dev/sda1

Automatically mount the partition

Most of the Ubuntu Core root file system is read-only, so it is not possible to edit /etc/fstab. Therefore we’ll use systemd to achieve that.

Be aware of one of the systemd.mount pitfalls:

Mount units must be named after the mount point directories they control. Example: the mount point /home/lennart must be configured in a unit file home-lennart.mount.

Yes that’s right! The unit filename must match the mount point path.

Create the media-data.mount unit:

sudo vi /writable/system-data/etc/systemd/system/media-data.mount

Add the following content:

Description=Mount unit for data



Reload systemd, scanning for new or changed units:

sudo systemctl daemon-reload

Start the media-data.mount unit, which will mount the volume, and also enable it so it will be automatically mounted on boot.

sudo systemctl start media-data.mount
sudo systemctl enable media-data.mount

And just like any other unit, you can view its status using systemctl status:

sudo systemctl status media-data.mount

Update Ubuntu Core

Make sure Ubuntu Core is up-to-date and reboot.

sudo snap refresh
sudo reboot

After the reboot, make sure /media/data is mounted. If not double check the steps above.

Install Nextcloud

The Nextcloud snap uses the removable-media interface, which grants access to /media/*, and requires manual connection:

sudo snap install nextcloud
sudo snap connect nextcloud:removable-media core:removable-media

Browse to the Nextcloud IP address and create the admin user account, for example:

  • http://nextcloud.local/

Nextcloud configuration

In the examples below replace nextcloud.local with the IP address or hostname of your Nextcloud Box and replace with your domain.

External Storage

Enable the External Storge app via:

  • http://nextcloud.local/index.php/settings/apps?category=disabled#

Configure External Storage app via:

  • http://nextcloud.local/index.php/settings/admin/externalstorages

Use these settings:

  • Folder name: data
  • External storage: Local
  • Authentication: None
  • Configuration: /media/data
  • Available for: All


Configure your outgoing email settings via:

  • http://nextcloud.local/index.php/settings/admin/additional

I use Sendgrid for sending email alerts from my servers and devices. These are the settings that work for me:

  • Send mode: SMTP
  • Encryption: STARTTLS
  • From address: [email protected]
  • Authentication method: Plain
  • Authentication required: Yes
  • Server address:
  • Username: apikey
  • Password: theactualapikey

Enabling HTTPS

It is strongly recommend that you use HTTPS if you intend to expose your Nextcloud to the Internet.

First do a test to see if you can install a Let’s Encrypt certificate:

sudo nextcloud.enable-https -d

Answer the questions:

Have you met these requirements? (y/n) y
Please enter an email address (for urgent notices or key recovery): [email protected]
Please enter your domain name(s) (space-separated):
Attempting to obtain certificates... done
Looks like you're ready for HTTPS!

If everything went well, then install the certificate

sudo nextcloud.enable-https

Answer the questions again:

Have you met these requirements? (y/n) y
Please enter an email address (for urgent notices or key recovery): [email protected]
Please enter your domain name(s) (space-separated):
Attempting to obtain certificates... done
Restarting apache... done

If Let’s Encrypt didn’t work for you, you can always use Nextcloud with a self-signed certificate.

sudo nextcloud.enable-https -s

Manual configuration changes

If you need to make any tweaks to the Nextcloud configuration file you can edit it like so:

sudo vi /var/snap/nextcloud/current/nextcloud/config/config.php

If you have manually editted the Nextcloud configuration you may need to restart nextcloud:

sudo snap disable nextcloud
sudo snap enable nextcloud


So there it is, Nextcloud running on Ubuntu Core powered by a Raspberry Pi 3. The performance is reasonable, obviously not stellar, but certainly good enough to move some cloud services for a small family away from the likes of Google and Dropbox. Now go and install some Nextcloud clients for your desktops and devices :-)

HP Microserver N54L power saving and performance tuning using Debian.

I’ve installed Open Media Vault on a HP ProLiant MicroServer G7 N54L and use it as media server for the house. OpenMediaVault (OMV) is a network attached storage (NAS) solution based on Debian.

I want to minimise power consumption but maximise performance. Here are some tweaks reduce power consumption and improve network performance.

Power Saving

Install the following.

apt-get install amd64-microcode firmware-linux firmware-linux-free \
firmware-linux-nonfree pciutils powertop radeontool

And for ACPI.

apt-get install acpi acpid acpi-support acpi-support-base


First I enabled PCIE ASPM in the BIOS and forced the kernel to use it and ACPI via grub by changing GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub, so it looks like this:

GRUB_CMDLINE_LINUX_DEFAULT="quiet acpi=force pcie_aspm=force nmi_watchdog=0"

Then update grub and reboot.


Enable Power Saving via udev

The following rules file /etc/udev/rules.d/90-local-n54l.rules enables power saving modes for all PCI, SCSI and USB devices and ASPM. Futher the internal Radeon card power profile is set to low as there is rarely a monitor connected. The file contains the following:

SUBSYSTEM=="module", KERNEL=="pcie_aspm", ACTION=="add", TEST=="parameters/policy", ATTR{parameters/policy}="powersave"
SUBSYSTEM=="i2c", ACTION=="add", TEST=="power/control", ATTR{power/control}="auto"
SUBSYSTEM=="pci", ACTION=="add", TEST=="power/control", ATTR{power/control}="auto"
SUBSYSTEM=="usb", ACTION=="add", TEST=="power/control", ATTR{power/control}="auto"
SUBSYSTEM=="usb", ACTION=="add", TEST=="power/autosuspend", ATTR{power/autosuspend}="2"
SUBSYSTEM=="scsi", ACTION=="add", TEST=="power/control", ATTR{power/control}="auto"
SUBSYSTEM=="spi", ACTION=="add", TEST=="power/control", ATTR{power/control}="auto"
SUBSYSTEM=="drm", KERNEL=="card*", ACTION=="add", DRIVERS=="radeon", TEST=="power/control", TEST=="device/power_method", ATTR{device/power_method}="profile", ATTR{device/power_profile}="low"
SUBSYSTEM=="scsi_host", KERNEL=="host*", ACTION=="add", TEST=="link_power_management_policy", ATTR{link_power_management_policy}="min_power"

Add this to /erc/rc.local.

echo '1500' > '/proc/sys/vm/dirty_writeback_centisecs'

Hard disk spindown

Using the Open Media Vault web interface got to Storage -> Physical Disks, select each disk in turn and click Edit then set:

  • Advanced Power Management: Intermediate power usage with standby
  • Automatic Acoustic Management: Minimum performance, Minimum acoustic output
  • Spindown time: 20 minutes

Performance Tuning


The following tweaks improve network performance ,but I have a HP NC360T PCI Express Dual Port Gigabit Server Adapter in my N54L so these settings may not be applicable to the onboard NIC.

Add this to /erc/rc.local.

ethtool -G eth0 rx 4096
ethtool -G eth1 rx 4096
ethtool -G eth0 tx 4096
ethtool -G eth1 tx 4096
ifconfig eth0 txqueuelen 1000
ifconfig eth1 txqueuelen 1000

Add the following to /etc/sysctl.d/local.conf.

fs.file-max = 100000
net.core.netdev_max_backlog = 50000
net.core.optmem_max = 40960
net.core.rmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_default = 16777216
net.core.wmem_max = 16777216
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
vm.swappiness = 10


With these settings applied powertop reports everything that can be in a power saving mode is and the room temperature is measurably cooler. More importantly, with four 4TB drives in a RAID-5 configuration formatted with XFS and dual bonded gigabit ethernet, I am able to backup data to the server at a sustained rate of 105MB/s, which is 0.85 Gbit.

Not too shabby for an AMD Turion II Neo N54L (2.2GHz) :-D


Intel NUC5i7RYH with Ubuntu

I’ve just bought my first brand new computer since 2008. Thanks to the Black Friday and Cyber Monday sales on and this year I was able to put together a pretty sweet Intel NUC which is now running Ubuntu MATE 15.10.

I spoke about this new system on LINUX Unplugged Episode 122 and have been contacted by people wanting more details. Hopefully this blog post will answer any outstanding questions. Press play below to hear to what I said on the podcast.


I purchased an Intel Next Unit of Computing (NUC) Kit NUC5I7RYH.

Everything works out of the box with Ubuntu MATE 15.10 including sending audio to the monitor over HDMI and DisplayPort.


The Core i7 5557U specs state that DDR3L 1866 Mhz RAM is supported. The arstechnica Mini-review: Intel’s powered-up Core i7 Broadwell mini PC has some benchmarks that show a performance improvement when using 1866 Mhz clocked RAM, so I purchased:

The SSDs

I have two SSDs in the NUC.

This is where you might need to do some more research. At the time of writing, it is not possible to boot directly from the Samsung SM951 NVMe SSD. Although other quad channel NVMe SSDs do appear to be supported as the boot device. It is possible that the Samsung SSD 950 Pro, which is also NVMe, can be used as the boot device in Linux, but don’t take my word for it. Do your research.

My work around was make the SanDisk Ultra II the boot device by putting /boot and the MBR on it. I have put / and swap (swap because I want to experiment with suspend and hibernate) are on the Samsung SM951 and /home is on the SanDisk Ultra II.

There are faster SSDs than the SanDisk Ultra II but this was 50% off during Black Friday and just too good a deal to pass by. I did sacrifice a little performance on this component, so if absolute performance is your goal look at alternative SSDs, the Samsung 850 EVO seems to benchmark favourably.

The Monitor

A week after I purchased the NUC I noticed were selling the monitor I wanted with a £100 discount. So I snapped one up.

The NUC is connected via mini Display Port and my Dell Precision T7400 is connected via HDMI. The Samsung S27D850T has an audio out and a 2.1 speaker set is connected to it.


I’m extremely happy with the NUC5I7RYH. Linux compatibility is first class, it’s fast and has relatively low power consumption. You can even charge a mobile phone using one of the front USB ports (the yellow one) when the NUC is powered off. It is my principle workstation and is able to handle everything I demand from it, with ease:

  • mp3 and ogg audio encoding
  • h.264 video encoding (~1 min of video @480p encodes in 1 second)
  • running multiple virtual machines
  • compiling large applications
  • creating xz compressed images of Ubuntu flavours for the Raspberry Pi 2

I’ve not tried gaming on it yet, but the holidays are approaching and GRID Autosport was released for SteamOS this week. So I know what I’ll be doing in a couple of weeks time :-D

Installing Nikola on Ubuntu

Nikola is a static site and blog generator written in Python that I’ve been using for a good while now. This blog post describes how to install Nikola on Ubuntu 14.04 or newer. Now, this may look like a long winded way to install Nikola, given that .deb package exist, but in my opinion it is the correct way to install Nikola on Ubuntu.

Installing Python

First you’ll need Python.

sudo apt-get install cython3 libpython3.4 python3.4 python3.4-dev python3.4-minimal

Now install the Python “package” management utilities.

sudo apt-get install python-setuptools python-virtualenv python-pip virtualenvwrapper

The Snakepit

Create a “Snakepit” directory for storing all the virtualenvs.

  mkdir ~/Snakepit

Create a virtualenv for Nikola

The following will create a new virtualenv called nikola based on Python 3.4.

virtualenv -p /usr/bin/python3.4 ~/Snakepit/nikola-773

Working on a virtualenv

To activate the virtualenv do the following.

source ~/Snakepit/nikola-773/bin/activate

Your shell prompt will change while a virtualenv is being worked on to indicate which virtualenv is currently active.

While working on a virtualenv you can pip install what you need or manually install any Python libraries safe in the knowledge you will not adversely damage any other virtualenvs or the global packages in the process. Very useful for developing a new branch which may have different library requirements than the master/head.

When you are finished working in a virtualenv you can deactivate it by simply executing deactivate.

Install Nikola requirements

Nikola requires some additional packages.

sudo apt-get install liblcms2-dev libfreetype6-dev libjpeg8-dev \
libopenjp2-7-dev libtiff5-dev libwebp-dev libxslt1-dev libxml2-dev \
libyaml-dev libzmq-dev zlib1g-dev

Some of the content optimisation filters require additional packages.

sudo apt-get install closure-compiler jpegoptim optipng yui-compressor

Install Tidy 5. (optional)

sudo apt-get -y remove libtidy-0.99-0 tidy
wget -O /tmp/tidy5.deb
sudo dpkg -i /tmp/tidy5.deb
sudo ln -s /usr/bin/tidy /usr/local/bin/tidy5
rm /tmp/tidy5.deb

What are these requirements for?

The following are required to build pillow, the Python imaging library.

  • liblcms2-dev
  • libfreetype6-dev
  • libjpeg8-dev
  • libopenjp2-7-dev
  • libtiff5-dev
  • libwebp-dev
  • zlib1g-dev

The following are required to build lxml, a Python XML library.

  • libxml2-dev
  • libxslt1-dev

The following are required to build python-coveralls.

  • libyaml-dev

The following are required to build pyzmq.

  • libzmq-dev

Install Nikola

First install Cython, which will ensure some of the packages required by Nikola use all the available optimisations.

pip install --upgrade Cython

Install all of Nikola.

pip install --upgrade "Nikola[extras,tests]"

Create a site

After installing Nikola, you should create a site. A site is a collection of all assets needed to render your website, including configuration, posts, pages, images, and all other files and customizations.

To create a site, you need to run:

nikola init <directory_name>

A wizard will guide your initial setup The --demo option can be used to populate your site with some example content. If you do not want the wizard, use the --quiet argument.

Nikola is now installed and and initial site is setup. nikola help and the Nikola Handbook will assist you from here.

Installing Willie IRC Bot on Debian

Willie is an IRC bot written in Python that I’ve recently started using. This blog post describes how to install Willie on Debian and as usual I will be using virtualenv to isolate this Python application from the rest of the system.

Installing Python

First you’ll need Python.

sudo apt-get install libpython2.7 python2.7 python2.7-dev python2.7-minimal

The following will also be required to enable all the features Willie supports.

sudo apt-get install enchant python2.7-dev libxslt1-dev libxml2-dev

Remove any apt installed Python packages that we are about to replace. The versions of these packages in the Debian repositories soon get stale.

sudo apt-get purge python-setuptools python-virtualenv python-pip python-profiler

Install pip.

sudo python2.7

Use pip to install virtualenv.

sudo pip install virtualenv --upgrade

The Snakepit

Create a “Snakepit” directory for storing all the Python virtual environments.

mkdir ~/Snakepit

Create a virtualenv for Willie

The following will create a new virtualenv called willie using Python 2.7 as the interpreter.

virtualenv -p /usr/bin/python2.7 ~/Snakepit/willie

Working on a virtualenv

Activate the virtualenv for Willie.

source ~/Snakepit/willie/bin/activate

Your shell prompt will change, something like (willie)[email protected]:~$, while a virtualenv is being worked on to indicate which virtualenv is currently active.

While working on a virtualenv you can pip install what you need or manually install any Python libraries safe in the knowledge you will not upset any other virtualenvs or the global packages in the process. Very useful for developing a new branch which may have different library requirements than the current stable release.

When you are finished working in a virtualenv you can deactivate it by simply executing deactivate.

Install Willie

I’ve decided to use Python 2.7 to run Willie and therefore have to install backports.ssl_match_hostname which is not required if you use Python 3.3.

pip install willie backports.ssl_match_hostname

Additional functionality

Willie has no external dependencies, besides Python. However, some of the modules do have external dependencies. So install the following Python modules so that I can make use of everything Willie can do.

pip install feedparser pytz lxml praw pyenchant pygeoip ipython --upgrade

Configure Willie

I am not going to explain to how to configure Willie because all that good stuff is very well documented by the project.

But for reference, my default.cfg looks something like this:

nick = nicofyourbot
user = nicofyourbot
name = Give You Bot A Name
host =
use_ssl = true
verify_ssl = true
port = 6697
owner = nicofthebotowner
channels = #example
nickserv_password = ************
prefix = \.
timeout = 120

userdb_type = sqlite
userdb_file = /home/username/.willie/willie.db

Willie as a daemon

From this point on I assume you’ve completed the first run configuration of Willie and have .willie/default.cfg in your home directory.

Add the following to /etc/init.d/willie.

# Provides: willie
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Willie IRC Bot.
# Description: Start and stops the Willie IRC bot for a given user.

# NOTE! Replace with the user you want to run Willie.

HOMEDIR=$(getent passwd $willie_USER | awk -F: '{print $6}')

startd() {
    if [ -f ${CONFIG} ]; then
        echo "Starting Willie for $willie_USER"
        start-stop-daemon -c $willie_USER -u $willie_USER -x $DAEMON -S -- --config ${CONFIG} --fork --quiet
        echo "Couldn't start Willie for $willie_USER (no $CONFIG found)"

stopd() {
    echo "Stopping Willie for $willie_USER"
    willie_PID=$(pgrep -fu $willie_USER $DAEMON)
    if [ -z "$willie_PID" ]; then
        echo "Willie for USER $willie_USER: not running."
        kill -15 $willie_PID

status() {
    willie_PID=$(pgrep -fu $willie_USER $DAEMON)
    if [ -z "$willie_PID" ]; then
        echo "Willie for USER $willie_USER: not running."
        echo "Willie for USER $willie_USER: running (pid $willie_PID)"

case "$1" in
    start) startd ;;
    stop) stopd ;;
    restart|reload|force-reload) stopd && startd ;;
    status) status ;;
    *) echo "Usage: /etc/init.d/willie {start|stop|reload|force-reload|restart|status}"
       exit 1

exit 0

Set the permissions.

sudo chmod +x /etc/init.d/willie

Check that you can start/stop Willie.

sudo /etc/init.d/willie start
sudo /etc/init.d/willie status
sudo /etc/init.d/willie stop

Add willie to the startup/shutdown sequence.

sudo update-rc.d willie defaults

And that’s it. Willie is now running as a daemon inside a virtualenv.

ZNC IRC proxy

I have been using the BIP IRC proxy that maintains a persistent connection(s) to a list of IRC channels. However, I’ve heard good things about ZNC and decided to give it a try.

The purpose of an IRC proxy, or bouncer, is that you can then point your IRC clients to them to maintain a transparent connection from multiple clients and playback the conversations that took place while you were away.

Installing ZNC

The ZNC package for Debian Wheezy are very old, so I decide to install from source.

Install required packages

We first need to make sure we have all the packages required to build ZNC.

sudo apt-get install build-essential libssl-dev libperl-dev pkg-config

Compile ZNC

Now download and compile ZNC.

tar zxvf znc-1.4.tar.gz
cd znc-1.4
./configure --with-openssl
sudo make install

Create a user

Create a separate ZNC user so that ZNC does not need to run as root:

sudo groupadd znc
sudo adduser --system --home /var/lib/znc --group znc

Configuring ZNC

You can use the interactive wizard to configure ZNC which really help create the initial configuration.

sudo -u znc /usr/local/bin/znc --datadir=/var/lib/znc --makeconf

Here is a transcript of how I answered the initial configuration questions.

[ .. ] Checking for list of available modules...
[ >> ] ok
[ ** ] Building new config
[ ** ]
[ ** ] First let's start with some global settings...
[ ** ]
[ ?? ] What port would you like ZNC to listen on? (1025 to 65535): 7778
[ ?? ] Would you like ZNC to listen using SSL? (yes/no) [no]: yes
[ ?? ] Would you like ZNC to listen using both IPv4 and IPv6? (yes/no) [yes]:
[ .. ] Verifying the listener...
[ >> ] ok
[ ** ] Unable to locate pem file: [/var/lib/znc/znc.pem], creating it
[ .. ] Writing Pem file [/var/lib/znc/znc.pem]...
[ >> ] ok
[ ** ]
[ ** ] -- Global Modules --
[ ** ]
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] | Name      | Description                                              |
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] | partyline | Internal channels and queries for users connected to znc |
[ ** ] | webadmin  | Web based administration module                          |
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] And 10 other (uncommon) modules. You can enable those later.
[ ** ]
[ ?? ] Load global module <partyline>? (yes/no) [no]: yes
[ ?? ] Load global module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ** ] Now we need to set up a user...
[ ** ]
[ ?? ] Username (AlphaNumeric): yournick
[ ?? ] Enter Password:
[ ?? ] Confirm Password:
[ ?? ] Would you like this user to be an admin? (yes/no) [yes]:
[ ?? ] Nick [yournick]:
[ ?? ] Alt Nick [yournick_]:
[ ?? ] Ident [yournick]:
[ ?? ] Real Name [Got ZNC?]: Your Name
[ ?? ] Bind Host (optional):
[ ?? ] Number of lines to buffer per channel [50]: 1024
[ ?? ] Would you like to clear channel buffers after replay? (yes/no) [yes]:
[ ?? ] Default channel modes [+stn]:
[ ** ]
[ ** ] -- User Modules --
[ ** ]
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] | Name         | Description                                                                              |
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] | chansaver    | Keep config up-to-date when user joins/parts                                             |
[ ** ] | controlpanel | Dynamic configuration through IRC. Allows editing only yourself if you're not ZNC admin. |
[ ** ] | perform      | Keeps a list of commands to be executed when ZNC connects to IRC.                        |
[ ** ] | webadmin     | Web based administration module                                                          |
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] And 21 other (uncommon) modules. You can enable those later.
[ ** ]
[ ?? ] Load module <chansaver>? (yes/no) [no]: yes
[ ?? ] Load module <controlpanel>? (yes/no) [no]: tes
[ ?? ] Load module <controlpanel>? (yes/no) [no]: yes
[ ?? ] Load module <perform>? (yes/no) [no]: yes
[ ?? ] Load module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ?? ] Would you like to set up a network? (yes/no) [no]:
[ ** ]
[ ?? ] Would you like to set up another user? (yes/no) [no]:
[ .. ] Writing config [/var/lib/znc/configs/znc.conf]...
[ >> ] ok
[ ** ]
[ ** ]To connect to this ZNC you need to connect to it as your IRC server
[ ** ]using the port that you supplied.  You have to supply your login info
[ ** ]as the IRC server password like this: user/network:pass.
[ ** ]
[ ** ]Try something like this in your IRC client...
[ ** ]/server <znc_server_ip> +7778 flexiondotorg:<pass>
[ ** ]And this in your browser...
[ ** ]https://<znc_server_ip>:7778/
[ ** ]
[ ?? ] Launch ZNC now? (yes/no) [yes]: no

Running ZNV as a daemon

Here is a /etc/init.d/znc for Debian based on this installation method:

#! /bin/sh
# Provides:          znc
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ZNC IRC bouncer
# Description:       ZNC is an IRC bouncer

DESC="ZNC daemon"

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

# Function that starts the daemon/service
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    if [ ! -d $PIDDIR ]
        mkdir $PIDDIR
    chown $USER:$GROUP $PIDDIR
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test --chuid $USER > /dev/null || return 1
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $USER -- $DAEMON_ARGS > /dev/null || return 2

# Function that stops the daemon/service
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --chuid $USER
    [ "$RETVAL" = 2 ] && return 2
    # Wait for children to finish too if this is a daemon that forks
    # and if the daemon is only ever run from this initscript.
    # If the above conditions are not satisfied then add some other code
    # that waits for the process to drop all resources that could be
    # needed by services started subsequently.  A last resort is to
    # sleep for some time.
    start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON --chuid $USER
    [ "$?" = 2 ] && return 2
    # Many daemons don't delete their pidfiles when they exit.
    rm -f $PIDFILE
    return "$RETVAL"

# Function that sends a SIGHUP to the daemon/service
do_reload() {
    start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME --chuid $USER
    return 0

case "$1" in
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
    log_daemon_msg "Reloading $DESC" "$NAME"
    log_end_msg $?
    log_daemon_msg "Restarting $DESC" "$NAME"
    case "$?" in
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_end_msg 1 ;; # Old process is still running
            *) log_end_msg 1 ;; # Failed to start
        # Failed to stop
        log_end_msg 1
    echo "Usage: $SCRIPTNAME {status|start|stop|reload|restart}" >&2
    exit 3

After you’ve created the script, you must give it the proper permissions to run and add the script to the startup/shutdown sequence.

sudo chmod 755 /etc/init.d/znc
sudo update-rc.d znc defaults

Start the service:

sudo service znc start

Stop the service:

sudo service znc stop

Web configuration

I love that ZNC comes bundled with a web based configuration tool. Just login to to add users, add networks to users and to add channels to networks. Really simple stuff.

IRC client configuration

I use HexChat, but other IRC clients are available. Just add a new Network to HexChat for your ZNC server, use the username, suffixed with the network name you configured in ZNC, and your ZNC password.


I much prefer ZNC to BIP.

  • I really like the web and IRC configuration but I still have the option to configure the config files directly.
  • ZNC is far less cryptic with regard to setting up IRC client connections and user management is much better implemented.
  • When I add a new channel to an existing network in ZNC it automatically appears in my connected clients without the need to restart anything.
  • ZNC’s IRC backlogs don’t have the confusing double time stamps present in BIP and ZNC is much faster re-establishing connections to my multiple IRC network and channels.
  • Most importantly, ZNC has been far more stable than BIP.


Monitorix on Debian

I have a few Debian servers that run at home and on VPSs. I wanted to add some basic systems monitoring to them, but didn’t want anything too complicated to look after. I found Monitorix.

Monitorix is a free, open source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. It has been created to be used under production Linux/UNIX servers, but due to its simplicity and small size can be used on embedded devices as well.

Install Monitorix

This install has been tested on Debian Squeeze and Wheezy. First install the dependencies.

sudo apt-get install rrdtool perl libwww-perl libmailtools-perl \
libmime-lite-perl librrds-perl libdbi-perl libxml-simple-perl \
libhttp-server-simple-perl libconfig-general-perl libio-socket-ssl-perl

Now Monitorix itself.

wget -c "" -O monitorix_3.5.1-izzy1_all.deb
sudo dpkg -i monitorix_3.5.1-izzy1_all.deb

At this point Monitorix is installed and running. Point your browser to and enjoy!

Configuring Monitorix

Everything in /etc/monitorix/monitorix.conf is comprehensively documented, just get tweaking.

Each time you update the configuration Monitorix will require a restart.

sudo service monitorix restart

nginx status

If you run nginx then you’ll want to drop the following into /etc/nginx/conf.d/status.conf so that Monitorix can monitor nginx.

server {
    listen localhost:80;
    location /nginx_status {
        stub_status on;
        access_log off;
        deny all;

subSonic on Debian

Last year I removed all my music from Google Play Music and created my own subSonic server. I really like subSonic but don’t use it a huge amount, mostly for syncing some music to my phone prior to going on holiday or business. Therefore, I’ve made a single one time donation to the project rather than the ongoing monthly usage fee.

Installing subSonic on Debian

This is how I install subSonic on Debian Wheezy.

Install Tomcat.

sudo apt-get install tomcat7

Install subSonic.

apt-get install ffmpeg
sudo mkdir /var/subsonic
sudo chown tomcat7: /var/subsonic
sudo wget -c
sudo cp subsonic.war /var/lib/tomcat7/webapps

Restart Tomcat.

sudo service tomcat7 restart

Login to subSonic by visiting and login with the credentials admin and admin. Make sure you change the password straight away.

Right, that is it. You can stop here and start filling subSonic with your music.

subSonic clients

On the rare occasions that I listen to music via subSonic I use UltraSonic for Android and Clementine on my Arch Linux workstations.


Headless cloudprint server on Debian for MFC-7360N

I have a Brother MFC-7360N printer at home and there is also one at work. I wanted to to get Cloudprint working with Android devices rather than use the Android app Brother provide, which is great when it works but deeply frustrating (for my wife) when it doesn’t.

What I describe below is how to Cloudprint enable “Classic printers” using Debian Wheezy.

Install CUPS

Install CUPS and the Cloudprint requirements.

sudo apt-get install cups python-cups python-daemon python-pkg-resources

Install the MFC-7360N Drivers

I used the URL below to access the .deb files required.

If you’re running a 64-bit Debian, then install ia32-libs first.

sudo apt-get install ia32-libs

Download and install the MFC-7360N drivers.

wget -c
wget -c
sudo dpkg -i --force-all mfc7360nlpr-2.1.0-1.i386.deb
sudo dpkg -i --force-all cupswrapperMFC7360N-2.0.4-2.i386.deb

Configure CUPS

Edit the CUPS configuration file commonly located in /etc/cups/cupsd.conf and make the section that looks like:

# Only listen for connections from the local machine.
Listen localhost:631
Listen /var/run/cups/cups.sock

look like this:

# Listen on all interfaces
Port 631
Listen /var/run/cups/cups.sock

Modify the Apache specific directives to allow connections from everywhere as well. Find the follow section in /etc/cups/cupsd.conf:

<Location />
# Restrict access to the server...
  Order allow,deny

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny

# Restrict access to the configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny

Add Allow All after each Order allow,deny so it looks like this:

<Location />
# Restrict access to the server...
  Order allow,deny
  Allow All

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny
  Allow All

# Restrict access to the configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
  Allow All

Add the MFC-7360N to CUPS.

If your MFC-7360N is connected to your server via USB then you should be all set. Login to the CUPS administration interface on http://yourserver:631 and modify the MFC7360N printer (if one was created when the drivers where installed) then make sure you can print a test page via CUPS before proceeding.

Install Cloudprint and Cloudprint service

wget -c
wget -c
sudo dpkg -i cloudprint_0.11-5.1_all.deb
sudo dpkg -i cloudprint-service_0.11-5.1_all.deb


Google accounts with 2 step verification enabled need to use an application-specific password.

Authenticate cloudprintd.

sudo service cloudprintd login

You should see something like this.

Accounts with 2 factor authentication require an application-specific password
Google username: [email protected]
Added Printer MFC7360N

Start the Cloudprint daemon.

sudo service cloudprintd start

If everything is working correctly you should see your printer the following page:

Printing from mobile devices


Add the Google Cloud Print app to Android devices and you’ll be able to configure your printer preferences and print from Android..

Chrome and Chromium

When printing from within Google Chrome and Chromium you can now select Cloudprint as the destination and choose your printer.

Flattr this