<?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>thinking sysadmin &#187; Applications</title>
	<atom:link href="http://andyleonard.com/category/applications/feed/" rel="self" type="application/rss+xml" />
	<link>http://andyleonard.com</link>
	<description>qstat -u aleonard -s z</description>
	<lastBuildDate>Sun, 22 Jan 2012 03:46:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>HAProxy and Keepalived: Example Configuration</title>
		<link>http://andyleonard.com/2011/02/01/haproxy-and-keepalived-example-configuration/</link>
		<comments>http://andyleonard.com/2011/02/01/haproxy-and-keepalived-example-configuration/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 05:17:14 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[keepalived]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[vrrp]]></category>

		<guid isPermaLink="false">http://andyleonard.com/?p=628</guid>
		<description><![CDATA[HAProxy is load balancer software that allows you to proxy HTTP and TCP connections to a pool of back-end servers; Keepalived &#8211; among other uses &#8211; allows you to create a redundant pair of HAProxy servers by moving an IP address between HAProxy hosts in an active-passive configuration. Example Network For this example, the following [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://haproxy.1wt.eu/">HAProxy</a> is load balancer software that allows you to proxy HTTP and TCP connections to a pool of back-end servers; <a href="http://www.keepalived.org/">Keepalived</a> &#8211; among other uses &#8211; allows you to create a redundant pair of HAProxy servers by moving an IP address between HAProxy hosts in an active-passive configuration.<br />
<span id="more-628"></span><br />
<strong>Example Network</strong></p>
<p>For this example, the following services are present, or will be configured here:</p>
<ul>
<li>192.168.1.34: Syslog server</li>
<li>192.168.1.68: Web backend #1</li>
<li>192.168.1.69: Web backend #2</li>
<li>192.168.1.80: HAProxy host #1 management address</li>
<li>192.168.1.81: HAProxy host #2 management address</li>
<li>192.168.1.84: Load balancer &#8220;front end&#8221; &#8211; the IP address users will ultimately connect to, managed by Keepalived</li>
<li>192.168.1.119: SMTP server</li>
</ul>
<p>Note that all interfaces are on the same subnet (192.168.1.0/24); the load balancer communicates with the backends on the same interface it uses for client connections.</p>
<p><strong>HAProxy</strong></p>
<p>To install HAProxy on Ubuntu, simply install the &#8220;haproxy&#8221; package; as described above, this example uses two hosts with IP addresses of 192.168.1.80 and 192.168.1.81.  Set &#8220;ENABLED=1&#8243; in /etc/default/haproxy to have the init script that comes with the package start HAProxy.  HAProxy&#8217;s configuration lives at /etc/haproxy/haproxy.cfg:</p>
<pre class="brush: plain; title: ; notranslate">
# this config needs haproxy-1.1.28 or haproxy-1.2.1

global
        # log 127.0.0.1 local0
        # log 127.0.0.1 local1 notice
        log 192.168.1.34 local0
        user haproxy
        group haproxy
        daemon
        maxconn 20000

defaults
        log global
        option dontlognull
        balance leastconn
        clitimeout 60000
        srvtimeout 60000
        contimeout 5000
        retries 3
        option redispatch

listen stats 192.168.1.80:80 # or 192.168.1.81:80 for second HAProxy host
        mode http
        stats enable
        stats uri /stats
        stats realm HAProxy\ Statistics
        stats auth admin:supersecret

listen http 192.168.1.84:80
        mode tcp
        option tcplog
        balance source
        maxconn 10000
        server web01 192.168.1.68:80 maxconn 5000
        server web02 192.168.1.69:80 maxconn 5000

 listen https 192.168.1.84:443
        mode tcp
        option tcplog
        balance roundrobin
        maxconn 10000
        server web01 192.168.1.68:443 maxconn 5000
        server web02 192.168.1.69:443 maxconn 5000
</pre>
<p><strong>Config Notes</strong><br />
06. Send log messages to the syslog server at 192.168.1.34 using the local0 facility<br />
22. Only stats are provided on this interface &#8211; eth0 on the host.<br />
27. Replace &#8220;supersecret&#8221; with your password for the statistics interface.<br />
29. HTTP listener &#8211; 192.168.1.84 is the IP address Keepalived will manage.<br />
30. We are passing HTTP through &#8211; not terminating it on &#8211; the HAProxy host.<br />
31. In case you&#8217;re wondering why we&#8217;re not using Keepalived alone, given that we&#8217;re not terminating HTTP at HAProxy: The log format options available with HAProxy.  (This also gives us the option of changing to HTTP termination in HAProxy later, without installing new software, of course.)<br />
32. Balance based on source address.<br />
34-35. Two HTTP backends.<br />
37. HTTPS listener, again on the Keepalived IP address.<br />
38. HTTPS is also passed through to the web back-ends.<br />
39. See 31 above.<br />
40. Use a round-robin balancing algorithm.<br />
42-43. Two HTTPS backends.</p>
<p>Start HAProxy as follows:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
# service haproxy start
</pre>
<p><strong>Keepalived</strong></p>
<p>Keepalived is installed via the Ubuntu &#8220;keepalived&#8221; package, intuitively enough.  The following entry needs to be made in /etc/sysctl.conf:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
net.ipv4.ip_nonlocal_bind=1
</pre>
<p>(net.ipv4.ip_forward does not need to be set to &#8220;1&#8243; for this type of configuration.)  Run &#8220;sysctl -p&#8221; or reboot to apply the sysctl setting.</p>
<p>The keepalived file &#8211; /etc/keepalived/keepalived.conf &#8211; contains:</p>
<pre class="brush: plain; title: ; notranslate">
global_defs {
    notification_email {
        sysadmin@example.com
    }
    notification_email_from keepalived@haproxy01.example.com
    smtp_server 192.168.1.119
    smtp_connect_timeout 30
}

vrrp_script chk_haproxy { # Requires keepalived-1.1.13
    script &quot;killall -0 haproxy&quot; # widely used idiom
    interval 2 # check every 2 seconds
    weight 2 # add 2 points of prio if OK
}

vrrp_instance VI_1 {
    interface eth0
    state MASTER # or &quot;BACKUP&quot; on backup
    priority 101 # 101 on master, 100 on backup
    virtual_router_id 51

    smtp_alert # Activate SMTP notifications

    authentication {
        auth_type AH
        auth_pass supersecret
    }

    virtual_ipaddress {
        192.168.1.84
    }

    track_script {
        chk_haproxy
    }
}
</pre>
<p><strong>Config Notes</strong><br />
02-07. Configuration for email notifications on master/backup state changes.<br />
10-14. Script to check if HAProxy is still alive. (&#8220;<a href="http://www.google.com/search?q=cheaper+than+pidof">killall -0</a>&#8221; is a common idiom seen in Keepalived configurations; I&#8217;m curious to know the original source.)<br />
18-19. Configure master (or backup).<br />
22. Send SMTP notifications on master/backup state change for this interface.<br />
26. Set authentication password to something better than &#8220;supersecret&#8221; here.<br />
30. IP address of the virtual interface &#8211; in this case, the IP address in front of the load balancer.<br />
34. Use the chk_haproxy script defined above to check whether to fail over this interface or not.</p>
<p>Start the keepalived daemon:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
service keepalived start
</pre>
<p><strong>Acknowledgement:</strong> My co-worker Will Winslow helped with much of the research for this post.<br />
<strong>Reference:</strong> <a href="http://haproxy.1wt.eu/download/1.3/doc/architecture.txt">HAProxy Architecture Guide</a></p>
]]></content:encoded>
			<wfw:commentRss>http://andyleonard.com/2011/02/01/haproxy-and-keepalived-example-configuration/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>One More Useful Tool: f.lux</title>
		<link>http://andyleonard.com/2011/01/13/one-more-useful-tool-f-lux/</link>
		<comments>http://andyleonard.com/2011/01/13/one-more-useful-tool-f-lux/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 19:27:52 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[f.lux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://andyleonard.com/?p=604</guid>
		<description><![CDATA[Following on to my previous post about ack and autojump, one more new-to-me tool that I&#8217;ve become quite fond of is f.lux. When you find yourself passing up your dual-core hot-rod workstation for your underpowered netbook solely because the netbook has f.lux installed, take it as a sign that the creators of f.lux are on [...]]]></description>
			<content:encoded><![CDATA[<p>Following on to my previous post about ack and autojump, one more new-to-me tool that I&#8217;ve become quite fond of is <a href="http://www.stereopsis.com/flux/">f.lux</a>.  When you find yourself passing up your dual-core hot-rod workstation for your underpowered netbook solely because the netbook has f.lux installed, take it as a sign that the creators of f.lux are on to something.</p>
<p>From the f.lux website: &#8220;f.lux makes your computer screen look like the room you&#8217;re in, all the time. When the sun sets, it makes your computer look like your indoor lights. In the morning, it makes things look like sunlight again.&#8221;  For me, the decrease in eye strain is palpable; at night, picking up a mobile phone or even looking at a TV after using a machine with f.lux installed is painful.  (Obviously, if you need accurate color representation, you can&#8217;t have f.lux on; thankfully, temporarily disabling it is a breeze.)</p>
<p>There are are Windows, OS X and Linux versions available; installation on Ubuntu is made easy through a PPA.  Here&#8217;s a little Puppet module for Ubuntu Maverick hosts, if Puppet is your thing:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
class flux {

  exec { &quot;add f.lux ppa&quot;:
    command =&gt; &quot;/usr/bin/apt-add-repository ppa:kilian/f.lux&quot;,
    creates =&gt; &quot;/etc/apt/sources.list.d/kilian-f_lux-maverick.list&quot;,
    notify =&gt; Exec[&quot;apt-get update&quot;],
  }

  package { &quot;fluxgui&quot;:
    ensure =&gt; present,
    require =&gt; Exec[&quot;add f.lux ppa&quot;],
  }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://andyleonard.com/2011/01/13/one-more-useful-tool-f-lux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two Useful Tools: ack and autojump</title>
		<link>http://andyleonard.com/2011/01/08/two-useful-tools-ack-and-autojump/</link>
		<comments>http://andyleonard.com/2011/01/08/two-useful-tools-ack-and-autojump/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 23:51:04 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[cd]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://andyleonard.com/?p=594</guid>
		<description><![CDATA[A recent answer to a question on Quora &#8211; What are some time-saving tips that every Linux user should know? &#8211; suggested two tools I&#8217;ve found very useful: ack and autojump. Ack advertises itself as &#8220;better than grep&#8221; and is &#8220;designed for programmers with large trees of heterogeneous source code.&#8221; In a nutshell, it&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>A recent answer to a question on Quora &#8211; <a href="http://www.quora.com/Linux/What-are-some-time-saving-tips-that-every-Linux-user-should-know">What are some time-saving tips that every Linux user should know?</a> &#8211; suggested two tools I&#8217;ve found very useful: <a href="http://betterthangrep.com/">ack</a> and <a href="https://github.com/joelthelion/autojump">autojump</a>.<br />
<span id="more-594"></span><br />
Ack advertises itself as &#8220;better than grep&#8221; and is &#8220;designed for programmers with large trees of heterogeneous source code.&#8221;  In a nutshell, it&#8217;s a more straightforward tool for searching only one type of code file than combining &#8220;find&#8221; and &#8220;grep&#8221;.  Here&#8217;s an example of it in action, searching only PHP files (.php .phpt .php3 .php4 .php5 .phtml) for the string &#8220;phpinfo&#8221; &#8211; and imagine the output with color highlighting:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
&gt; ack --php phpinfo
utilities.php
141:	   Gather phpinfo into a string variable - This has to be done before
147:	phpinfo(INFO_MODULES);

phpinfo.php
1:&lt;?php phpinfo(); ?&gt;
</pre>
<p>I have a <a href="https://github.com/anl/ack">fork of ack on Github</a> &#8211; a very trivial fork, adding only support for Puppet (.pp) files.  (I did submit a pull request to the author, but he quite reasonably rejected it as he is focused on version two, which will have new features for handling file types.)  (<strong>Update:</strong> See comment below from ack&#8217;s creator on a better way to do this.)</p>
<p>Autojump is &#8220;a cd command that learns.&#8221;  As in, with minimal input, it picks the right directory to jump to based on your previous actions:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
&gt; pwd
/tmp
&gt; j git
/haiku/home/anl/git
&gt; pwd
/haiku/home/anl/git
</pre>
<p>&#8220;jumpstat&#8221; tells you the relative ranking of directories in the autojump database:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
&gt; jumpstat
1.0:	/haiku/home/anl/git/hrc-puppet/modules/puppet
2.0:	/haiku/photos/andy/201012
2.0:	/cloud/leonard/photos/201012
2.0:	/opt
2.0:	/haiku/home/anl/git/hrc-puppet/modules/apt
2.0:	/home/anl/Desktop
[...]
</pre>
<p>Tab completion works, too; typing &#8220;j user&#8221; and three tabs yields the following for me:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
&gt; j user__
user__1__/haiku/home/anl/git/hrc-puppet/modules/users
user__2__/haiku/home/anl/git/ext/puppet/modules/users
</pre>
<p>Installation is straightforward, with an install script and manual instructions.  To scratch my own particular itch, I have a <a href="https://github.com/anl/autojump">fork</a> on Github that adds an install script for non-root users.  (I haven&#8217;t submitted a pull request, and I doubt I will, as I don&#8217;t think my code is particularly useful to most folks; it also isn&#8217;t particularly polished.)</p>
]]></content:encoded>
			<wfw:commentRss>http://andyleonard.com/2011/01/08/two-useful-tools-ack-and-autojump/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drupal Deployment Sysadmin Best Practices</title>
		<link>http://andyleonard.com/2009/12/09/drupal-deployment-sysadmin-best-practices/</link>
		<comments>http://andyleonard.com/2009/12/09/drupal-deployment-sysadmin-best-practices/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 04:14:55 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://andyleonard.com/?p=401</guid>
		<description><![CDATA[Drupal is a popular open source CMS reportedly used on tens of thousands of sites ranging from personal blogs to whitehouse.gov; for readers of this blog, it probably requires no further introduction. Despite its many desirable features and continuing popularity, Drupal is not without its shortcomings, as many readers are also likely aware. Although Drupal [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://drupal.org/">Drupal</a> is a popular open source CMS reportedly used on tens of thousands of sites ranging from personal blogs to <a href="http://www.whitehouse.gov/">whitehouse.gov</a>; for readers of this blog, it probably requires no further introduction.</p>
<p>Despite its many desirable features and continuing popularity, Drupal is not without its shortcomings, as many readers are also likely aware.  Although Drupal has an active and responsive <a href="http://drupal.org/security-team">security team</a>, the software has a long track record of requiring frequent security patches &#8211; Secunia has seven 2009 advisories for <a href="http://secunia.com/advisories/product/17839/?task=advisories_2009">Drupal 6.x</a> listed as of this writing.  Although by its nature an apples-to-oranges comparison, this ranks Drupal behind similarly large and complex PHP projects such as <a href="http://secunia.com/advisories/product/6745/?task=advisories_2009">WordPress 2.x</a> (5) and <a href="http://secunia.com/advisories/product/5879/?task=advisories_2009">Gallery 2.x</a> (0) &#8211; and the number for Drupal does not include dozens of additional advisories for Drupal modules.  Further, Drupal has <a href="http://drupal.org/node/360605">struggled and lagged</a> with support for PHP 5.3.x, suggesting to this outside observer that the project is having difficulties maintaining its codebase.</p>
<p>All that being said, I do not personally believe that the above issues rule out using Drupal; the benefits outweigh the shortcomings.  So, assuming the question is not whether to deploy Drupal, but how to do so most securely and efficiently, my recommendations from a systems administration perspective are below.<br />
<span id="more-401"></span><br />
<strong>Goals</strong></p>
<p>The recommendations described stem from three goals for a Drupal installation:</p>
<ol>
<li><strong>Security</strong> &#8211; Avoid compromise of your site and system.</li>
<li><strong>Flexibility</strong> &#8211; Create an environment that allows for easy modification of the OS, server and application, and provides for straightforward roll-back of those changes should those need arise.</li>
<li><strong>Stability and Security over Performance</strong> &#8211; Although not mutually exclusive, designing for stability and security can entail trade-offs that may impact performance.  I don&#8217;t directly address performance in these recommendations.</li>
</ol>
<p>The below recommendations are written assuming that the sysadmin (you) responsible for the Drupal server and the developer are two different people.  If you wear both hats, the recommendations can obviously adapted to fit your dual role.</p>
<p><strong>Recommendations</strong></p>
<ol>
<li><strong>Insist on the latest version of Drupal, and plan to upgrade as Drupal releases come out.</strong>  Some developers may be hesitant to use the latest (stable) version of Drupal, but Drupal&#8217;s security track record dictates this; anything else is not serving the site owner&#8217;s interests.</li>
<li><strong>Use the latest supported version of PHP.</strong>  Drupal&#8217;s PHP version requirements are more brittle than most applications; the latest version of PHP is almost always the most stable and secure version.  Combining the two is obvious: Aggressively track latest version of PHP that Drupal supports.  Additionally, use the latest version of your preferred web server and patch as it is updated.  Note that this implies a source-based installation of PHP and your web server instead of a package-based installation from your distribution.  Carefully consider your build and deployment strategies with an eye towards reproducibility, documentation and ease of roll-back should a problem arise.</li>
<li><strong>Isolate Drupal from other applications.</strong>  Run Drupal on its own system &#8211; physical or virtual &#8211; and in doing so, reduce operating complexity while limiting collateral damage if your Drupal instance should be compromised.  Depending on your backup strategy, don&#8217;t overlook the possibility that running a VM may have obvious recovery and forensic advantages over a physical install should your Drupal site get broken into.</li>
<li><strong>mod_security</strong> &#8211; Consider integrating a &#8220;web application firewall&#8221; such as <a href="http://www.modsecurity.org/">mod_security</a> directly into your web server.  Carefully evaluate the trade-off of additional complexity for enhanced security in your environment.</li>
<li><strong>Deploy a host-based firewall for inbound and outbound traffic</strong> &#8211; This has two functions &#8211; prevent your server from being compromised through a hole in a service other than your web server, and limit damage to other systems if/when you are compromised.  There&#8217;s a decent chance that the only external service you need exposed other than HTTP for your Drupal site is SSH for remote management &#8211; and you can probably lock that down to a very limited set of IP addresses.  And, in the situation where your server is compromised, outbound rules can reduce the ability of your server to attack other machines: Consider, for example, the effect of an outbound rule on port 25 if an attacker attempts to use your compromised server as a spam bot.</li>
<li><strong>Use SELinux</strong> &#8211; Security-Enhanced Linux provides a the ability to audit and possibly deny actions on your system through <a href="http://en.wikipedia.org/wiki/Mandatory_access_control">mandatory access control policies</a>.  You will likely want to run SELinux in &#8220;permissive&#8221; mode before your site is publicly available, at which point you would switch to &#8220;enforcing&#8221; mode; &#8220;audit2allow&#8221; and &#8220;audit2why&#8221; can be very helpful tools when developing policies.  See &#8220;man selinux&#8221; for more information.</li>
<li><strong>Use a Sysadmin Staging Server</strong> &#8211; The site developer likely has a staging instance of Drupal for testing out their code changes; deploy a similar environment for testing Sysadmin changes, such as PHP updates or the latest version of Drupal with your code.  Consider using a software testing framework such as <a href="http://seleniumhq.org/">Selenium</a> to automate the tests you run on the sysadmin staging site.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://andyleonard.com/2009/12/09/drupal-deployment-sysadmin-best-practices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

