<?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>-= n8v =- &#187; Linux</title>
	<atom:link href="http://n8v.enteuxis.org/tags/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://n8v.enteuxis.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 27 Sep 2011 00:52:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2-beta2-18055</generator>
		<item>
		<title>Symfony log management with `logrotate` on Linux</title>
		<link>http://n8v.enteuxis.org/2009/10/symfony-log-management-with-logrotate-on-linux/</link>
		<comments>http://n8v.enteuxis.org/2009/10/symfony-log-management-with-logrotate-on-linux/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 20:44:34 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=282</guid>
		<description><![CDATA[It sucks when server disks fill up. I have Nagios set up to notify me well before it&#8217;s a problem, but it happens annoyingly frequently, and it&#8217;s always the same cause: log files. Symfony&#8217;s production environments don&#8217;t create logs, but the development environments do, and for one project I had several batch jobs logging to [...]]]></description>
			<content:encoded><![CDATA[<p>It sucks when server disks fill up.  I have <a href="http://www.nagios.org/">Nagios</a> set up to notify me well before it&#8217;s a problem, but it happens annoyingly frequently, and it&#8217;s always the same cause:  log files.</p>

<p>Symfony&#8217;s production environments don&#8217;t create logs, but the development environments do, and for one project I had several batch jobs logging to the <var>myproject/log</var> directory.  (Troubleshooting batch jobs without logs is just crazy).</p>

<p>I was going to use <a href="http://www.symfony-project.org/book/1_2/16-Application-Management-Tools#chapter_16_sub_symfony_logs"><code>symfony log:rotate</code></a>, but</p>

<ul>
<li>I would need one cron job for each log</li>
<li>I had permission issues since some of the logs belong to <var>apache</var> and others to <var>root</var></li>
<li>Everything else on the machine, pretty much, is managed with the standard Linux utility <a href="http://linux.die.net/man/8/logrotate"><var>logrotate</var></a>.  Logrotate has been around for about 174 Linux Years, and is common to most distributions.</li>
</ul>

<p>So here&#8217;s how I did it using with <var>logrotate</var>.</p>

<p><span id="more-282"></span></p>

<ol>

    <li><strong>WARNING</strong>:  You might want to make a convenient copy of your log directory before you do this.  I accidently wiped all the logs out while messing with it.
</li>

    <li>Create a file <var>config/myproject.logrotate</var>.  Very simple, I just want it to use the same rotation schedule specified for the whole machine in <var>/etc/logrotate.conf</var>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>myproject<span class="sy0">/</span>log<span class="sy0">/*</span>.log <span class="br0">&#123;</span>
        weekly
        rotate <span class="nu0">4</span>
<span class="br0">&#125;</span></pre></div></div>



</li>

    <li>Check that it will do stuff by running it with the debug flag


<div class="wp_syntax"><div class="code"><pre class="bash">logrotate <span class="re5">-df</span> config<span class="sy0">/</span>badge.logrotate</pre></div></div>


</li>


    <li>Make a symlink to it in <var>/etc/logrotate.d</var>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>myproject<span class="sy0">/</span>config<span class="sy0">/</span>myproject.logrotate  <span class="sy0">/</span>etc<span class="sy0">/</span>logrotate.d<span class="sy0">/</span>myproject</pre></div></div>



</li>

    <li>Run it the first time manually to rotate your logs and make sure it does the right thing!


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> logrotate <span class="re5">-fv</span> <span class="sy0">/</span>etc<span class="sy0">/</span>logrotate.d<span class="sy0">/</span>myproject</pre></div></div>



</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2009/10/symfony-log-management-with-logrotate-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More Secure AND More Convenient: Secure Shell keys and agents everywhere you go</title>
		<link>http://n8v.enteuxis.org/2009/05/more-secure-and-more-convenient-secure-shell-keys-and-agents-everywhere-you-go/</link>
		<comments>http://n8v.enteuxis.org/2009/05/more-secure-and-more-convenient-secure-shell-keys-and-agents-everywhere-you-go/#comments</comments>
		<pubDate>Fri, 29 May 2009 00:50:50 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[public key]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=38</guid>
		<description><![CDATA[As security increases, convenience tends to decrease. But in this case we gain some of both. CONCEPTS Problem 1: Brute force SSH attackers I recently made a Linux machine accessible by port 22 from the Internet, so I could remotely administer it with SSH. Within a day or two, there were hosts from all over [...]]]></description>
			<content:encoded><![CDATA[<p>As security increases, convenience tends to decrease.  But in this case we gain some of both.</p>

<h2>CONCEPTS</h2>

<h3>Problem 1: Brute force SSH attackers</h3>

<p>I recently made a Linux machine accessible by port 22 from the Internet, so I could remotely administer it with SSH.  Within a day or two, there were hosts from all over the Internet trying to log in using random usernames (&#8216;root&#8217;, &#8216;dave&#8217;, &#8216;mysql&#8217;, &#8216;neo&#8217;) and random passwords.</p>

<h3>Problem 2: Weak system passwords</h3>

<p>System passwords are becoming easier to guess by brute force every time a new processor comes out.  It doesn&#8217;t matter how complicated your alphabet soup is, it&#8217;s just not long enough, or won&#8217;t be long enough eventually.  The bad guys also have botnets full of machines and all the time in the world.</p>

<h3>Working around problems 1 and 2: Key authentication</h3>

<p>An SSH key is complex (random) and much, much longer than your password (<a href="http://en.wikipedia.org/wiki/Public-key_cryptography">see Wikipedia for more details about how public-key cryptography works</a>).  You store the private part of your key securely on your client machine, and tell the server to trust only the public key that goes with it.  BUT, you should really use a nice, long, complex passphrase to lock up your private key so that someone who gains access to it can&#8217;t get free access to all your servers, which leads to</p>

<h3>Problem 3:  I&#8217;m too lazy to unlock my inconvenient SSH key all the time</h3>

<p>I log in to different machines all the time, from a bunch of different workstations.  But, I have a long passphrase on my SSH key.  Too long to type every time, especially if I&#8217;m just looking at something or transferring a file or two.</p>

<h3>Solution to problem 3:  A key agent</h3>

<p>An SSH key agent lets you unlock your key and load it into memory once, and then automatically uses it to get you in to all your servers.  SUPER convenient.</p>

<h3>Problem 4:  It&#8217;s confusing</h3>

<p>I tried to explain it to a friend recently and found nowhere on the internets that explained it all in one place.</p>

<p>Coming up:  detailed instructions for getting started with SSH keys and using a key agent on Mac OS X (command line), Windows (PuTTY and Cygwin commandline ssh), and Linux/Unix (command line).</p>

<p><span id="more-38"></span></p>

<h2>HOW TO START USING SSH KEYS</h2>

<h3>References:</h3>

<ul>
<li><a href="http://www.tartarus.org/~simon/puttydoc/Chapter8.html#pubkey">PuTTY manual chapter 8</a>
and <a href="http://www.tartarus.org/~simon/puttydoc/Chapter9.html">chapter 9</a></li>
<li>section 2.4 of the <a href="http://www.snailbook.com/">O&#8217;Reilly SSH book by Barrett/Silverman</a></li>
<li><code>man <a href="http://linux.die.net/man/5/ssh_config">ssh_config</a></code></li>
<li><code>man <a href="http://linux.die.net/man/1/ssh-agent">ssh-agent</a></code></li>
</ul>

<h3>Generate your key with a command-line (Open)SSH client (Cygwin, Mac OS X, Linux)</h3>

<p>I&#8217;m going to start with this client, because the command-line OpenSSH is the common denominator on all the OSes I use.</p>

<ol>
<li><p>Write down a nice long, complex, memorable passphrase that you&#8217;re capable of typing reliably, and store it in a safe place.  You probably won&#8217;t need it every day (unless you reboot a lot), so make sure you can remember and type it.  Security expert Bruce Schneier suggests <a href="http://www.schneier.com/blog/archives/2005/06/write_down_your.html">a scrap of paper in your wallet is a pretty good place</a>.</p></li>
<li><p>Generate a private key with <var>ssh-keygen </var>from your client machine&#8217;s command line:</p></li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">ssh-keygen</span> <span class="re5">-t</span> rsa
Generating public<span class="sy0">/</span>private rsa key pair.
Enter <span class="kw2">file</span> <span class="kw1">in</span> <span class="kw2">which</span> to save the key <span class="br0">&#40;</span><span class="sy0">/</span>home<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa<span class="br0">&#41;</span>:
Enter passphrase <span class="br0">&#40;</span>empty <span class="kw1">for</span> no passphrase<span class="br0">&#41;</span>:     <span class="co0"># use yours from step 1</span>
Enter same passphrase again:
Your identification has been saved <span class="kw1">in</span> <span class="sy0">/</span>home<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa.
Your public key has been saved <span class="kw1">in</span> <span class="sy0">/</span>home<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa.pub.
The key fingerprint is:
9a:<span class="nu0">89</span>:9c:6b:<span class="nu0">87</span>:a7:e8:<span class="nu0">93</span>:9a:f5:f7:<span class="nu0">35</span>:bf:<span class="nu0">23</span>:<span class="nu0">87</span>:c6 myusername<span class="sy0">@</span>myhostname</pre></div></div>


<ol>
<li>The file permissions of your new <var>.ssh</var> directory and the files in it (except maybe your public key) should be very restrictive, allowing only you to read them.  But just in case, reset them restrictively:</li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">chmod</span> <span class="nu0">700</span> ~<span class="sy0">/</span>.ssh
<span class="kw2">chmod</span> <span class="nu0">600</span> ~<span class="sy0">/</span>.ssh<span class="sy0">/*</span>
<span class="kw2">chmod</span> <span class="nu0">644</span> ~<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa.pub</pre></div></div>


<ol>
<li>You need to append your public key to <var>~/.ssh/authorized_keys</var> on each of your servers:

<ul>
<li>if you don&#8217;t have an authorized_keys file in your <var>~/.ssh</var> directory, just copy your public key to it on each server:</li>
</ul></li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">scp</span> <span class="re5">-r</span> ~<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa.pub  myserver:.ssh<span class="sy0">/</span>authorized_keys</pre></div></div>


<ul>
<li>if you already have one, you&#8217;ll need to append your key to it.  Use a text editor and paste, copy and paste, or, courtesy of <a href="http://codesnippets.joyent.com/posts/show/906">CodeSnippets</a>,</li>
</ul>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">cat</span> .ssh<span class="sy0">/</span>id_dsa.pub <span class="sy0">|</span> <span class="kw2">ssh</span> user<span class="sy0">@</span>domain.tld <span class="st_h">'cat &gt;&gt; .ssh/authorized_keys'</span></pre></div></div>


<ol>
<li>Test and make sure it works!  When you ssh to the server, it should prompt you for your passphrase to unlock your private key, and then you should successfully connect.  Using the -d flag to ssh gives you verbose debugging information which is usually useful.</li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">ssh</span> <span class="re5">-v</span> myserver
... <span class="co0"># copious debug information about which keys or </span>
... <span class="co0"># authentication methods ssh is trying ]</span>
Enter passphrase <span class="kw1">for</span> key <span class="st_h">'~/.ssh/id_rsa'</span>:
... <span class="co0"># here's where you type your passphrase correctly</span>
... <span class="co0"># more debugging</span>
debug1: Entering interactive session.
Last <span class="kw2">login</span>: Thu May <span class="nu0">21</span> <span class="nu0">14</span>:<span class="nu0">30</span>:<span class="nu0">31</span> <span class="nu0">2009</span> from 10.0.0.2</pre></div></div>


<ol>
<li><p>I like to turn on agent forwarding by adding this line to <var>~/.ssh/config</var> file on each server.  This allows you to ssh from server A to another server B that trusts your key, using the agent on your client machine to pass your key through.
ForwardAgent yes</p></li>
<li><p>If all the users on the server will be using keys from now on, it&#8217;s a good idea to turn off password authentication for the whole server, in sshd_config, which is usually located in <var>/etc/</var>:
PasswordAuthentication no
Unfortunately, I can&#8217;t figure out how to lock one account on the server from using password authentication.  You can put that line in your <var>~/.ssh/config</var> file, but it only affects your use of ssh <em>from</em> that account, not <em>to</em> it.</p></li>
</ol>

<h3>Or, generate your key with PuTTY on Windows:</h3>

<p>PuTTY is rock-solid terminal and SSH software for Windows.  I usually generate my key with the command-line OpenSSH tools and then import it to PuTTY, but here&#8217;s how you do it the other way around:</p>

<ol>
<li><p>Install the <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">latest version of the whole PuTTY package</a>.  At the time of this writing, the PuTTY author&#8217;s site has been inaccessible for a while, but there are <a href="http://the.earth.li/~sgtatham/putty/0.60/x86/">mirrors available</a> for downloading the software.</p></li>
<li><p>Generate an RSA key with puttygen.exe, using a good passphrase (see instructions in the <a href="http://www.tartarus.org/~simon/puttydoc/Chapter8.html#pubkey">PuTTY manual chapter 8</a>)
<div id="attachment_233" class="wp-caption alignnone" style="width: 493px"><img src="http://n8v.enteuxis.org/wp-content/uploads/2009/05/puttygen.png" alt="Generating a key with puttygen.exe" title="puttygen" width="483" height="471" class="size-full wp-image-233" /><p class="wp-caption-text">Generating a key with puttygen.exe</p></div></p></li>
<li><p>Save the private key somewhere using the &#8216;Save private key&#8217; button, like maybe in <var>C:\Documents and Settings\<samp>yourusername</samp>&#92;.ssh\puttyprivkey</var> to be compatible with command-line SSH tools.  Save the public key somewhere too (though you will paste it, below).</p></li>
<li><p>Make the file permissions of that directory and the files in it very restrictive (only you should have access).</p></li>
<li><p>On one server, edit <var>.ssh/authorized_keys</var> in your home directory (creating it if it doesn&#8217;t exist yet), and paste your public key from puttygen in there</p></li>
<li><p>Test that it works!  Tell PuTTY to try key authentication instead of password authentication by setting your private key under Connection->SSH->Auth in the connection settings:
<div id="attachment_232" class="wp-caption alignnone" style="width: 466px"><img src="http://n8v.enteuxis.org/wp-content/uploads/2009/05/putty_ssh_key_settings.png" alt="Tell PuTTY to use your key" title="putty_ssh_key_settings" width="456" height="442" class="size-full wp-image-232" /><p class="wp-caption-text">Tell PuTTY to use your key</p></div></p></li>
<li><p>Copy the <var>authorized_keys</var> file and/or the whole <var>.ssh</var> directory to each other server.  Eg on the first server, <code>scp -r .ssh myotherserver:</code></p></li>
<li><p>Turn on agent forwarding (and &#8220;try to use Pageant&#8221;&#8230; see screenshot above) for each ssh session config in PuTTY in the Connection-&gt;SSH-&gt;Auth pane (this lets you ssh from server A to another server using the agent on your client machine)</p></li>
<li><p>Put your username in the &#8220;Auto-login username&#8221; field under Connection-&gt;Data for each saved PuTTY session:
<div id="attachment_249" class="wp-caption alignnone" style="width: 466px"><img src="http://n8v.enteuxis.org/wp-content/uploads/2009/05/putty_username.png" alt="Don&#039;t forget to fill in the Auto-login username field for each saved PuTTY session." title="putty_username" width="456" height="442" class="size-full wp-image-249" /><p class="wp-caption-text">Don't forget to fill in the Auto-login username field for each saved PuTTY session.</p></div></p></li>
</ol>

<h4>Using your PuTTY key with command-line ssh client (Cygwin, Mac OS X, Linux):</h4>

<p>If you want to use the key you just generated with puttygen.exe with
another ssh client (eg cygwin commandline <var>ssh</var>), export your
private key from puttygen and store it in your <var>.ssh</var> dir
(ssh looks by default for <var>.ssh/id_rsa</var> but these
instructions let you specify another name), and put these lines in
your <var>.ssh/config</var> file:</p>

<pre><code>ForwardAgent yes
IdentityFile ~/.ssh/id_rsa_putty_priv.openssh
</code></pre>

<p>( i.e., the filename of your exported private key )</p>

<h4>To change your ssh key password</h4>

<p>Load it in <var>puttygen</var> and change the password, save and
export it for your other ssh client(s) if necessary</p>

<h4>Using a different key from home or another machine or whatever</h4>

<p>You can copy your private key to several machines, or you can generate
a new key on each and append the public key to the
<var>.ssh/authorized_keys</var> file on the server. Think about how
much you want to expose/replace if something gets compromised.</p>

<p>In my case, I use one private key on all my client computers at work, one
on my home computers, and one on my Palm handheld. That way if one of
my client computers is lost, stolen or compromised, I can disallow
that key but keep the others.</p>

<h2>USE A KEY AGENT TO KEEP YOUR KEYS HANDY</h2>

<p>So far, we&#8217;ve made SSH more secure, but my key passphrase is at least as much of a pain as using my password &#8212; in fact, more so because it&#8217;s about twice as long.</p>

<p>Using an SSH Key Agent offers a killer mix of security <em>and</em> convenience.  When you open the agent and load your keys, you can unlock them and they&#8217;re held unlocked in memory.  This lets you open connections all day without having to type your password or passphrase.  <strong>NOTE WELL</strong>, lock your machine when it is unattended if you have an agent running; otherwise anyone who walks up to it can conceivably log in to any of the servers you&#8217;ve configured to trust your key.</p>

<h3>To use PuTTY&#8217;s agent &#8220;Pageant&#8221; on Windows:</h3>

<ol>
<li>Launch <var>pageant.exe</var>, PuTTY&#8217;s ssh agent, right-click it in the system tray, and add your private key.</li>
</ol>

<p>Now you can log into all your servers conveniently and get from server to server using agent forwarding.</p>

<p>You may want to convince pageant.exe to run at login.  See <a href="http://www.tartarus.org/~simon/puttydoc/Chapter9.html">Chapter 9 of the PuTTY manual</a>.</p>

<p>I just made a shortcut to pageant and edited the Target to load the key and launch PuTTY at startup thusly:
<code>
"C:\Program Files\putty\pageant.exe" "C:\Documents and Settings\myusername&#46;ssh\puttyprivkey.ppk" -c "C:\Program Files\PuTTY\putty.exe"</code></p>

<h3>To run an agent with the command-line OpenSSH client:</h3>

<p>This applies to Linux, Mac OS X, and Cygwin.</p>

<p>Basically, add this line to your <var>.profile</var> file in your home directory, to start the agent whenever you open a shell:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">eval</span> <span class="sy0">`</span><span class="kw2">ssh-agent</span> -s<span class="sy0">`</span></pre></div></div>


<p>Then, before you ssh to anything in that terminal, use the <code>ssh-add</code> command (if your private key in openssh format is named <var>.ssh/id_rsa</var>) or <code>ssh-add ~/.ssh/puttyprivkey.openssh</code> if you&#8217;ve got a weirdly named one you made with puttygen.exe, above.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">ssh-add</span>
Enter passphrase <span class="kw1">for</span> <span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>Documents and Settings<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa:
Identity added: <span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>Documents and Settings<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa <span class="br0">&#40;</span><span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>Documents and Settings<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa<span class="br0">&#41;</span></pre></div></div>


<p><code>ssh-add -l</code> (ell) shows which keys the agent is currently holding.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">ssh-add</span> <span class="re5">-l</span>
9a:<span class="nu0">89</span>:9c:6b:<span class="nu0">87</span>:a7:e8:<span class="nu0">93</span>:9a:f5:f7:<span class="nu0">35</span>:bf:<span class="nu0">23</span>:<span class="nu0">87</span>:c6 <span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>Documents and Settings<span class="sy0">/</span>myusername<span class="sy0">/</span>.ssh<span class="sy0">/</span>id_rsa <span class="br0">&#40;</span>RSA<span class="br0">&#41;</span></pre></div></div>


<h3>Making it nicer in with <code>keychain</code></h3>

<p>The <a href="http://www.gentoo.org/proj/en/keychain/">keychain
utility</a> you can get with Cygwin (and some Linuxes) is also nice.
I put this line in my <var>.bashrc</var> so that every Cygwin shell
either starts the ssh agent or connects to the already running one.</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">eval</span> <span class="sy0">`</span>keychain <span class="re5">--eval</span> <span class="re5">-q</span> <span class="re5">-Q</span> --noask<span class="sy0">`</span></pre></div></div>


<p>Then I can use <var>ssh-add</var> (see above) when I want to load my keyring, and
all my open Cygwin shells get it, until I log out or restart Windows.</p>

<h3>Running an agent on Mac OS X</h3>

<p>In Leopard (Mac OS X 10.5, released in October 2007), the <a href="http://www.dribin.org/dave/blog/archives/2007/11/28/ssh_agent_leopard/">SSH Agent is integrated into the OS</a>, so if you&#8217;ve generated your keys with <code>ssh-keygen</code> as above and they live in <code>~/.ssh/id_rsa</code> and <code>id_rsa.pub</code>, you will get prompted to unlock your key the first time you try to <code>ssh</code> or <code>scp</code> anywhere:</p>

<div id="attachment_253" class="wp-caption alignnone" style="width: 591px"><img src="http://n8v.enteuxis.org/wp-content/uploads/2009/05/leopard-ssh-agent.png" alt="This dialog box prompts you to unlock your key and/or start the agent." title="leopard-ssh-agent" width="581" height="414" class="size-full wp-image-253" /><p class="wp-caption-text">This dialog box prompts you to unlock your key and/or start the agent.</p></div>

<p>The &#8220;Remember password in my keychain&#8221; checkbox makes it keep an ssh agent running.  It works great.</p>

<p>For older versions of Mac OS, you want <a href="http://www.sshkeychain.org/download.php">SSHKeychain</a>.  It also works with the Apple Keychain, to remember your key&#8217;s passphrase.</p>

<p>Both solutions work seamlessly for all the OpenSSH tools (ssh, sftp, scp, etc) in all your terminals.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2009/05/more-secure-and-more-convenient-secure-shell-keys-and-agents-everywhere-you-go/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDAP powered by MySQL on RHEL5</title>
		<link>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/</link>
		<comments>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 02:01:12 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=133</guid>
		<description><![CDATA[Background We need a quick-and-dirty LDAP server with basically a list of usernames and passwords to point Cisco ACS gear at, in order to provide people with limited-time authentication tokens to a wireless network. I need to populate that with an HL7 interface in Perl and make a web app UI frontend (preferably using symfony). [...]]]></description>
			<content:encoded><![CDATA[<h3>Background</h3>

<p>We need a quick-and-dirty <abbrev title="Lightweight Directory Access Protocol">LDAP</abbrev> server with basically a list of usernames and passwords to point Cisco ACS gear at, in order to provide people with limited-time authentication tokens to a wireless network.  I need to populate that with an <a href="http://hl7toolkit.sf.net">HL7 interface in Perl</a> and make a web app UI frontend (preferably using symfony).  The latter two interfaces are well established around here with MySQL, so I am trying to use OpenLDAP&#8217;s SQL backend to make that happen naturally.</p>

<h4>Simplifications</h4>

<p>Unlike other similar implementations out there, I have smaller goals:</p>

<ul>
    <li>The database will be updated/written by the HL7 interface and web interface.  The LDAP tools don&#8217;t need to write to it.</li>
    <li>All my user data should fit nicely into two tables (users and groups&#8230; and another table to relate many-to-many), and two Objectclasses in LDAPland.</li>
</ul>

<p><span id="more-133"></span></p>

<h3>Resources</h3>

<p>These were unexpectedly hard to Google up, which is partly why I&#8217;m documenting them here for Posterity.</p>

<ul>
    <li>Zytrax has an open source book about LDAP entitled <a href="http://www.zytrax.com/books/ldap/">LDAP for Rocket Scientists</a>, which has <a href="http://www.zytrax.com/books/ldap/ch2/index.html#basic">an excellent chapter about LDAP concepts</a>, which is nice since I don&#8217;t really understand LDAP like I do the other technologies involved.</li>

    <li><a href="http://www.openldap.org/doc/admin24/backends.html#SQL">Section &#8220;10.10.2. back-sql Configuration&#8221; of the OpenLDAP manual</a></li>
    <li>The <a href="http://linux.die.net/man/5/slapd-sql">slapd-sql man page</a> is indispensible.  See especially the &#8220;METAINFORMATION USED&#8221; section.</li>
    <li>The <a href="http://www.openldap.org/devel/cvsweb.cgi/~checkout~/servers/slapd/back-sql/rdbms_depend/README?rev=1.4.4.1&#038;hideattic=1&#038;sortbydate=0">README that comes with the back-sql samples</a></li>
    <li>The samples themselves (either unpack <var>servers/slapd/back-sql/rdbms_depend/mysql</var> from the <a href="http://www.openldap.org/software/download/">source tarball </a>or <a href="http://www.openldap.org/devel/cvsweb.cgi/servers/slapd/back-sql/rdbms_depend/mysql/?hideattic=1&#038;sortbydate=0">browse them</a>, but you&#8217;ll probably want them unpacked so you can feed the schema to the <var>mysql </var> client.  MOST OF WHAT YOU NEED TO LEARN is demonstrated in the samples.</li>
    <li>This <a href="http://www.flatmtn.com/article/setting-ldap-back-sql#LdapBacksql-2">4-year-old blog article at/by &#8220;Flat Mountain&#8221;</a> is sketchy but an improvement over the documents above!</li>
    <li><a href="http://www.docunext.com/blog/2006/10/openldap-mysql-documentation.html">Albert Lash at DocuNext has a 2-year-old post similar to this one </a> with another list of fine references! 
    <li>This <a href="http://www.darold.net/projects/ldap_pg/HOWTO/index.html">HOWTO for OpenLDAP and Postgresql</a> by Gilles Darold is far superior than the other articles, but needs adaptation of course for MySQL</li>
    <li>Likewise, here&#8217;s <a href="http://www.easysoft.com/applications/openldap/back-sql-odbc.html">a good article for doing the same thing with Oracle/MSSQL</a></li>
    <li>And here are some <a href="http://www.cmu.edu/acs/ldap/sql_notes">extended notes from someone who did it with Oracle</a>, including another explanation of the data mapping part.</li>

</ul>

<h3>I. Install Stuff</h3>

<p>I&#8217;m using <abbr title="Red Hat Enterprise Linux 5.0">RHEL5</abbr> on a virtual machine.  Your package system may vary.  You may in fact have to compile from source to get SQL support in LDAP.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> yum <span class="kw2">install</span> openldap openldap-clients openldap-servers openldap-devel openldap-servers-sql</pre></div></div>


<h3>II. Get and unpack the source code for the MySQL samples</h3>

<ol>
    <li><a href="http://www.openldap.org/software/download/">Download the source tarball</a> to your machine</li>
    <li>Unpack it


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">tar</span> zxf openldap-stable-<span class="nu0">20080813</span>.tgz</pre></div></div>



</li>
</ol>

<h3>III. Create the database and tables</h3>

<p>Make sure the mysql server is running of course.  We&#8217;re assuming it&#8217;s on the same host as the LDAP server.</p>

<p>Create the database (<samp>my_db_name</samp>) and a password-having user (<samp>my_mysql_user</samp>) with all privileges to that database (I recommend the MySQL Administrator GUI for this, strangely enough since I usually dislike clicking on stuff).  You should be able to connect to your database like this now:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ mysql -umy_mysql_user <span class="re5">-pxxxxxxxxxxxxx</span>  my_db_name</pre></div></div>


<p>Build the tables that configure how OpenLDAP talks to the database.</p>

<ol>
    <li><var>cd</var> into <var>servers/slapd/back-sql/rdbms_depend/mysql</var> from the unpacked openldap source</li>
    <li>Feed <var>backsql_create.sql</var> to the &#8216;mysql&#8217; client


<div class="wp_syntax"><div class="code"><pre class="bash">$ mysql -umy_mysql_user <span class="re5">-pxxxxxxxxxxxxx</span>  my_db_name <span class="sy0">&lt;</span> backsql_create.sql</pre></div></div>



</li>
</ol>

<h3>IV. Hack the basic config files</h3>

<h4>a. <var>slapd.conf</var></h4>

<p>Basically I&#8217;m starting from the <var>slapd.conf</var> in the rdbms_depend/mysql sample (see above), but folding in some RedHatese file locations from the distributed <var>slapd.conf</var>.</p>

<p>I define an adminstrative user with the <code>rootdn </code> and <code>rootpw</code> directives.  Use <var>slappasswd</var> to generate the hashed password:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ slappasswd <span class="re5">-h</span> <span class="br0">&#123;</span>crypt<span class="br0">&#125;</span></pre></div></div>


<p>and type in the password.  It will spit out the string you need, which is prefixed by the algorithm in curly braces.</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># See slapd.conf<span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span> for details on configuration options.
# This file should NOT be world readable.
#
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
&nbsp;
pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args
# Timeout in seconds, <span class="nu0">0</span> <span class="sy0">=</span><span class="re2"> never</span>
idletimeout     <span class="nu0">30</span>
threads         <span class="nu0">32</span>
# Debuging level, <span class="nu0">0</span> <span class="sy0">=</span><span class="re2"> none</span>
loglevel        <span class="nu0">32</span>
&nbsp;
# THIS IS IMPORTANT-- without it you will get <span class="st0">&quot;&lt;database&gt; failed init (sql)!&quot;</span>
# Load dynamic backend modules:
modulepath    /usr/lib/openldap
# modules available in openldap-servers-sql RPM package:
moduleload back_sql.la
&nbsp;
&nbsp;
#######################################################################
# SQL Database Definitions
#######################################################################
&nbsp;
database        sql
suffix          <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span>
rootdn          <span class="st0">&quot;cn=root,ou=Users,ou=Junk,ou=AK,DC=,mycompany,DC=com&quot;</span>
rootpw          <span class="br0">&#123;</span>CRYPT<span class="br0">&#125;</span>xxxxxxxxxxxx
&nbsp;
#  The name of the ODBC datasource <span class="br0">&#40;</span>from odbc.ini,
#     not necessarily the database instance<span class="br0">&#41;</span> to use.
dbname          my_database
dbuser          my_database_user
dbpasswd        xxxxxxxxxxxxxxxx
&nbsp;
# this is important because my simple view for the ldap_entries table
# has no 'organization' object.  See `man slapd-sql`.
baseObject
&nbsp;
subtree_cond    <span class="st0">&quot;ldap_entries.dn LIKE CONCAT('%',?)&quot;</span>
insentry_stmt   <span class="st0">&quot;INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)&quot;</span>
has_ldapinfo_dn_ru      no
&nbsp;
&nbsp;
#######################################################################
# Access Control
#    see http://www.openldap.org/doc/admin24/access-control.html
#    and `man slapd.access`
#######################################################################
&nbsp;
# Here we define who can see which parts of the directory
&nbsp;
# Hide the password attribute <span class="br0">&#40;</span>except for the root user of course<span class="br0">&#41;</span> but
#   allow authentication against it
access to attrs<span class="sy0">=</span><span class="re2">userPassword</span>
        by anonymous auth
        by * none
&nbsp;
# don't allow anonymous access
# allow authenticated users to see their own entry
access to *
        by self read
        by * none</pre></div></div>


<p>I started without the Access Control section and added it after I had things basically working.</p>

<h4>b. ODBC config files</h4>

<p>In my case they are in <var>/etc/odbc.ini</var> and <var>/etc/odbcinst.ini</var> already existed and just needed a MySQL section added to <var>odbcinst.ini</var> and a section for this particular database in <var>odbc.ini</var>, but I had to get the paths right for Red Hat.  See the MySQL section of step 2 of the <a href="http://www.openldap.org/devel/cvsweb.cgi/~checkout~/servers/slapd/back-sql/rdbms_depend/README?rev=1.5&#038;hideattic=1&#038;sortbydate=0">samples README document</a></p>

<p><var>/etc/odbcinst.ini</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># Driver from the MyODBC package
# Setup from the unixODBC package
<span class="re0"><span class="br0">&#91;</span>MySQL<span class="br0">&#93;</span></span>
<span class="re1">Description</span>     <span class="sy0">=</span><span class="re2"> ODBC for MySQL</span>
<span class="re1">Driver</span>          <span class="sy0">=</span><span class="re2"> /usr/lib/libmyodbc3.so  # note, filename includes a 3, differs from docs</span>
<span class="re1">Setup</span>           <span class="sy0">=</span><span class="re2"> /usr/lib/libodbcmyS.so</span>
<span class="re1">FileUsage</span>       <span class="sy0">=</span><span class="re2"> 1</span></pre></div></div>


<p><var>/etc/odbc.ini</var></p>


<div class="wp_syntax"><div class="code"><pre class="ini"><span class="re0"><span class="br0">&#91;</span>my_database<span class="br0">&#93;</span></span>
<span class="re1">Description</span>         <span class="sy0">=</span><span class="re2"> my database</span>
<span class="re1">Driver</span>              <span class="sy0">=</span><span class="re2"> MySQL</span>
<span class="re1">Trace</span>               <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">Database</span>            <span class="sy0">=</span><span class="re2"> my_db_name</span>
<span class="re1">Servername</span>          <span class="sy0">=</span><span class="re2"> localhost</span>
<span class="re1">UserName</span>            <span class="sy0">=</span><span class="re2"> my_database_user</span>
<span class="re1">Password</span>            <span class="sy0">=</span><span class="re2"> xxxxxxxxxxxxxxxxx</span>
<span class="re1">ReadOnly</span>            <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">RowVersioning</span>       <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ShowSystemTables</span>    <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ShowOidColumn</span>       <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">FakeOidIndex</span>        <span class="sy0">=</span><span class="re2"> No</span>
<span class="re1">ConnSettings</span>        <span class="sy0">=</span>
<span class="re1">SOCKET</span>              <span class="sy0">=</span><span class="re2"> /var/lib/mysql/mysql.sock</span></pre></div></div>


<p>(OK, here&#8217;s where I dinked with the example database and read lots of examples and stuff, but hopefully you can skip that because of this excellent documentation <img src='http://n8v.enteuxis.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>

<h3>V. Create and populate your user and group tables</h3>

<p>These are my basic tables of users and groups:</p>


<div class="wp_syntax"><div class="code"><pre class="sql"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_user <span class="br0">&#40;</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  username <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  password <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  first_name <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  last_name <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="sy0">,</span>username<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_group <span class="br0">&#40;</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  <span class="st0">`name`</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> my_group_member <span class="br0">&#40;</span>
  <span class="co1">-- unique id isn't necessary but easier for symfony</span>
  id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span><span class="sy0">,</span>
  my_user_id <span class="kw1">INT</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">UNSIGNED</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  my_group_id <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">45</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span><span class="sy0">,</span>
  <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span>  <span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">,</span>
  <span class="kw1">UNIQUE</span> <span class="kw1">KEY</span> uniquepair <span class="br0">&#40;</span>my_user_id<span class="sy0">,</span>my_group_id<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;</pre></div></div>


<p>You&#8217;ll need to populate the tables with a user or two and at least one group, of course.</p>

<h3>VI. Insert the special configuration rows</h3>

<p>I entered these data sets using the <a href="http://dev.mysql.com/downloads/gui-tools/">MySQL Administrator</a> GUI.  The most helpful explanation was in the &#8220;METAINFORMATION USED&#8221; section of the <a href="http://linux.die.net/man/5/slapd-sql">slapd-sql man page</a>.</p>

<p>Basically, the <samp>ldap_*</samp> tables show the SQL backend how to map the database tables onto LDAP objects.  <a href="http://www.oav.net/mirrors/LDAP-ObjectClasses.html#atDisplayName">This is a nice reference to the common LDAP object schemas</a>.  That&#8217;s important because you can only map your database fields to fields in the schema for the objectClass you&#8217;re using (unless you want to start making your own schema, which is beyond my scope here).  In my case I&#8217;m using <var>inetOrgPerson</var>, which inherits from <var>organizationalPerson</var>, which inherits from <var>Person</var>, and for groups, <var>groupOfUniqueNames</var>.</p>

<p>The <strong>ldap_entry_objclasses</strong> table needs one row for each objectClass we&#8217;re using:</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>entry_id</th><th>oc_name</th></tr>
<tr>
<td>1</td><td>inetOrgPerson</td></tr>
<tr>
<td>2</td><td>groupOfUniqueNames</td></tr>
</table>

<p>The <strong>ldap_oc_mappings</strong> table also has a row for each objectClass, and it shows the sql backend how to find objects corresponding to those object classes.</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>id</th><th>name</th><th>keytbl</th><th>keycol</th><th>create_proc</th><th>delete_proc</th><th>expect_return</th></tr>
<tr>
<td>1</td><td>inetOrgPerson</td><td>my_user</td><td>id</td><td></td><td></td><td>0</td></tr>
<tr>
<td>2</td><td>groupOfUniqueNames</td><td>my_group</td><td>id</td><td></td><td></td><td>0</td></tr>
</table>

<p>The <strong>ldap_attr_mappings</strong> table is the most complex part.  Basically you&#8217;re showing the sql backend how to build queries that map the database columns onto LDAP attributes.</p>

<table border=1 cellspacing=1 cellpadding=0><tr>
<th>id</th><th>oc_<wbr />map_<wbr />id</th><th>name</th><th>sel_<wbr />expr</th><th>sel_<wbr />expr<wbr />_u</th><th>from_tbls</th><th>join_where</th><th>add_proc</th><th>delete_<wbr />proc</th><th>param_<wbr />order</th><th>expect_<wbr />return</th></tr>
<tr>
<td>1</td><td>1</td><td>cn</td><td>concat( first_name, &#8216; &#8216;, last_name )</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>2</td><td>1</td><td>givenName</td><td>first_name</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>3</td><td>1</td><td>sn</td><td>last_name</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>4</td><td>1</td><td>userPassword</td><td>password</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>5</td><td>1</td><td>uid</td><td>username</td><td></td><td>my_user</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>7</td><td>2</td><td>cn</td><td>name</td><td></td><td>my_group</td><td></td><td></td><td></td><td>3</td><td>0</td></tr>
<tr>
<td>8</td><td>2</td><td>uniqueMember</td><td>dn</td><td></td><td>my_group, my_<wbr />group_<wbr />member gu, my_<wbr />user u, ldap_<wbr />entries</td><td>my_group.id = gu.<wbr />my_<wbr />group_<wbr />id and gu.<wbr />my_<wbr />user_<wbr />id = u.id and oc_<wbr />map_<wbr />id = 1 and keyval = u.id</td><td></td><td></td><td>3</td><td>0</td></tr>
</table>

<h4>Create a view for the <abbrev title="Distinguished Name">DN</abbrev>s in ldap_entries</h4>

<p>I&#8217;m going to use the username field in my DN instead of the common name (CN) in most examples, because it&#8217;s more guaranteed to be unique, and <a href="http://www.zytrax.com/books/ldap/apa/dn-rdn.html">it is apparently OK to do so</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="sql"><span class="kw1">DROP</span> <span class="kw1">TABLE</span> ldap_entries;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">VIEW</span> ldap_entries <span class="kw1">AS</span>
  <span class="kw1">SELECT</span> 
    <span class="co1">-- differentiate id spaces here </span>
    <span class="br0">&#40;</span><span class="nu0">100000</span> <span class="sy0">+</span> my_user<span class="sy0">.</span>id<span class="br0">&#41;</span> <span class="kw1">AS</span> id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- calculate a DN for each user</span>
    ucase<span class="br0">&#40;</span>concat<span class="br0">&#40;</span>
     <span class="st0">'uid='</span><span class="sy0">,</span> my_user<span class="sy0">.</span>username<span class="sy0">,</span> 
     <span class="st0">',ou=Users,ou=Junk,ou=AK,DC=mycompany,DC=com'</span>
    <span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> dn<span class="sy0">,</span> 
&nbsp;
    <span class="co1">-- the id of the inetOrgUser objectClass in ldap_entry_objclasses</span>
    <span class="nu0">1</span> <span class="kw1">AS</span> oc_map_id<span class="sy0">,</span>    
&nbsp;
    <span class="co1">-- zero for every row </span>
    <span class="co1">-- (see baseObject in the `slapd-sql` man page)</span>
    <span class="nu0">0</span> <span class="kw1">AS</span> parent<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- the real id in the user table</span>
    my_user<span class="sy0">.</span>id <span class="kw1">AS</span> keyval 
&nbsp;
  <span class="kw1">FROM</span>
    my_user 
&nbsp;
<span class="kw1">UNION</span> 
&nbsp;
  <span class="kw1">SELECT</span> 
    <span class="co1">-- a different id space</span>
    <span class="br0">&#40;</span><span class="nu0">200000</span> <span class="sy0">+</span> my_group<span class="sy0">.</span>id<span class="br0">&#41;</span> <span class="kw1">AS</span> id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- calculate a DN for each object in our group table </span>
    ucase<span class="br0">&#40;</span>concat<span class="br0">&#40;</span>
    <span class="st0">'cn='</span><span class="sy0">,</span>my_group<span class="sy0">.</span>name<span class="sy0">,</span>
     <span class="st0">',ou=Users,ou=Junk,ou=AK,DC=mycompany,DC=com'</span>
    <span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> dn
&nbsp;
    <span class="co1">-- the id of groupOfUniqueNames in ldap_entry_objclasses</span>
    <span class="nu0">2</span> <span class="kw1">AS</span>  oc_map_id<span class="sy0">,</span>
&nbsp;
    <span class="co1">-- like above</span>
    <span class="nu0">0</span> <span class="kw1">AS</span> parent<span class="sy0">,</span>
    my_group<span class="sy0">.</span>id <span class="kw1">AS</span> id 
&nbsp;
  <span class="kw1">FROM</span> 
    my_group</pre></div></div>


<h3>VII. Test and stuff</h3>

<h4>Launch the Slap daemon</h4>

<p>It&#8217;s nice to launch <var>slapd</var> in debug mode in one terminal.  This is pretty verbose and will hopefully tell you if you&#8217;ve got something wrong in your mapping tables or anything:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>slapd <span class="re5">-d</span> <span class="nu0">5</span></pre></div></div>


<h4>Test connectivity and data with an LDAP client</h4>

<p>Hint:  it would help to <strong>LEARN HOW TO USE <a href="http://linux.die.net/man/1/ldapsearch">ldapsearch</a> correctly.</strong></p>

<p>Connect anonymously and spit out all the LDAP data (if ACL allows it&#8211; by slapd.conf above allows anonymous connections but won&#8217;t show any of the data):</p>


<div class="wp_syntax"><div class="code"><pre class="bash">ldapsearch <span class="re5">-x</span> <span class="re5">-s</span> sub <span class="re5">-b</span> <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span> <span class="st0">&quot;(objectClass=*)&quot;</span></pre></div></div>


<p>Connect as root (the special account defined in slapd.conf) and show all the data in the directory:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">ldapsearch <span class="re5">-x</span> <span class="re5">-D</span> <span class="re2">uid</span>=root,<span class="re2">ou</span>=USERS,<span class="re2">OU</span>=JUNK,<span class="re2">OU</span>=AK,<span class="re2">DC</span>=MYCOMPANY,<span class="re2">DC</span>=COM <span class="re5">-w</span> xxxxxxxxx <span class="re5">-s</span> sub <span class="re5">-b</span> <span class="st0">&quot;ou=Junk,ou=AK,DC=mycompany,DC=com&quot;</span> <span class="st0">&quot;(objectClass=*)&quot;</span></pre></div></div>


<p>Here&#8217;s an example of what it shows me:</p>


<div class="wp_syntax"><div class="code"><pre class="ini"># extended LDIF
#
# LDAPv3
# base &lt;ou<span class="sy0">=</span><span class="re2">Junk,ou=AK,DC=mycompany,DC=com&gt; with scope subtree</span>
# filter: <span class="br0">&#40;</span>objectClass<span class="sy0">=</span><span class="re2">*<span class="br0">&#41;</span></span>
# requesting: ALL
#
&nbsp;
# Junk, AK, mycompany.com
dn: ou<span class="sy0">=</span><span class="re2">Junk,ou=AK,dc=mycompany,dc=com</span>
objectClass: extensibleObject
description: builtin baseObject for back-sql
description: all entries mapped in the <span class="st0">&quot;ldap_entries&quot;</span> table
description: must have <span class="st0">&quot;0&quot;</span> in the <span class="st0">&quot;parent&quot;</span> column
ou: Junk
&nbsp;
# TESTUSER, USERS, JUNK, AK, MYCOMPANY.COM
dn: uid<span class="sy0">=</span><span class="re2">TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: inetOrgPerson
cn: test user
ou: guest
sn: user
uid: testuser
givenName: test
userPassword:: dGVzdHBhc3M<span class="sy0">=</span>
&nbsp;
# <span class="nu0">1234567890</span>, USERS, JUNK, AK, MYCOMPANY.COM
dn: uid<span class="sy0">=</span><span class="re2">1234567890,ou=USERS,ou=JUNK,ou=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: inetOrgPerson
cn: test2 user2
ou: guest
sn: user2
uid: <span class="nu0">1234567890</span>
givenName: test2
userPassword:: MTIzNDU2Nzg5MA<span class="sy0">=</span><span class="re2">=</span>
&nbsp;
...
&nbsp;
# VALIDUSERS, GROUPS, JUNK, AK, MYCOMPANY.COM
dn: cn<span class="sy0">=</span><span class="re2">VALIDUSERS,ou=GROUPS,ou=JUNK,ou=AK,DC=MYCOMPANY,DC=COM</span>
objectClass: groupOfUniqueNames
cn: validUsers
uniqueMember: uid<span class="sy0">=</span><span class="re2">1234567890,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
...
uniqueMember: uid<span class="sy0">=</span><span class="re2">TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM</span>
&nbsp;
# search result
search: <span class="nu0">2</span>
result: <span class="nu0">0</span> Success
&nbsp;
# numResponses: <span class="nu0">8</span>
# numEntries: <span class="nu0">7</span></pre></div></div>


<p>Connect as a valid user and ask for everything, but according to my ACLs the user can only see itself:
<pre>
ldapsearch -x -D uid=TESTUSER,ou=USERS,OU=JUNK,OU=AK,DC=MYCOMPANY,DC=COM -w testpass -s sub -b "ou=Junk,ou=AK,DC=mycompany,DC=com" "(objectClass=*)"
</pre></p>

<h4>Additional Considerations</h4>

<p><var>chkconfig</var> is the Red Hat tool for managing init scripts&#8211; here&#8217;s how to make sure the slapd starts at boot time.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> chkconfig <span class="re5">--add</span> ldap
$ <span class="kw2">sudo</span> chkconfig ldap on</pre></div></div>


<p>Ah, Mr. Flat Mountain reminds,</p>

<blockquote>
9) Ports for the Firewall

LDAP runs on port 389/tcp by default and LDAP over SSL is 636/tcp.
</blockquote>

<p>Securing communication between the LDAP client and OpenLDAP server with SSL/TLS is beyond my scope here, but it seems to be much better documented.</p>

<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2009/02/ldap-powered-by-mysql-on-rhel5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Compiling DBD::Oracle for Red Hat Linux with the Oracle Instant Client</title>
		<link>http://n8v.enteuxis.org/2008/07/compiling-dbd-oracle-for-linux-with-the-oracle-instant-client/</link>
		<comments>http://n8v.enteuxis.org/2008/07/compiling-dbd-oracle-for-linux-with-the-oracle-instant-client/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 20:59:54 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org.ti.sabren.com/?p=8</guid>
		<description><![CDATA[From my work intrablog, Tuesday, April 29th, 2008. I tested today and the same patch is necessary. It&#8217;s annoying how much harder this is than the MySQL driver&#8230; Download these RPMs from Oracle&#8217;s Instant Client for Linux page:Instant Client Package &#8211; Basic: All files required to run OCI, OCCI, and JDBC-OCI applications Instant Client Package [...]]]></description>
			<content:encoded><![CDATA[<p>From my work intrablog, Tuesday, April 29th, 2008.  I tested today and the same patch is necessary.</p>

<p>It&#8217;s annoying how much harder this is than the MySQL driver&#8230;</p>

<ol>
    <li>Download these RPMs from Oracle&#8217;s <a href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html">Instant Client for Linux</a> page:<strong>Instant Client Package &#8211; Basic</strong>: All files required to run OCI, OCCI, and JDBC-OCI applications
<strong>Instant Client Package &#8211; SDK</strong>: Additional header files and an example makefile for developing Oracle applications with Instant Client
[just for future fun] <strong>Instant Client Package &#8211; ODBC</strong>: Additional libraries for enabling ODBC applications</li>
    <li>Installify them,


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> rpm <span class="re5">-ivh</span> oracle-instantclient-<span class="sy0">*</span>.rpm</pre></div></div>



</li>
    <li>Get DBD::Oracle
<pre>sudo cpan</pre>
<pre>cpan&gt; look DBD::Oracle</pre>
</li>
    <li>Look at <var>README.linux.txt</var></li>
    <li>Set up the environment
<pre>export ORACLE_HOME=/usr/lib/oracle/11.1.0.1/client/lib
export LD_LIBRARY_PATH=$ORACLE_HOME
export LIBPATH=$ORACLE_HOME

export ORACLE_DSN="DBI:Oracle:<samp>host=myhost;sid=MYINSTANCE</samp>"  # remember to quote the ;
export ORACLE_USERID=myusername/<samp>mypassword</samp></pre>
</li>
    <li>I had to patch the Makefile.PL (sent changes to the maintainer) to find the header files with a longer &#8220;client_version_full&#8221;:


<div class="wp_syntax"><div class="code"><pre class="diff"># diff -u Makefile.PL Makefile.PL.dist
<span class="re3">--- Makefile.PL 2008-07-31 10:53:00.253634000 -0800</span>
<span class="re4">+++ Makefile.PL.dist    2008-07-31 10:51:49.327631000 -0800</span>
<span class="re6">@@ -1538,7 +1538,7 @@</span>
     if <span class="br0">&#40;</span>!$client_version_full<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        print &quot;I'm having trouble finding your Oracle version number... trying harder\n&quot;
            unless $force_version;
<span class="re7">-       if <span class="br0">&#40;</span> $OH =~ m!<span class="br0">&#91;</span>^\d\.<span class="br0">&#93;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>?:<span class="nu0">8</span>|<span class="nu0">9</span>|1\d<span class="br0">&#41;</span>\.\d+\.\d+&lt;strong&gt;<span class="br0">&#40;</span>\.\d+<span class="br0">&#41;</span>?&lt;/strong&gt;<span class="br0">&#41;</span>! <span class="br0">&#41;</span> <span class="br0">&#123;</span> #decode it from $OH if possible</span>
<span class="re8">+       if <span class="br0">&#40;</span> $OH =~ m!<span class="br0">&#91;</span>^\d\.<span class="br0">&#93;</span><span class="br0">&#40;</span><span class="br0">&#40;</span>?:<span class="nu0">8</span>|<span class="nu0">9</span>|1\d<span class="br0">&#41;</span>\.\d+\.\d+<span class="br0">&#41;</span>! <span class="br0">&#41;</span> <span class="br0">&#123;</span> #decode it from $OH if possible</span>
            $client_version_full = $1;
        <span class="br0">&#125;</span>
        elsif <span class="br0">&#40;</span> &quot;$OH/&quot; =~ m!\D<span class="br0">&#40;</span><span class="nu0">8</span>|<span class="nu0">9</span>|<span class="nu0">10</span><span class="br0">&#41;</span><span class="br0">&#40;</span>\d<span class="br0">&#41;</span><span class="br0">&#40;</span>\d?<span class="br0">&#41;</span>\D!<span class="br0">&#41;</span> <span class="br0">&#123;</span> # scary but handy</pre></div></div>



</li>
    <li>Install normally:
<pre>perl Makefile.PL
make
make test # a few minor failures
make install</pre>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2008/07/compiling-dbd-oracle-for-linux-with-the-oracle-instant-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

