Category Archives: Services

Using stunnel to add SSL/TLS to non-secure services (Foscam Webcam with Audio)

What is stunnel?

The stunnel program is designed to work as SSL encryption wrapper between remote client and local (inetd-startable) or remote server. The concept is that having non-SSL aware daemons running on your system you can easily setup them to communicate with clients over secure SSL channel.

Why use it?

I originally was using an Apache reverse proxy for a similar result. See this post. Still, turns out some services don’t quite work perfectly. I have a Foscam Webcam – FI8910W – which I would like to be able to securely access. Using the Apache reverse proxy results in the audio portion of the webcam streaming not making it. Over at Warped.org, stunnel was recommended, and it works great. It would work just as easily for any other non-secure service using very similar steps. Here are those steps for Ubuntu.

Step 1 – Install the service

sudo apt-get install stunnel4

This installs the service, creates a separate username and group for security reasons, and makes the default configuration file directory: /etc/stunnel/

Step 2 – Configure the service

My installation did not make a default configuration file, but since the file is so simple, let’s just make one from scratch.
Depending on your SSL certificate needs, the actual certificate lines you may need in your configuration will vary. Based on my setup as outlined in this post, all three cert lines are needed.

sudo nano /etc/stunnel/stunnel.conf

Add the following, customizing it to your service:

client = no

#SSL client cert file
cert = /etc/ssl/certs/server.crt
#SSL private key
key = /etc/ssl/private/server.key
#SSL Certificate Authority file
CAfile = /etc/ssl/certs/StartSSL_Class1.pem

# Service for foscam webcam
[foscam]
#new incoming port
accept = 1666
#target service address and port
connect = 192.168.1.89:80

Step 3 – Activate the service

sudo nano /etc/default/stunnel4

Change the line with “ENABLED=0″ to

ENABLED=1

Then start the service:

sudo /etc/init.d/stunnel4 start

Step 4 – Test the service

Pull open your web browser of choice and enter in the address of your server running stunnel and the port you chose. For example, https://192.168.1.2:1666. Make sure you use https. It should redirect to the service you desired to wrap in SSL. Good job!

Full local backup using Duplicity and Duply

I of course also need my local system backed up, and after way too much searching for the best approach, I settled on duplicity and duply.

Duply is a script that simplifies profiles for duplicity. Let’s get it installed. The python-paramiko package is needed if you want to use ssh or scp to reach the destination.

sudo apt-get install duply duplicity python-paramiko python-gobject-2

If you don’t install python-paramiko, you may receive the error “BackendException: Could not initialize backend: No module named paramiko” and if you don’t installed python-gobject-2 you may receive the warning “Import of duplicity.backends.giobackend Failed: No module named gio.”
Since I needed at least duplicity version 0.6.19, i manually downloaded and installed the latest version of both duplicity and duply from their websites then installed.

Also, because my scripts will be running as root in order to access all files, let’s create a better landing place for the duply profiles in /etc/duply/. If you create this prior to setting up a profile, duply will automatically use it.

sudo mkdir /etc/duply

Now create the first backup profile

sudo duply fullsystem create

A configuration file is now created in /etc/duply/fullsystem/ called conf. Modify it to set the encryption, source and target location, etc.

sudo nano /etc/duply/fullsystem/conf

Commands to run prior to backup should be in a file named pre: /etc/duply/fullsystem/pre
Commands to run prior to backup should be in a file named post:/etc/duply/fullsystem/post
If you are using encryption, you may want to have the pre or post script to backup the encryption keys and the duply conf file separately to make restores simpler in the case of a full drive loss.

Exclusions should be listed in /etc/duply/fullsystem/exclude
For a full system backup, these are my excludes:

/cdrom
/dev
/lost+found
/media
/mnt
/proc
/run
/sys
/tmp
/var/tmp
/zfsdisk

Check the status of your conf setup by running:

sudo duply fullsystem status

If it works, then you can backup using

sudo duply fullsystem backup

I add the local backup directory to my CrashPlan backup list, in order to get it off-site as well.

Automating With cron

Edit the crontab for root:
sudo crontab -e
You want two tasks. One that runs each month to clean up old backups and one that runs to create daily incremental backups:

0 2 1 * * duply fullsystem backup_verify_purge --force
0 3 * * * duply fullsystem backup
How to Restore

To list the backups available:

sudo duply fullsystem status

To restore the entire backup to /tmp/restore (make sure you have the room):

sudo duply fullsystem restore /tmp/restore

To restore the latest version of /etc/network/interfaces to /tmp/interfaces:

sudo duply fullsystem fetch etc/network/interfaces /tmp/interfaces

To restore /etc/network/interfaces to a version from 14 days ago:

sudo duply fullsystem fetch etc/network/interfaces /tmp/interfaces 14D

If your system crashes, and you didn't have a backup of the duply conf file, you can still restore all or certain files to /tmp/restore using duplicity:

sudo duplicity --no-encryption --file-to-restore etc/duply/ scheme:///backup.location /tmp/restore

L2TP/IPSec with Pre-Shared Key (PSK) VPN server

I want to be able to break through into my network from my phone or laptop – PPTP is too insecure and OpenVPN is still too much of a headache plus not generally built into Android.

I followed these two guides: http://pleasefeedthegeek.wordpress.com/2012/04/21/l2tp-ubuntu-server-setup-for-ios-clients/ and http://vitobotta.com/l2tp-ipsec-vpn-server/

Let’s install/modify several files.
We will assume that 192.168.1.0/24 is your local subnet, and your server is 192.168.1.2 in that subnet. The VPN will be on the 10.10.0.0/24 subnet.

sudo apt-get install openswan ppp xl2tpd

Edit /etc/ipsec.conf to contain the following:

config setup
    nat_traversal=yes
    virtual_private=%v4:10.10.0.0/24
    protostack=netkey
	
conn L2TP-PSK-NAT
    rightsubnet=vhost:%priv
    also=L2TP-PSK-noNAT
 
conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    type=transport
    left=192.168.1.2
    leftnexthop=192.168.1.1
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=15
    dpdtimeout=30
    dpdaction=clear

Edit /etc/xl2tpd/xl2tpd.conf to contain the following:

[global]
ipsec saref = yes
[lns default]
ip range = 10.10.0.2-10.10.0.10
local ip = 10.10.0.1
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

Edit /etc/ppp/options.xl2tpd to contain the following:

require-mschap-v2
ms-dns 192.168.1.1
ms-dns 8.8.8.8
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

Edit /etc/ppp/chap-secrets to contain the following (changing the client names and the client passwords):

Client1 l2tpd Client1Password 10.10.0.2
Client2 l2tpd Client2Password 10.10.0.3

Edit /etc/ipsec.secrets to contain the following (changing IP’s and the PSK):

192.168.1.2 %any: PSK "YourPreSharedKey"

Restart the daemons:

sudo /etc/init.d/pppd-dns restart
sudo /etc/init.d/xl2tpd restart
sudo /etc/init.d/ipsec restart

You must forward ports 500, 4500, and 1701 (UDP only) to your server on your router, and then also add the following to your /etc/rc.local above the “exit 0″ line:

echo 1 > /proc/sys/net/ipv4/ip_forward

for each in /proc/sys/net/ipv4/conf/*
do
  echo 0 > $each/accept_redirects
  echo 0 > $each/send_redirects
done

iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT 
iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT 
iptables -A INPUT -p udp -m udp --dport 1701 -j ACCEPT
iptables -A FORWARD -s 10.10.0.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE

Run your /etc/rc.local:

sudo /etc/rc.local

Then set up your client:

Type: L2TP/IPSec PSK
Server address: (your public facing domain or IP, could be dynamic domain)
L2TP secret: (not used)
IPSec identifier: (not used)
IPSec pre-shared key: YourPreSharedKey
Username: Client1
Password: Client1Password

Enjoy!

Bare Metal with Incremental Windows Backups

So recent Windows have imaging backup tools built in, which could easily be used. However, after using WHS for so long I wanted a central view and de-dupe of my backups on my new server too. I believe I found the solution for me with URBackup.
It is installed using a PPA source by running:

sudo add-apt-repository ppa:uroni/urbackup
sudo apt-get update<
sudo apt-get install urbackup-server

The following sets up access to URBackup from an apache subdirectory:

libapache2-mod-fastcgi
sudo ln -s /var/urbackup/www /var/www/urbackup

Add following line to the ’fastcgi.conf’:

FastCgiExternalServer /var/www/urbackup/x -host 127.0.0.1:55413

Restart Apache.

Then you install the Windows client from here, install, and it backs up an image of your primary partition.

Remote Logging Service for my Router

I’d like to have my DD-WRT router keep a log on my server, rather than in it’s memory. Ubuntu’s rsyslog service does that. Here are the changes needed:
Modify the rsyslog configuration file

Using your favorite text editor, edit a new file named /etc/rsyslog.d/60-remotelogging.conf
Add the following to enable the UDP listening service:

# Begin /etc/rsyslog.d/45-remotelogging.conf
# Enable remote logging server
$ModLoad imudp
$UDPServerRun 514

# Send all logging from DD-Wrt router to a specific log file.
if $fromhost == 'router.home' then /var/log/ddwrt-syslog
& ~

# End /etc/rsyslog.d/45-remotelogging.conf

Now restart the syslog daemon

sudo service rsyslog restart

Now I just need to figure out how to analyze it :D.

Webcam streaming, time-lapse and motion detection

I have a webcam connected to my server, and I want to use it to offer a stream I can access using my phone, and also to perform some time-lapse capturing as well as motion detection when I’m not at home with email notification.

Previously I had tried zoneminder, but I didn’t really like the approach. This time I’m using a great package just called “motion.” I didn’t think it would be full-featured, but it is great. Installation is simple:

sudo apt-get install motion

Then I edited the /etc/default/motion, setting start_motion_daemon=yes.
The last setup file to edit is /etc/motion/motion.conf. It is very well documented and has so many options. Here are some of the tweaks I made:

v4l2_palette 2 #mjpeg palette
width 1280 #capture resolution
height 720 #capture resolution
text_double on #easier to read time/date
snapshot interval 4
target_dir /tmp/motion #stores snapshots/motion videos in RAM using tmp dir
snapshot_filename timelapse/%Y%m%d_%H%M%S #subdirectory for snapshots
webcam_port 39820 #changed to random port

This gave a webcam stream visible using a web browser, and captures a snapshot every 4 seconds for time-lapse. This is all stored in the tmp RAM disk in order to not be constantly writing to the hard drives more than needed. So that I don’t lose the snapshots upon reboot, I use the following file in /etc/init.d/transientmotion based on my /var/log RAM disk script of /etc/init.d/transientlog.

#!/bin/sh
### BEGIN INIT INFO
# Provides: transientmotion
# X-Start-Before:	motion
# X-Stop-After:		motion
# X-Interactive:	yes
# Required-Start:	
# Required-Stop:	
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	Keeps RAM timelapse photos between reboots
# Description: Moves the contents of /tmp/motion/ to disk upon
#              shutdown/reboot, and restores upon startup.
### END INIT INFO

# Version 1.0
#
# Inspired by transientlog.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=transientmotion
DESC="Transient motion directory"
LOCKFILE=/var/lock/$NAME.lock
VARLOG=/tmp/motion/timelapse

# 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/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

if [ -z "$VARLOGPERM" ]; then
	var=/var
	log=`basename $VARLOG`
	VARLOGPERM="$var/permanent$log"
	unset var log
fi


do_start()
{
	# Return
	#   0 if transient motion has been started
	#   1 if transient motion was already running
	#   2 if transient motion could not be started

	[ -f $LOCKFILE ] && return 1
	
	# Check if I'm root
	[ `id -u` -eq 0 ] || return 2

	# If VARLOG does not exist?
	[ -d $VARLOG ] || return 2

	# VARLOGPERM either does not exist (first invocation)
	# or is empty (left from previous invocation).
	# 
	[ -d $VARLOGPERM ] || mkdir -p $VARLOGPERM || return 2
	[ -d $VARLOG ] || mkdir -p $VARLOG || return 2

	# Mount a tmpfs over VARLOG.
	# The mount will shadow the current contents of VARLOG.
	# So, before, make a bind mount so that looking into VARLOGPERM
	# we'll see the current contents of VARLOG, which
	# will not be available anymore as soon as we mount
	# a tmpfs over it.
	#
	if [ $? -eq 0 ]; then
		# Populate the tmpfs
		if cp -rfp $VARLOGPERM -T $VARLOG; then
			# Success!
			rm $VARLOGPERM/*
			touch $LOCKFILE
			return 0
		fi

		# Something went wrong...

		# Rollback the mount
	fi

	# Rollback the directory mangling
	return 2
}

do_stop() {
	# 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

	#[ -f $LOCKFILE ] || return 1

	# Check if I am root
	[ `id -u` -eq 0 ] || return 2

	# Merge back to permanent storage
	cp -rfup $VARLOG -T $VARLOGPERM

	# The following cannot fail... or can it?
	rm -f $LOCKFILE
	return 0
}

do_reload() {
	# Return
	#   0 if transient log has been reloaded
	#   1 if transient log was not running
	#   2 if transient log could not be reloaded

	#[ -f $LOCKFILE ] || return 1
	
	# Check if I am root
	[ `id -u` -eq 0 ] || return 2

	# Merge back to permanent storage
	cp -rfup $VARLOG -T $VARLOGPERM
	touch $LOCKFILE
	return 0
}
	





case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
  	if [ -f $LOCKFILE ]; then
		echo "$DESC is running"
	else
		echo "$DESC is stopped"
		exit 1
	fi
	;;
  reload)
	log_daemon_msg "Reloading $DESC" "$NAME"
	do_reload
	log_end_msg $?
	;;
  *)
	echo "Usage: $0 {start|stop|status|reload}" >&2
	exit 3
	;;
esac

Then I checked the start up priority of motion

sudo find /etc/rc*.d -iname ???motion
/etc/rc0.d/K60motion
/etc/rc1.d/K60motion
/etc/rc2.d/S60motion
/etc/rc3.d/S60motion
/etc/rc4.d/S60motion
/etc/rc5.d/S60motion
/etc/rc6.d/K60motion

I set my new script to 1 lower (using a higher number) than it, so that it will start and stop after.

sudo update-rc.d transientmotion defaults 61

Additionally, I want to transcode my snapshots into x264 mp4 video on a schedule. The following script does that, making the video and then deleting the snapshots upon finishing. I set this to cron at 11pm and 6am (the hours between 11pm and 6am are usually just darkness).

#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi
DATER=`date +%Y-%m-%d_%H%M%S`
FOLDERIN="/tmp/motion/timelapse"
FOLDERTMP="/tmp/motiontmp"
FOLDEROUT="/datapool/Videos/timelapse"
mkdir $FOLDERTMP
mv $FOLDERIN/*.jpg $FOLDERTMP/
mencoder "mf://$FOLDERTMP/*.jpg" -fps 60 -ofps 60 -of lavf -ovc x264 -x264encopts preset=veryslow:crf=24:threads=auto -o $FOLDEROUT/$DATER.mp4
RC=$?
if [ "${RC}" -ne "0" ]; then
    # Handle the error.
    echo "error"
else
    # Everything was ok.
    echo "no error"
    rm -r $FOLDERTMP
fi

This stores the resulting file outside of the /tmp, archiving it.

I’ll add information about turning on/off motion detection and emailing images/movies at some point, but not now.

Setting up UPS monitoring

Install nut

sudo apt-get install nut

Then edit the configuration files, first /etc/nut/nut.conf based on your configuration:

MODE=standalone

Then edit /etc/nut/ups.conf based on your UPS device:

[apc]
driver = usbhid-ups
port = auto 

Start the driver with:

sudo upsdrvctrl start 

I received an error that it can’t claim USB device. To fix this, I changed the group of the UPS device to but using the following command after identifying the USB bus and device numbers using lsusb command:

sudo chown root:nut /dev/bus/usb/xxx/yyy

Where xxx is the bus and yyy is the device found with the previous command.
Once that was done, I ran the following and it was working:

sudo upsdrvctrl start
sudo apsd

Then running apsc apc shows all the good details.

Setup Command Line Email and Email Alerts

Once you’ve got your server up and running the last thing you want to be doing is logging onto it every 5 minutes to check everything is ok. I instead want my server to be able to email me for any important events.

Whilst you can install and configure a fully featured email system you really don’t need to do so if all you want to do is send emails and not receive them too. I use msmtp which is a simple Mail Transfer Agent (MTA).

It’s easy enough to install:

sudo apt-get install msmtp msmtp-mta

Then you need a configuration file at /etc/msmtprc. Set it up with the following:

sudo touch /etc/msmtprc
sudo chmod 600 /etc/msmtprc

Then edit the file however you like with the following:

# A system wide configuration is optional.
# If it exists, it usually defines a default account.
# This allows msmtp to be used like /usr/sbin/sendmail.
account default

# The SMTP smarthost.
auth on
host smtp.gmail.com
port 587
user sender@gmail.com
from sender@gmail.com
password senderpassword
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt

# Alias file for local emails
aliases /etc/aliases

# Syslog logging with facility LOG_MAIL instead of the default LOG_USER.
syslog LOG_MAIL

Now your system can send mail using the sendmail command or msmtp.
In order to receive emails directed at root or postmaster or localuser, you also need to add an alias file at /etc/aliases with the following contents:

root: youremail@gmail.com
default: youremail@gmail.com

DNS Server with Bind and local Dynamic DNS with DHCP

UPDATE: I’ve moved my DNS Server back to the router using DD-WRT. Having it on the server was giving me trouble within MythTV. It was unable to find the tuners, making watching TV impossible… So here is what I did, but I wouldn’t recommend it. Turning on DNSMasq with the LocalDNS as home gave me the result with much less work as I was trying to achieve using the procedures below.

I want an internal network name of .home for referencing all the internal devices, and it looks like that is done using bind. I followed this and this guide.

Installing it is easy enough, dnsutils are also useful: sudo apt-get install bind9 dnsutils

Then edit the configuration file with sudo nano /etc/bind/named.conf.options

Set the forwarders with the following, this will be where uncached requests will be found:

	forwarders {
		8.8.8.8;
		8.8.4.4;
	};

Edit the configuration file with sudo nano /etc/bind/named.conf.local to include:

zone "home" {
             type master;
             file "/etc/bind/db.home";
        };
 
zone "10.10.10.in-addr.arpa" {
        type master;
        notify no;
        file "/etc/bind/db.10";
};

then

DHCP Server setup from within Webmin

UPDATE: I’ve moved my DHCP Server back to the router using DD-WRT. Having it on the server was giving me trouble within MythTV. It was unable to find the tuners, making watching TV impossible… So here is what I did, but I wouldn’t recommend it.

I followed this guide to setup a DHCP server. I first had to install the isc-dhcp-server package. Then I had to modify a few settings for the DHCP Server module of webmin since it was designed for dhcp3:

DHCP server config file: /etc/dhcp/dhcpd.conf
DHCP server executable: /usr/sbin/dhcpd
Command to start/stop/restart: /etc/init.d/isc-dhcp-server start/stop/restart
DHCP server lease file: /var/lib/dhcp/dhcpd.leases

After doing that, the webmin module works and I was able to set it up. The resulting file is setup like this:

# Internal Network
subnet 10.10.10.0 netmask 255.255.255.0 {
range 10.10.10.100 10.10.10.200;
# Home Network
group {
# My Laptop
host laptop {
hardware ethernet ab:cd:ef:g1:23:45;
fixed-address 10.10.10.10;
}
...
}
}
}