<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Electricmonk.nl weblog &#187; linux</title>
	<atom:link href="http://www.electricmonk.nl/log/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.electricmonk.nl/log</link>
	<description>Ferry Boender&#039;s ramblings</description>
	<lastBuildDate>Mon, 16 Jan 2012 15:23:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Tmux scrolling with shift-pageup/down</title>
		<link>http://www.electricmonk.nl/log/2012/01/05/tmux-scrolling-with-shift-pageupdown/</link>
		<comments>http://www.electricmonk.nl/log/2012/01/05/tmux-scrolling-with-shift-pageupdown/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 06:38:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4803</guid>
		<description><![CDATA[Put this in your .tmux.conf to enable scrolling using the Shift-PageUp/Down keys: set -g terminal-overrides 'xterm*:smcup@:rmcup@']]></description>
			<content:encoded><![CDATA[<p>Put this in your <tt>.tmux.conf</tt> to enable scrolling using the Shift-PageUp/Down keys:</p>
<pre>set -g terminal-overrides 'xterm*:smcup@:rmcup@'</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2012/01/05/tmux-scrolling-with-shift-pageupdown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple VirtualBox VMs using one base image (copy-on-write)</title>
		<link>http://www.electricmonk.nl/log/2011/09/24/multiple-virtualbox-vms-using-one-base-image-copy-on-write/</link>
		<comments>http://www.electricmonk.nl/log/2011/09/24/multiple-virtualbox-vms-using-one-base-image-copy-on-write/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 08:34:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4737</guid>
		<description><![CDATA[As a developer and systems administrator, I use VirtualBox a lot for building binaries, testing upgrades, etc. It always struck me as a waste that I&#039;d have to clone an entire HD image whenever I needed a fresh install of a machine. Why couldn&#039;t I just use a single base image for each Virtual Machine, [...]]]></description>
			<content:encoded><![CDATA[<p>As a developer and systems administrator, I use VirtualBox a lot for building binaries, testing upgrades, etc. It always struck me as a waste that I&#039;d have to clone an entire HD image whenever I needed a fresh install of a machine. Why couldn&#039;t I just use a single base image for each Virtual Machine, and have VirtualBox perform copy-on-write whenever it made changes? That way, only the changes to the base image would have to be stored separately for each clone, saving lots of disk space. <a href="http://www.xaprb.com/blog/2011/08/31/making-auto-resetting-virtualbox-machines/">Turns out it is possible to do just that</a>! I had some problems with the steps in that article though, so here&#039;s how I did it.</p>
<p>First, I created a new Virtual Machine and installed it like I always do. Once the VM was all set up, I shut it down, and cloned its harddisk:</p>
<pre>$ <b>VBoxManage clonehd ~/VirtualBox\ VMs/minimal.deb.local/minimal.deb.local.vdi ~/base.vdi</b></pre>
<p>Next, I created a new Virtual Machine:</p>
<pre>$ <b>VBoxManage createvm --name "clone1" --ostype Debian_64 --register</b>
Virtual machine 'clone1' is created and registered.
UUID: 1becc453-f4a9-44a8-a6c8-e43b80baf04d
Settings file: '/home/fboender/VirtualBox VMs/clone1/clone1.vbox'
$ <b>VBoxManage modifyvm "clone1" --nic1 hostonly --hostonlyadapter1 "vboxnet0"</b>
$ <b>VBoxManage storagectl "clone1" --name "sata1" --add sata</b>
$ <b>VBoxManage storageattach "clone1" --storagectl "sata1" --port 0 --device 0 --type hdd --medium ~/base.vdi --mtype multiattach</b></pre>
<p>The trick here lies in the <tt>--mtype multiattach</tt> option to the <tt>storageattach</tt> command. It tells VirtualBox that I&#039;m going to attach this harddisk image to multiple different Virtual Machines. VirtualBox will then automatically do Copy-on-Write of all changes to a snapshot instead of to the base image. If I simply set the <tt>base.vdi</tt> harddisk image to immutable, as instructed by the article on Xaprb, I cannot attach it to multiple VirtualMachines. Using the <tt>--mtype multiattach</tt> also instructs VirtualBox to make persistant Copy-on-Writes. This means that, unlike the Xaprb article, your snapshot is not reset when starting the VirtualMachine. Thus you will not have to change the snapshots to <tt>autoreset=false</tt>.</p>
<p>You can start the VM now:</p>
<pre>$ <b>VBoxManage startvm "clone1"</b></pre>
<p>If you want to create another VirtualMachine using the same base image, you can repeat the steps above, and replace every occurance of &#034;<tt>clone1</tt>&#034; with &#034;<tt>clone2</tt>&#034; or some other name. Then, when you attach the storage, <b>you must not refer to the actual VDI file as it exists on disk</b>, but you must simply refer to its name. So instead of specifying &#034;<tt>--medium ~/base.vdi</tt>&#034;, simply enter: &#034;<tt>--medium base.vdi</tt>&#034;. The full command thus becomes:</p>
<pre>$ <b>VBoxManage storageattach "clone2" --storagectl "sata1" --port 0 --device 0 --type hdd --medium base.vdi --mtype multiattach</b></pre>
<p>We cannot refer directly to the image on disk, because it is already registered with VirtualBox. If you try to do this anyway, you will get an error such as:</p>
<pre>VBoxManage: error: Cannot register the hard disk '/home/fboender/./base.vdi' {d3c861c1-6861-46c7-94a1-fd7a91987507} because a hard disk '/home/fboender/base.vdi' with UUID {d3c861c1-6861-46c7-94a1-fd7a91987507} already exists
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component VirtualBox, interface IVirtualBox, callee nsISupports
Context: "OpenMedium(Bstr(pszFilenameOrUuid).raw(), enmDevType, AccessMode_ReadWrite, pMedium.asOutParam())" at line 209 of file VBoxManageDisk.cpp
VBoxManage: error: Invalid UUID or filename "./base.vdi"</pre>
<p>If you create new VMs through the GUI, and attach the existing &#034;<tt>base.vdi</tt>&#034; harddisk during the Wizard, it will automatically attach that image in multiattach mode.</p>
<p>Like I said, all changes to the Virtual Machines are not written to the base.vdi image, but to a snapshot instead. The snapshots are very minimal in size:</p>
<pre>$ <b>ls -lh VirtualBox\ VMs/clone1/Snapshots/</b>
total 26M
-rw------- 1 fboender fboender 26M 2011-09-24 10:30 {8f91d6ba-71bb-4618-8c82-5d8bd13fb045}.vdi
</pre>
<p>Only 26 Mb for a full-blown Debian install. Not bad.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/09/24/multiple-virtualbox-vms-using-one-base-image-copy-on-write/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating simple Debian packages</title>
		<link>http://www.electricmonk.nl/log/2011/09/06/creating-simple-debian-packages/</link>
		<comments>http://www.electricmonk.nl/log/2011/09/06/creating-simple-debian-packages/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 19:51:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4705</guid>
		<description><![CDATA[Here&#039;s a quick way to create your own Debian package. This is merely a simple package which will not be included in the official Debian repositories, so we can ignore most of the Debian packaging guidelines. First off, we need to create a directory which shall hold the contents of the package. In this case, [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#039;s a quick way to create your own Debian package. This is merely a simple package which will not be included in the official Debian repositories, so we can ignore most of the Debian packaging guidelines. </p>
<p>First off, we need to create a directory which shall hold the contents of the package. In this case, a simple Python script called &#039;<tt>myscript</tt>&#039;.</p>
<pre>mkdir myscript</pre>
<p>Next, we need to create the <tt>control</tt> file. This file contains some meta-data for the Debian package such as the name, description, etc. It lives in a special directory called &#039;<tt>DEBIAN</tt>&#039; in the root of the package.</p>
<pre>mkdir myscript/DEBIAN</pre>
<pre>vi myscript/DEBIAN/control</pre>
<p>We put the following contents in the <tt>control file</tt></p>
<pre>Package: myscript
Version: 0.1
Section: utils
Priority: optional
Architecture: all
Essential: no
Depends: python
Maintainer: Your Name <your.name@example.com>
Description: The short description of the script
 A longer description of the descript, possible
 spanning multiple lines.</pre>
<p>Most of these fields are rather self-explanatory. You can find a list of valid <tt>Sections</tt> on the &#034;<a href="http://packages.debian.org/stable/">List of Sections</a>&#034; page. Make sure to use the last part of the URL, not the actual title of the section. For scripts, the <tt>Architecture</tt> will almost always be &#039;<tt>all</tt>&#039;. The <tt>Depends</tt> field tells the package installation software which other packages should be installed for this package to work correctly. Multiple packages can be specified by separating them with commas. See <a href="http://www.debian.org/doc/debian-policy/ch-relationships.html">Chapter 7 of the Debian Policy Manual</a> for details. The <tt>Description</tt> field is a single line containing a simple description of the package. The extended description can be placed under it, and may span multiple lines. Prefix each line with a single space.</p>
<p>Now we add the actual contents of the package to the <tt>myscript</tt> directory. We shall be installing the script in <tt>/usr/bin</tt>, so we create that directory and place our script in it.</p>
<pre>mkdir -p myscript/usr/bin</pre>
<pre>cp ~/dev/myscript myscript/usr/bin/</pre>
<p>Here&#039;s the final directory layout of the <tt>myscript</tt> directory:</p>
<pre>
myscript
myscript/usr
myscript/usr/bin
myscript/usr/bin/myscript
myscript/DEBIAN
myscript/DEBIAN/control
</pre>
<p>The final step: actually creating the package!</p>
<pre>fakeroot dpkg-deb --build myscript</pre>
<p><tt>fakeroot</tt> is a special tool that runs another program (in this case <tt>dpkg-deb</tt>) and fakes all filesystem ownerships as being <tt>'root:root'</tt>. This is needed because the files in this Debian package need to be owned by root. The <tt>dpkg-deb --build</tt> command takes care of creating the package.</p>
<p>The <tt>myscript.deb</tt> Debian package can now be installed on your system using <tt>dpkg</tt>:</p>
<pre>dpkg -i ./myscript.deb</pre>
<p>Users of a GUI can usually right-click <tt>.deb</tt> files in their file managers and choose to install them from there. There are no special things to consider for de-installation of the package, unless the binary in your package creates files in non-temporary storage or users&#039; homedirs.</p>
<p><b>Please note again</b> that this is not an official Debian package, and is missing many things required in well-made Debian packages ready for inclusion in the official Debian repositories.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/09/06/creating-simple-debian-packages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netfilter (iptables) performance tests</title>
		<link>http://www.electricmonk.nl/log/2011/07/29/netfilter-iptables-performance-tests/</link>
		<comments>http://www.electricmonk.nl/log/2011/07/29/netfilter-iptables-performance-tests/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 10:26:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4675</guid>
		<description><![CDATA[Here&#039;s a nice study on the performance of Linux&#039;s network firewalling/packet mangling layer: Netfilter Performance Testing Conclusions (mine, based on the study): Netfilter/iptables is up to par with other filter solutions when it comes to plain routing. Netfilter/iptables is not up to par with other filter solutions when it comes to connection tracking (basically just [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#039;s a nice study on the performance of Linux&#039;s network firewalling/packet mangling layer:</p>
<p><a href="http://people.netfilter.org/kadlec/nftest.pdf">Netfilter Performance Testing</a></p>
<p>Conclusions (mine, based on the study):</p>
<ul>
<li>Netfilter/iptables is up to par with other filter solutions when it comes to plain <i>routing</i>.</li>
<li>Netfilter/iptables is not up to par with other filter solutions when it comes to <i>connection tracking (basically just getting all the traffic through netfilter and keeping track of it) and filtering</i>
<li>When a chain has many rules, netfilter/iptables filtering performance drops significantly. Chain modifications (adding rules) performance also degrades significantly. This starts at <b>256</b> rules, so don&#039;t use more.</li>
</ul>
<p>The problems seem to stem from the way Netfilter stores and processes the rules:</p>
<blockquote><p>
It is well known that netfilter/iptables does not scale well if one wants to use large number of rules in a single chain. The reason of the problem lies in the fact that the rules are processed in netfilter/iptables one after another, linearly.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/07/29/netfilter-iptables-performance-tests/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Minecraft Server optimization</title>
		<link>http://www.electricmonk.nl/log/2011/07/22/minecraft-server-optimization/</link>
		<comments>http://www.electricmonk.nl/log/2011/07/22/minecraft-server-optimization/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 18:40:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4665</guid>
		<description><![CDATA[The Minecraft server was running very slowly and gobbling up a significant amount of memory. Game-play was laggy, chunk loading stuttery and I saw a LOT of the following message in the server.log: [WARNING] Can't keep up! Did the system time change, or is the server overloaded? I decided to unleash my google-fu, dug through [...]]]></description>
			<content:encoded><![CDATA[<p>The Minecraft server was running very slowly and gobbling up a significant amount of memory. Game-play was laggy, chunk loading stuttery and I saw a LOT of the following message in the server.log:</p>
<p><code>[WARNING] Can't keep up! Did the system time change, or is the server overloaded?</code></p>
<p>I decided to unleash my google-fu, dug through the Java manuals and found some optimizations that:</p>
<ul>
<li>Significantly <b>reduced the CPU load</b>.</li>
<li><b>Reduced the memory usage</b> of Minecraft from about 80% to 20 to 30% (of 1Gb). That means you can run Minecraft server on as little as 200Mb.</li>
<li>Got rid of the &#034;Can&#039;t keep up!&#034; messages.</li>
<li><b>Reduced lag</b> on the server to almost nothing.</li>
<li><b>Reduced chunk loading</b> stuttering.</li>
</ul>
<p>It does seem there has been a slight increase in chunks not loading properly, but that might be my imagination.</p>
<p>So what did I do? It&#039;s really simple:</p>
<ul>
<li><b>Run the Minecraft server and world from a RAM disk</b>. This will greatly enhance performance of loading chunks and at the same time reduce CPU load. Memory usage in total will go up (because the entire world is now in RAM), but since the new Minecraft McRegion storage format (introduced in Minecraft v1.3 Beta) uses a lot less disk space, it&#039;s no big deal.</li>
<li><b>Provide the -Xincgc option to Java</b>. This enabled the concurrent incremental garbage collector, which basically means that Java won&#039;t pause for a couple of seconds to clean up old unused stuff (unloaded chunks). This reduces lag and choppiness in the loading of chunks/movement of mobs and destruction/placement of blocks.</li>
</ul>
<p>I&#039;ll discuss here how to set up a RAM disk and how to make persistent copies of your live Minecraft map (or you&#039;d lose everything on reboot).</p>
<h2>Setting up a RAM disk</h2>
<p>This section assumes that you&#039;re running under GNU/Linux, you&#039;ve got Minecraft in a directory <tt>/home/minecraft/minecraft/minecraft_server/</tt> (the directory where the <tt>minecraft_server.jar</tt> lives). Commands are prefixed by either a &#039;<tt>$</tt>&#039; or a &#039;<tt>#</tt>&#039; prompt, meaning you should either run the command as the <tt>minecraft</tt> user (or whichever user has read/write access to the minecraft server) or the <tt>root</tt> user. </p>
<p>Let&#039;s get started! First, check how much space you will need for your minecraft world:</p>
<pre>$ du -hs /home/minecraft/minecraft/minecraft_server
50M	/home/minecraft/minecraft/minecraft_server
</pre>
<p>The minecraft directory is currently using 50mb. It&#039;s already a fairly large world, so we&#039;ll give it double that: 100Mb.</p>
<p>Now, move the minecraft_server directory to a different name, because we need to create an empty RAM disk in its place:</p>
<pre>$ mv /home/minecraft/minecraft/minecraft_server /home/minecraft/minecraft/minecraft_server.persistent
$ mkdir /home/minecraft/minecraft/minecraft_server</pre>
<p>Next, add an entry for the RAM disk to /etc/fstab. This will make sure it is automatically remounted when your system restarts</p>
<pre>$ sudo echo "tmpfs    /home/minecraft/minecraft/minecraft_server     tmpfs    rw,size=100M    0    0" >> /etc/fstab</pre>
<p>Mount it:</p>
<pre># mount /home/minecraft/minecraft/minecraft_server</pre>
<p>Copy the contents off the backup minecraft_server directory over to the RAM disk:</p>
<pre>$ cp -ar /home/minecraft/minecraft/minecraft_server.persistent/* /home/minecraft/minecraft/minecraft_server/</pre>
<p>You can now start Minecraft with the following command:</p>
<pre>$ tmux new -d -n "minecraft" "minecraft" "java -Xincgc -Xmx1G -jar minecraft_server.jar nogui"</pre>
<h2>Making persistent copies</h2>
<p>It is <b>imperative that you regularly create a persistent copy of the RAM disk</b>! If the power on your server ever fails (or if you reboot it manually), your world is LOST! If you&#039;re running the Minecraft server in a `tmux` session (and you&#039;ve started tmux with: &#039;tmux -n minecraft -s minecraft&#039;), you can create a shellscript and call it from a CRON job say every hour. You can also get <a href="http://www.electricmonk.nl/Programmings/MC">my Minecraft Server run script</a>, which can also do backups and start/stop the Minecraft server without having to attach to the console. But for those who just want the persistent-copy script, here you go:</p>
<pre>PATH_MC="/home/minecraft/minecraft/minecraft_server"

# Temporary turn off MC saving so we don't get a corrupt backup
tmux send -t "minecraft" "save-off" C-m
tmux send -t "minecraft" "save-all" C-m
# Wait until the MC server log indicates the save is complete
while true; do
    sleep 0.2
    TMP=`grep "Save complete." $PATH_MC/server.log | wc -l`
    if [ $TMP -gt $SAVE_COMPLETE ]; then
        break
    fi
done
# Create persistent copy from RAM to disk
rm -rf "$PATH_MC.persistent"
cp -ar "$PATH_MC" "$PATH_MC.persistent"
# Turn world saving back on
tmux send -t "minecraft" "save-on" C-m
</pre>
<p>Save it as a file called /home/minecraft/mc_persistent.sh and make it executable:</p>
<pre>chmod 750 /home/minecraft/mc_persistent.sh</pre>
<p>Create a now cronjob and call it every hour:</p>
<pre>0 * * * * /home/minecraft/mc_persistent.sh</pre>
<p>That&#039;s it! Happy lag-free mining.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/07/22/minecraft-server-optimization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SSH Tips and Tricks</title>
		<link>http://www.electricmonk.nl/log/2011/05/02/ssh-tips-and-tricks/</link>
		<comments>http://www.electricmonk.nl/log/2011/05/02/ssh-tips-and-tricks/#comments</comments>
		<pubDate>Mon, 02 May 2011 14:18:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4606</guid>
		<description><![CDATA[(The lastest version of this article is always available in stand-alone HTML format and in PDF format. The original AsciiDoc source is also available. Please link to the HTML version, not this Blog post!) SSH is capable of more than you&#039;d think! This article describes some of the lesser known features and configuration options. It [...]]]></description>
			<content:encoded><![CDATA[<p>(The lastest version of this article is always available in stand-alone <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=ssh_tips_tricks.html">HTML format</a> and in <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=ssh_tips_tricks.pdf">PDF format</a>. The original <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=ssh_tips_tricks.txt">AsciiDoc source</a> is also available. Please link to the HTML version, not this Blog post!)</p>
<p>SSH is capable of more than you&#039;d think! This article describes some of the lesser known features and configuration options. It covers authentication, authorization, tunnels and proxies, file transfer and more. </p>
<p><span id="more-4606"></span></p>
<div id="content">
<h2 id="_authentication">Authentication</h2>
<div class="sectionbody">
<h3 id="_passwordless_key">Passwordless key</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>One very useful feature of SSH are passwordless keys. They are especially useful when you&#039;re writing scripts that need to run commands on a remote hosts. Since those will run unattended, you don&#039;t want them to prompt for a password.</p>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">Be careful when using passwordless keys! If the security of the client machine is compromised, the remote server will be <strong>just as compromised</strong>! Check the Authorization section of this article for tips on how to limit the damage of a compromised client machine! You can also use an ssh agent, in which case you will only have to enter the password once after system boot after which scripts can run without requiring a password.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>You can generate passwordless keys using the <tt>ssh-keygen</tt> tool. Simply press <tt>enter</tt> when asked for the password:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): /home/user/passwordless_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/passwordless_rsa.
Your public key has been saved in /home/user/passwordless_rsa.pub.
The key fingerprint is:
70:50:84:e3:ea:de:62:43:4e:cf:76:a4:86:8e:c7:29 user@eek</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This generates a normal public key and a private key without a password. We can add the public key to a remote machine&#039;s list of authorized keys using the <tt>ssh-copy-id</tt> tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh-copy-id -i /home/user/passwordless_rsa.pub user@remote_host
Now try logging into the machine, with "ssh 'user@remote_host'", and check in:
  .ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We specify which public key to transport using the <tt>-i /home/user/passwordless_rsa.pub</tt> option.</p>
</div>
<div class="paragraph">
<p>Now we can ssh to the <tt>remote_host</tt> without using a password. If the private key has been placed in the current user&#039;s <tt>.ssh</tt> directory, ssh will automatically detect it when trying to connect. If you want to be sure it finds the private key to connect with, you can once again specify the <tt>-i path_to_private_key</tt> option:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -i /home/user/passwordless_rsa user@remote_host
user@remote_host$</tt></pre>
</div>
</div>
<div class="paragraph">
<p>When using passwordless keys, you may provide the <tt>-q</tt> and <tt>-o "BatchMode=yes"</tt> options to SSH in order to make it quiet. Otherwise, errors related to SSH might be interpreted as errors from remote commands.</p>
</div>
<h3 id="_ssh_agent">SSH Agent</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The SSH Agent is a tool which can keep your private keys in memory. When connecting to a remote machine, any SSH session (including <tt>scp</tt> and <tt>sftp</tt>) will try to contact a running agent on the machine to see if the required private key is already loaded. If it is, it will be used to connect to the remote machine. This way you only have to enter your password for a private key once, instead of each time you want to connect.</p>
</div>
<div class="paragraph">
<p>You can test if an SSH Agent is already running with the following command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh-add -l
Could not open a connection to your authentication agent.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>As you can see, no agent is currently running. We can start one with the following command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ eval `ssh-agent`
Agent pid 6265</tt></pre>
</div>
</div>
<div class="paragraph">
<p>The above command runs the <tt>ssh-agent</tt> program, which will output some other commands, which are then run by the current shell. This is the actual output of the <tt>ssh-agent</tt> program:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>SSH_AUTH_SOCK=/tmp/ssh-tXJFfB6269/agent.6269; export SSH_AUTH_SOCK;
SSH_AGENT_PID=6270; export SSH_AGENT_PID;
echo Agent pid 6270;</tt></pre>
</div>
</div>
<div class="paragraph">
<p>As you can see, the <tt>ssh-agent</tt> is started. It then creates a socket in the <tt>/tmp</tt> directory and sets that location as an environment variable so that SSH clients (<tt>ssh</tt>, <tt>scp</tt>, <tt>sftp</tt>) know where to contact the agent.</p>
</div>
<div class="paragraph">
<p>We can add keys to the agent using the <tt>ssh-add</tt> tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh-add user.rsa
Enter passphrase for user.rsa:
Identity added: user.rsa (user.rsa)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We can now connect to any remote machine that has the public key counterpart in its <tt>authorized_keys</tt> file without having to enter our password again.</p>
</div>
<div class="paragraph">
<p>The <tt>ssh_agent</tt> program generates a random name for the socket. One frequent problem with starting the SSH agent like we did just now is that only the current shell knows about the socket location. If we open another terminal, it won&#039;t know about the running SSH agent, since the environment variable isn&#039;t set in the new terminal. We can work around this by specifying our own path to a socket with the <tt>-a</tt> option.</p>
</div>
<div class="paragraph">
<p>Combining this knowledge, we can add a few lines to our <tt>.profile</tt> (or <tt>.bashrc</tt>) startup script to start an agent if none is running yet. We also check for a forwarded agent and don&#039;t do anything if a forwarded agent is found (more on forwarding agents later on).</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt># Do not start an SSH agent if the user has a forwarded agent.
if [ -z "$SSH_AUTH_SOCK" ]; then
    # Check if a local SSH agent is already running. If not, start one.
    export SSH_AUTH_SOCK="$HOME/.ssh/sshagent.socket"
    if [ ! -S "$SSH_AUTH_SOCK" ]; then
        eval `ssh-agent -a "$SSH_AUTH_SOCK"`
    fi
fi</tt></pre>
</div>
</div>
<div class="paragraph">
<p>With this script in your <tt>.profile</tt>, you will only have to start one agent ever for a given user as long as that machine doesn&#039;t reboot (or the agent is killed in some other way). If you log out, the agent is not killed, and will be re-used the next time you log in.</p>
</div>
<h3 id="_agent_forwarding">Agent forwarding</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Perhaps the most useful feature of SSH is Agent Forwarding. We can tell <tt>ssh</tt> it should do Agent Forwarding by supplying the <tt>-A</tt> commandline option when we ssh to remote machine. For this to work, you have to have an SSH agent running locally, or agent forwarding had to be enabled when you SSHed into your current session. (Use <tt>ssh-add -l</tt> to see if an agent is avaiable).</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -A user@remote_host</tt></pre>
</div>
</div>
<div class="paragraph">
<p>When enabling Agent Forwarding with the <tt>-A</tt> switch, ssh will automatically create a socket at the remote host and set some environment variables (<tt>SSH_AUTH_SOCK</tt>, most notably) when you connect to a remote machine. If an ssh session needs to perform authentication, it will first try to reach the SSH agent through the socket. All requests will be sent back to the original SSH agent. This works for as many nested sessions as you&#039;d like.</p>
</div>
<div class="paragraph">
<p>Using Agent forwarding, you can start a single agent on, say, your desktop machine. Every authentication request made by any SSH session will be sent back to the agent running on your desktop machine, without the need to start additional SSH agents on remote machines and loading keys there. As you can imagine, this is a much better method of keeping private keys secure than storing them on every machine you need to SSH from.</p>
</div>
<div class="paragraph">
<p>You can enable SSH agent forwarding for all the hosts you SSH to automatically (without the need to specify the <tt>-A</tt> switch) by putting the following in your <tt>~/.ssh/config</tt>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>Host *
        ForwardAgent yes</tt></pre>
</div>
</div>
</div>
<h2 id="_authorization">Authorization</h2>
<div class="sectionbody">
<h3 id="_restricting_commands">Restricting commands</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>You can restrict which command can be run by someone logging in with a public/private key in the <tt>authorized_keys</tt> file. For instance, to restrict a certain public/private key to running the <tt>df -h</tt> command (to view avaiable diskspace), you add a line to the <tt>authorized_keys</tt> file like this (Public key shortened for brevity):</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>command="/bin/df -h" ssh-dss AAAAC8ghi9ldw== user@host</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Now when we SSH to that machine (and we have that key loaded):</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh user@remote_host
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/dev-root   39G  2.2G   35G   6% /
Connection to host closed.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Its not possible for a single key to run multiple commands via any normal SSH configuration mechanism. However, SSH will set an environment variable <tt>$SSH_ORIGINAL_COMMAND</tt> with the command the user tried to run. We can take advantage of that by writing a shellscript. For example, we can create a script called <tt>commands.sh</tt> on the remote host:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>#!/bin/sh

case $SSH_ORIGINAL_COMMAND in
        "diskspace")
                df -h
                ;;
        "dirlist")
                ls -1
                ;;
        "apache_restart")
                /etc/init.d/apache restart
                ;;
        *)
                echo "Unknown command"
esac</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Then we restrict the user to running that shellscript:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>command="/bin/sh /home/user/commands.sh" ssh-dss AAAAC8ghi9ldw== user@host</tt></pre>
</div>
</div>
<div class="paragraph">
<p>The user can now run multiple commands by specifying as an argument after the ssh command (The -q+ option makes ssh quiet, so it doesn&#039;t show any output other than that of the remote command):</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -q user@remote_host diskspace
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/dev-root   39G  2.2G   35G   6% /</tt></pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -q remote_host dirlist
commands.sh
dump.sql</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">Make sure you do not include any commands which lets the user run an interactive shell. Also, make sure users cannot overwrite the <tt>commands.sh</tt> and <tt>.ssh/authorized_keys</tt> files.</td>
</tr>
</table>
</div>
<h3 id="_restricting_addition_of_keys">Restricting addition of keys</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>By default, SSH puts the <tt>authorized_keys</tt> files in the user&#039;s home directory. This allows users to add other keys themselves; a situation you might want to avoid. You can change the location where the key files are kept in the <tt>/etc/ssh/sshd_config</tt> file, using the <tt>AuthorizedKeysFile</tt> option:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>#AuthorizedKeysFile     %h/.ssh/authorized_keys
AuthorizedKeysFile      /etc/ssh/authorized_keys/%u</tt></pre>
</div>
</div>
<div class="paragraph">
<p>The <tt>%u</tt> will expand to the username. The location of the <tt>authorized_keys</tt> file for a user named &#034;john&#034; will become <tt>/etc/ssh/authorized_keys/john</tt>. <tt>%h</tt> expands to the users homedirectory.</p>
</div>
<div class="paragraph">
<p>Make sure users can&#039;t write to the files in question.</p>
</div>
<h3 id="_restricting_which_users_can_ssh">Restricting which users can SSH</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>You can restrict which users are allowed to use SSH with the <tt>AllowUsers</tt> option in <tt>/etc/ssh/sshd_config</tt>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>AllowUsers john pete</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">if the AllowUsers setting is completely missing from the sshd config file, all users are allowed (see man sshd_config). You may prefer to leave it that way&#8201;&#8212;&#8201;your choice. I prefer to make the usernames explicit because I&#039;m paranoid ;-)</td>
</tr>
</table>
</div>
</div>
<h2 id="_input_output">Input / Output</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Like every other Unix tool, SSH can use input and output redirection. When running a command on a remote machine using SSH, it will redirect any input given to it locally to the remote command. Any output from the remote command is redirected back to your local machine. This allows for some very useful time-savers.</p>
</div>
<div class="paragraph">
<p>For instance, we can run the command <tt>du</tt> (diskusage) on the remote machine, and locally pipe it into <tt>xdu</tt> to get a graphical representation on our local X11 desktop of the remote disk usage:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh remote_host du /var/www/ | xdu</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Or suppose we want to transfer a remote directory&#039;s contents to the local machine without using scp (for whatever reason). We can remotely create a tar archive of the directory, and instruct <tt>tar</tt> to write it to the standard output (using the minus as the filename) instead of a file. SSH will transfer the remote standard output of tar to our local machine, where we can untar it in the same manner:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh remote_host tar -cf - Documents/notes | tar -xf -
$ ls Documents/notes/
dev.c.txt                            sysadmin.networking.txt
dev.git.txt                          sysadmin.openssl.txt
dev.mysql.txt                        sysadmin.solaris.txt</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Perhaps we need to create a local copy of a MySQL database on a remote machine. Unfortunatelly, MySQL access is not remotely allowed and the harddisk on the remote machine is full, so we can&#039;t create a dump there, transport it to our local machine and read it in. No worry, SSH to the rescue:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh remote_host mysqldump -u USER -pPASSWORD -h localhost DATABASENAME &gt; dump.sql</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Or we can just import it directly:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh remote_host mysqldump -u USER -pPASSWORD -h localhost DATABASENAME | mysql -u USER -pPASSWORD -h localhost DATABASENAME</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Likewise we can locally pipe data into ssh and use it at the remote host. Again, we use the minus-sign to indicate reading from standard in:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ echo "hello world" | ssh remote_host "cat &gt;foo.txt"</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This will put &#034;hello world&#034; in a file called <tt>foo.txt</tt> on the remote host. We need to quote the parts that contain the redirection on the host (<tt>"cat &gt;foo.txt"</tt>) or it will be picked up by the local shell.</p>
</div>
</div>
<h2 id="_tunnels_and_proxies">Tunnels and proxies</h2>
<div class="sectionbody">
<h3 id="_local_port_tunnel">Local port tunnel</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Sometimes you may need to use a certain service on a network, but the network has been firewalled against external connections on ports other than the SSH port. SSH allows us to create a <em>tunnel</em> into the remote network. Suppose we are on a network 192.168.1.x and we want to connect to port 80 on a machine with 192.168.56.3. But the 192.168.56.x network is firewalled, and we can only access it through a bastion host at 192.168.56.1. Here&#039;s what we do:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -L 80:192.168.56.3:80 user@192.168.56.1</tt></pre>
</div>
</div>
<div class="paragraph">
<p>SSH will now create a tunnel to 192.168.56.3 port 80 through 192.168.56.1. The <tt>-L</tt> option takes three arguments, separated with colons: <tt>local_port:remote_host:remote_port</tt>. The <tt>local_port</tt> is where SSH will listen for incoming connections on the machine where you issued this command. <tt>remote_host:remote_port</tt> is the machine/port to which you wish to create the tunnel. It is important to remember that this is as you&#039;d view it from the server you&#039;re ssh-ing too (192.168.56.1 in this case), not as you&#039;d view it from your local machine.</p>
</div>
<div class="paragraph">
<p>You can additionally specify the <tt>-N</tt> switch to prevent SSH from actually logging in to 192.168.56.1.</p>
</div>
<h3 id="_socks5_proxy">SOCKS5 proxy</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>We can use SSH as a SOCKS5 proxy. An SOCKS5 proxy works much like a normal tunnel, but works with multiple clients at the same time, and is not restricted to forwarding of a single port. We can start a SOCKS5 using the <tt>-D</tt> option:</p>
</div>
<div class="paragraph">
<p>Socks5 is pretty neat, as it allows you to proxy stuff without the server having to know anything about the way the client works. For instance, if we give the following command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ ssh -D 8080 remote_host</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Now we can configure local clients (such as Firefox, Pidgin Instant Messanger, Chrome, etc) to use the proxy. All network traffic (with the exception of DNS, possibly!) will go through the SOCKS5 proxy. For instance:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ chromium-browser --proxy-server="socks5://127.0.0.1:8080"</tt></pre>
</div>
</div>
<h3 id="_proxycommand">ProxyCommand</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Many networks require you to SSH to a bastion (firewall/gateway) server before you&#039;re able to SSH to any machine on the network. This becomes tedious quickly, as you have to SSH twice each time. The <tt>ProxyCommand</tt> is a setting in your ssh configuration file which can do this for you automatically.</p>
</div>
<div class="paragraph">
<p>Assume we want to SSH to a host &#039;web1.example.com&#039;. Before we can SSH to this host we first have to SSH to &#039;example.com&#039;. We can SSH directly to &#039;web1.example.com&#039; by putting the following in our <tt>~.ssh/config</tt> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>Host web1
        ProxyCommand ssh example.com nc web1.example.com 22</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This requires that the <tt>nc</tt> (<tt>netcat</tt>) tool is installed on web1.example.com. If we SSH to <tt>web1</tt> now, we are automatically sent to web1.example.com. It&#039;s even possible to use <tt>scp</tt> and other SSH tricks directly, thus saving us the trouble of having to transfer files to example.com first, then to our local machine (or vice versa).</p>
</div>
<div class="paragraph">
<p>ProxyCommand can also be used with other things. To SSH through a HTTP proxy at 192.0.2.0 port 8080:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p</tt></pre>
</div>
</div>
</div>
<h2 id="_configuration">Configuration</h2>
<div class="sectionbody">
<h3 id="_client_configuration">Client configuration</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The SSH client configuration lives in the file <tt>/home/USER/.ssh/config</tt>. It has many useful directives. The basic way it works is we specify a host identifier, and add configuration settings to that host.</p>
</div>
<div class="paragraph">
<p>For instance, if your local username is <tt>john</tt>, but on the backup machine <tt>backup.example.com</tt> it&#039;s always <tt>backup</tt>, you can tell SSH to automatically use that username to log in:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>Host backup.example.com
        User backup</tt></pre>
</div>
</div>
<div class="paragraph">
<p>You can create aliases (much like the <tt>/etc/hosts</tt> file) to save some typing:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>Host backup
        Hostname backup.example.com
        User backup</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to apply a certain configuration option to <strong>every</strong> host, use the asterisk wildcard:</p>
</div>
<div class="listingblock">
<div class="content">
<pre><tt>Host *
        ForwardAgent yes
        ServerAliveInterval 5
        ServerAliveCountMax 720</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Check <tt>man ssh_config</tt> for more useful options in this configuration file.</p>
</div>
</div>
<h2 id="_transferring_files">Transferring files</h2>
<div class="sectionbody">
<h3 id="_secure_copy_scp">Secure Copy (scp)</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>This should be obvious, but you can use the <tt>scp</tt> tool to transfer files between hosts using SSH. To copy a file <tt>localhost.txt</tt> to your home directory on the remote host:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>scp localfile.txt user@remote_host:</tt></pre>
</div>
</div>
<div class="paragraph">
<p>To put the file in a different path:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>scp localfile.txt user@remote_host:/path/absolute/to/root/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>and</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>scp localfile.txt user@remote_host:path/in/homedir/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Transferring an entire directory is possible using the <tt>-r</tt> switch:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>scp -r dir/ user@remote_host:</tt></pre>
</div>
</div>
<h3 id="_sftp">SFTP</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>OpenSSH (and most other SSH implementations) offer a secure FTP server. With it you can securely (encrypted) transfer files and authenticate using the default SSH authentication methods such as passwords or public keys. Contrary to ordinary FTP server (unless they run on TLS or some other form of encryption), passwords are not sent in plain-text over the network. SFTP also makes it easier for Windows user to transfer files between hosts, as there are many good free SFTP clients available. I personally recommend Filezilla.</p>
</div>
<div class="paragraph">
<p>The SFTP server needs to be enabled in the SSH server configuration. Edit <tt>/etc/ssh/sshd.config</tt> on the server and add the following line:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Subsystem sftp /usr/lib/openssh/sftp-server</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Restart SSH and you should be able to user the SFTP server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>/etc/init.d/ssh restart</tt></pre>
</div>
</div>
<div class="paragraph">
<p>On the client, issue the <tt>sftp</tt> command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ sftp user@remote_host
Connected to host.
sftp&gt; ls
bin          svn.tar.gz   xims
sftp&gt; get svn.tar.gz
Fetching /home/user/svn.tar.gz to svn.tar.gz
/home/user/svn.tar.gz           100%   11KB  11.0KB/s   00:00</tt></pre>
</div>
</div>
<div class="paragraph">
<p>You may get an error like this:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>subsystem request failed on channel 0
Couldn't read packet: Connection reset by peer</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This means that either the sftp-server was not properly configurated, or your login shell on the remote server is outputting some text not expected by the SFTP server (perhaps a welcome message or something). Remove the output and try again.</p>
</div>
<div class="paragraph">
<p>A different way of enabling the SFTP server is in the <tt>authorized_keys</tt> file:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>command="/usr/lib/openssh/sftp-server" ssh-dss AAAAC8ghi9ldw== user@host</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This will restrict any user that logs in using the public key <tt>AAAAC8ghi9ldw==</tt> to SFTP. The user cannot login using a normal SSH session. This does not require you to enable the SFTP server in <tt>/etc/ssh/sshd.conf</tt>.</p>
</div>
<div class="paragraph">
<p>You&#039;ll have to make sure that the user can&#039;t write to the .ssh directory nor upload any files such as .bashrc, .profile, etc, otherwise the user can overwrite those by uploading their own version, and they can still execute anything they like by just logging in with sftp. You can do this by creating these files and then changing their ownership and rights in such a way that the user can&#039;t write to them. Because it&#039;s hard to guess what files you should create so that the user can&#039;t cause any harm, it&#039;s best to simply create a seperate directory in which they can upload stuff, and lock off write access to their entire home directory.</p>
</div>
<div class="paragraph">
<p>Unlike the <tt>ssh</tt> and <tt>scp</tt> commands, <tt>sftp</tt> does not have a <tt>-i</tt> switch with which you can manually give the location of the private key to log in with. Fortunately, we can still provide one through the <tt>-o</tt> (options) switch:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>sftp -o IdentityFile=/home/user/.ssh/some_key_rsa username@hostname</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This can be convenient in the case of automated tasks. The custom key does not have to have a password and can be placed anywhere. Speaking of automated tasks, here&#039;s an example of running <tt>sftp</tt> in a batch-mode:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>echo "PUT myfile" | sftp -o IdentityFile=/home/user/.ssh/some_key_rsa -b - username@hostname</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Most normal FTP servers support jailing the user in a certain directory, preventing them from wandering around the file system. SFTP does not have this built-in ability, but we can use normal linux chroot/jails to jail a user to certain directory. For more information, see <a href="http://www.electricmonk.nl/log/2007/08/09/jailing-sftpscp/">http://www.electricmonk.nl/log/2007/08/09/jailing-sftpscp/</a></p>
</div>
<h3 id="_remote_mount_filesystem_sshfs">Remote mount filesystem (SSHfs)</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Perhaps the most useful tool in existance: <tt>sshfs</tt>. SSHfs provides tools to locally mount a directory on a remote server over SSH, much like NFS. SSHfs requires remote support for SFTP. See the previous section on how to enable it. SSHfs is separate from the normal ssh tools, and is implemented as a FUSE (userland) filesystem. On Debian and Ubuntu machines you can easily install it using aptitude:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt># aptitude install sshfs</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Once installed, we can mount a remote directory using the <tt>sshfs</tt> tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ sshfs user@remote_host:path/to/dir ./local_mountpoint
$ cd local_mountpoint
$ ls
file1    file2    file3</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Unmounting can be done with the <tt>fusermount</tt> tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>$ fusermount -u ./local_mountpoint</tt></pre>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/05/02/ssh-tips-and-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy way to create a Debian package and repository</title>
		<link>http://www.electricmonk.nl/log/2011/04/25/easy-way-to-create-a-debian-package-and-repository/</link>
		<comments>http://www.electricmonk.nl/log/2011/04/25/easy-way-to-create-a-debian-package-and-repository/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 06:56:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[link]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4593</guid>
		<description><![CDATA[Interesting article over at Linuxconfig.org: This article describes a simple way on how to create a home made debian package and include it into a local package repository. Although we could use a existing Debian/Ubuntu package, we will start from scratch by creating our own minimalistic unofficial debian package. Once our package is ready, we [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://linuxconfig.org/easy-way-to-create-a-debian-package-and-local-package-repository">Interesting article</a> over at Linuxconfig.org:</p>
<blockquote><p>
This article describes a simple way on how to create a home made debian package and include it into a local package repository. Although we could use a existing Debian/Ubuntu package, we will start from scratch by creating our own minimalistic unofficial debian package. Once our package is ready, we will include it into our local package repository. <a href="http://linuxconfig.org/easy-way-to-create-a-debian-package-and-local-package-repository">This article illustrates</a> very simplistic approach of creating debian package, however it may serve as a template in many different scenarios.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/04/25/easy-way-to-create-a-debian-package-and-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim, X11 and the clipboard (Copy, paste)</title>
		<link>http://www.electricmonk.nl/log/2011/04/05/vim-x11-and-the-clipboard-copy-paste/</link>
		<comments>http://www.electricmonk.nl/log/2011/04/05/vim-x11-and-the-clipboard-copy-paste/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 12:34:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4580</guid>
		<description><![CDATA[A while ago I fiddled around with my Vim configuration, and I removed some things I thought weren&#039;t necessary. A little while later I noticed that, when I copied things in a terminal Vim by selecting them with the mouse or a normal visual selection, I couldn&#039;t paste them into other X11 programs such as [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I fiddled around with my Vim configuration, and I removed some things I thought weren&#039;t necessary. A little while later I noticed that, when I copied things in a terminal Vim by selecting them with the mouse or a normal visual selection, I couldn&#039;t paste them into other X11 programs such as the terminal, Firefox and other Vim instances. Of course, I didn&#039;t have a backup of my old vimrc.</p>
<p>After much fiddling around with the various <tt>guioptions</tt>, <tt>mouse</tt> and <tt>clipboard</tt> settings, and many a Google search, I found a page which offered some insight:</p>
<blockquote><p>
For this to work, your Vim has to be compiled with the <tt>+xterm_clipboard</tt> setting. Run
<pre><tt>vim --version | grep xterm_clipboard</tt></pre>
<p> to see if that option is compiled in
</p></blockquote>
<p>My Vim (Xubuntu 10.10) showed <tt>-xterm_clipboard</tt> instead of <tt>+xterm_clipboard</tt> meaning it didn&#039;t support directly cutting/copying to the X11 clipboard. It turns out that I had removed the <tt>vim-gtk</tt> package and installed the normal <tt>vim</tt> package, since I never use the GTK/Gnome version anyway. </p>
<p>Re-installing the vim-gtk package solved the problem:</p>
<pre>
aptitude install vim-gtk
</pre>
<p>If you want to be able to select with the mouse, you will also need to set the following in your <tt>~/.vimrc</tt>:</p>
<pre>
set mouse=a
</pre>
<p>If you don&#039;t have that you can still select with the mouse, but it won&#039;t be Vim who does your selection but your terminal emulator. That results in line numbers being included in your selection (if you&#039;ve <tt>set number</tt>) as well as lines longer than the terminal being cut off.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/04/05/vim-x11-and-the-clipboard-copy-paste/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BoxBackup on Debian/Ubuntu</title>
		<link>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/</link>
		<comments>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 15:36:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4555</guid>
		<description><![CDATA[(The lastest version of this article is always available in stand-alone HTML format and in PDF format. The original AsciiDoc source is also available. Please link to the HTML version, not this Blog post!) 1. Introduction BoxBackup is an online remote backup tool for Unix systems (BSDs, Linux, MacOSX). It is robust, secure, low on [...]]]></description>
			<content:encoded><![CDATA[<p>(The lastest version of this article is always available in <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.html">stand-alone HTML format</a> and in <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.pdf">PDF format</a>. The original <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.txt">AsciiDoc source</a> is also available. <b>Please link to the HTML version, not this Blog post!</b>)</p>
<h2 id="_introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>BoxBackup is an online remote backup tool for Unix systems (BSDs, Linux, MacOSX). It is robust, secure, low on resources and can perform both in continues backup mode and snapshotting. In continues backup mode changes will be pushed to the server soon after they happen; in snapshot mode mode BoxBackup behaves more like traditional backup programs and creates snapshots every fixed amount of time.</p>
</div>
<div class="paragraph">
<p>This article will describe how to set up a BoxBackup server and client on Debian and Ubuntu machines. Much of this article can also be used on other Unix-like systems, however it will not discuss how to compile BoxBackup.</p>
</div>
<p><span id="more-4555"></span></p>
<h3 id="_assumptions">1.1. Assumptions</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>This article assumes the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>
The server (where backups will be stored) is called <tt>server</tt>. Its FQDN will be <tt>server.example.com</tt>.
</p>
</li>
<li>
<p>
The client (which will be backed up) is called <tt>client</tt>. Its FQDN will be <tt>client.example.com</tt>.
</p>
</li>
<li>
<p>
Backups will be stored in a directory <tt>/storage/backup</tt> on <tt>server</tt>.</p>
</li>
</ul>
</div>
</div>
<h2 id="_for_the_lazy">2. For the lazy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter is for the lazy. It quickly describes how to setup BoxBackup, but provides no in-depth information. Please note that commands are prefixed by a prompt that indicates on which machine and in which directory to run the command.</p>
</div>
<div class="paragraph">
<p>The server will allow the client 100Gb of storage with a hard limit of 120Gb. The client will have account ID <tt>00000001</tt> (more on account IDs later). BoxBackup&#039;s user-land RAID-like configuration will not be used. We will have to move some files between the <tt>client</tt> and the <tt>server</tt>. For this we use the <tt>scp</tt> program and the user account named <tt>user</tt> on both machines.</p>
</div>
<h3 id="_server_configuration">2.1. Server configuration</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Install the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# aptitude install boxbackup-server</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Delete Debian&#039;s generated configuration (We&#039;ll recreate it ourselves):</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# rm -rf /etc/boxbackup/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Find out filesystem block size:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /sbin/dumpe2fs -h /dev/sdb1 | grep 'Block size'
dumpe2fs 1.41.4 (27-Jan-2009)
Block size:               4096</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create RAID-like configuration file:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# raidfile-config  /etc/boxbackup/ 4096 /storage/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create backup storage directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mkdir /storage/backup/
server:/root# chown bbstored:bbstored /storage/backup
server:/root# chmod 750 /storage/backup</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create BoxBackup server configuration and certificates:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-config /etc/boxbackup/ server.example.com bbstored
server:/root# bbstored-certs ca init
server:/root# bbstored-certs ca sign-server /etc/boxbackup/bbstored/server.example.com-csr.pem
server:/root# cp ca/servers/server.example.com-cert.pem /etc/boxbackup/bbstored
server:/root# cp ca/roots/clientCA.pem /etc/boxbackup/bbstored
server:/root# chown -R bbstored:bbstored /etc/boxbackup/
server:/root# chmod 700 /etc/boxbackup/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Start the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /etc/init.d/boxbackup-server start
server:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:45:13 server Box Backup (bbstored)[30775]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">Keep the <tt>/root/ca</tt> directory around. It is required to sign new BoxBackup clients&#039; certificate files.</td>
</tr>
</table>
</div>
<h3 id="_client_configuration">2.2. Client configuration</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Create an account on the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstoreaccounts create 00000001 0 100g 120g</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Install the client software:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# aptitude install boxbackup-client
client:/root# rm /etc/boxbackup/bbackupd.conf
client:/root# rm /etc/boxbackup/bbackupd/*</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create client configuration and certificates:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupd-config /etc/boxbackup/ lazy 00000001 server.example.com /var/run /var/lib/svn/
client:/root# scp /etc/boxbackup/bbackupd/00000001-FileEncKeys.raw user@server.example.com:
client:/root# scp /etc/boxbackup/bbackupd/00000001-csr.pem user@server.example.com:</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Sign certificates on the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign /home/user/00000001-csr.pem
server:/root# scp ca/clients/00000001-cert.pem user@client.example.com:
server:/root# scp ca/roots/serverCA.pem user@client.example.com:
server:/root# /etc/init.d/boxbackup-server restart</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Install signed certificates on the client and start client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# mv /home/user/00000001-cert.pem /etc/boxbackup/bbackupd/
client:/root# mv /home/user/serverCA.pem /etc/boxbackup/bbackupd/
client:/root# /etc/init.d/boxbackup-client start
client:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbackupd.conf
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Beginning scan of local files</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">Keep the <tt>0000001-FileEncKeys.raw</tt> file around. It is required to restore backups.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If anything fails, please take a look at the rest of this document. It explains in more detail how to setup BoxBackup and may provide clues as to the problems you are encountering.</p>
</div>
</div>
<h2 id="_setting_up_the_server_bbstored">3. Setting up the server (bbstored)</h2>
<div class="sectionbody">
<h3 id="_installation">3.1. Installation</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The first thing is setting up the server. This is where the backups will be stored. It will run the <tt>bbstored</tt> program, which is a server daemon that clients can connect to in order to upload data.</p>
</div>
<div class="paragraph">
<p>The server will be designated as <tt>server</tt> in the commands given in this chapter. Each command is prefixed with a shell-prompt to indicate on which machine (<tt>client</tt> or <tt>server</tt>) the command should be entered. The server&#039;s Fully Qualified Domain Name will be <tt>server.example.com</tt>. The client&#039;s will be <tt>client.example.com</tt>. We will have to move some files (certificates) around between the server and the client in order to sign them. For this we will use a user account with username <tt>user</tt>. It is assumed the root user on both systems can use secure copy (<tt>scp</tt>) to move files from one system to the other under this user account.</p>
</div>
<div class="paragraph">
<p>Let&#039;s get started by installing the BoxBackup server. We use Debian, but it should also work under Ubuntu. It is unknown to me which different versions of BoxBackup are compatible with each other, so I assume you&#039;ll be using the same version on both the client and the server. If you&#039;re not using Debian or Ubuntu, please check your distribution&#039;s package list to see if a pre-compiled version of BoxBackup is available. If not, you will have to compile it yourself. This is beyond the scope of this article, so check the BoxBackup documentation for instructions.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# aptitude install boxbackup-server</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Debian/Ubuntu will install the BoxBackup server and some configuration tools. It will also create a user called <tt>bbstored</tt>. The BoxBackup server (<tt>bbstored</tt>) will run as this user.</p>
</div>
<div class="paragraph">
<p>Debian also might generate a configuration file and certificates for you. We will <strong>delete</strong> those because they confuse the process of installing and configuring BoxBackup (as what Debian does for you and what you need to do manually is terribly documented and it stores things in the wrong place).</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# rm -rf /etc/boxbackup/</tt></pre>
</div>
</div>
<h3 id="_creating_a_store">3.2. Creating a store</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>BoxBackup server stores backups in a <tt>store</tt>. We will configure this store at <tt>/storage/backup</tt>. This directory will contain a store for each client that backs up using the server. E.g. the backups for the client with account ID <tt>00000001</tt> (more on account IDs later on) will be stored in <tt>/storage/backup/00000001/</tt>.</p>
</div>
<div class="paragraph">
<p>BoxBackup provides a RAID-like setup where backups are written to multiple locations; usually different physical disks. This RAID-like setup <strong>has nothing to do with actual RAID</strong>, so don&#039;t get confused by that. This article will <strong>not</strong> be using the RAID-like facilities of BoxBackup.</p>
</div>
<div class="paragraph">
<p>Before we can create our store, we must first determine the block size of our file system . This can be done using the dumpe2fs tool. Provide the proper device name to the tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mount | grep storage
/dev/sdb1 on /storage type ext3 (rw)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the device is <tt>/dev/sdb1</tt>. Let&#039;s get the block size:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /sbin/dumpe2fs -h /dev/sdb1 | grep 'Block size'
dumpe2fs 1.41.4 (27-Jan-2009)
Block size:               4096</tt></pre>
</div>
</div>
<div class="paragraph">
<p>As we can see, our block size is 4096. We can now configure a Boxbackup store.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# raidfile-config  /etc/boxbackup/ 4096 /storage/
WARNING: userland RAID is disabled.
Config file written.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If the BoxBackup user (<tt>bbstored</tt>) has write permissions to the <tt>/storage/</tt> directory, you can skip the following steps and continue with the <tt>bbstored-config</tt> step.</p>
</div>
<div class="paragraph">
<p>Now we create a directory for the backups and set the proper permissions:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mkdir /storage/backup/
server:/root# chown bbstored:bbstored /storage/backup
server:/root# chmod 750 /storage/backup</tt></pre>
</div>
</div>
<h3 id="_server_configuration_file_certificates">3.3. Server configuration file / certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Time to create the bbstored configuration. We do this with the <tt>bbstored-config</tt> tool. It takes three parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">
<tt>config_dir</tt></p>
</dt>
<dd>
<p>
    The <strong>configuration location</strong>. In our case, <tt>/etc/boxbackup/</tt>.
</p>
</dd>
<dt class="hdlist1">
<tt>server_name</tt>
</dt>
<dd>
<p>    The <strong>FQDN of the server</strong>. We use <tt>server.example.com</tt>.
</p>
</dd>
<dt class="hdlist1">
<tt>username</tt>
</dt>
<dd>
<p>
    The <strong>user which bbstored will run as</strong>. Debian created the <tt>bbstored</tt> user for us, so we&#039;ll use that. It&#039;s the same as the daemon name, which is customary.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Run the command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-config /etc/boxbackup/ server.example.com  bbstored

Checking permissions on /storage//backup
Checking permissions on /storage//backup
Checking permissions on /storage//backup

Setup bbstored config utility

Configuration:
   Writing configuration file: /etc/boxbackup//bbstored.conf
   Writing empty accounts file: /etc/boxbackup//bbstored/accounts.txt
   Server hostname: server.example.com
   RaidFile config: /etc/boxbackup//raidfile.conf

Creating blank accounts file
Generating private key...
Generating RSA private key, 2048 bit long modulus
................................................................
............................................................................+++
.............................................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Writing configuration file /etc/boxbackup//bbstored.conf
===================================================================

bbstored basic configuration complete.

What you need to do now...
1) Sign /etc/boxbackup//bbstored/server.example.com-csr.pem
   using the bbstored-certs utility.
2) Install the server certificate and root CA certificate as
      /etc/boxbackup//bbstored/server.example.com-cert.pem
      /etc/boxbackup//bbstored/clientCA.pem
3) You may wish to read the configuration file
      /etc/boxbackup//bbstored.conf
   and adjust as appropraite.
4) Create accounts with bbstoreaccounts
5) Start the backup store daemon with the command
      /usr/local/bin/bbstored /etc/boxbackup//bbstored.conf
   in /etc/rc.local, or your local equivalent.
===================================================================</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This will generate a configuration file at <tt>/etc/boxbackup/bbstored.conf</tt> and generate a server certificate sign request file at <tt>/etc/boxbackup/bbstored/server.example.com-csr.pem</tt>.</p>
</div>
<div class="paragraph">
<p>The next step is to create and sign the server certificate. For this we need to generate a root certificate first. We use the <tt>bbstored-certs</tt> tool to do this:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca init

Generating RSA private key, 2048 bit long modulus
...................................................................
.................................................................+++
................................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Signature ok
subject=/CN=Backup system client root
Getting Private key
Generating RSA private key, 2048 bit long modulus
.........................+++
............................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Signature ok
subject=/CN=Backup system server root
Getting Private key</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This generates a <tt>co</tt> directory at our current location. This directory contains a bunch of certificates, including the root certificate. We need this root certificate to sign the server and client certificates.</p>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">We need to keep this <tt>ca</tt> directory around as it is required to sign client certificates! Store it in a <strong>secure</strong> location!</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Okay, let&#039;s sign the server certificate using our root certificate:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign-server /etc/boxbackup/bbstored/server.example.com-csr.pem

This certificate is for backup server

server.example.com

Signing the wrong certificate compromises the security of your backup system.

Would you like to sign this certificate? (type 'yes' to confirm)
yes
Signature ok
subject=/CN=server.example.com
Getting CA Private Key

Certificate signed

Install the files

  ca/servers/server.example.com-cert.pem
  ca/roots/clientCA.pem

on the server.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We do as the output says and copy the signed server certificates to the configuration directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# cp ca/servers/server.electricmonk.nl-cert.pem /etc/boxbackup/bbstored
server:/root# cp ca/roots/clientCA.pem /etc/boxbackup/bbstored
server:/root# chown -R bbstored:bbstored /etc/boxbackup/
server:/root# chmod 700 /etc/boxbackup/</tt></pre>
</div>
</div>
<h3 id="_starting_the_server">3.4. Starting the server</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>That concludes the configuration part of the server. We will have to create client accounts, but that will be covered in the chapter on client configuration. Let&#039;s try out the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /etc/init.d/boxbackup-server start
Starting boxbackup-server: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf
bbstored.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It seems to start. We can check <tt>/var/log/syslog</tt> to see if it really did:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:53:14 server Box Backup (bbstored)[15884]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If that&#039;s all the output, everything is now okay. Final verifications to see if the server is really running can be made using <tt>ps</tt> and <tt>netstat</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# ps axf | grep bbstored
 15884 ?        S      0:00 /usr/sbin/bbstored /etc/boxbackup/bbstored.conf
 15885 ?        S      0:14  \_ /usr/sbin/bbstored /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It&#039;s running.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# netstat -pant | grep bbstored
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 82.171.91.37:2201       0.0.0.0:*               LISTEN      15884/bbstored</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It&#039;s listening for incoming connections on IP <tt>82.171.91.37</tt>, at TCP port <tt>2201</tt>. Time to set up the client!</p>
</div>
</div>
<h2 id="_setting_up_a_client_bbackupd">4. Setting up a client (bbackupd)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this chapter we will set up a client. The client will run the <tt>bbackupd</tt> program, which is a daemon that scans the files you want to backup and sends them to the server if it encounters new or modified files. It does this efficiently: if there are no changes, nothing is sent to the server. Otherwise it only sends the parts of the files that have changed; not the whole file is transmitted unless it is not yet on the server.</p>
</div>
<div class="paragraph">
<p>In this chapter we designate the client (the machine you wish to backup) as <tt>client</tt>. The backup server which will store our backups is designated <tt>server</tt>. Each command is prefixed with a shell-prompt to indicate on which machine (<tt>client</tt> or <tt>server</tt>) the command should be entered. The server&#039;s Fully Qualified Domain Name will be <tt>server.example.com</tt>. The client&#039;s will be <tt>client.example.com</tt>. We will have to move some files (certificates) around between the server and the client in order to sign them. For this we will use a user account with username <tt>user</tt>. It is assumed the root user on both systems can use secure copy (<tt>scp</tt>) to move files from one system to the other under this user account.</p>
</div>
<h3 id="_creating_an_account">4.1. Creating an account</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Before we start installing things on the client machine, we should first create a BoxBackup store account on the server. We use the <tt>bbstoreaccounts</tt> tool for this. It takes five parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">
<tt>command</tt>
</dt>
<dd>
<p>
    The <tt>command</tt> determines <strong>which action</strong> we want to perform on the account. In this case we wish to create an account, so we will use the <tt>create</tt> command.</p>
</dd>
<dt class="hdlist1">
<tt>account_id</tt>
</dt>
<dd>
<p>
    The Account ID is a a <strong>hexdecimal account number</strong>. We will use 00000001. A second client would be 00000002, a tenth client would be 0000000A, etc.
</p>
</dd>
<dt class="hdlist1">
<tt>raid_disk</tt></p>
</dt>
<dd>
<p>
    We must specify <strong>a RAID (BoxBackup&#039;s userland RAID-like concept) disk</strong> on which to store the backups for this client. In our case, we didn&#039;t setup multiple RAID disks, so we have only one: <strong>0</strong>.
</p>
</dd>
<dt class="hdlist1">
<tt>soft_limit</tt></p>
</dt>
<dd>
<p>
    The <strong>Soft Limit</strong> determines when the client will voluntarily stop sending file changes to the server. Presumably (though I&#039;m not sure) it will not start transferring new changes when the soft limit has been exceeded on the server. However, if a single change exceeds the soft limit after the client has started uploading it, it will continue uploading until it hits the hard_limit. We&#039;ll set the soft limit to 100Gb.
</p>
</dd>
<dt class="hdlist1">
<tt>hard_limit</tt>
</dt>
<dd>
<p>
    The <strong>hard limit</strong>. This should NEVER be bigger than the free space you have. We set it too 120Gb.
</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Let&#039;s create the account:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstoreaccounts create 00000001 0 100g 120g
NOTICE: Account 0x00000001 created.</tt></pre>
</div>
</div>
<h3 id="_installation_2">4.2. Installation</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Time to move on to the actual client. Note that some of these commands are run on the client and some are run on the server. <strong>Double check the prompt to see on which machine the command needs to be run!</strong>.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# aptitude install boxbackup-client</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Debian will configure some things for us, but that&#039;s just confusing (and didn&#039;t work for me), so we <strong>remove Debian&#039;s configuration and keys</strong>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# rm /etc/boxbackup/bbackupd.conf
client:/root# rm /etc/boxbackup/bbackupd/*</tt></pre>
</div>
</div>
<h3 id="_client_configuration_certificates">4.3. Client configuration / certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Now we generate the configuration ourselves. We supply the <tt>lazy</tt> mode parameter which will continuously scan our system for changes. This sounds resource intensive, but it actually spreads the load better over time. We also supply the account ID (which we generated earlier on), the server name (FQDN), a run directory where BoxBackup can store temporary information and a path we want backed up. (We add more later on). We will be backing up <tt>/var/lib/svn</tt>.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupd-config /etc/boxbackup/ lazy 00000001 server.electricmonk.nl /var/run /var/lib/svn/

Setup bbackupd config utility.

Configuration:
   Writing configuration file: /etc/boxbackup//bbackupd.conf
   Account: 00000001
   Server hostname: server.electricmonk.nl
   Directories to back up:
      /var/lib/svn/

Note: If other file systems are mounted inside these directories, then
they will NOT be backed up. You will have to create separate locations for
any mounted filesystems inside your backup locations.

Generating private key...
Generating RSA private key, 2048 bit long modulus
...................................+++
.................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Generating keys for file backup
Writing notify script /etc/boxbackup//bbackupd/NotifySysadmin.sh
Writing configuration file /etc/boxbackup//bbackupd.conf

===================================================================

bbackupd basic configuration complete

What you need to do now...

1) Make a backup of /etc/boxbackup//bbackupd/00000001-FileEncKeys.raw
   This should be a secure offsite backup.
   Without it, you cannot restore backups. Everything else can
   be replaced. But this cannot.
   KEEP IT IN A SAFE PLACE, OTHERWISE YOUR BACKUPS ARE USELESS.
2) Send /etc/boxbackup//bbackupd/00000001-csr.pem
   to the administrator of the backup server, and ask for it to
   be signed.
3) The administrator will send you two files. Install them as
      /etc/boxbackup//bbackupd/00000001-cert.pem
      /etc/boxbackup//bbackupd/serverCA.pem
   after checking their authenticity.
4) You may wish to read the configuration file
      /etc/boxbackup//bbackupd.conf
   and adjust as appropriate. There are some
   notes in it on excluding files you do not
   wish to be backed up.
5) Review the script
      /etc/boxbackup//bbackupd/NotifySysadmin.sh
   and check that it will email the right person when the store
   becomes full. This is important -- when the store is full, no
   more files will be backed up. You want to know about this.
6) Start the backup daemon with the command
      /usr/local/bin/bbackupd /etc/boxbackup//bbackupd.conf
   in /etc/rc.local, or your local equivalent.
   Note that bbackupd must run as root.
===================================================================

Remember to make a secure, offsite backup of your backup keys,
as described in step 1 above. If you do not, you have no backups.</tt></pre>
</div>
</div>
<h3 id="_signing_certificates">4.4. Signing certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The previous step has generated a file encryption key (<tt>/etc/boxbackup/bbackupd/00000001-FileEncKeys.raw</tt>) and a client SSL certificate sign request at <tt>/etc/boxbackup/bbackupd/00000001-csr.pem</tt>. These must be sent to the server so they can be signed and added to the server&#039;s known SSL certificates. Here we use <tt>scp</tt> to copy the files to the server, but you can use any other means to get them there.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# scp /etc/boxbackup/bbackupd/00000001-FileEncKeys.raw user@server.electricmonk.nl:
    00000001-FileEncKeys.raw           100% 1024     1.0KB/s   00:00
client:/root# scp /etc/boxbackup/bbackupd/00000001-csr.pem user@server.electricmonk.nl:
    00000001-csr.pem                   100%  899     0.9KB/s   00:00</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Now we must sign the certificate on the server. <strong>Note</strong> that the following commands are ran <strong>on the server, not the client</strong>. Also note that your current working directory must be the one in which we previously ran the <tt>bbstored-certs ca init</tt> command. (the <tt>ca</tt> directory must be present).</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign /home/user/00000001-csr.pem

This certificate is for backup account

00000001

Ensure this matches the account number you are expecting. The filename is

/home/user/00000001-csr.pem

which should include this account number, and additionally, you should check
that you received it from the right person.

Signing the wrong certificate compromises the security of your backup system

Would you like to sign this certificate? (type 'yes' to confirm)
yes
Signature ok
subject=/CN=BACKUP-00000001
Getting CA Private Key

Certificate signed.

Send the files

  ca/clients/00000001-cert.pem
  ca/roots/serverCA.pem

to the client.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We send the signed certificate and the server&#039;s certificate to the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# scp ca/clients/00000001-cert.pem user@client:
    00000001-cert.pem          100%  997     1.0KB/s   00:00
server:/root# scp ca/roots/serverCA.pem user@client:
    serverCA.pem               100% 1021     1.0KB/s   00:00</tt></pre>
</div>
</div>
<div class="paragraph">
<p>And <strong>on the client we install them</strong> in the correct directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# mv /home/user/00000001-cert.pem /etc/boxbackup/bbackupd/
client:/root# mv /home/user/serverCA.pem /etc/boxbackup/bbackupd/</tt></pre>
</div>
</div>
<h3 id="_starting_the_client">4.5. Starting the client</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Now we can start the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:# /etc/init.d/boxbackup-client start</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In the syslog on the <strong>client</strong> we should see:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbackupd.conf
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Beginning scan of local files
Jan 31 21:55:14 client Box Backup (bbackupd)[20975]: NOTICE: About to notify administrator about event backup-start, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-start'
Jan 31 21:59:45 client Box Backup (bbackupd)[20975]: NOTICE: Finished scan of local files
Jan 31 21:59:46 client Box Backup (bbackupd)[20975]: NOTICE: About to notify administrator about event backup-finish, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-finish'
Jan 31 21:59:46 client Box Backup (bbackupd)[20975]: NOTICE: File statistics: total file size uploaded 36012577, bytes already on server 0, encoded size 7161527</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In the syslog on the <strong>server</strong> we should see:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 21:55:13 server Box Backup (bbstored)[15884]: WARNING: Message from child process 16488: Incoming connection from 213.19.146.55 port 52963
Jan 31 21:55:13 server Box Backup (bbstored)[16488]: NOTICE: Login from Client ID 0x00000001 Read/Write
Jan 31 21:58:46 server Box Backup (bbstored)[19666]: NOTICE: Session finished for Client ID 0x00000001</tt></pre>
</div>
</div>
<h3 id="_verifying_backups">4.6. Verifying backups</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>After the initial backup is done, we can verify that files have been transfered using the <tt>bbackupquery</tt> tool. This tool should be run on the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupquery
NOTICE: Box Backup Query Tool v0.11rc2, (c) Ben Summers and contributors 2003-2008
Login complete.

Type "help" for a list of commands.

query &gt; ls
00000002 -d---- var-lib-svn-
00001798 -d---- etc-
query &gt; cd var-lib-svn-
query &gt; ls
00000003 f----- .htpasswd
00000004 f----- .svnaccess
query &gt; exit</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Not all files may have been transferred initially. For instance, Box Backup doesn&#039;t transfer files if they&#039;ve been modified recently. It will try again later. If a file is continuously modified, it will eventually (after a max age) upload the file anyway.</p>
</div>
<h3 id="_adding_additional_paths">4.7. Adding additional paths</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>If you want to add additional paths which need to backed up, edit the <tt>/etc/boxbackup/bbackupd.conf</tt> file and search for the <tt>BackupLocations</tt> directive. You can add paths here. For example, to backup <tt>/var/lib/svn</tt> and <tt>/etc</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>BackupLocations
{
        var-lib-svn-
        {
                Path = /var/lib/svn/
        }
        etc-
        {
                Path = /etc/
        }
}</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Afterwards simply restart <tt>bbackupd</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# /etc/init.d/bbackupd restart</tt></pre>
</div>
</div>
</div>
<h2 id="_troubleshooting">5. Troubleshooting</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The primary methods of troubleshooting are experimentation and the <tt>/var/log/syslog</tt> file.</p>
</div>
<h3 id="_server_connectivity">5.1. Server connectivity</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>We can use various tools to test if the server is running and can be reached. To check if the server is running, use <tt>ps</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# ps axf | grep bbstored
 15884 ?        S      0:00 /usr/sbin/bbstored /etc/boxbackup/bbstored.conf
 15885 ?        S      0:14  \_ /usr/sbin/bbstored /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If it&#039;s not running, check <tt>/var/log/syslog</tt> for any errors.</p>
</div>
<div class="paragraph">
<p>To see if the server is listening for incoming connections from the clients:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# netstat -pant | grep bbstored
tcp        0      0 82.171.91.37:2201       0.0.0.0:*               LISTEN      15884/bbstored</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This shows the server is listening on IP <tt>82.171.91.37</tt> on TCP port <tt>2201</tt>. The daemon should listen on an which can be reached by the clients. If it listens on IP <tt>0.0.0.0</tt>, it will accept connections from any machine.</p>
</div>
<div class="paragraph">
<p>To test if we can reach the server from the client, we can use a port scanner such as <tt>nmap</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root#  nmap -p 2201 server.example.com
Starting Nmap 4.62 ( http://nmap.org ) at 2011-02-01 14:21 CET
Interesting ports on server.example.com (82.171.91.37):
PORT     STATE SERVICE
2201/tcp open  ats</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If <tt>nmap</tt> lists the port as <tt>open</tt>, the client can reach the server.</p>
</div>
<h3 id="_syslog_errors_and_warning">5.2. Syslog errors and warning</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Both the server and the client will log errors to <tt>/var/log/syslog</tt>. Here are a couple of errors you might run into:</p>
</div>
<h4 id="_expired_certificate">5.2.1. Expired certificate</h4>
<div class="paragraph">
<p>If you spot this in the syslog:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 17:32:45 server Box Backup (bbstored)[30775]: WARNING: Message from child process 31604: Incoming connection from 213.19.146.55 port 59381
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: ERROR: SSL error during Accept: error:14094415:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate expired
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: WARNING: Exception thrown: ConnectionException(Conn_TLSHandshakeFailed) at SocketStreamTLS.cpp(245)
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: ERROR: Error in child process, terminating connection: exception Connection TLSHandshakeFailed(7/30)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>One of the certificates has expired. You may be dealing with a bug in older Debian/Ubuntu versions. More information is available here:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>http://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg242206.html</tt></pre>
</div>
</div>
<h4 id="_certificates_missing">5.2.2. Certificates missing</h4>
<div class="paragraph">
<p>THe following error is reported when certificates can&#039;t be loaded. In this case, because they couldn&#039;t be found.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:02001002:system library:fopen:No such file or directory
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:20074002:BIO routines:FILE_CTRL:system lib
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:140DC002:SSL routines:SSL_CTX_use_certificate_chain_file:system lib
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: WARNING: Exception thrown: ServerException(TLSLoadCertificatesFailed) at TLSContext.cpp(118)
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: FATAL: Terminating due to exception Server TLSLoadCertificatesFailed (3/25)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Double check the instructions to make sure you&#039;ve moved certificates to the correct place.</p>
</div>
<h4 id="_permission_denied">5.2.3. Permission denied</h4>
<div class="paragraph">
<p>Various permission denied problems may arise:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Feb  1 10:47:21 server Box Backup[29518]: ERROR: FileHandleGuard: failed to open file '/etc/boxbackup/bbstored.conf': Permission denied
Feb  1 10:47:21 server Box Backup[29518]: WARNING: Exception thrown: CommonException(OSFileOpenError) at ../../lib/common/Guards.h(81)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Check the permission and ownership on the server to make sure that the files in <tt>/etc/boxbackup</tt> belong to the user <tt>bbstored</tt>. Also check that the <tt>bbstored</tt> user can write to <tt>/storage/backup</tt>.</p>
</div>
<h4 id="_certificate_verification_failure">5.2.4. Certificate verification failure</h4>
<div class="paragraph">
<p>On the <strong>client</strong>, you may see the following error:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: ERROR: SSL error during Connect: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: WARNING: Exception thrown: ConnectionException(Conn_TLSHandshakeFailed) at SocketStreamTLS.cpp(250)
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: NOTICE: About to notify administrator about event backup-error, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-error'
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: ERROR: Exception caught (Connection TLSHandshakeFailed 7/30), reset state and waiting to retry...
Jan 31 17:32:56 client Box Backup (bbackupd)[7339]: NOTICE: File statistics: total file size uploaded 0, bytes already on server 0, encoded size 0
Jan 31 17:33:13 client Box Backup (bbackupd)[7339]: NOTICE: Terminating daemon</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This might be related to the Debian bug mentioned in the <em>Expired certificate</em> troubleshooting chapter. Check the server&#039;s <tt>/var/log/syslog</tt> for more details.</p>
</div>
<h4 id="_network_connectivity_problem">5.2.5. Network connectivity problem</h4>
<div class="paragraph">
<p>In case of the following:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: ERROR: Failed to connect to socket (type 1, name server.example.com, port 2201): Connection refused (111)
Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: WARNING: Exception thrown: ConnectionException(Conn_SocketConnectError) at SocketStream.cpp(223)
Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: NOTICE: About to notify administrator about event backup-error, running script '/etc/boxbackup/bbackupd/NotifySysadmin.sh backup-error'
Jan 31 18:34:29 client Box Backup (bbackupd)[27060]: ERROR: Exception caught (Connection SocketConnectError (Probably a network issue between client and server, bad hostname, or server not running.) 7/15), reset state and waiting to retry...
Jan 31 18:34:39 client Box Backup (bbackupd)[27060]: NOTICE: File statistics: total file size uploaded 0, bytes already on server 0, encoded size 0</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Perform the checks given in <em>Server connectivity</em> part of the troubleshooting chapter.</p>
</div>
<h3 id="_missing_files">5.3. Missing files</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Sometimes, after a backup, files may not be present on the remote server. Not all files may have been transferred initially. For instance, Box Backup doesn&#039;t transfer files if they&#039;ve been modified recently. It will try again later. If a file is continuously modified, it will eventually (after a max age) upload the file anyway.</p>
</div>
<h4 id="_other_problems">5.3.1. Other problems</h4>
<div class="paragraph">
<p>The BoxBackup homepage lists some other possible problems:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>http://boxbackup.org/trouble.html</tt></pre>
</div>
</div>
</div>
<h2 id="_about_this_document">6. About this document</h2>
<div class="sectionbody">
<h3 id="_copyright_license">6.1. Copyright / License</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Copyright (c) 2008, Ferry Boender</p>
</div>
<div class="paragraph">
<p>This document may be freely distributed, in part or as a whole, on any medium, without the prior authorization of the author, provided that this Copyright notice remains intact, and there will be no obstruction as to the further distribution of this document. You may not ask a fee for the contents of this document, though a fee to compensate for the distribution of this document is permitted.</p>
</div>
<div class="paragraph">
<p>Modifications to this document are permitted, provided that the modified document is distributed under the same license as the original document and no copyright notices are removed from this document. All contents written by an author stays copyrighted by that author.</p>
</div>
<div class="paragraph">
<p>Failure to comply to one or all of the terms of this license automatically revokes your rights granted by this license</p>
</div>
<div class="paragraph">
<p>All brand and product names mentioned in this document are trademarks or registered trademarks of their respective holders.</p>
</div>
<h3 id="_feedback">6.2. Feedback</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>All feedback on this document is welcome at &lt;ferry DOT boender AT gmail DOT com&gt;.</p>
</div>
</div>
</div>
<div id="footnotes">
<hr /></div>
<div id="footer">
<div id="footer-text">
Version 1.0<br />
Last updated 2011-02-01 16:08:40 CEST
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Modifying Boxee keybindings</title>
		<link>http://www.electricmonk.nl/log/2010/10/21/modifying-boxee-keybindings/</link>
		<comments>http://www.electricmonk.nl/log/2010/10/21/modifying-boxee-keybindings/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 12:50:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4498</guid>
		<description><![CDATA[Boxee is a pretty awesome media player for Linux. Now, I don&#039;t have a remote to control it, but I do have a Logitech DiNovo Wireless keyboard with a detachable numeric pad. Modifying Boxee to support controlling it using the numeric pad is rather easy: Browse to the map that contains the Boxee installation. For [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.boxee.tv/">Boxee</a> is a pretty awesome media player for Linux. Now, I don&#039;t have a remote to control it, but I do have a Logitech DiNovo Wireless keyboard with a detachable numeric pad. Modifying Boxee to support controlling it using the numeric pad is rather easy:</p>
<p>Browse to the map that contains the Boxee installation. For me that&#039;s <tt>/opt/boxee</tt> but it&#039;s probably different on your system (try <tt>/usr/share/boxee</tt> or <tt>/usr/lib/boxee</tt>). Open up the file <tt>system/keymaps/keyboard.xml</tt> in your favorite editor. Here you will see a big list of keybindings. Find the <tt>&lt;global&gt;</tt> section which contains the <tt>&lt;keyboard&gt;</tt> section. In that section, add the following:</p>
<pre>
      &lt;one&gt;SkipPrevious&lt;/one&gt;
      &lt;three&gt;SkipNext&lt;/three&gt;
      &lt;four&gt;Left&lt;/four&gt;
      &lt;five&gt;Down&lt;/five&gt;
      &lt;six&gt;Right&lt;/six&gt;
      &lt;seven&gt;BigStepBack&lt;/seven&gt;
      &lt;eight&gt;Up&lt;/eight&gt;
      &lt;nine&gt;BigStepForward&lt;/nine&gt;
      &lt;period&gt;Pause&lt;/period&gt;
</pre>
<p>Now comment out the following lines:</p>
<pre>
      &lt;!--
      &lt;zero&gt;Number0&lt;/zero&gt;
      &lt;one&gt;Number1&lt;/one&gt;
      &lt;two&gt;Number2&lt;/two&gt;
      &lt;three&gt;Number3&lt;/three&gt;
      &lt;four&gt;Number4&lt;/four&gt;
      &lt;five&gt;Number5&lt;/five&gt;
      &lt;six&gt;Number6&lt;/six&gt;
      &lt;seven&gt;Number7&lt;/seven&gt;
      &lt;eight&gt;Number8&lt;/eight&gt;
      &lt;nine&gt;Number9&lt;/nine&gt;
      --&gt;
</pre>
<p>You may also want to modify the <tt>&lt;FullscreenVideo&gt;</tt> section and add these:</p>
<pre>
      &lt;four&gt;StepBack&lt;/four&gt;
      &lt;six&gt;StepForward&lt;/six&gt;
</pre>
<p>Save the file, exit, and start Boxee. You can now control using your numeric pad.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2010/10/21/modifying-boxee-keybindings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

