<?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>Standing On The Shoulders Of Ants &#187; Linux Administration</title>
	<atom:link href="http://blog.defsdoor.org/category/linux-admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.defsdoor.org</link>
	<description>It&#039;s the little guys that counts</description>
	<lastBuildDate>Tue, 10 Apr 2012 21:24:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The Origin</title>
		<link>http://blog.defsdoor.org/2012/04/10/the-origin/</link>
		<comments>http://blog.defsdoor.org/2012/04/10/the-origin/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 21:24:27 +0000</pubDate>
		<dc:creator>defsdoor</dc:creator>
				<category><![CDATA[Linux Administration]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[videos]]></category>

		<guid isPermaLink="false">http://blog.defsdoor.org/?p=60</guid>
		<description><![CDATA[This was an entry in the Linux Foundation&#8217;s We Are Linux competition in 2009. It&#8217;s very well done &#8211; a slight translation mishap aside (that actually works well) &#8211; the...]]></description>
			<content:encoded><![CDATA[<p>This was an entry in the Linux Foundation&#8217;s We Are Linux competition in 2009.  It&#8217;s very well done &#8211; a slight translation mishap aside (that actually works well) &#8211; the ending still gives me tingles.</p>
<p><iframe src="http://player.vimeo.com/video/3771567?title=0&amp;byline=0&amp;portrait=0" width="400" height="220" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><a href="http://vimeo.com/3771567">The Origin&#8230;</a> from <a href="http://vimeo.com/user991497">Agustin Eguia</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.defsdoor.org/2012/04/10/the-origin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>20 Years Of Linux</title>
		<link>http://blog.defsdoor.org/2012/04/10/20-years-of-linux/</link>
		<comments>http://blog.defsdoor.org/2012/04/10/20-years-of-linux/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 21:13:09 +0000</pubDate>
		<dc:creator>defsdoor</dc:creator>
				<category><![CDATA[Linux Administration]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[videos]]></category>

		<guid isPermaLink="false">http://blog.defsdoor.org/?p=58</guid>
		<description><![CDATA[Another Linux video]]></description>
			<content:encoded><![CDATA[<p>Missed this video when it first came out&#8230;.</p>
<p><iframe width="620" height="349" src="http://www.youtube.com/embed/5ocq6_3-nEw?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.defsdoor.org/2012/04/10/20-years-of-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IBM Prodigy Advert</title>
		<link>http://blog.defsdoor.org/2012/04/03/ibm-prodigy-advert/</link>
		<comments>http://blog.defsdoor.org/2012/04/03/ibm-prodigy-advert/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 19:17:27 +0000</pubDate>
		<dc:creator>defsdoor</dc:creator>
				<category><![CDATA[Linux Administration]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[videos]]></category>

		<guid isPermaLink="false">http://blog.defsdoor.org/?p=53</guid>
		<description><![CDATA[This very prophetic IBM advert is, believe it or not, from 2003.]]></description>
			<content:encoded><![CDATA[<p>This very prophetic IBM advert is, believe it or not, from 2003.</p>
<p><iframe width="620" height="465" src="http://www.youtube.com/embed/vV_mSNI_b8Q?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.defsdoor.org/2012/04/03/ibm-prodigy-advert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Videos</title>
		<link>http://blog.defsdoor.org/2012/04/03/linux-videos/</link>
		<comments>http://blog.defsdoor.org/2012/04/03/linux-videos/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 19:07:54 +0000</pubDate>
		<dc:creator>defsdoor</dc:creator>
				<category><![CDATA[Linux Administration]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[videos]]></category>

		<guid isPermaLink="false">http://blog.defsdoor.org/?p=49</guid>
		<description><![CDATA[I&#8217;ve just watched this new video, posted by the Linux Foundation, on Linux collaborative development. It&#8217;s inspired me to dig out some of the old Linux videos so I&#8217;ll post...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just watched this new video, posted by the Linux Foundation, on Linux collaborative development. It&#8217;s inspired me to dig out some of the old Linux videos so I&#8217;ll post a few more over the next few days.</p>
<p><iframe width="620" height="349" src="http://www.youtube.com/embed/yVpbFMhOAwE?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.defsdoor.org/2012/04/03/linux-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Large Openvpn Server Deployment</title>
		<link>http://blog.defsdoor.org/2011/06/02/large-openvpn-server-deployment/</link>
		<comments>http://blog.defsdoor.org/2011/06/02/large-openvpn-server-deployment/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 21:53:18 +0000</pubDate>
		<dc:creator>defsdoor</dc:creator>
				<category><![CDATA[Linux Administration]]></category>
		<category><![CDATA[Openvpn]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[openvpn]]></category>

		<guid isPermaLink="false">http://blog2.defsdoor.org/?p=5</guid>
		<description><![CDATA[How to configure and deploy openvpn for 1000+ users.]]></description>
			<content:encoded><![CDATA[<p>I was recently asked if I could build and deploy an Openvpn Server that could cope with 400 clients.</p>
<p>I’ve been using Openvpn for at least 8 years in both client to server and server to server contexts without any issues and was confident that this project wouldn’t be a problem. Without any real concurrency data I assumed that only 10% of users would be connected or active at any time so therefore 40 connections wouldn’t be a problem on the hardware I was going to use.</p>
<p>However I decided that I had to tackle any potential obstacles to deployment before they were raised so I set out to determine if Openvpn could cope with 400 simultaneous active connections and to ensure that there was enough security to prevent unauthorized access.</p>
<p>Information on large scale Openvpn deployments is hard to come by – no one wants to discuss their VPN solutions openly for obvious reasons, but there is anecdotal discussion of over 1000 simultaneous connections working fine.</p>
<p>There is also mention of a typical CPU hitting a wall at 250 active connections. This is purely down to the amount of CPU time it takes to encrypt and decrypt the traffic – it can only do so much, but again there are no specifics available on what type or speed of CPU this is on. So all I really knew is that I needed enough CPU power for 400 active connections and I couldn’t rely on a single CPU to deliver this.</p>
<p>I’ve always said that you can tell when a program or application you are using is good by the number of different ways there are to solve a problem. This generally means that the developers understood fully the problem they were solving and the many ways their program would be used. Openvpn has more configuration options than you could imagine and I had to select wisely the way I delivered this.</p>
<p>The solution I ended up with runs 4 instances of openvpn on a single server with each process bound to a CPU (or core). I wrote an authentication plugin to perfom simple htpasswd based authentication for users and installed a modified Windows GUI that talks to the openvpn management interface to provide user authentication details. When clients connect DNS is updated so support staff can access them by host name.</p>
<h1>4 Openvpn Instances</h1>
<p>With 4 instances of openvpn – each of them bound to a specific CPU – in theory the processing wall will now be at least 1000 active connections. Each instance has to listen on it’s own port though and also has to serve a separate subnet so that traffic can be routed correctly back to the right tun device. This isn’t a problem though as long as each subnet is inside a larger one that I can add specific routes to from the internal network.</p>
<p>I could have gone with a single configuration file and provided the variances for each server on the command line but I decided to have 4 separate openvpn configuration files – server0.conf, server1.conf, server2.conf and server3.conf, and I modified the openvpn init.d startup script to extract the numeric part of the server name and use that as the CPU affinity to bind to using the handy <code>taskset</code> program.</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">diff /etc/init.d/openvpn
<span style="color: #440088;">25c25,26</span>
&amp;lt; DAEMON=/usr/sbin/openvpn
<span style="color: #991111;">- - -</span>
&amp;gt; DAEMON=/usr/bin/taskset
&amp;gt; DAEMON2=/usr/sbin/openvpn
<span style="color: #440088;">57a59,60</span>
&amp;gt;   CPU=`echo $NAME | sed 's/<span style="">&#91;</span>A-Za-z<span style="">&#93;</span>*//g'`
&amp;gt;
<span style="color: #440088;">63c66</span>
&amp;lt;   --exec $DAEMON -- $OPTARGS --writepid /var/run/openvpn.$NAME.pid \
<span style="color: #991111;">- - -</span>
&amp;gt;   --exec $DAEMON --  $OPTARGS -c $CPU $DAEMON2 --writepid /var/run/openvpn.$NAME.pid \</pre></div></div>

<p>Doing it this way also means I can easily stop and start specific instances and the usual startup process will start all 4 instances automatically as it looks for and starts an instance for each *.conf file in /etc/openvpn.</p>
<p>Each instance has a limit to the number of connected clients set to 250 – this ensures that no one instance can get overloaded.</p>
<p>The differences between two instances’ config files are below -</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">server0.conf
port 1194
ifconfig 10.250.0.1 10.250.0.2
route 10.250.0.0 255.255.252.0
push &quot;route 10.250.0.1&quot;
ifconfig-pool 10.250.0.4 10.250.3.251 # 255 clients sized pool
status /etc/openvpn/openvpn-status0.log
log-append /var/log/openvpn/server0.log</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">server1.conf
port 1195
ifconfig 10.250.4.1 10.250.4.2
route 10.250.4.0 255.255.252.0
push &quot;route 10.250.4.1&quot;
ifconfig-pool 10.250.4.4 10.250.4.251 # 255 clients sized pool
status /etc/openvpn/openvpn-status1.log
log-append /var/log/openvpn/server1.log</pre></div></div>

<p>A full server config can be found towards the end of this post.</p>
<h1>Load Balancing</h1>
<p>The client configuration specifies 4 separate remote hosts to connect to. The addition of the remote-random directive tells the client to randomise the list and try each one in turn. This should balance out the number of clients connected fairly evenly but in the event of the client being rejected by an instance that is at it’s 250 client limit, the client will simply try the next instance.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">client.ovpn
remote vpn.example.com 1194
remote vpn.example.com 1195
remote vpn.example.com 1196
remote vpn.example.com 1197
remote-random</pre></div></div>

<h1>Scaling Even Further</h1>
<p>By adding multiple DNS records for vpn.example.com I can also replicate the vpn setup onto another server and very simply cope with twice as many clients. This would require some syncing of certificates and authentication data but is by no means a difficult task.</p>
<h1>User Authentication</h1>
<p>With windows clients you have to run the openvpn process as a user that has the privilege to add to and amend the routing table. The best way to do this is to run the process as a service, but this then means that there is no way to interact with the user.</p>
<p>Luckily openvpn now has a management interface in the form of a socket that you can connect to and talk to the process. There is a modified version of the standard openvpn-gui program that supports the management interface available here and with the following additions to the openvpn client configuration file the user is prompted for user/pass whenever they try to connect.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">client.ovpn
management 127.0.0.1 7777
management-hold
management-query-passwords auth-retry interact</pre></div></div>

<p>All that is required then is to add some form of authentication to the server. I chose a simple method using htpasswd format files. This meant I could use the existing htpasswd tools to add and amend users etc..</p>
<p>I couldn’t find an existing simple auth plugin for openvpn so I wrote my own (I love the excuse to do a bit of C every now and then.)</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">openvpn<span style="color: #339933;">-</span>passwd.<span style="color: #202020;">c</span>
<span style="color: #808080; font-style: italic;">/*
 *
 *  gcc -o openvpn-passwd openvpn-passwd.c -lcrypt
 *
 */</span>
<span style="color: #339933;">#include </span>
<span style="color: #339933;">#define _XOPEN_SOURCE</span>
<span style="color: #339933;">#include </span>
<span style="color: #339933;">#include </span>
<span style="color: #339933;">#include </span>
&nbsp;
<span style="color: #993333;">void</span> chomp<span style="color: #009900;">&#40;</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>s <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> get_user_password<span style="color: #009900;">&#40;</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> user_name <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> password_file<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> verify_password_file<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> input_line<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1024</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
FILE <span style="color: #339933;">*</span> vpf<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> user_name<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> user_password<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> crypted_password<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> salt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> crypt_output<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> argc <span style="color: #339933;">!=</span> <span style="color: #0000dd;">3</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Usage: %s PasswordFile VerifyPasswordFile<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> argv<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">99</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  password_file <span style="color: #339933;">=</span> argv<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  verify_password_file <span style="color: #339933;">=</span> argv<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Get user name and password from verification file</span>
  vpf <span style="color: #339933;">=</span> fopen<span style="color: #009900;">&#40;</span>verify_password_file<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;r&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> vpf <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    perror<span style="color: #009900;">&#40;</span>verify_password_file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> fgets<span style="color: #009900;">&#40;</span> input_line<span style="color: #339933;">,</span> <span style="color: #0000dd;">1023</span><span style="color: #339933;">,</span> vpf<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Invalid verification file<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  chomp<span style="color: #009900;">&#40;</span> input_line <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  user_name <span style="color: #339933;">=</span> strdup<span style="color: #009900;">&#40;</span> input_line <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> fgets<span style="color: #009900;">&#40;</span> input_line<span style="color: #339933;">,</span> <span style="color: #0000dd;">1023</span><span style="color: #339933;">,</span> vpf<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Invalid verification file<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  chomp<span style="color: #009900;">&#40;</span> input_line <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  user_password <span style="color: #339933;">=</span> strdup<span style="color: #009900;">&#40;</span> input_line <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  fclose<span style="color: #009900;">&#40;</span> vpf <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> crypted_password <span style="color: #339933;">=</span> get_user_password<span style="color: #009900;">&#40;</span> user_name <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  strncpy<span style="color: #009900;">&#40;</span> salt<span style="color: #339933;">,</span> crypted_password<span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  salt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #339933;">;</span>
&nbsp;
  crypt_output <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#41;</span> crypt<span style="color: #009900;">&#40;</span> user_password<span style="color: #339933;">,</span> salt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>strcmp<span style="color: #009900;">&#40;</span>crypted_password<span style="color: #339933;">,</span> crypt_output <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> chomp<span style="color: #009900;">&#40;</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>s <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> c <span style="color: #339933;">=</span> s <span style="color: #339933;">+</span> strlen<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">*</span>c <span style="color: #339933;">==</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span>c<span style="color: #339933;">--</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #808080; font-style: italic;">/*
 * Returns the crypted password from the password file for a specified user
 */</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> get_user_password<span style="color: #009900;">&#40;</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> user_name <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
FILE <span style="color: #339933;">*</span> pf<span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span> s<span style="color: #339933;">;</span>
  pf <span style="color: #339933;">=</span> fopen<span style="color: #009900;">&#40;</span>password_file<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;r&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> pf <span style="color: #339933;">==</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    perror<span style="color: #009900;">&#40;</span>password_file<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span><span style="color: #009900;">&#40;</span>NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> fgets<span style="color: #009900;">&#40;</span> input_line<span style="color: #339933;">,</span> <span style="color: #0000dd;">1023</span><span style="color: #339933;">,</span> pf <span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> NULL <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    chomp<span style="color: #009900;">&#40;</span>input_line<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    s <span style="color: #339933;">=</span> input_line<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>s <span style="color: #339933;">!=</span> <span style="color: #ff0000;">':'</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #339933;">*</span>s <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span> s<span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>s <span style="color: #339933;">==</span> <span style="color: #ff0000;">':'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #339933;">*</span>s <span style="color: #339933;">=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>strcmp<span style="color: #009900;">&#40;</span> user_name<span style="color: #339933;">,</span> input_line <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        s<span style="color: #339933;">++;</span>
        fclose<span style="color: #009900;">&#40;</span> pf <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// Invalid password file line</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
  fclose<span style="color: #009900;">&#40;</span> pf <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span><span style="color: #009900;">&#40;</span> NULL <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The server directive for authentication is -</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">server0.conf
auth-user-pass-verify &quot;/etc/openvpn/openvpn-passwd /etc/openvpn/passwd&quot; via-file</pre></div></div>

<h1>Updating DNS</h1>
<p>I also wanted IT support to be able to access or refer to the client by client name if remote support was needed. Because I have 4 instances serving different subnets I could not simply allocate static IP addresses per client as the IP would be different depending on the instance that the client just happened to be connected to. So I made use of openvpn’s learn-address option</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">server0.conf
script-security 2 execve
learn-address /etc/openvpn/learn_address</pre></div></div>

<p>learn-address is a simple script which, using nsupdate, removes any DNS and reverse DNS entries for the client and it’s IP address and then inserts new relevant entries.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>openvpn<span style="color: #000000; font-weight: bold;">/</span>learn-address
<span style="color: #666666; font-style: italic;">#!/bin/ksh</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #007800;">IP</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ifconfig_pool_remote_ip</span>&quot;</span>
<span style="color: #007800;">NAME</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$common_name</span>&quot;</span>
&nbsp;
. <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>openvpn<span style="color: #000000; font-weight: bold;">/</span>vpn.ctl
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> revip <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">|</span>
  <span style="color: #c20cb9; font-weight: bold;">nawk</span> -F. <span style="color: #ff0000;">'{print $4&quot;.&quot;$3&quot;.&quot;$2&quot;.&quot;$1}'</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #007800;">DNSKEY</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">nawk</span> <span style="color: #ff0000;">'{print $7}'</span> <span style="color: #007800;">$DNSKEYFILE</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #007800;">REVIP</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>revip <span style="color: #007800;">$IP</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">umask</span> 0077
<span style="color: #007800;">UPDATEFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>nsupdate.<span style="color: #007800;">$$</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt; <span style="color: #007800;">$UPDATEFILE</span> <span style="color: #000000; font-weight: bold;">&amp;</span>lt;<span style="color: #000000; font-weight: bold;">&amp;</span>lt; EOF
server localhost
key vpnupdate <span style="color: #007800;">$DNSKEY</span>
update delete <span style="color: #007800;">$REVIP</span>.in-addr.arpa.
&nbsp;
update delete <span style="color: #007800;">$NAME</span>.<span style="color: #007800;">$VPNZONE</span>.
&nbsp;
update add <span style="color: #007800;">$NAME</span>.<span style="color: #007800;">$VPNZONE</span>. <span style="color: #007800;">$TTL</span> IN A <span style="color: #007800;">$IP</span>
&nbsp;
update add <span style="color: #007800;">$REVIP</span>.in-addr.arpa. <span style="color: #007800;">$TTL</span> PTR <span style="color: #007800;">$NAME</span>.<span style="color: #007800;">$VPNZONE</span>.
&nbsp;
EOF
nsupdate <span style="color: #007800;">$UPDATEFILE</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span>  <span style="color: #007800;">$UPDATEFILE</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span></pre></div></div>

<p>This is simple to follow but note that it takes some settings from variables defined in the vpn.ctl file. The two zones serve as masters that the main nameservers can then transfer from as slaves. A short TTL (defined in vpn.ctl) ensures that IP address changes will propagate swiftly.</p>
<h1>Additional Configuration</h1>
<p>I specify client-config-dir and also ccd-exclusive in the server configuration. This is so that if I revoke a certificate and later remove it, when the revocation list is rebuilt the client will still not be able to connect as I also remove the client’s ccd directory.</p>
<p>I manage the setup, addition, revocation and removal of clients and settings of user password etc.. with a simple script that presents a menu if no command line arguments are specified but can also be command line driven to allow bulk/scripted creation.<br />
Password Generator</p>
<p>One of the problems users have is remembering passwords. I.T. departments typically generate either complex ones that the user has to write down somewhere (therefore no security) or use the same password for all users (just as bad).</p>
<p>So I decided to write a generator of simple but remember-able passwords. I did this by pulling out all of the 4-8 letter words (34757 in total) from a local dictionary and then picking 2 words at random and joining them together.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">makepassword
<span style="color: #000000; font-weight: bold;">function</span> makepassword <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #007800;">WORD1</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>getrandomword<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  <span style="color: #007800;">WORD2</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>getrandomword<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$WORD1</span><span style="color: #007800;">$WORD2</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> getrandomword <span style="color: #7a0874; font-weight: bold;">&#123;</span>
 <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$RANDOM</span> <span style="color: #000000; font-weight: bold;">%</span> <span style="color: #000000;">34757</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">'p'</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>openvpn<span style="color: #000000; font-weight: bold;">/</span>words
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>It might seem obvious but the sheer number of permutations (over a billion) mean its practically unbreakable and even more so without local access to the encrypted passwords.</p>
<p>It’s output is surprisingly good, but I give the user the option of generating a different password until they see one they like.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Some Examples
lingoesbumper
silkylibrary
persistfridge
arrestedcomb
freshendingiest
lovergiveaway
shamingsaltier
hoodingcrumbs
scorpionigloos
checkedsimulate
telexhiking
donatingtalk
gruesomedefer
hansomschiffon
bedrockschewers
totalledjewelled
prolixgenders</pre></div></div>

<p>I have spawned this idea into a <a href="http://sensiblepassword.com/">dedicated password generator website</a></p>
<h1>Server Configuation File</h1>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">dev tun
port 1194
&nbsp;
max-clients 250
mode server
tls-server
&nbsp;
push &quot;topology net30&quot;
&nbsp;
ifconfig 10.250.0.1 10.250.0.2
route 10.250.0.0 255.255.252.0
push &quot;route 10.250.0.1&quot;
&nbsp;
ifconfig-pool 10.250.0.4  10.2510.250.251
tmp-dir /tmp
script-security 2 execve
&nbsp;
user nobody
group nogroup
&nbsp;
proto udp
dh /etc/openvpn/keys/dh1024.pem
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
crl-verify /etc/openvpn/keys/crl.pem
tls-auth /etc/openvpn/keys/ta.key 0
cipher BF-CBC
&nbsp;
push &quot;register-dns&quot;
push &quot;dhcp-option DNS 10.0.0.10&quot;
push &quot;dhcp-option WINS 10.0.0.10&quot;
push &quot;dhcp-option DOMAIN lan.3gcomms.co.uk&quot;
push &quot;route 10.0.0.0 255.255.255.0&quot;
push &quot;route 10.0.0.0 255.0.0.0&quot;
push &quot;explicit-exit-notify&quot;
&nbsp;
auth-user-pass-verify &quot;/etc/openvpn/openvpn-passwd /etc/openvpn/passwd&quot; via-file
&nbsp;
client-config-dir ccd
ccd-exclusive
&nbsp;
keepalive 10 30
comp-lzo
persist-key
persist-tun
status /etc/openvpn/openvpn-status0.log
verb 4
&nbsp;
client-config-dir /etc/openvpn/ccd
learn-address /etc/openvpn/learn_address
log-append /var/log/openvpn/server0.log</pre></div></div>

<h1>Client Config</h1>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">dev tun
pull
remote vpn.example.com 1194
remote vpn.example.com 1195
remote vpn.example.com 1196
remote vpn.example.com 1197
remote-random
&nbsp;
tls-client
ca ca.crt
cert %%CLIENT%%.crt
key %%CLIENT%%.key
tls-auth ta.key 1
auth-user-pass
cipher BF-CBC
remote-cert-tls server
management 127.0.0.1 7777
management-hold
management-query-passwords
auth-retry interact
&nbsp;
comp-lzo
verb 3</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.defsdoor.org/2011/06/02/large-openvpn-server-deployment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

