<?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>Lennart&#039;s weblog &#187; sysadmin</title>
	<atom:link href="http://blog.karssen.org/tag/sysadmin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.karssen.org</link>
	<description>Open source, computers, Africa and other more (or less) interesting stuff.</description>
	<lastBuildDate>Thu, 02 Feb 2012 19:15:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Installing Loggerhead behind Apache on Ubuntu 11.04</title>
		<link>http://blog.karssen.org/2011/08/22/installing-loggerhead-behind-apache-on-ubuntu-11-04/</link>
		<comments>http://blog.karssen.org/2011/08/22/installing-loggerhead-behind-apache-on-ubuntu-11-04/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 22:29:52 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=163</guid>
		<description><![CDATA[Introduction Loggerhead is a webfrontend for Bazaar (usually abbreviated as bzr) repositories. Bazaar is a so-called distributed version control system. So, if you have one or more bzr repositories you can use Loggerhead to look at the files, read the change logs and see the differences between revisions from within your web browser. The main [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="https://launchpad.net/loggerhead">Loggerhead</a> is a webfrontend for <a href="http://bazaar.canonical.com/">Bazaar</a> (usually abbreviated as bzr) repositories. Bazaar is a so-called distributed version control system. So, if you have one or more bzr repositories you can use Loggerhead to look at the files, read the change logs and see the differences between revisions from within your web browser.</p>
<p>The main purpose of this post is to document the steps needed to configure Loggerhead and Apache to work together to publish your bzr repos on the web. The need for this post arose when I tried to get this setup to work and found that there isn&#8217;t a lot of documentation on how to get this done and most of it is out of date. The folowing steps were performed on a Linux server with Ubuntu 11.04 installed.</p>
<h2>Basic Loggerhead configuration</h2>
<p>First, let&#8217;s install Loggerhead:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> loggerhead</pre></div></div>

<p>Although the package is called loggerhead, the actual binary that is run is called serve-branches. The package provides start and stop scripts for the service (<code>/etc/init.d/loggerhead</code>), but to start successfully the file <code>/etc/serve-branches.conf</code> needs to exist. Older documentation I found on the web refers to the file <code>/etc/loggerhead.conf</code>, but that file has become obsolete.</p>
<p>The <code>serve-branches.conf</code> file contains three lines:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000099;">served_branches</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/home/bzr</span>
<span style="color: #000099;">prefix</span><span style="color: #000066; font-weight:bold;">=</span>
<span style="color: #000099;">port</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">8080</span></pre></div></div>

<p>Here, the line <code>served_branches</code> points to the directory under which you store your bzr repositories. Each repo needs to be stored in its own directory. So in this example all the repos are in subdirectories of <code>/home/bzr/</code>.</p>
<p>You have to make sure that loggerhead can read the files in that directory. Loggerhead runs as the <code>loggerhead</code> user but I made the directories readable and accessible by all users:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #660033;">-R</span> a+rx <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>bzr<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>If you now start Loggerhead:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ service start loggerhead</pre></div></div>

<p>you should be able to visit http://localhost:8080 in your browser and see your repositories.</p>
<h2>How to publish your branch to this shared repository?</h2>
<p>Now that our repository browser is set up, how do we publish our branches to it so that there actually is something to browse through? Here is how you publish your branch to the server, assuming that you are in a directory that contains a branch and want to publish it as <code>myTests</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ bzr push <span style="color: #660033;">--create-prefix</span> sftp:<span style="color: #000000; font-weight: bold;">//</span>username<span style="color: #000000; font-weight: bold;">@</span>server.yourdomain.com<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>bzr<span style="color: #000000; font-weight: bold;">/</span>myTests</pre></div></div>

<p>As you probably suspected, the <code>--create-prefix</code> option is only necessary the first time you push your branch. Note that we are using sftp here. Loggerhead itself doesn&#8217;t allow writes to the published repos. So, every user that want to push his/her changes to this repository needs to have sftp access to the <code>/home/bzr</code> directory. I solved that problem by adding all people that need to be able to push changes to a Linux group called <i>vcs</i> (for Version Control Systems) and then set the primary group of <code>/home/bzr/</code> to <i>vcs</i> as well as giving group write permissions to this directory:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-ld</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>bzr<span style="color: #000000; font-weight: bold;">/</span>
drwxrwxr-x <span style="color: #000000;">4</span> root vcs <span style="color: #000000;">4096</span> <span style="color: #000000;">2011</span>-08-<span style="color: #000000;">16</span> <span style="color: #000000;">23</span>:<span style="color: #000000;">10</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>bzr<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<h2>Adding Apache to the mix</h2>
<p>In my case I already have a web server (Apache) running on port 80. Since I&#8217;d rather not open yet another port (8080 in this case) on my router, I wanted to use Apache to hand over the requests for bzr page to Loggerhead. For that I needed to install the following packages:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> python-pastedeploy</pre></div></div>

<p>Next, I needed to change the contents of the <code>/etc/serve-branches.conf</code> file to this:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000099;">served_branches</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/home/bzr</span>
<span style="color: #000099;">prefix</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/bzr</span>
<span style="color: #000099;">port</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">8080</span></pre></div></div>

<p>The prefix indicates the location in the URL where Apache will serve the repos. In this case that will be http://server.yourdomain.com/bzr/.</p>
<p>And finally I needed to configure Apache. First, make sure that the <code>proxy</code> and <code>proxy-http</code> modules are loaded:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ a2enmod proxy proxy_http</pre></div></div>

<p>Next, create a file <code>/etc/apache/conf.d/sites-available/loggerhead</code> with the following contents:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># Configuration for browsing of Bazaar repos. Make sure loggerhead is running.</span>
&lt;<span style="color: #000000; font-weight:bold;">Location</span> <span style="color: #7f007f;">&quot;/bzr/&quot;</span>&gt;
    <span style="color: #00007f;">ProxyPass</span> http://127.0.0.1:<span style="color: #ff0000;">8080</span>/
    <span style="color: #00007f;">ProxyPassReverse</span> http://127.0.0.1:<span style="color: #ff0000;">8080</span>/
&lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;</pre></div></div>

<p>Note that Loggerhead and Apache run on the same host, that&#8217;s why I set the IP to 127.0.0.1.</p>
<p>Finally it&#8217;s time to enable the site and restart Apache:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ a2ensite loggerhead
$ service apache2 restart</pre></div></div>

<p>Now it should be possible to browse your repos at http://server.yourdomain.com/bzr/. Note the final <code>/</code>, it&#8217;s important.</p>
<h2>Securing access with an LDAP connection</h2>
<p>I have stored all my Unix user and group information in an LDAP server. To make sure that only people in the Unix group <code>vcs</code> are allowed access to the loggerhead pages, change the Apache configuration file <code>loggerhead</code> to the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># Configuration for browsing of Bazaar repos. Make sure loggerhead is running.</span>
&lt;<span style="color: #000000; font-weight:bold;">Location</span> <span style="color: #7f007f;">&quot;/bzr/&quot;</span>&gt;
    <span style="color: #00007f;">ProxyPass</span> http://127.0.0.1:<span style="color: #ff0000;">8080</span>/
    <span style="color: #00007f;">ProxyPassReverse</span> http://127.0.0.1:<span style="color: #ff0000;">8080</span>/
&nbsp;
    <span style="color: #adadad; font-style: italic;"># LDAP authentication</span>
    <span style="color: #00007f;">AuthType</span> Basic
    <span style="color: #00007f;">AuthName</span> <span style="color: #7f007f;">&quot;Karssen.org VCS users&quot;</span>
    <span style="color: #00007f;">AuthBasicProvider</span> ldap
    <span style="color: #00007f;">AuthLDAPURL</span> <span style="color: #7f007f;">&quot;ldap://ldap.yourdomain.com/ou=Users,dc=yourdomain,dc=com?uid&quot;</span>
    <span style="color: #00007f;">AuthLDAPGroupAttribute</span> memberUid
    <span style="color: #00007f;">AuthLDAPGroupAttributeIsDN</span> <span style="color: #0000ff;">off</span>
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">Allow</span>,<span style="color: #00007f;">Deny</span>
    <span style="color: #00007f;">Allow</span> From <span style="color: #0000ff;">All</span>
    <span style="color: #00007f;">Require</span> ldap-<span style="color: #00007f;">group</span> cn=vcs,ou=Groups,dc=yourdomain,dc=com
&lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;</pre></td></tr></table></div>

<p>Lines 11 and 12 are needed because the <code>vcs</code> group is not an LDAP group. I store my Unix (POSIX) groups in a separate OU in the LDAP tree (see line 15).<br />
Don&#8217;t forget to restart Apache after making these changes.</p>
<h2>References</h2>
<ul>
<li><a href="http://doc.bazaar.canonical.com/latest/en/admin-guide/code-browsing.html">Bazaar documentation on Apache integration</a></li>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/loggerhead/+bug/563118">Launchpad bug 563118 describing the unexpected change from <code>loggerhead.conf</code> to <code>serve-branches.conf</code></a></li>
<li><a href="http://blather.michaelwlucas.com/archives/99">Apache, LDAP and groups</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2011/08/22/installing-loggerhead-behind-apache-on-ubuntu-11-04/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Installing and configuring Puppet</title>
		<link>http://blog.karssen.org/2011/07/29/installing-and-configuring-puppet/</link>
		<comments>http://blog.karssen.org/2011/07/29/installing-and-configuring-puppet/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 16:26:08 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Puppet]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=135</guid>
		<description><![CDATA[Puppet is a configuration management system. In short this means that by setting up a server (the Puppet master) you can manage many other machines (nodes) with this server by specifying which packages should be installed, files that need to be present, their permissions, etc. The nodes poll the server every 30 minutes (by default) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.puppetlabs.com/puppet/introduction/">Puppet</a> is a configuration management system. In short this means that by setting up a server (the Puppet master) you can manage many other machines (nodes) with this server by specifying which packages should be installed, files that need to be present, their permissions, etc. The nodes poll the server every 30 minutes (by default) to see if they should apply any changes to their configuration. Other packages that implement a similar idea are CfEnfine and Chef.</p>
<p>Note that all these instructions were performed as root.</p>
<h2>The puppet master</h2>
<p>Gaffel will be puppet master. I&#8217;ve added a DNS entry for <i>puppet.karssen.org</i> that points to <i>gaffel</i>. This installs the client and the Puppet master:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> puppet puppetmaster</pre></div></div>

<p>The main configuration of server and client can be found in <i>/etc/puppet/puppet.conf</i>. We&#8217;ll leave it at the default for now. The file <i>/etc/puppet/manifests/sites.pp</i> contains options that apply to the whole site. Let&#8217;s make it and add the following contents:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">import <span style="color: #933;">&quot;nodes&quot;</span>
&nbsp;
# The filebucket is for backups. Originals of files that Puppet modifies
# get stored here.
filebucket <span style="">&#123;</span> main: server <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; 'puppet.karssen.org' <span style="">&#125;</span></span>
File  <span style="">&#123;</span> backup <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; main<span style="">&#125;</span></span>
&nbsp;
# Set the default $PATH$ for executing commands on node systems.
Exec <span style="">&#123;</span> path <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/usr/bin:/usr/sbin:/bin:/sbin:&quot;</span> <span style="">&#125;</span></pre></div></div>

<p>The file <i>/etc/puppet/manifests/nodes.pp</i> defines the nodes/clients that will be managed by puppet as well as what configuration will be applied to them, so-called roles. For now, let&#8217;s make a quick example:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">node common <span style="">&#123;</span>
	include packages
<span style="">&#125;</span>
&nbsp;
node lambik inherits common <span style="">&#123;</span>
	include ntp::client
<span style="">&#125;</span></pre></div></div>

<p>Both the &#8216;packages&#8217; and the &#8216;ntp&#8217; modules still need to be defined. Let&#8217;s do that now.</p>
<p>Modules are collections of puppet code (known as manifests) and related files that are used for client configuration. Modules are stored in <i>/etc/puppet/modules/</i>.<br />
Let&#8217;s start with the ntp example. First make the necessary directory structure:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>ntp<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>manifests,files,templates<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Every modules needs a file <i>init.pp</i> that declares the class. It can also include other files. The <i>files</i> and <i>templates</i> directories are used to store files that need to be copied to the node or templates to make such files, respectively. We&#8217;ll come across some examples of both. This is the <i>init.pp</i> file for the ntp role (<i>/etc/puppet/modules/ntp/manifests/init.pp</i>):</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">class ntp::client <span style="">&#123;</span>
	 package <span style="">&#123;</span> <span style="color: #933;">&quot;ntp&quot;</span>:
    		 <span style="color: #000099;">ensure</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; installed,</span>
	 <span style="">&#125;</span>
&nbsp;
	 service <span style="">&#123;</span> <span style="color: #933;">&quot;ntp_client&quot;</span>:
		 <span style="color: #000099;">name</span>       <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;ntp&quot;</span>
    		 <span style="color: #000099;">ensure</span>     <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; running,</span>
#		 hasstatus  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
		 <span style="color: #000099;">hasrestart</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
		 <span style="color: #000099;">require</span>    <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; Package<span style="">&#91;</span></span><span style="color: #933;">&quot;ntp&quot;</span><span style="">&#93;</span>,
	 <span style="">&#125;</span>
<span style="">&#125;</span></pre></div></div>

<p>Here we indicate that the NTP service must be running and that it&#8217;s init script (in <i>/etc/init.d</i>) accepts the <i>status</i> and <i>restart</i> options. Lastly in the <i>require</i> line we note that before this manifest can be applied we must make sure that the package <i>ntp</i> has been installed. This is necessary, because the order in which the two directives are executed is not necessarily the order in<br />
which they appear in the manifest.</p>
<p>The <i>#</i> in from of the <i>hasstatus</i> attribute is because of a bug inthe puppet version (2.6.4) shipped with Ubuntu 11.04. See http://projects.puppetlabs.com/issues/5610 for the bug report. In version 2.6.7 it is supposedly fixed.</p>
<p>In our <i>nodes.pp</i> file we also mentioned a <i>packages</i> class. In this class we list all the packages that we want to have installed on the node. Let&#8217;s make the <i>packages</i> module. First create the necessary directories:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>packages<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>manifests,files,templates<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Add the file <i>/etc/puppet/modules/packages/manifests/init.pp</i>:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">class packages <span style="">&#123;</span>
	 $base_packages <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#91;</span></span>
	 <span style="color: #933;">&quot;openssh-server&quot;</span>,
	 <span style="color: #933;">&quot;nfs-common&quot;</span>,
	 <span style="color: #933;">&quot;etckeeper&quot;</span>,
	 <span style="color: #933;">&quot;htop&quot;</span>,
	 <span style="color: #933;">&quot;iotop&quot;</span>,
	 <span style="color: #933;">&quot;iftop&quot;</span>,
	 <span style="">&#93;</span>
&nbsp;
	 $editor_packages <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#91;</span></span>
	 <span style="color: #933;">&quot;emacs&quot;</span>,
	 <span style="color: #933;">&quot;emacs-goodies-el&quot;</span>,
	 <span style="color: #933;">&quot;elscreen&quot;</span>,
	 <span style="">&#93;</span>
&nbsp;
	 $all_packages <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> <span style="">&#91;</span></span>
	 $base_packages,
	 $editor_packages,
	 <span style="">&#93;</span>
&nbsp;
	 package <span style="">&#123;</span> $all_packages:
	      <span style="color: #000099;">ensure</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; installed,</span>
	 <span style="">&#125;</span>
<span style="">&#125;</span></pre></div></div>

<p>Here I&#8217;ve defined three variables (beginning with a <i>$</i> sign), one for base packages, one for editor-related packages and one called <i>$all_packages</i> that incorporates them both. Finally, I tell puppet to ensure they are all installed.</p>
<h2>Setting up a client</h2>
<p>As a test client I&#8217;m using <i>lambik</i>, one of my MythTV frontends.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> puppet</pre></div></div>

<p>To make sure that puppet starts by default on system startup edit the file <i>/etc/default/puppet</i> and set <i>START</i> to <i>yes</i>:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"># Defaults for puppet - sourced by /etc/init.d/puppet
&nbsp;
# Start puppet on boot?
<span style="color: #000099;">START</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">yes</span>
&nbsp;
# Startup options
<span style="color: #000099;">DAEMON_OPTS</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #933;">&quot;&quot;</span></pre></div></div>

<p>Now edit <i>/etc/puppet/puppet.conf</i> (on the client) and add the FQDN of the puppet master server to the <i>[main]</i> section:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>main<span style="">&#93;</span></span>
<span style="color: #000099;">logdir</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/var/log/puppet</span>
<span style="color: #000099;">vardir</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/var/lib/puppet</span>
<span style="color: #000099;">ssldir</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/var/lib/puppet/ssl</span>
<span style="color: #000099;">rundir</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/var/run/puppet</span>
<span style="color: #000099;">factpath</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">$vardir/lib/facter</span>
<span style="color: #000099;">templatedir</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">$confdir/templates</span>
<span style="color: #000099;">prerun_command</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/etc/puppet/etckeeper-commit-pre</span>
<span style="color: #000099;">postrun_command</span><span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/etc/puppet/etckeeper-commit-post</span>
<span style="color: #000099;">server</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> puppet.karssen.org</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>master<span style="">&#93;</span></span>
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
<span style="color: #000099;">ssl_client_header</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> SSL_CLIENT_S_DN</span>
<span style="color: #000099;">ssl_client_verify_header</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> SSL_CLIENT_VERIFY</span></pre></div></div>

<h2>Setting up secure communication between master and nodes and first test run</h2>
<p>Puppet uses SSL certificates to set up a secure connection between master and nodes. Before you can apply any changes to the client, certificates need to be exchanged and signed. First, tell the client to connect to the puppet master:</p>
<pre lang="">
$ puppetd --test
info: Creating a new SSL key for lambik.karssen.org
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for ca
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
info: Creating a new SSL certificate request for lambik.karssen.org
info: Certificate Request fingerprint (md5): 1D:A3:3A:4A:A6:DA:D6:C8:96:F4:D4:7E:52:F4:12:1D
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
Exiting; no certificate found and waitforcert is disabled
</pre>
<p>On the puppet master we can now sign the certificate:</p>
<pre lang="">
$ puppetca -l
lambik.karssen.org
$ puppetca -s lambik.karssen.org
notice: Signed certificate request for lambik.karssen.org
notice: Removing file Puppet::SSL::CertificateRequest lambik.karssen.org at '/var/lib/puppet/ssl/ca/requests/lambik.karssen.org.pem'
</pre>
<p>On the client we can now rerun <i>puppetd</i>:</p>
<pre lang="">
root@lambik:~# puppetd --test
info: Caching catalog for lambik.karssen.org
info: Applying configuration version '1311930908'
notice: /Stage[main]/Packages/Package[iotop]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]/Packages/Package[iftop]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]/Ntp/Package[ntp]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]/Packages/Package[emacs-goodies-el]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]/Packages/Package[htop]/ensure: ensure changed 'purged' to 'present'
info: Creating state file /var/lib/puppet/state/state.yaml
notice: Finished catalog run in 78.43 seconds
</pre>
<p>If all went well, we can now start the puppet client daemon to keep our system under puppet control:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ service puppet start</pre></div></div>

<h2>Adding (configuration) files to the roles</h2>
<p>Since I run my own NTP server (<i>ntp.karssen.org</i>, only accessible from inside my LAN), the NTP configuration file (<i>/etc/ntp.conf</i>) must be changed. Of course, we want Puppet to take care of this. The <i>ntp.conf</i> file I want to distribute to all nodes has the following contents (note that the only change is the name of the server and commenting the <i>restrict</i> lines):</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"># /etc/ntp.conf, configuration for ntpd<span style="color: #666666; font-style: italic;">; see ntp.conf(5) for help</span>
&nbsp;
driftfile /var/lib/ntp/ntp.drift
&nbsp;
&nbsp;
# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/
&nbsp;
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
&nbsp;
# Specify one or more NTP servers.
&nbsp;
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on <span style="">2011</span>-02-08 <span style="">&#40;</span>LP: #<span style="">104525</span><span style="">&#41;</span>. See http://www.pool.ntp.org/join.html for
# more information.
server ntp.karssen.org
&nbsp;
# Use Ubuntu's ntp server as a fallback.
server ntp.ubuntu.com
&nbsp;
# Access control configuration<span style="color: #666666; font-style: italic;">; see /usr/share/doc/ntp-doc/html/accopt.html for</span>
# details.  The web page &lt;http://support.ntp.org/bin/view/Support/AccessRestrict
ions&gt;
# might also be helpful.
#
# Note that <span style="color: #933;">&quot;restrict&quot;</span> applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.
&nbsp;
# By default, exchange time with everybody, but don't allow configuration.
#restrict -<span style="">4</span> default kod notrap nomodify nopeer noquery
#restrict -<span style="">6</span> default kod notrap nomodify nopeer noquery
&nbsp;
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::<span style="">1</span>
&nbsp;
# Clients from this <span style="">&#40;</span>example!<span style="">&#41;</span> subnet have unlimited access, but only if
# cryptographically authenticated.
#restrict 192.168.123.0 mask 255.255.255.0 notrust
&nbsp;
&nbsp;
# If you want to provide time to your local subnet, change the next line.
# <span style="">&#40;</span>Again, the address is an example only.<span style="">&#41;</span>
#broadcast 192.168.123.255
&nbsp;
# If you want to listen to time broadcasts on your local subnet, de-comment the
# next lines.  Please do this only if you trust everybody on the network!
#disable auth
#broadcastclient</pre></div></div>

<p>Save this file in <i>/etc/puppet/modules/ntp/files</i> (on the puppet master). Now edit the manifest for the ntp role (<i>/etc/puppet/modules/ntp/manifest/init.pp</i>) to add the file section and a <i>subscribe</i> command:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">class ntp::client <span style="">&#123;</span>
	 package <span style="">&#123;</span> <span style="color: #933;">&quot;ntp&quot;</span>:
		      <span style="color: #000099;">ensure</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; installed,</span>
	 <span style="">&#125;</span>
&nbsp;
	 service <span style="">&#123;</span> <span style="color: #933;">&quot;ntp_client&quot;</span>:
	      <span style="color: #000099;">name</span>       <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;ntp&quot;</span>,
	      <span style="color: #000099;">ensure</span>     <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; running,</span>
#	      hasstatus  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
	      <span style="color: #000099;">hasrestart</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
	      <span style="color: #000099;">require</span>    <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; Package<span style="">&#91;</span></span><span style="color: #933;">&quot;ntp&quot;</span><span style="">&#93;</span>,
	      <span style="color: #000099;">subscribe</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; File<span style="">&#91;</span></span><span style="color: #933;">&quot;ntp_client_config&quot;</span><span style="">&#93;</span>,
	 <span style="">&#125;</span>
&nbsp;
	 file <span style="">&#123;</span> <span style="color: #933;">&quot;ntp_client_config&quot;</span>:
		   <span style="color: #000099;">path</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/etc/ntp.conf&quot;</span>,
	   <span style="color: #000099;">owner</span>   <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; root,</span>
	   <span style="color: #000099;">group</span>   <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; root,</span>
	   <span style="color: #000099;">mode</span>    <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; 644,</span>
	   <span style="color: #000099;">source</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;puppet:///ntp/ntp.conf&quot;</span>,
	   <span style="color: #000099;">require</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; Package<span style="">&#91;</span></span><span style="color: #933;">&quot;ntp&quot;</span><span style="">&#93;</span>,
	 <span style="">&#125;</span>
<span style="">&#125;</span></pre></div></div>

<p>The URL specified in the <i>source</i> line automatically looks in the right place (as mentioned just above) for the file. Because we don&#8217;t want to wait for puppet to automatically pass on this configuration, let&#8217;s run it by hand:</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">root@lambik:~# puppetd --test
info: Caching catalog for lambik.karssen.org
info: Applying configuration version '<span style="">1311936811</span>'
<span style="color: #888822;">--- /etc/ntp.conf	2011-06-17 07:59:54.000000000 +0200</span>
<span style="color: #888822;">+++ /tmp/puppet-file20110729-12128-1h3fupz-0	2011-07-29 12:53:33.279622938 +0200</span>
<span style="color: #440088;">@@ -16,16 +16,14 @@</span>
 # Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
 # on <span style="">2011</span>-02-08 <span style="">&#40;</span>LP: #<span style="">104525</span><span style="">&#41;</span>. See http://www.pool.ntp.org/join.html for
 # more information.
<span style="color: #991111;">-server 0.ubuntu.pool.ntp.org</span>
<span style="color: #991111;">-server 1.ubuntu.pool.ntp.org</span>
<span style="color: #991111;">-server 2.ubuntu.pool.ntp.org</span>
<span style="color: #991111;">-server 3.ubuntu.pool.ntp.org</span>
<span style="color: #00b000;">+server ntp.karssen.org</span>
&nbsp;
 # Use Ubuntu's ntp server as a fallback.
 server ntp.ubuntu.com
&nbsp;
<span style="color: #440088;">@@ -33,8 +31,8 @@</span>
 # up blocking replies from your own upstream servers.
&nbsp;
 # By default, exchange time with everybody, but don't allow configuration.
<span style="color: #991111;">-restrict -4 default kod notrap nomodify nopeer noquery</span>
<span style="color: #991111;">-restrict -6 default kod notrap nomodify nopeer noquery</span>
<span style="color: #00b000;">+#restrict -4 default kod notrap nomodify nopeer noquery</span>
<span style="color: #00b000;">+#restrict -6 default kod notrap nomodify nopeer noquery</span>
&nbsp;
 # Local users may interrogate the ntp server more closely.
 restrict 127.0.0.1
info: FileBucket adding /etc/ntp.conf as <span style="">&#123;</span>md5<span style="">&#125;</span><span style="color: #440088;">32280703a4</span>ba7aa<span style="color: #440088;">1148c48895097</span>ed07
info: /Stage<span style="">&#91;</span>main<span style="">&#93;</span>/Ntp::Client/File<span style="">&#91;</span>ntp_client_config<span style="">&#93;</span>: Filebucketed /etc/ntp.conf to main with sum <span style="color: #440088;">32280703a4</span>ba7aa<span style="color: #440088;">1148c48895097</span>ed07
notice: /Stage<span style="">&#91;</span>main<span style="">&#93;</span>/Ntp::Client/File<span style="">&#91;</span>ntp_client_config<span style="">&#93;</span>/content: content changed '<span style="">&#123;</span>md5<span style="">&#125;</span><span style="color: #440088;">32280703a4</span>ba7aa<span style="color: #440088;">1148c48895097</span>ed07' to '<span style="">&#123;</span>md5<span style="">&#125;</span><span style="color: #440088;">0d1</span>b<span style="color: #440088;">81c95</span>bab1f6b08eb27dfaeb18bb5'
info: /Stage<span style="">&#91;</span>main<span style="">&#93;</span>/Ntp::Client/File<span style="">&#91;</span>ntp_client_config<span style="">&#93;</span>: Scheduling refresh of Service<span style="">&#91;</span>ntp_client<span style="">&#93;</span>
notice: /Stage<span style="">&#91;</span>main<span style="">&#93;</span>/Ntp::Client/Service<span style="">&#91;</span>ntp_client<span style="">&#93;</span>: Triggered 'refresh' from <span style="">1</span> events
notice: Finished catalog run in <span style="">3.06</span> seconds</pre></div></div>

<h2>Setting NFS mounts in <i>/etc/fstab</i></h2>
<p>On my clients I want to mount several NFS shares. Let&#8217;s create the directories for the <i>nfs_mounts</i> module (on the puppet master of course):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>puppet<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>nfs_mounts<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>manifests,files,templates<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Next, let&#8217;s edit the manifest (<i>/etc/puppet/modules/nfs_mounts/manifests/init.pp</i>):</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">class nfs_mounts <span style="">&#123;</span>
	 # Create the shared folder unless it already exists
	 exec <span style="">&#123;</span> <span style="color: #933;">&quot;/bin/mkdir -p /var/sharedtmp/&quot;</span>:
		   <span style="color: #000099;">unless</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/usr/bin/test -d /var/sharedtmp/&quot;</span>,
	 <span style="">&#125;</span>
&nbsp;
	 mount <span style="">&#123;</span> <span style="color: #933;">&quot;/var/sharedtmp/&quot;</span>:
	    <span style="color: #000099;">atboot</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
	    <span style="color: #000099;">ensure</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; mounted,</span>
	    <span style="color: #000099;">device</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;nfs.karssen.org:/var/sharedtmp&quot;</span>,
	    <span style="color: #000099;">fstype</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;nfs&quot;</span>,
	    <span style="color: #000099;">options</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;vers=3&quot;</span>,
	    <span style="color: #000099;">require</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; Package<span style="">&#91;</span></span><span style="color: #933;">&quot;nfs-common&quot;</span><span style="">&#93;</span>,
	 <span style="">&#125;</span>
<span style="">&#125;</span></pre></div></div>

<p>This should make the <i>/var/sharedtmp</i> directory and mount it. Note that I mention the <i>nfs_common</i> package in a <i>require</i> line. This package was defined in the <i>packages</i> module (in the <i>$base_packages</i> variable. Now let&#8217;s add this module to the <i>nodes.pp</i> file:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">node common <span style="">&#123;</span>
  include packages
<span style="">&#125;</span>
&nbsp;
node lambik inherits common <span style="">&#123;</span>
	include ntp::client
	include nfs_mounts
<span style="">&#125;</span></pre></div></div>

<p>Since I&#8217;ve got more than a single NFS mount, let&#8217;s extend the previous example and use a defined resource. Change the file <i>/etc/puppet/modules/nfs_mounts/manifests/init.pp</i> as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">define nfs_mount<span style="">&#40;</span>
	  $location,
	  $server  <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;nfs.karssen.org&quot;</span>,
	  $options <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;vers=3&quot;</span>,
	  $fstype  <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;nfs&quot;</span>
<span style="">&#41;</span> <span style="">&#123;</span>
  file <span style="">&#123;</span><span style="color: #933;">&quot;$location&quot;</span>:
	  <span style="color: #000099;">ensure</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; directory,</span>
  <span style="">&#125;</span>
&nbsp;
  mount <span style="">&#123;</span> <span style="color: #933;">&quot;$location&quot;</span>:
  	<span style="color: #000099;">atboot</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; true,</span>
	<span style="color: #000099;">ensure</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; mounted,</span>
	<span style="color: #000099;">device</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;${server}:${location}&quot;</span>,
	<span style="color: #000099;">fstype</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;$fstype&quot;</span>,
	<span style="color: #000099;">options</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;$options&quot;</span>,
	<span style="color: #000099;">require</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; <span style="">&#91;</span> Package<span style="">&#91;</span></span><span style="color: #933;">&quot;nfs-common&quot;</span><span style="">&#93;</span>, File<span style="">&#91;</span><span style="color: #933;">&quot;$location&quot;</span><span style="">&#93;</span> <span style="">&#93;</span>,
  <span style="">&#125;</span>
<span style="">&#125;</span>
&nbsp;
class nfs_mounts <span style="">&#123;</span>
&nbsp;
			 nfs_mount <span style="">&#123;</span> <span style="color: #933;">&quot;/home&quot;</span>:
		 	   <span style="color: #000099;">location</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/home&quot;</span>,
		 <span style="">&#125;</span>
&nbsp;
			 nfs_mount <span style="">&#123;</span> <span style="color: #933;">&quot;/var/sharedtmp&quot;</span>:
		 	    <span style="color: #000099;">location</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/var/sharedtmp&quot;</span>,
 		 <span style="">&#125;</span>
&nbsp;
			 nfs_mount <span style="">&#123;</span> <span style="color: #933;">&quot;/var/video&quot;</span>:
	 	    	    <span style="color: #000099;">location</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/var/video&quot;</span>,
 		 <span style="">&#125;</span>
&nbsp;
			 nfs_mount <span style="">&#123;</span> <span style="color: #933;">&quot;/var/music&quot;</span>:
	 	    	    <span style="color: #000099;">location</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">&gt; </span><span style="color: #933;">&quot;/var/music&quot;</span>,
 		 <span style="">&#125;</span>
<span style="">&#125;</span></pre></div></div>

<p>Here we first define a resource called <i>nfs_mount</i>, which can accept various parameters, all of which have a default value, except <i>$location</i>. Secondly we ensure that this location is a directory and then we define how it should be mounted. In the subsequent class definition we use this <i>nfs_mount</i> resource several times to mount the various NFS shares.<br />
Note that it would have been easier if the definition of <i>nfs_mount</i> would have started with</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">define nfs_mount <span style="">&#40;</span>
	  $location <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> $name,</span></pre></div></div>

<p>because then the invocations of <i>nfs_mount</i> in the class would not<br />
need the <i>location =></i> line. Unfortunately this doesn&#8217;t work. It&#8217;s<br />
a known bug that has been fixed in version 2.6.5<br />
(http://projects.puppetlabs.com/issues/5061).</p>
<h2>Links</h2>
<ul>
<li>Article by Jes Fraser in the July 2011 edition of Linux Journal. A lot of this info was taken from this article.</li>
<li><a href="http://blog.fandotech.com/archives/938">A blog</a></li>
<li><a href="http://docs.puppetlabs.com/">The Puppet documentation</a></li>
<li><a href="http://docs.puppetlabs.com/guides/language_guide.html">The Puppet language guide</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2011/07/29/installing-and-configuring-puppet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making a .deb package for software that doesn&#8217;t accept the DESTDIR variable in its Makefile</title>
		<link>http://blog.karssen.org/2011/04/06/making-a-deb-package-for-software-that-doesnt-accept-the-destdir-variable-in-its-makefile/</link>
		<comments>http://blog.karssen.org/2011/04/06/making-a-deb-package-for-software-that-doesnt-accept-the-destdir-variable-in-its-makefile/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 22:07:13 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=116</guid>
		<description><![CDATA[Because I&#8217;ll be deploying a new server in the near future and I want to keep it as clean as possible I decided (again) to try to find out how to create a .deb package (as used for example by Debian and Ubuntu Linux) for some software that doesn&#8217;t follow the autotools way of doing [...]]]></description>
			<content:encoded><![CDATA[<p>Because I&#8217;ll be deploying a new server in the near future and I want to keep it as clean as possible I decided (again) to try to find out how to create a .deb package (as used for example by <a href="http://www.debian.org">Debian</a> and <a href-"http://www.ubuntu.com">Ubuntu</a> Linux) for some software that doesn&#8217;t follow the autotools way of doing things. This time I found a/the way. But first some background info.</p>
<p>In the Unix/Linux world many programs are compiled from source in three steps:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>configure
<span style="color: #c20cb9; font-weight: bold;">make</span>
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div>

<p>Usually the necessary files for this have been created using the <a href="http://www.gnu.org/software/hello/manual/automake/Autotools-Introduction.html#Autotools-Introduction">autotools</a>. The goal of the first step is to create a so-called <code>Makefile</code> that contains instructions on how to compile and install the files (as done in the two subsequent <code>make</code> steps.</p>
<p>Some software packages, however, include a ready-made <code>Makefile</code> that, in addition, doesn&#8217;t accept the environment variable <code>DESTDIR</code>. This last point is what makes packaging the application into a .deb file a bit tricky. The reason for this is that the package build scripts want to install the files of your application in a temporary directory and not into system-wide directories like <code>/usr/bin/</code> etc. during the packing process. As such, packaging does not require root privileges.</p>
<p>At work we use many programs and tool sets developed by ourselves and other scientists. I know from my own experience that setting up autotools for your program is not trivial. Actually, for lack of time I&#8217;ve never successfully done it and for most of the rather simple programs that I&#8217;ve written setting up a complete autoconf/automake environment seems a bit overkill. I usually ended up writing a simple <code>Makefile</code> that compiles to code and installs it (usually in <code>/usr/local/bin</code>).</p>
<p><a href="http://www.sph.umich.edu/csg/abecasis/merlin/index.html">Merlin</a> by Abecasis <i>et al</i>. is a great piece of software developed at the University of Michigan. However, as you may have expected by now, its <code>Makefile</code> does not accept the <code>DESTDIR</code> variable, instead running <code>make</code> tells you that in order to install in a different directory you&#8217;ll have to run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #007800;">INSTALLDIR</span>=<span style="color: #000000; font-weight: bold;">/</span>some<span style="color: #000000; font-weight: bold;">/</span>other<span style="color: #000000; font-weight: bold;">/</span>directory</pre></div></div>

<p>Therefore, all quick and dirty .deb recipes one finds on the Internet do not work without some adaptations. So here is what I did to make a .deb of it. It won&#8217;t be a full tutorial on how to do packaging, see the references at the end of this post for that. I&#8217;ll assume here that you have your build environment set up (e.g. the <code>build-essential</code> and <code>fakeroot</code> packages, as well as some others).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xzf</span> merlin-1.1.2.tar.gz
<span style="color: #7a0874; font-weight: bold;">cd</span> merlin-1.1.2
dh_make <span style="color: #660033;">--single</span> <span style="color: #660033;">--email</span> youremail<span style="color: #000000; font-weight: bold;">@</span>address <span style="color: #660033;">--file</span> ..<span style="color: #000000; font-weight: bold;">/</span>merlin-1.1.2.tar.gz</pre></div></div>

<p>Now the basic files are ready. Apart from the untarred source files the files needed for Debian packaging have also been created (in <code>merlin-1.1.2/debian</code>).</p>
<p>Time to make the necessary changes. First, since the Makefile included with merlin does not accept the <code>DESTDIR</code> variable that the Debian packaging system uses we&#8217;ll patch the Makefile in such a way that it works (I tried to fix this in the <code>debian/control</code> file, but in the end adapting the <code>Makefile</code> was much easier). I do this by changing the line</p>

<div class="wp_syntax"><div class="code"><pre class="make" style="font-family:monospace;">INSTALLDIR<span style="color: #004400;">=/</span>usr<span style="color: #004400;">/</span>local<span style="color: #004400;">/</span>bin</pre></div></div>

<p>to</p>

<div class="wp_syntax"><div class="code"><pre class="make" style="font-family:monospace;"><span style="color: #339900; font-style: italic;"># default installation directory</span>
<span style="color: #666622; font-weight: bold;">ifeq</span> <span style="color: #004400;">&#40;</span><span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">DESTDIR</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">,</span><span style="color: #CC2200;">&quot;&quot;</span><span style="color: #004400;">&#41;</span>
    INSTALLDIR<span style="color: #004400;">=/</span>usr<span style="color: #004400;">/</span>local<span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>
<span style="color: #666622; font-weight: bold;">else</span>
    INSTALLDIR<span style="color: #004400;">=$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">DESTDIR</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">/</span>usr<span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>
<span style="color: #666622; font-weight: bold;">endif</span></pre></div></div>

<p>Let&#8217;s do some polishing of the package. I don&#8217;t want to make the perfect package, but adding a bit of text to the <code>debian/control</code> file make a lot of difference. This is what it looked like after my edits:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Source: merlin
Section: science
Priority: extra
Maintainer: Lennart C. Karssen &lt;youremail@address&gt;
Build-Depends: debhelper (&gt;= 7)
Standards-Version: 3.8.3
Homepage: http://www.sph.umich.edu/csg/abecasis/merlin/index.html
&nbsp;
Package: merlin
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Package for fast pedigree analysis
 MERLIN uses sparse trees to represent gene flow in pedigrees
 and is one of the fastest pedigree analysis packages around
 (Abecasis et al, 2002).</pre></div></div>

<p>Also editing the file <code>debian/changelog</code> is a good idea, especially since I changed the source code (remember the <code>Makefile</code>?). This is what I wrote:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">merlin (1.1.2-1) unstable; urgency=low
&nbsp;
  * Initial release
  * Adjusted Makefile to make DESTDIR work.
&nbsp;
 -- Lennart C. Karssen &lt;youremail@address&gt;  Tue, 05 Apr 2011 12:04:21 +0200</pre></div></div>

<p>Officially you should edit the <code>debian/copyright</code> file as well, but since the merlin licence doesn&#8217;t allow distribution of the source or the binaries I didn&#8217;t bother.</p>
<p>To finally build the package run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">dpkg-buildpackage <span style="color: #660033;">-rfakeroot</span> <span style="color: #660033;">-us</span> <span style="color: #660033;">-uc</span></pre></div></div>

<p>This creates a <code>.deb</code> file in the directory where you started. As a final touch you can check your package for errors with</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">lintian ..<span style="color: #000000; font-weight: bold;">/</span>merlin_1.1.2-<span style="color: #000000;">1</span>_amd64.deb</pre></div></div>

<p>References:</p>
<ul>
<li>
<a href="http://www.debian.org/doc/maint-guide">http://www.debian.org/doc/maint-guide</a>
</li>
<li>
<a href="http://www.debian-administration.org/articles/337">http://www.debian-administration.org/articles/337</a>
</li>
<li>
<a href="http://www.webupd8.org/2010/01/how-to-create-deb-package-ubuntu-debian.html">http://www.webupd8.org/2010/01/how-to-create-deb-package-ubuntu-debian.html</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2011/04/06/making-a-deb-package-for-software-that-doesnt-accept-the-destdir-variable-in-its-makefile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using rsync to backup to a remote Synology Diskstation</title>
		<link>http://blog.karssen.org/2011/02/06/using-rsync-to-backup-to-a-remote-synology-diskstation/</link>
		<comments>http://blog.karssen.org/2011/02/06/using-rsync-to-backup-to-a-remote-synology-diskstation/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 20:54:36 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=108</guid>
		<description><![CDATA[I recently bought a NAS, a Synology DiskStation DS211j and stuffed two 1TB disks in it. I configured the disks to be in RAID 1 (mirrored) in case one of them decides to die. I then brought the NAS to a family member&#8217;s house and installed it there. Now she uses it to back up [...]]]></description>
			<content:encoded><![CDATA[<p>I recently bought a NAS, a <a href="http://www.synology.com/nld/products/DS211j/index.php"> Synology DiskStation DS211j</a> and stuffed two 1TB disks in it. I configured the disks to be in RAID 1 (mirrored) in case one of them decides to die. I then brought the NAS to a family member&#8217;s house and installed it there. Now she uses it to back up her important files (and as a storage tank for music and videos).</p>
<p>The good thing for me is that I can now make off-site backups of my home directories. I configured the DS211j to accept SSH connections so that I can log into it (as user admin or root). I used the web interface to create a directory for my backups (which appeared to be <code>/volume1/BackupLennart</code> after logging in with SSH).</p>
<p>After making a hole in her firewall that allowed me to connect to the DS211j, I created a backup script in <code>/etc/cron.daily</code> with the following contents:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># This script makes a backup of my home dirs to a Synology DiskStation at</span>
<span style="color: #666666; font-style: italic;"># another location. I use LVM for my /home, so I make a snapshot first and</span>
<span style="color: #666666; font-style: italic;"># backup from there.</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Time-stamp: &lt;2011-02-06 21:30:14 (lennart)&gt;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">###############################</span>
<span style="color: #666666; font-style: italic;"># Some settings</span>
<span style="color: #666666; font-style: italic;">###############################</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># LVM options</span>
<span style="color: #007800;">VG</span>=raidvg01
<span style="color: #007800;">LV</span>=home
<span style="color: #007800;">MNTDIR</span>=<span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>home_rsync_snapshot<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># rsync options</span>
<span style="color: #007800;">DEST</span>=root<span style="color: #000000; font-weight: bold;">@</span>remote-machine.example.com:<span style="color: #000000; font-weight: bold;">/</span>volume1<span style="color: #000000; font-weight: bold;">/</span>BackupLennart<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #007800;">SRC</span>=<span style="color: #800000;">${MNTDIR}</span><span style="color: #000000; font-weight: bold;">/*</span>
<span style="color: #007800;">OPTIONS</span>=<span style="color: #ff0000;">&quot;-e ssh --delete --progress -azvhHS --numeric-ids --delete-excluded &quot;</span>
<span style="color: #007800;">EXCLUSIONS</span>=<span style="color: #ff0000;">&quot;--exclude lost+found --exclude .thumbnails --exclude .gvfs --exclude .cache --exclude Cache&quot;</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">###############################</span>
<span style="color: #666666; font-style: italic;"># The real work</span>
<span style="color: #666666; font-style: italic;">###############################</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Create the LVM snapshot</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$MNTDIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #666666; font-style: italic;"># If the snapshot directory exists, another backup process may be</span>
    <span style="color: #666666; font-style: italic;"># running</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$MNTDIR</span> already exists! Another backup still running?&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #660033;">-1</span>
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #666666; font-style: italic;"># Let's make snapshots</span>
    <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #007800;">$MNTDIR</span>
    lvcreate <span style="color: #660033;">-L5G</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-n</span> snap<span style="color: #007800;">$LV</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VG</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$LV</span>
    <span style="color: #c20cb9; font-weight: bold;">mount</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VG</span><span style="color: #000000; font-weight: bold;">/</span>snap<span style="color: #007800;">$LV</span> <span style="color: #007800;">$MNTDIR</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Do the actual backup</span>
rsync <span style="color: #007800;">$OPTIONS</span> <span style="color: #007800;">$EXCLUSIONS</span> <span style="color: #007800;">$SRC</span> <span style="color: #007800;">$DEST</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Remove the LVM snapshot</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$MNTDIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #c20cb9; font-weight: bold;">umount</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VG</span><span style="color: #000000; font-weight: bold;">/</span>snap<span style="color: #007800;">$LV</span>
    lvremove <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$VG</span><span style="color: #000000; font-weight: bold;">/</span>snap<span style="color: #007800;">$LV</span>
    <span style="color: #c20cb9; font-weight: bold;">rmdir</span> <span style="color: #007800;">$MNTDIR</span>
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$MNTDIR</span> does not exist!&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #660033;">-1</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Let&#8217;s walk through it: in the first section I configure several variables. Since I use LVM on my server, I can use it to make a snapshot of my /home partition. The LVM volume group I use is called &#8216;raidvg01&#8242;. Withing that VG my /home partition resides in a logical volume called &#8216;home&#8217;. The variable <code>MNTDIR</code> is the place where I mount the LVM snapshot of &#8216;home&#8217;.</p>
<p>The rsync options are quite straight forward. Check the rsync man page to find out what they mean. Note that I used the <code>--numeric-ids</code> option because the DS211j doesn&#8217;t have the same users as my server and this way all ownerships will still be correct if I ever need to restore from this backup.</p>
<p>In the section called &#8220;The real work&#8221; I first create the <code>MNTDIR</code> directory. Subsequently I create the LVM snapshot and mount it. After this the rsync backup can be run and finally I unmount the snapshot and remove it, followed by the removal of the <code>MNTDIR</code>.</p>
<p>Since the script is placed in <code>/etc/cron.daily</code> it will be executed every day. Since we use SSH to connect to the remote DS211j I set up SSH key access without a password. <a href="http://www.debian-administration.org/article/SSH_with_authentication_key_instead_of_password">This Debian howto</a> will tell you how to set that up.</p>
<p>The only thing missing in this setup is that the backups are not stored in an encrypted form on the remote NAS, but for now this is good enough. I can&#8217;t wait until the network bandwidth on both sides of this backup connection get so fast (and affordable) that I can easily sync my music as well. Right now uploads are so slow that I hardly dare to include those. I know that I shouldn&#8217;t complain since the Netherlands has one of the highest broadband penetrations in the world, but, hey, don&#8217;t you just always want a little more, just like Oliver Twist?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2011/02/06/using-rsync-to-backup-to-a-remote-synology-diskstation/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Recompiling the quota package in CentOS so that it can use LDAP to find email adresses</title>
		<link>http://blog.karssen.org/2010/10/19/recompiling-the-quota-package-in-centos-so-that-it-can-use-ldap-to-find-email-adresses/</link>
		<comments>http://blog.karssen.org/2010/10/19/recompiling-the-quota-package-in-centos-so-that-it-can-use-ldap-to-find-email-adresses/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 22:42:50 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[CentOS/RHEL]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=96</guid>
		<description><![CDATA[Today I compiled my first RPM package from source ! But let&#8217;s start at the beginning&#8230; At work I recently implemented disk quota on our server. While trying to setup /etc/warnquota.conf I noticed the example lines at the bottom that showed how to configure warnquota to look up e-mail addresses in an LDAP directory. This [...]]]></description>
			<content:encoded><![CDATA[<p>Today I compiled my first RPM package from source <img src='http://blog.karssen.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ! But let&#8217;s start at the beginning&#8230;</p>
<p>At work I recently implemented disk quota on our server. While trying to setup <code>/etc/warnquota.conf</code> I noticed the example lines at the bottom that showed how to configure warnquota to look up e-mail addresses in an LDAP directory. This was exactly what I needed, because we store our user&#8217;s e-mail address in our LDAP tree. Without this feature warnquota would try to send its warning mails to <code>user@our-server.example.com</code> instead of <user@example.com> (or even other addresses for guests that only visit us for a few weeks). The lines in <code>/etc/warnquota.conf</code> were:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">LDAP_MAIL = true
LDAP_HOST = ldap.example.com
LDAP_PORT = 389
LDAP_BASEDN = ou=Users,dc=example,dc=com
LDAP_SEARCH_ATTRIBUTE = uid
LDAP_MAIL_ATTRIBUTE = mail
LDAP_DEFAULT_MAIL_DOMAIN = example.com</pre></div></div>

<p>So, after saving the file I tested it by running  <code>warnquota -s</code> (as root, and I also made sure I reduced my own quota so I would be the one getting an e-mail warning).</p>
<p>Unfortunately warnquota spitted out some errors:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">warnquota: Error in config file (line 65), ignoring
warnquota: Error in config file (line 66), ignoring
warnquota: Error in config file (line 67), ignoring
warnquota: Error in config file (line 68), ignoring
warnquota: Error in config file (line 69), ignoring
warnquota: Error in config file (line 70), ignoring
warnquota: Warning: Mailer exitted abnormally.</pre></div></div>

<p>These were the line numbers with the LDAP options above <img src='http://blog.karssen.org/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> . Google pointed me to <a href="https://bugzilla.redhat.com/show_bug.cgi?id=133207">an old bug in Fedora</a> that was marked as resolved. I also found out that the quota tools should be compiled with LDAP support for this to work. To be sure that it was actually possible I configured warnquota on my home server that runs Ubuntu 10.04 and also uses LDAP. There, it all worked as expected.</p>
<p>So, my next step was clear: make my own RPM package for <code>quota</code>. The one installed by CentOS 5.4 is <code>quota-3.13-1.2.5.el5</code>. These are the steps I took:</p>
<ul>
<li>Enable the CentOS source repository by creating the file <code>etc/yum.repos.d/CentOS-Source.repo</code> with this contents:

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">[centos-src]
name=CentOS $releasever - $basearch - Source
baseurl=http://mirror.centos.org/centos/$releasever/os/SRPMS/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5</pre></div></div>

<p>The run <code>yum update</code> and check that the new repository is listed.</p>
<li>Install the <code>yum-utils</code> and <code>rpmdevtools</code> packages: <code>sudo yum install yum-utils rpmdevtools</code>.
<li>Set up a directory to do your build work in. I created the directory <code>~/tmp/pkgtest</code>.
<li>Run <code>rpmdev-setuptree</code> to create the required sub directories.
<li>Set the basic build configuration by creating the file <code>~/.rpmmacros</code> with the following contents:

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;"># Path to top of build area
%_topdir    /home/lennart/tmp/pkgtest</pre></div></div>

<li>Go into the SRPMS directory and download the source package: <code>yumdownloader --source quota</code>
<li>In the top level directory run <code>rpm -i SRPMS/quota-3.13-1.2.5.el5.src.rpm</code> to unpack the package.
<li>The <code>SPECS</code> directory now contains the <code>.spec file</code> that contains the build instructions. The <code>SOURCES</code> directory contains the source files and patches from Red Hat. In a temporary directory I untar-ed the quotatools source tar.gz file and ran <code>./configure --help</code> to find out which option I should add to the spec file in order to enable LDAP lookup. The option was: <code>--enable-ldapmail=yes</code>. The set of configure lines in the spec file now looked like this:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span>build
<span style="color: #000000; font-weight: bold;">%</span>configure \
	--with-ext2<span style="color: #007800;">direct</span>=no <span style="color: #660033;">--enable-rootsbin</span> <span style="color: #660033;">--enable-ldapmail</span>=<span style="color: #c20cb9; font-weight: bold;">yes</span>
<span style="color: #c20cb9; font-weight: bold;">make</span></pre></div></div>

<p>In the spec file I also added a changelog entry:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">* Mon Oct 18 2010 Lennart Karssen &lt;lennart@karssen.org 1:3.13-1.2.6
- Added --enable-ldapmail=try to the ./configure line to enable LDAP
  for looking up mail addresses. (Resolves Red Hat Bugzilla 133207,
  it is marked as resolved there, but apparently was reintroduced.)</pre></div></div>

<p>And I also bumped the build version number at the top of the file (the <code>Release:</code> line). Finally, I added <code>openldap-devel</code> to the <code>BuildPreReq</code> line (of course I ran into a compilation error first and then installed the <code>openldap-devel</code> package <img src='http://blog.karssen.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<li>Now it&#8217;s time to build the package. In the <code>SPEC</code> directory run: <code>rpmbuild -bb quota.spec</code> and wait. The RPM package is created in the <code>RPMS</code> directory.
<li>Install the package: <code>sudo rpm -Uvh RPMS/x86_64/quota-3.13-1.2.6.x86_64.rpm</code> (if you didn&#8217;t bump the package version number the <code>--replacepkgs</code> must be added to &#8216;upgrade&#8217; to the same version).
</ul>
<p>And that was it! The package installed cleanly and a test run of <code>warnquota -s</code> was successful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2010/10/19/recompiling-the-quota-package-in-centos-so-that-it-can-use-ldap-to-find-email-adresses/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nagios event handlers for services on remote machines</title>
		<link>http://blog.karssen.org/2010/09/14/nagios-event-handlers-for-services-on-remote-machines/</link>
		<comments>http://blog.karssen.org/2010/09/14/nagios-event-handlers-for-services-on-remote-machines/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 13:44:28 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=85</guid>
		<description><![CDATA[Part of my work consists of managing the servers on which we do our data analysis. At the moment we&#8217;ve got two servers and one virtual machine running. The VM is used as a management server, it runs things like Nagios, Cacti, Subversion, etc. Today I implemented Nagios event handlers in this setup. The idea [...]]]></description>
			<content:encoded><![CDATA[<p>Part of my work consists of managing the servers on which we do our data analysis. At the moment we&#8217;ve got two servers and one virtual machine running. The VM is used as a management server, it runs things like Nagios, Cacti, Subversion, etc. </p>
<p>Today I implemented Nagios event handlers in this setup. The idea behind an event handler is the following: If e.g. a service goes down, Nagios should try to solve this problem itself before notifying the administrator (me). It should, in this case, simply try to restart the service.</p>
<p>The Nagios documentation [<a href="#ref1">1</a>] describes how to do this for a service that runs on the same machine as the Nagios service. In my case, however, the services are running on the to real servers. To me it seemed logical to use NRPE to execute the necessary commands on the remote hosts (since NRPE was already running on those machines anyway).<br />
In order to adapt the scheme from the Nagios docs to work on remote servers as well three things need to be done:</p>
<ul>
<li>The command that is executed by the event handler script should be changed to use NRPE
<li>On the remote machine the <code>nagios</code> user (under which the NRPE service is running) should be given some sudo rights so that it is actually allowed to start a service.
<li>The NRPE configuration on the remote machine should of course be changed to include the new command(s) for starting services.
</ul>
<p>So here we go! First, the Nagios configuration on the management host. In the service definition file I added one line for the event handler to each service. The definition of one service now looks like this (the last line was added):</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">define service {
       use                      generic-service
       hostgroup_name           sge-exec-servers
       service_description      SGE execd
       check_command            check_nrpe_1arg!check_sge_execd
       notification_interval    0 ; set &gt; 0 if you want to be renotified
       event_handler            restart-service!sge-execd
}</pre></div></div>

<p>Next, the <code>restart-service</code> command must be defined. I did that in a file that I called <code>/etc/nagios3/conf.d/event-handlers.cfg</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">define command {
       command_name     restart-service
       command_line     /etc/nagios3/conf.d/event_handler_script.sh $SERVICESTATE$ $SERVICESTATETYPE $ $SERVICEATTEMPT$ $HOSTADDRESS$ $ARG1$ $SERVICEDESC$
}</pre></div></div>

<p>The variable <code>$ARG1$</code> here is the name of the service that needs to be restarted. In this example it is <code>sge-execd</code> from the <code>event_handler</code> line in the service definition. The <code>$HOSTADDRESS</code> will be used in the event handler script to send the right host name to NRPE.<br />
The <code>event_handler_script.sh</code> referenced here is almost identical to the one in the Nagios documentation. As mentioned in the plan above, I changed it slightly so that it uses NRPE.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh                                                                                            </span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Event handler script for restarting the nrpe server on the local machine</span>
<span style="color: #666666; font-style: italic;"># Taken from the Nagios documentation and</span>
<span style="color: #666666; font-style: italic;"># http://www.techadre.com/sites/techadre.com/files/event_handler_script_0.txt</span>
<span style="color: #666666; font-style: italic;"># Adapted by L.C. Karssen</span>
<span style="color: #666666; font-style: italic;"># Time-stamp: &lt;2010-09-14 15:24:33 (root)&gt;</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Note: This script will only restart the nrpe server if the service is</span>
<span style="color: #666666; font-style: italic;">#       retried 3 times (in a &quot;soft&quot; state) or if the web service somehow</span>
<span style="color: #666666; font-style: italic;">#       manages to fall into a &quot;hard&quot; error state.</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #007800;">date</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># What state is the NRPE service in?</span>
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
OK<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #666666; font-style: italic;"># The service just came back up, so don't do anything...</span>
        <span style="color: #000000; font-weight: bold;">;;</span>
WARNING<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #666666; font-style: italic;"># We don't really care about warning states, since the service is probably still running...</span>
        <span style="color: #000000; font-weight: bold;">;;</span>
UNKNOWN<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #666666; font-style: italic;"># We don't know what might be causing an unknown error, so don't do anything...</span>
        <span style="color: #000000; font-weight: bold;">;;</span>
CRITICAL<span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #666666; font-style: italic;"># Aha!  The BLAH service appears to have a problem - perhaps we should restart the server...</span>
&nbsp;
        <span style="color: #666666; font-style: italic;"># Is this a &quot;soft&quot; or a &quot;hard&quot; state?</span>
        <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$2&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
&nbsp;
        <span style="color: #666666; font-style: italic;"># We're in a &quot;soft&quot; state, meaning that Nagios is in the middle of retrying the</span>
        <span style="color: #666666; font-style: italic;"># check before it turns into a &quot;hard&quot; state and contacts get notified...</span>
        SOFT<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                <span style="color: #666666; font-style: italic;"># What check attempt are we on?  We don't want to restart the web server on the firs\</span>
t
                <span style="color: #666666; font-style: italic;"># check, because it may just be a fluke!</span>
                <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$3&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
&nbsp;
                <span style="color: #666666; font-style: italic;"># Wait until the check has been tried 3 times before restarting the web server.</span>
                <span style="color: #666666; font-style: italic;"># If the check fails on the 4th time (after we restart the web server), the state</span>
                <span style="color: #666666; font-style: italic;"># type will turn to &quot;hard&quot; and contacts will be notified of the problem.</span>
                <span style="color: #666666; font-style: italic;"># Hopefully this will restart the web server successfully, so the 4th check will</span>
                <span style="color: #666666; font-style: italic;"># result in a &quot;soft&quot; recovery.  If that happens no one gets notified because we</span>
                <span style="color: #666666; font-style: italic;"># fixed the problem!</span>
                <span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Restarting service $6 (3rd soft critical state)...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
                        <span style="color: #666666; font-style: italic;"># Call NRPE to restart the service on the remote machine</span>
                        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>check_nrpe <span style="color: #660033;">-H</span> <span style="color: #007800;">$4</span> <span style="color: #660033;">-c</span> restart-<span style="color: #007800;">$5</span>
                        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$date</span> - restart $6 - SOFT&quot;</span>  <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>eventhandlers
                        <span style="color: #000000; font-weight: bold;">;;</span>
                        <span style="color: #000000; font-weight: bold;">esac</span>
                <span style="color: #000000; font-weight: bold;">;;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;"># The service somehow managed to turn into a hard error without getting fixed.</span>
        <span style="color: #666666; font-style: italic;"># It should have been restarted by the code above, but for some reason it didn't.</span>
        <span style="color: #666666; font-style: italic;"># Let's give it one last try, shall we?</span>
        <span style="color: #666666; font-style: italic;"># Note: Contacts have already been notified of a problem with the service at this</span>
        <span style="color: #666666; font-style: italic;"># point (unless you disabled notifications for this service)</span>
        HARD<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$3&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
&nbsp;
                <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Restarting $6 service...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
                        <span style="color: #666666; font-style: italic;"># Call the init script to restart the NRPE server</span>
                        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$date</span> - restart $6 - HARD&quot;</span>  <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>eventhandlers
                        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>check_nrpe <span style="color: #660033;">-H</span> <span style="color: #007800;">$4</span> <span style="color: #660033;">-c</span> restart-<span style="color: #007800;">$5</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
                        <span style="color: #000000; font-weight: bold;">esac</span>
                <span style="color: #000000; font-weight: bold;">;;</span>
        <span style="color: #000000; font-weight: bold;">esac</span>
        <span style="color: #000000; font-weight: bold;">;;</span>
<span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>Now Nagios can be restarted and should continue its work as usual. Time to make the changes on the remote hosts.</p>
<p>First, we&#8217;ll grant the necessary sudo rights to the <code>nagios</code> user. Run <code>visudo</code> and add these lines:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">## Allow NRPE to restart sevices
User_Alias NAGIOS = nagios,nagcmd
Cmnd_Alias NAGIOSCOMMANDS = /usr/sbin/service
Defaults:NAGIOS !requiretty
NAGIOS    ALL=(ALL)    NOPASSWD: NAGIOSCOMMANDS</pre></div></div>

<p>And finally add the required lines in the NRPE config file (<code>/etc/nagios/nrep.cfg</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">command[restart-sge-execd]=/usr/bin/sudo /usr/sbin/service gridengine-exec start</pre></div></div>

<p>Restart the NRPE daemon and it should all work. Test it by manually stopping the service.</p>
<p>[<a name="ref1">1</a>] <a href="http://nagios.sourceforge.net/docs/3_0/eventhandlers.html">Nagios documentation on Event Handlers</a><br />
[2] <a href="http://www.techadre.com/content/nagios-event-handler-restarting-service">Two</a> blog <a href="http://www.techadre.com/content/nagios-event-handler-restart-remote-service">posts</a> that describe a similar set up. I used these as a starting point for my own set up. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2010/09/14/nagios-event-handlers-for-services-on-remote-machines/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Script that converts a Squirrelmail address book to vcf format</title>
		<link>http://blog.karssen.org/2010/05/24/script-that-converts-a-squirrelmail-address-book-to-vcf-format/</link>
		<comments>http://blog.karssen.org/2010/05/24/script-that-converts-a-squirrelmail-address-book-to-vcf-format/#comments</comments>
		<pubDate>Mon, 24 May 2010 16:14:51 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=60</guid>
		<description><![CDATA[Today I installed Roundcube as a replacement for my Squirrelmail webmail setup. All went well, but Roundcube only accepts adresses in vCard format (.vcf-format), whereas Squirrelmail only exports in CSV format. To solve this I wrote the following script that converts a Squirrelmail address book to vCard format. The results are sent to stdout, so [...]]]></description>
			<content:encoded><![CDATA[<p>Today I installed <a href="http://www.roundcude.net">Roundcube</a> as a replacement for my <a href="http://www.squirrelmail.org">Squirrelmail</a> webmail setup. All went well, but Roundcube only accepts adresses in vCard format (<code>.vcf</code>-format), whereas Squirrelmail only exports in CSV format. To solve this I wrote the following script that converts a Squirrelmail address book to vCard format. The results are sent to <code>stdout</code>, so run it like this: <code>abook2vcf.awk user@example.com.abook > my_addresses.vcf</code>.<br />
On my Debian install the Squirrelmail address books (files ending in <code>.abook</code> are located in <code>/var/lib/squirrelmail/data</code>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/awk</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># This script converts a Squirrelmail address book to </span>
<span style="color: #666666; font-style: italic;"># vcards for import in Roundcube for example.</span>
BEGIN<span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">FS</span>=<span style="color: #ff0000;">&quot;|&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
    full_name  = <span style="color: #007800;">$1</span>;
    first_name = <span style="color: #007800;">$2</span>;
    last_name  = <span style="color: #007800;">$3</span>;
    email      = <span style="color: #007800;">$4</span>;
&nbsp;
    print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;BEGIN:VCARD&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
    print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;VERSION:3.0&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
    <span style="color: #7a0874; font-weight: bold;">printf</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;FN:%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, full_name<span style="color: #7a0874; font-weight: bold;">&#41;</span>;
    <span style="color: #7a0874; font-weight: bold;">printf</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;N:%s;%s;;;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, last_name, first_name<span style="color: #7a0874; font-weight: bold;">&#41;</span>;
    <span style="color: #7a0874; font-weight: bold;">printf</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;EMAIL;type=INTERNET;type=HOME;type=pref:%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, email<span style="color: #7a0874; font-weight: bold;">&#41;</span>;
    print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;END:VCARD&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2010/05/24/script-that-converts-a-squirrelmail-address-book-to-vcf-format/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Windows AD for Apache authentication</title>
		<link>http://blog.karssen.org/2010/03/03/using-windows-ad-for-apache-authentication/</link>
		<comments>http://blog.karssen.org/2010/03/03/using-windows-ad-for-apache-authentication/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 17:00:29 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=59</guid>
		<description><![CDATA[Recently I was setting up a Subversion repository (on a Linux server) that needs to be accessed via HTTP. Users should be able connect to the repositories without authentication, but authentication is needed to perform write actions. Of course Apache&#8217;s htpasswd/htaccess combination would provide just that, but since we have a Windows 2008 Active Domain [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was setting up a <a href="http://subversion.tigris.org">Subversion</a> repository (on a Linux server) that needs to be <a href="http://svnbook.red-bean.com/nightly/en/svn.serverconfig.choosing.html#svn.serverconfig.choosing.apache">accessed via HTTP</a>. Users should be able connect to the repositories without authentication, but authentication is needed to perform write actions. Of course Apache&#8217;s <code>htpasswd/htaccess</code> combination would provide just that, but since we have a Windows 2008 Active Domain controller that provides authentication to our Windows machines I thought it would be a good idea to use it. </p>
<p>Configuration of the autentication and authorization is done by <a href="http://httpd.apache.org/docs/trunk/mod/mod_authnz_ldap.html">Apache&#8217;s mod_authnz_ldap</a> and (on Red Hat EL) configured in <code>/etc/httpd/conf.d/subversion.conf</code> (which exists after installing the subversion package with <code>yum</code>. </p>
<p><strong>Basic configuration with htaccess</strong><br />
For simple authentication with Apache&#8217;s htaccess mechanism the config looks like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">LoadModule</span> dav_svn_module     modules/mod_dav_svn.so
<span style="color: #00007f;">LoadModule</span> authz_svn_module   modules/mod_authz_svn.so
&nbsp;
&lt;<span style="color: #000000; font-weight:bold;">Location</span> /repos&gt;
   <span style="color: #00007f;">DAV</span> svn
   <span style="color: #00007f;">SVNParentPath</span> /var/www/svn
   <span style="color: #00007f;">SVNReposName</span> <span style="color: #7f007f;">&quot;My company's repository&quot;</span>
&nbsp;
   <span style="color: #adadad; font-style: italic;"># Limit write permission to list of valid users.</span>
   &lt;<span style="color: #000000; font-weight:bold;">LimitExcept</span> GET PROPFIND <span style="color: #00007f;">OPTIONS</span> REPORT&gt;
      <span style="color: #00007f;">AuthType</span> Basic
      <span style="color: #00007f;">AuthName</span> <span style="color: #7f007f;">&quot;Authorization Realm for SVN&quot;</span>
      <span style="color: #00007f;">AuthUserFile</span> /etc/httpd/conf.d/svn_htpasswd
      <span style="color: #00007f;">Require</span> valid-<span style="color: #00007f;">user</span>
&nbsp;
   &lt;/<span style="color: #000000; font-weight:bold;">LimitExcept</span>&gt;
&lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;</pre></td></tr></table></div>

<p>After using <code>htpasswd</code> to create a file with usernames and passwords on the server users could commit to the repository.</p>
<p><strong>Configuration for AD Global Catalog</strong><br />
The first LDAP-like construction I got working was when using the AD Global Catalog. Normal LDAP traffic uses port 389, but the AD&#8217;s Global Catalog uses port 3268. The username needed to commit with SVN is <code>windows_logon_name@your_AD.suffix</code>, the so-called <code>userPrincipalName</code>. Here, <code>your_AD</code> and <code>suffix</code> are the DC&#8217;s of the LDAP/AD tree. By using this userPrincipalName users from different DC trees can be authenticated. The configuration file looks this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">LoadModule</span> dav_svn_module     modules/mod_dav_svn.so
<span style="color: #00007f;">LoadModule</span> authz_svn_module   modules/mod_authz_svn.so
&nbsp;
&lt;<span style="color: #000000; font-weight:bold;">Location</span> /repos&gt;
    <span style="color: #00007f;">DAV</span> svn
    <span style="color: #00007f;">SVNParentPath</span> /var/www/svn
    <span style="color: #00007f;">SVNReposName</span> <span style="color: #7f007f;">&quot;My company's repository&quot;</span>
&nbsp;
    <span style="color: #adadad; font-style: italic;"># Limit write permission to list of valid users.</span>
    &lt;<span style="color: #000000; font-weight:bold;">LimitExcept</span> GET PROPFIND <span style="color: #00007f;">OPTIONS</span> REPORT&gt;
      <span style="color: #00007f;">AuthType</span> Basic
      <span style="color: #00007f;">AuthName</span> <span style="color: #7f007f;">&quot;Authorization using your LDAP account&quot;</span>
      <span style="color: #00007f;">AuthBasicProvider</span> ldap
      <span style="color: #00007f;">AuthzLDAPAuthoritative</span> <span style="color: #0000ff;">off</span>
      <span style="color: #adadad; font-style: italic;"># Active Directory requires an authenticating DN to access records</span>
      <span style="color: #00007f;">AuthLDAPBindDN</span> <span style="color: #7f007f;">&quot;svntest@your_AD.suffix&quot;</span>
&nbsp;
      <span style="color: #adadad; font-style: italic;"># This is the password for the AuthLDAPBindDN user in Active Directory</span>
      <span style="color: #00007f;">AuthLDAPBindPassword</span> <span style="color: #7f007f;">&quot;some_good_password&quot;</span>
&nbsp;
      <span style="color: #adadad; font-style: italic;"># The LDAP query URL</span>
      <span style="color: #00007f;">AuthLDAPURL</span> <span style="color: #7f007f;">&quot;ldap://ldap.your_company.com:3268/?userPrincipalName?sub&quot;</span>
      <span style="color: #00007f;">AuthUserFile</span> /dev/null
&nbsp;
      <span style="color: #adadad; font-style: italic;"># Require a valid user</span>
      <span style="color: #00007f;">Require</span> valid-<span style="color: #00007f;">user</span>
    &lt;/<span style="color: #000000; font-weight:bold;">LimitExcept</span>&gt;
&lt;/<span style="color: #000000; font-weight:bold;">Location</span>&gt;</pre></td></tr></table></div>

<p>With this configuration I could commit with this command: <code>svn commit -m "First AD test" --username your_windows_username@your_AD.suffix</code>.</p>
<p><strong>Configuration for AD + Windows logon Name</strong><br />
As mentioned earlier, the previous method allows people from different parts of the AD tree to log in. In order to restrict access to for example a specific OU, the <code>AuthLDAPURL</code> has to be changed. In our case the LDAP tree is not a simple <code>OU=Users,DC=our_company,DC=com</code>, but consists of several nested OU structures. I used the <code>adsiedit.msc</code> snapin (ADSI editor) on the AD controller to find out the exact structure, since I needed to find out which parts were CNs and which where OUs.<br />
In order to authenticate against a the windows login names in a certain sub-OU the <code>AuthLDAPURL</code> is</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">AuthLDAPURL</span> <span style="color: #7f007f;">&quot;ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1, DC=your_AD, DC=suffix?sAMAccountName?sub?(objectClass=*)&quot;</span></pre></div></div>

<p><strong>Configuration for AD + Windows Display Name</strong><br />
If you want the users to use their common name (the Display Name in the AD) use:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">AuthLDAPURL</span> <span style="color: #7f007f;">&quot;ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1 DC=your_AD, DC=suffix?cn&quot;</span></pre></div></div>

<p>Users can now commit with: <code>svn commit -m "Another AD test" --username "Firstname Lastname"</code>.</p>
<p><strong>Configuration for AD + another field</strong><br />
In our case login authentication on the Linux/UNIX machines is not done through the AD. Furthermore, the user names are not synchronised between Linux and Windows. This poses a small inconvenience, since by default an <code>svn commit</code> uses the Linux username. As the AD doesn&#8217;t know about this name, the first authentication fails. subsequently Apache asks for the user name, and then the user can enter his Windows AD credentials (principle name, display name or windows login name, depending on which of the above configurations was chosen). So as a quick workaround (and just to see if I could get it to work) I entered my Linux user name into the Office field in the AD. In the ADSI Editor I found the real name of the field: <code>physicalDeliveryOfficeName</code> With the following <code>AuthLDAPURL</code> I could use the Office field to authenticate me:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">AuthLDAPURL</span> <span style="color: #7f007f;">&quot;ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1 DC=your_AD, DC=suffix?physicalDeliveryOfficeName&quot;</span></pre></div></div>

<p>Now a simple <code>svn commit</code> works. </p>
<p><strong>Some useful links:</strong></p>
<ul>
<li><a href="http://httpd.apache.org/docs/trunk/mod/mod_authnz_ldap.html">Documentation of mod_authnz_ldap</a></li>
<li><a href="http://www.jejik.com/articles/2007/06/apache_and_subversion_authentication_with_microsoft_active_directory/">A blog post where I learned the basics</a></li>
<li><a href="http://blogs.open.collab.net/svn/2009/03/subversion-with-apache-and-ldap-updated.html">Another blog about SVN + AD, with a good commented example</a></li>
</ul>
</li>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2010/03/03/using-windows-ad-for-apache-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Script to tunnel RDP connections through stepping stone server using SSH</title>
		<link>http://blog.karssen.org/2010/02/10/script-to-tunnel-rdp-connections-through-a-stepping-stone-server-using-ssh/</link>
		<comments>http://blog.karssen.org/2010/02/10/script-to-tunnel-rdp-connections-through-a-stepping-stone-server-using-ssh/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 13:12:05 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=57</guid>
		<description><![CDATA[In order to connect to the servers at work we need to connect through a stepping stone host (via SSH). Since some of the servers are MS Windows machines which can be managed via the Remote Desktop Protocol (RDP), this traffic needs to be tunneled over SSH as well. I wrote the following bash script [...]]]></description>
			<content:encoded><![CDATA[<p>In order to connect to the servers at work we need to connect through a stepping stone host (via SSH). Since some of the servers are MS Windows machines which can be managed via the Remote Desktop Protocol (RDP), this traffic needs to be tunneled over SSH as well.<br />
I wrote the following bash script to automate setting up the tunnel. It sets some default variables and then looks for an available port between 1234 and 1254 (chosen completely arbitrarily) and uses it for the tunnel. Then it uses the <tt>rdesktop</tt> program to start the RDP connection.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># This script makes an ssh tunnel to a stepping stone server</span>
<span style="color: #666666; font-style: italic;"># and uses it to start an rdesktop connection to the machine </span>
<span style="color: #666666; font-style: italic;"># given as the first argument of the script. </span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># (C) L.C. Karssen</span>
<span style="color: #666666; font-style: italic;"># $Id: winremote.sh,v 1.14 2010/02/10 13:03:08 lennart Exp $</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># User-configurable variables</span>
<span style="color: #007800;">ssh_username</span>=your_steppingstone_username_here
<span style="color: #007800;">steppingstone</span>=steppingstone.your_company.com
<span style="color: #007800;">rdesktop_username</span>=your_windows_username_here
<span style="color: #007800;">rdesktop_domain</span>=your_windows_domain_here
<span style="color: #007800;">rdesktop_opts</span>=<span style="color: #ff0000;">&quot;-z -g 1024x768 -a 16&quot;</span>
<span style="color: #007800;">rdesktop_port</span>=<span style="color: #000000;">3389</span> <span style="color: #666666; font-style: italic;"># This is the standard MS rdesktop port</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># For ordinary users it should not be necessary to change anything below this line. </span>
<span style="color: #666666; font-style: italic;"># Some functions:</span>
usage<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt;EOF
Usage:
    $program [options] rdesktop_hostname 
&nbsp;
Make a remote desktop connection through an SSH tunnel.
&nbsp;
Options: 
    -h, --help                                   print this help message
    -s, --steppingstone steppingstone_hostname   set other stepping stone host
                                                   (default: $steppingstone)
    -t, --timeout sec                            set timeout (default: 1)
    -v, --verbose                                verbose output
     --version                                   print version
&nbsp;
Note that some customisations need to be made in the first few lines of this 
script (e.g. user names and other defaults)
EOF</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #007800;">program</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Command line option parsing. Shift all options </span>
<span style="color: #007800;">verbose</span>=
<span style="color: #007800;">timeout</span>=<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-gt</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span> 
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">in</span>
	<span style="color: #660033;">-v</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">--verbose</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">-d</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">--debug</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	    <span style="color: #007800;">verbose</span>=<span style="color: #c20cb9; font-weight: bold;">true</span>
	    <span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #660033;">--version</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'$Revision: 1.14 $'</span>
	    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
	    <span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #660033;">-t</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">--timeout</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	    <span style="color: #7a0874; font-weight: bold;">shift</span>
	    <span style="color: #007800;">timeout</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
	   <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$timeout</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	       <span style="color: #007800;">timeout</span>=<span style="color: #000000;">1</span>
	   <span style="color: #000000; font-weight: bold;">fi</span>
	   <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	       <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Timeout set to <span style="color: #007800;">$timeout</span>&quot;</span>
	   <span style="color: #000000; font-weight: bold;">fi</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">--steppingstone</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	   <span style="color: #7a0874; font-weight: bold;">shift</span>
	   <span style="color: #007800;">steppingstone</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
	   <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	       <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Steppingstone server is <span style="color: #007800;">$steppingstone</span>&quot;</span>
	   <span style="color: #000000; font-weight: bold;">fi</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #660033;">-h</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #660033;">--help</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	   usage
	   <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
	-<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	   <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;$0: invalid option $1&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
 	   usage
	   <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> 
	   <span style="color: #7a0874; font-weight: bold;">break</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
    <span style="color: #7a0874; font-weight: bold;">shift</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Server name (as seen on the steppingstone) that we want to connect to:</span>
<span style="color: #007800;">rdesktop_server</span>=<span style="color: #007800;">$1</span> 
&nbsp;
<span style="color: #666666; font-style: italic;">################### Config done, let's get to work ########################</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Simple usage description</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$rdesktop_server</span>&quot;</span> == <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Error: No rdesktop host given&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
    usage
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Find a free port on the local machine that we can use to connect through</span>
<span style="color: #007800;">min_port</span>=<span style="color: #000000;">1234</span>
<span style="color: #007800;">max_port</span>=<span style="color: #000000;">1254</span>
<span style="color: #007800;">used_ports</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">netstat</span> <span style="color: #660033;">-tan</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $4}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> 127.0.0.1 <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> -F: <span style="color: #ff0000;">'{print $2}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> -g<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Used ports are: <span style="color: #007800;">${used_ports[@]}</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># In the next line we first print the $used_ports as an array, but with </span>
<span style="color: #666666; font-style: italic;"># each port on a single line. This is then piped to an awk script that </span>
<span style="color: #666666; font-style: italic;"># puts all the values in an array and subsequently walks through all ports </span>
<span style="color: #666666; font-style: italic;"># from $min_port to $max_port in order to find the first port that is not </span>
<span style="color: #666666; font-style: italic;"># in the array. This port is printed.</span>
<span style="color: #007800;">local_port</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;%i<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #800000;">${used_ports[@]}</span> <span style="color: #000000; font-weight: bold;">|</span> \
    <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-v</span> <span style="color: #007800;">minp</span>=<span style="color: #007800;">$min_port</span> <span style="color: #660033;">-v</span> <span style="color: #007800;">maxp</span>=<span style="color: #007800;">$max_port</span> \
    <span style="color: #ff0000;">'{ array[$1]=1 } END { for (i=minp; i&lt;=maxp; i++) { if (i in array) continue; else { print i; break } } }'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$local_port</span>&quot;</span> == <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Error: No ports free! Exiting...&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Selected port was: <span style="color: #007800;">$local_port</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Create tunnel:</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Creating SSH tunnel...&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #007800;">ssh_opts</span>=<span style="color: #ff0000;">&quot;-f -N -L&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #007800;">$ssh_opts</span> <span style="color: #007800;">$local_port</span>:<span style="color: #007800;">$rdesktop_server</span>:<span style="color: #007800;">$rdesktop_port</span> \
    <span style="color: #007800;">$ssh_username</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #007800;">$steppingstone</span> 
&nbsp;
<span style="color: #666666; font-style: italic;"># Allow the ssh tunnel to be established</span>
<span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #007800;">$timeout</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Abort if tunnel has not been established</span>
<span style="color: #007800;">pidof_ssh</span>=<span style="color: #000000; font-weight: bold;">`</span>pgrep <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;ssh <span style="color: #007800;">$ssh_opts</span> <span style="color: #007800;">$local_port</span>&quot;</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$pidof_ssh</span>&quot;</span> == <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Error: Timeout while establishing tunnel&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Exiting...&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Make rdesktop connection</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Opening Remote desktop connection to <span style="color: #007800;">$rdesktop_server</span>...&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
rdesktop <span style="color: #007800;">$rdesktop_opts</span> <span style="color: #660033;">-u</span> <span style="color: #007800;">$rdesktop_username</span> <span style="color: #660033;">-p</span> - \
    <span style="color: #660033;">-d</span> <span style="color: #007800;">$rdesktop_domain</span> localhost:<span style="color: #007800;">$local_port</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Clean up tunnel</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbose</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Cleaning up SSH tunnel with pid <span style="color: #007800;">$pidof_ssh</span> and local port <span style="color: #007800;">$local_port</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #007800;">$pidof_ssh</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2010/02/10/script-to-tunnel-rdp-connections-through-a-stepping-stone-server-using-ssh/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cloning Ubuntu virtual machines: some problems (and solutions)</title>
		<link>http://blog.karssen.org/2009/12/13/cloning-ubuntu-virtual-machines-some-problems-and-solutions/</link>
		<comments>http://blog.karssen.org/2009/12/13/cloning-ubuntu-virtual-machines-some-problems-and-solutions/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 13:33:09 +0000</pubDate>
		<dc:creator>LCK</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[qemu]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[virtual machine]]></category>

		<guid isPermaLink="false">http://blog.karssen.org/?p=55</guid>
		<description><![CDATA[Yesterday I set up a KVM virtual machine on my new Ubuntu 9.10 server. The VM also ran Ubuntu 9.10 server. In order to do some performance tests (what would be the speed up of having the VM&#8217;s disks on an LVM LV on the host, compared to having them in a file on the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I set up a KVM virtual machine on my new Ubuntu 9.10 server. The VM also ran Ubuntu 9.10 server. In order to do some performance tests (what would be the speed up of having the VM&#8217;s disks on an LVM LV on the host, compared to having them in a file on the host) I used virt-clone to clone the machine:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">virt-clone <span style="color: #660033;">--connect</span>=qemu:<span style="color: #000000; font-weight: bold;">///</span>system <span style="color: #660033;">-o</span> testldap <span style="color: #660033;">-n</span> testldap-lvm <span style="color: #660033;">-f</span> testldap-lvm<span style="color: #000000; font-weight: bold;">/</span>ubuntu-kvm<span style="color: #000000; font-weight: bold;">/</span>disk0.qcow2</pre></div></div>

<p>This clones the VM named <em>testldap</em> to <em>testldap-lvm</em> and put its disk file in the subdirectory <em>testldap-lvm/ubuntu-kvm/</em>. After that I still had to convert this qcow2 image to it&#8217;s location in an LV, but that&#8217;s not what this post is about. </p>
<p>As the machine is cloned, the MAC address of its virtual NIC is also changed. The &#8216;source&#8217; VM had 52:54:00:f2:cc:40, the new VM was given 00:16:36:46:34:42. As I booted the new VM I noticed it wouldn&#8217;t come up as expected. I couldn&#8217;t reach it via the fixed IP that I had given the source VM (even though the source VM was shut down, of course). Closer inspection revealed that the interface name for the NIC in the new VM had changed. I vaguely remembered that Debian-derived distro&#8217;s do that: because they don&#8217;t want NIC name assignments (eth0, eth1, etc.) to change if a new network adapter is added, they tie a name to a MAC address. And, as noted, the MAC address had indeed changed in the cloning process. </p>
<p>The assignments between MAC and <em>eth?</em> name are recorded in the file <em>/etc/udev/rules.d/70-persistent-net.rules</em>. They are set by the script <em>/lib/udev/write_net_rules</em>, so I removed the execute permissions on that file. However, this was not a clean solution, since it resulted in an error on start up. I found that editing <em>/lib/udev/rules.d/75-persistent-net-generator.rules</em> is a far better solution. Adding the lines</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># ignore KVM virtual interfaces</span>
ENV<span style="color: #7a0874; font-weight: bold;">&#123;</span>MATCHADDR<span style="color: #7a0874; font-weight: bold;">&#125;</span>==<span style="color: #ff0000;">&quot;52:54:00:*&quot;</span>, <span style="color: #007800;">GOTO</span>=<span style="color: #ff0000;">&quot;persistent_net_generator_end&quot;</span>
<span style="color: #666666; font-style: italic;"># This seems to be the range used by Xen, but also by virt-clone</span>
ENV<span style="color: #7a0874; font-weight: bold;">&#123;</span>MATCHADDR<span style="color: #7a0874; font-weight: bold;">&#125;</span>==<span style="color: #ff0000;">&quot;00:16:36:*&quot;</span>, <span style="color: #007800;">GOTO</span>=<span style="color: #ff0000;">&quot;persistent_net_generator_end&quot;</span></pre></div></div>

<p>seems to do the trick (don&#8217;t forget to remove the rules already added in <em>/etc/udev/rules.d/70-persistent-net.rules</em>). Make sure to add them after the lines</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># read MAC address</span>
ENV<span style="color: #7a0874; font-weight: bold;">&#123;</span>MATCHADDR<span style="color: #7a0874; font-weight: bold;">&#125;</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$attr</span>{address}&quot;</span></pre></div></div>

<p>so that the variable <em>MATCHADDR</em> has a value. I documented this solution in <a href="https://bugs.launchpad.net/ubuntu/+source/udev/+bug/345234">the Ubuntu bug report</a> that seemed the most appropriate as well. </p>
<p>This solved one problem. Then the next problem reared its ugly head: Both the source VM and the clone refused to finish their boot process, they kept hanging on the NFS mounts defined in <em>/etc/fstab</em>. The only option <em>mountall</em> gave was to enter the root password (after pressing ESC) or type Crtl-D to continue. Doing the latter resulted in nothing but an infinite wait. In <a href="https://bugs.launchpad.net/ubuntu/+source/mountall/+bug/461133">an Ubuntu bug report</a> I found that using DHCP for the network interface would solve the problem. And, indeed it did. However, since I want static IP addresses for my servers this was not a solution that I liked. Much to my surprise the NFS mounts worked perfectly after changing the interface (in <em> /etc/network/interfaces</em>) back to static. I don&#8217;t know why, but on both VMs I set the configuration for <em>eth0</em> from static to dhcp, rebooted, changed it back to static and rebooted again to find the problem solved&#8230; Strange!</p>
<p>Update 2009-12-18:<br />
As it turns out, the solution to the mount problem doesn&#8217;t always work. I tried it again, but now it failed to work after switchting back from DHCP to a static IP. I guess it has something to do with the lease time of the IP, because in the case I described above there was a night between using the DHCP IP and turning static back on. So somewhere, something needs to time out before switching back from DHCP to static IPs works again. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.karssen.org/2009/12/13/cloning-ubuntu-virtual-machines-some-problems-and-solutions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

