<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<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/"
	>

<channel>
	<title>Small linux deployments &#187; Computer Related</title>
	<link>http://erek.blumenthals.com/blog</link>
	<description>All about the system administration and application development behind a local linux-based company</description>
	<pubDate>Tue, 19 Aug 2008 21:52:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Xen Presentation Slides</title>
		<link>http://erek.blumenthals.com/blog/2008/05/17/xen-presentation-slides/</link>
		<comments>http://erek.blumenthals.com/blog/2008/05/17/xen-presentation-slides/#comments</comments>
		<pubDate>Sun, 18 May 2008 01:09:39 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/05/17/xen-presentation-slides/</guid>
		<description><![CDATA[I just finished a presentation at the Niagara Frontier LUG on Xen virtualization and how it applies to a managed hosting infrastructure.  Here is a copy of the presentation for anyone who&#8217;s interested (sorry, it&#8217;s MS powerpoint.  Yes, I do appreciate the irony).
NFLUG Xen Presentation
It goes over some of the pros and cons [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished a presentation at the Niagara Frontier LUG on Xen virtualization and how it applies to a managed hosting infrastructure.  Here is a copy of the presentation for anyone who&#8217;s interested (sorry, it&#8217;s MS powerpoint.  Yes, I do appreciate the irony).</p>
<p><a href='http://erek.blumenthals.com/blog/wp-content/uploads/2008/05/xen_nflug.ppt' title='NFLUG Xen Presentation'>NFLUG Xen Presentation</a></p>
<p>It goes over some of the pros and cons of all virtualization, different types of virtualization, strategies for achieving levels of availability, and finally, some xen-specific configuration options and tips.</p>
<p><i>Edit:</a>  Mark asked me to clarify the benchmark parameters, so here&#8217;s an excpert of an email that I sent to another reader about this.</p>
<blockquote><p>
as an FYI, the benchmarks were done with:<br />
core 2 duo 1.8Ghz<br />
single 7200RPM 2.5&#8243; drive</p>
<p>The image was done as a .img file on the same partition as the DomU, and the<br />
partition was a separate DOS partition on the same drive.  The only VMWare test<br />
I ran used an image file.  All of the OS installs were cloned from the same directory tree<br />
(stay tuned for a future post on converting a Xen image to vmware)</p>
<p>The Moodle benchmarks were a snapshot of a production moodle install,<br />
where I copied the install to my test system, logged in and clicked a<br />
few things, and replayed the session logs through jmeter several hundred<br />
times with five concurrent threads.</p>
<p>The images benchmark is transfer speed of randomly selecting 1 of 2500<br />
10kb-40kb images.  8 concurrent users and 1500 iterations.</p>
<p>The Mysql benchmark is the results from running all the tests in the<br />
mysql benchmark suite.</p>
<p>Of note, the image file generally performed a little bit better than the<br />
raw partition.  This is counter to what the Xen documentation and common<br />
sense would say, and I think a lot of it has to do with my pretty<br />
limited tests.  The image file was ending up in memory cache, whereas<br />
the block device wasn&#8217;t.  I doubt the same comparitive performance would<br />
play out in a production system where a lot more&#8217;s going on.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/05/17/xen-presentation-slides/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Quick Summary of the SMTP protocol for telnet to port 25</title>
		<link>http://erek.blumenthals.com/blog/2008/02/20/quick-summary-of-smtp-protocol/</link>
		<comments>http://erek.blumenthals.com/blog/2008/02/20/quick-summary-of-smtp-protocol/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 21:18:07 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/02/20/quick-summary-of-smtp-protocol/</guid>
		<description><![CDATA[It often comes up where I&#8217;ve got a mail delivery issue (user n can&#8217;t send email to domain n.com) and it&#8217;s difficult to troubleshoot just with the info in the logs. One thing that sometimes yields useful info is directly telnetting to port 25 of the offending mail server.  This way if it&#8217;s rejecting [...]]]></description>
			<content:encoded><![CDATA[<p>It often comes up where I&#8217;ve got a mail delivery issue (user n can&#8217;t send email to domain n.com) and it&#8217;s difficult to troubleshoot just with the info in the logs. One thing that sometimes yields useful info is directly telnetting to port 25 of the offending mail server.  This way if it&#8217;s rejecting messages you can see the exact reject message, or it could be violating the protocol in some creative way.</p>
<p>I just ran into a succinct protocol description at <a href="http://helpdesk.islandnet.com/pep/smtp.php">http://helpdesk.islandnet.com/pep/smtp.php</a></p>
<p>Here&#8217;s their transcipt of a successful SMTP session.  Be sure to notice the excra line break between the end of the headers and the beginning of the body.</p>
<blockquote><p>
telnet mail.islandnet.com 25<br />
220 Islandnet.com ESMTP server ready<br />
helo a.b.c<br />
250 mail.islandnet.com Hello x [YOUR_IP_ADDRESS]<br />
mail from:<YOUR_ADDRESS><br />
250 <YOUR_ADDRESS> is syntactically correct<br />
rcpt to:<YOUR_ADDRESS><br />
250 <YOUR_ADDRESS> verified<br />
data<br />
354 Enter message, ending with &#8220;.&#8221; on a line by itself<br />
From: Bugs Bunny<br />
To: Daffy Duck<br />
Subject: Loony Toons!</p>
<p>Hi there!<br />
.<br />
250 OK id=1778te-0009TT-00<br />
quit<br />
221 mail.islandnet.com closing connection
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/02/20/quick-summary-of-smtp-protocol/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CentOS Releases patched kernels</title>
		<link>http://erek.blumenthals.com/blog/2008/02/13/centos-releases-patched-kernels/</link>
		<comments>http://erek.blumenthals.com/blog/2008/02/13/centos-releases-patched-kernels/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 13:20:59 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/02/13/centos-releases-patched-kernels/</guid>
		<description><![CDATA[Well, it&#8217;s all over with.  I hope that everyone enjoyed the wild patching frenzy.  Make sure you update your kernel to the CentOS-supported one at your earliest convenience.  I&#8217;ll remove all the kernels except for the ones from the 53.1.4 tree soon to avoid confusion.  Many thanks to everyone in the [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it&#8217;s all over with.  I hope that everyone enjoyed the wild patching frenzy.  Make sure you update your kernel to the CentOS-supported one at your earliest convenience.  I&#8217;ll remove all the kernels except for the ones from the 53.1.4 tree soon to avoid confusion.  Many thanks to everyone in the Redhat and CentOS teams for their quick and diligent responses.</p>
<p>From Centos-Announce</p>
<blockquote><p>
The following updated files have been uploaded and are currently<br />
syncing to the mirrors:</p>
<p>i386:<br />
kernel-2.6.18-53.1.13.el5.i686.rpm<br />
kernel-devel-2.6.18-53.1.13.el5.i686.rpm<br />
kernel-doc-2.6.18-53.1.13.el5.noarch.rpm<br />
kernel-headers-2.6.18-53.1.13.el5.i386.rpm<br />
kernel-PAE-2.6.18-53.1.13.el5.i686.rpm<br />
kernel-PAE-devel-2.6.18-53.1.13.el5.i686.rpm<br />
kernel-xen-2.6.18-53.1.13.el5.i686.rpm<br />
kernel-xen-devel-2.6.18-53.1.13.el5.i686.rpm
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/02/13/centos-releases-patched-kernels/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Update: Redhat releases vmsplice-patched RPMs</title>
		<link>http://erek.blumenthals.com/blog/2008/02/12/update-redhat-releases-vmsplice-patched-rpms/</link>
		<comments>http://erek.blumenthals.com/blog/2008/02/12/update-redhat-releases-vmsplice-patched-rpms/#comments</comments>
		<pubDate>Tue, 12 Feb 2008 18:44:51 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/02/12/update-redhat-releases-vmsplice-patched-rpms/</guid>
		<description><![CDATA[Redhat has released updated RPMs for RHEL 5.1 uncharacteristically quickly, in recognition of the seriousness and internet coverage of the issue: RHSA-2008-0129.  I expect we&#8217;ll see a release from centos soon as well.  Of note, this release does not fix the nfs issues that were present in 2.6.18-53.1.6.
At the suggestion of a Centos [...]]]></description>
			<content:encoded><![CDATA[<p>Redhat has released updated RPMs for RHEL 5.1 uncharacteristically quickly, in recognition of the seriousness and internet coverage of the issue: <a href="https://rhn.redhat.com/errata/RHSA-2008-0129.html">RHSA-2008-0129</a>.  I expect we&#8217;ll see a release from centos soon as well.  Of note, this release does not fix the nfs issues that were present in 2.6.18-53.1.6.</p>
<p>At the suggestion of a Centos mailing list member, I&#8217;ll be posting RPMs from the 2.6.18-53.1.4 release soon, for people who need to run the earlier version because of NFS issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/02/12/update-redhat-releases-vmsplice-patched-rpms/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RHEL 5 / Centos 5 Kernel RPMs patched against vmsplice local root exploit</title>
		<link>http://erek.blumenthals.com/blog/2008/02/11/rhel-5-centos-5-kernel-rpms-patched-against-vmsplice-local-root-exploit/</link>
		<comments>http://erek.blumenthals.com/blog/2008/02/11/rhel-5-centos-5-kernel-rpms-patched-against-vmsplice-local-root-exploit/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 15:26:41 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/02/11/rhel-5-centos-5-kernel-rpms-patched-against-vmsplice-local-root-exploit/</guid>
		<description><![CDATA[I&#8217;ve built the following RPMs for RHEL 5 that fix the vmsplice() exploit in RHEL machines.  They are built off of the 2.6.18-53.1.6.el kernel, with the upstream patch from  kernel.org.  
I&#8217;ve tested them on i686 and x86_64 machines, however be aware that they have not undergone extensive QA, so I&#8217;m not responsible [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve built the following RPMs for RHEL 5 that fix the vmsplice() exploit in RHEL machines.  They are built off of the 2.6.18-53.1.6.el kernel, with the upstream patch from <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=712a30e63c8066ed84385b12edbfb804f49cbc44"> kernel.org</a>.  </p>
<p>I&#8217;ve tested them on i686 and x86_64 machines, however be aware that they have not undergone extensive QA, so I&#8217;m not responsible if they blow up your machine.  That said, I&#8217;m pretty confident that no one will have any problems with them, as they are literally a one-line difference.</p>
<p><b>Update:</b> Reminder to install these with rpm -ivh and not rpm -Uvh.  Otherwise you&#8217;ll remove your old kernels, which you may need to fall back to,. </p>
<p>i686:</p>
<ul>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-2.6.18-53.1.7.el5.erek.i686.rpm">kernel-2.6.18-53.1.7.el5.erek.i686.rpm </a></li>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-devel-2.6.18-53.1.7.el5.erek.i686.rpm">kernel-devel-2.6.18-53.1.7.el5.erek.i686.rpm</a></li>
</ul>
<p>i688-PAE:</p>
<ul>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-PAE-2.6.18-53.1.7.el5.erek.i686.rpm">kernel-PAE-2.6.18-53.1.7.el5.erek.i686.rpm</a></li>
<li><a href="http://erek.blumenthals.com/vmsplicekernels/kernel-PAE-devel-2.6.18-53.1.7.el5.erek.i686.rpm">kernel-PAE-devel-2.6.18-53.1.7.el5.erek.i686.rpm</a> </li>
</ul>
<p>x86_64:</p>
<ul>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-2.6.18-53.1.7.el5.erek.x86_64.rpm">kernel-2.6.18-53.1.7.el5.erek.x86_64.rpm </a></li>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-devel-2.6.18-53.1.7.el5.erek.x86_64.rpm">kernel-devel-2.6.18-53.1.7.el5.erek.x86_64.rpm</a></li>
</ul>
<p>Source:</p>
<ul>
<li> <a href="http://erek.blumenthals.com/vmsplicekernels/kernel-2.6.18-53.1.7.el5.erek.src.rpm">kernel-2.6.18-53.1.7.el5.erek.src.rpm</a></li>
</ul>
<p>Xen, and several other RPMs are available at: <a href="http://erek.blumenthals.com/vmsplicekernels">erek.blumenthals.com/vmsplicekernels</a>.  Note that the PAE and Xen kernels are entirely untested.</p>
<p>As this kernel is an odd-numbered release, yum should pick up the official upstream patch as soon as it&#8217;s available, but in case they do their numbering differently or pick the same release number that I did, it&#8217;d be a good idea to double check that yum picks up the latest.</p>
<p>Let me know any experiences with this, especially any confirmations that it&#8217;s safe with PAE or Xen.</p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/02/11/rhel-5-centos-5-kernel-rpms-patched-against-vmsplice-local-root-exploit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>2.6.17 to 2.6.42.1 Vulnerable to local user privilege escalation</title>
		<link>http://erek.blumenthals.com/blog/2008/02/10/2617-to-26421-vulnerable-to-local-user-privilege-escalation/</link>
		<comments>http://erek.blumenthals.com/blog/2008/02/10/2617-to-26421-vulnerable-to-local-user-privilege-escalation/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 00:19:35 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/02/10/2617-to-26421-vulnerable-to-local-user-privilege-escalation/</guid>
		<description><![CDATA[See http://www.milw0rm.com/exploits/5092 for proof of concept code.
  I&#8217;ve verified this to work:

[erek@centosmachine src]$ uname -a

[erek@centosmachine src]$ ./exploit
-----------------------------------
 Linux vmsplice Local Root Exploit
 By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7fad000 .. 0xb7fdf000
[+] root
[root@centos5machine src]# whoami
root
[root@centos5machine src]#

Ubuntu, [...]]]></description>
			<content:encoded><![CDATA[<p>See <a href="http://www.milw0rm.com/exploits/5092">http://www.milw0rm.com/exploits/5092</a> for proof of concept code.</p>
<p>  I&#8217;ve verified this to work:</p>
<pre>
[erek@centosmachine src]$ uname -a

[erek@centosmachine src]$ ./exploit
-----------------------------------
 Linux vmsplice Local Root Exploit
 By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7fad000 .. 0xb7fdf000
[+] root
[root@centos5machine src]# whoami
root
[root@centos5machine src]#
</pre>
<p>Ubuntu, Centos 5, and most Fedoras seem to be vulnerable.  Centos 4 is not.  I&#8217;m recompiling Centos 5 and FC 3 kernel RPMs with the appropriate patches, and will post them here in an hour or two.  These are using the <a href=http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=712a30e63c8066ed84385b12edbfb804f49cbc44>upstream kernel patch </a> and I&#8217;ll know soon whether they conflict with any of the RHEL-specfic code.  I doubt it does, as it&#8217;s a one-line patch. </p>
<p> And that&#8217;s the sound of 1000 admins running home from their Sunday afternoons to patch their boxes, and the sound of 1000 cell phones going off as their bosses read about this.</p>
<p><b>Update:</b>  Compiler is still going, and I&#8217;m heading out.  I&#8217;ll post the rpms in the morning.</p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/02/10/2617-to-26421-vulnerable-to-local-user-privilege-escalation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Extensible Web Appplication Database Design and Best Practices</title>
		<link>http://erek.blumenthals.com/blog/2008/01/31/extensible-web-appplication-database-design/</link>
		<comments>http://erek.blumenthals.com/blog/2008/01/31/extensible-web-appplication-database-design/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 00:28:33 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/01/31/extensible-web-appplication-database-design/</guid>
		<description><![CDATA[Some open source applications (ex. Request Tracker) have excellent practices when it comes to their database schemas, but a surprising number of them do not.  
This probably stems from many open source authors being programmers first and DBAs second, so the procedural logic is closer to their design decisions than the database schemas. The [...]]]></description>
			<content:encoded><![CDATA[<p>Some open source applications (ex. <a href="http://www.bestpractical.com">Request Tracker</a>) have excellent practices when it comes to their database schemas, but a surprising number of them do not.  </p>
<p>This probably stems from many open source authors being programmers first and DBAs second, so the procedural logic is closer to their design decisions than the database schemas. The other day, when I was reading the installation manual for a popular web calendar system, I came across the following:</p>
<pre>
Next, create the database user account
that will be used to access the database.
<pre><strong>mysql &#8211;user=root mysql</strong>
mysql> <strong>GRANT ALL PRIVILEGES ON *.*
TO webcalendar@localhost
IDENTIFIED BY &#8216;webcal01&#8242;
WITH GRANT OPTION;</strong>
mysql> <strong>FLUSH PRIVILEGES;</strong>
mysql> <strong>QUIT</strong></pre>
</pre>
<p>Obviously giving root mysql access to a single web application is a grave mistake.   This shows an absolute lack of the understanding of database administration. </p>
<p>So, with this example fresh in my head, I&#8217;m going to go through some practices that I&#8217;ve found to be helpful for maintaining extensible database schemas.  As usual, the examples will be tailored to MySQL >4.1 and PHP 5, but there&#8217;s no reason they couldn&#8217;t be adapted to other languages. I&#8217;ve optimized these examples for robustness and auditability, without a lot of regard for disk usage.  Frankly disk space is quite cheap, and throwing away information is rarely the best way to go.</p>
<p>This is in no particular order:</p>
<h3> INSERT data, rather than UPDATEing, and UPDATE rather than DELETEing</h3>
<p>If you&#8217;re building a CMS, when a user modifies a page, you can either add a new row for the modified page, or you can UPDATE the current row.  The difference is that inserting a second row makes rolling back the old page easy, and also allows you to generate a log straight from the database (&#8221;User &#8220;y&#8221; modified page &#8220;z&#8221;.  Diff: &#8230;).  Of course, this makes the SELECTs a little bit uglier:</p>
<p><code> SELECT pagename, content, title FROM pages<br />
WHERE pagename = "foo" ORDER BY timestamp DESC LIMIT 1 </code><br />
versus<br />
<code> SELECT pagename, content, title FROM pages<br />
WHERE pagename = "foo" </code></p>
<p>However, he first option is auditable and rollback-ready, and with a few simple modifications could allow administrator approvals, etc.  The second option requires the user who edits the page to get it right the first time.</p>
<p>Similiarly, if your goal is to remove a user, you can either DELETE that user&#8217;s row, or you can add a boolean Disabled field, and UPDATE them to Disabled instead.  This way you don&#8217;t have to be nearly as careful with referential integrity, as the user&#8217;s primary key still exists,and thus any tables that reference that id will stay consistent.</p>
<h3> When extending your application, add fields and tables, rather than altering existing ones </h3>
<p>If you add a new tables and fields as your functionality grows, rather than modifying the older ones, you can roll back the application to the previous version, and it will<br />
still work as it always did, since all of the data it expects will be in the form it was.  Over time this can result in somewhat bloated database schemas, but good documentation and<br />
cleanup can mitigate this.</p>
<h3>  Enumerate all of the fields you expect will be returned, rather than using wildcards </h3>
<p><code> SELECT * from foo; </code><br />
May break your application when you add extra fields to the database, or if the order of the fields changes, however:<br />
<code> SELECT field1, field2 from foo; </code><br />
will continue to work even as the database schema evolves.</p>
<p>An alternate way of accomplishing the same design goal is to use a wildcard in the SQL but access the fields by name in your application code.  For example:<br />
<code><br />
$result = $mysqli->query('SELECT * from foo;');<br />
$foo = $result->fetch_assoc;<br />
do_stuff_with_fields1_and_2($foo['field1'], $foo['field2'];<br />
</code></p>
<p>This strategy results in even easier application extension, as you can immediately use new fields in your application logic without having to modify your SQL queries.  The disadvantage is that you may be pulling more information out of your database than you plan to use, expending extra memory and loading down the DBMS.</p>
<h3>Use prepared statements whenever possible </h3>
<p>Here are two examples of PHP code that perform the same function (Error handling not included):</p>
<p><code><br />
$searchstringescaped = $mysqiobject->escape_string($searchstring)<br />
$result = $mysqli->query("SELECT foo, bar, bak WHERE bak like '$searchstringescaped'");<br />
while(list($foo, $bar, $bak) = $result->fetch_row()) {<br />
      do_stuff_with_bar_and_bak()<br />
}<br />
</code></p>
<p>Or, with prepared statements:<br />
<code><br />
$stmt = $mysqli->prepare("SELECT foo, bar, bak WHERE bak like ?");<br />
$stmt->bind_param('s', $searchstring);<br />
$stmt->execute();<br />
$stmt->bind_result($foo, $bar, $bak)<br />
while($stmt->fetch()) {<br />
     do_stuff_with_bar_and_bak();<br />
}<br />
</code></p>
<p>While the former may have fewer lines, the second one clearly separates the query logic from the parameters, and eliminates any possibility of SQL injection or double escaping.</p>
<h3> Use Transactions </h3>
<p>(This requires innodb)</p>
<p>Any database statement can fail.  It can be because of  programmer error, hardware failure, or any other host of issues.  When executing a group of statements, it&#8217;s almost always better for all of them to fail than for only some of them to fail.  For example, suppose that you want to transfer credits from one user&#8217;s account to another.  The naive solution would be:<br />
<code><br />
UPDATE users SET credits = credits + 1000 WHERE id = 1;<br />
UPDATE users SET credits = credits - 1000 WHERE id = 2;<br />
</code><br />
However, this code has two problems.  First of all, if there were a power failure at precisely the right time, it would result in both users having the thousand credits.  Second, for a short amount of time, the credits would be in both accounts, and a third client viewing the accounts between the two updates would see inconsistent data.  The proper way to do this would be:<br />
<code><br />
START TRANSACTION;<br />
UPDATE users SET credits = credits + 1000 WHERE id = 1;<br />
UPDATE users SET credits = credits - 1000 WHERE id = 2;<br />
COMMIT;<br />
</code><br />
Or, if you&#8217;re using PHP 5&#8217;s Mysqli extension, you can use the extension&#8217;s interface to transactions like:<br />
</code><br />
$mysqli->autocommit(false);<br />
//Run some mysqli queries<br />
$mysqli->commit();</p>
<p>Finally, if something in the business logic causes you to change your mind about running the transaction, you can call a rollback, which will cancel the last transaction:</p>
<p><code><br />
$mysqli->autocommit(false);<br />
$mysqli->query('UPDATE users SET credits = credits + 1000 WHERE id = 1;');<br />
$mysqli->query('UPDATE users SET credits = credits - 1000 WHERE id = 2;');<br />
$result = $mysqli->query('SELECT credits from users WHERE id = 2');<br />
list($giverbalance) = $result->fetch_row();<br />
if($giverbalance < 0) {<br />
      //Ooops, the giver now has a negative balance.<br />
     $mysqli->rollback();<br />
}<br />
</code></p>
<p>I hope that this helps, in a small way, to further the practices of database developers, and I&#8217;d love to hear any more suggestions or comments people have on the topic.</p>
<p><em>Update (Feb 02 2007): Fixed several grammatical errors </em></p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/01/31/extensible-web-appplication-database-design/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Apparently new Linux/apache web server exploit on the loose</title>
		<link>http://erek.blumenthals.com/blog/2008/01/24/0day-linux-exploit-on-the-loose/</link>
		<comments>http://erek.blumenthals.com/blog/2008/01/24/0day-linux-exploit-on-the-loose/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 23:27:39 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/01/24/0day-linux-exploit-on-the-loose/</guid>
		<description><![CDATA[There&#8217;s a linux worm currently spreading rapidly that exploits web servers.   Finjan  estimates that about 10,000 servers are affected.  Nobody has confirmed how it&#8217;s getting root access, but once it is in, it installs a dynamic apache module that randomly sends java script code to clients.  The javascript code exploits [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a linux worm currently spreading rapidly that exploits web servers.  <a href=http://finjan.com/> Finjan </a> estimates that about 10,000 servers are affected.  Nobody has confirmed how it&#8217;s getting root access, but once it is in, it installs a dynamic apache module that randomly sends java script code to clients.  The javascript code exploits vulnerabilities in Quicktime, Yahoo Messenger, and others.  It attempts to install Rbot, a malware suite on computers that access the sites, using a host of exploits including ones found in Quicktime, Yahoo Messenger, and Windows Media player.</p>
<p>An immediate way to test if you&#8217;re affected is to see if you can create an entirely numeric directory, and if you run into a file not found error, or the directory isn&#8217;t actually created, it means that you&#8217;re infected.  This is a bug in the rootkit, and there are some reports coming in that it&#8217;s already been fixed by the attackers.  A more robust way to check for the exploit is to run the following command:</p>
<p><code> tcpdump -nAs 2048 src port 80 | grep "[a-zA-Z]\{5\}\.js'" </code></p>
<p>and if you see some lines printed, it means that your server is sending infected javascript files.  If your web server is particularly low traffic, you may want to run:</p>
<p><code>ab -c 10 -n 100 http://www.yourdomain.com/somefile.html </code></p>
<p>This will generate some traffic on your web server, so that there are some requests for tcpdump to pick up on.  </p>
<p>I&#8217;ll post more if I hear any news about the nature of the underlying vulnerability.  In the meantime here&#8217;s some further reading:</p>
<ul>
<li><a href=http://finjan.com/Pressrelease.aspx?id=1820&#038;PressLan=1819&#038;lan=3 rel=nofollow> Finjan&#8217;s press release </a> &#8212; A lot of self-promotion, but they were the first major security company to pick it up</li>
<li><a href=http://www.secureworks.com/research/threats/linuxservers/?threat=linuxservers rel=nofollow> Securework&#8217;s press release </a> &#8211;They seem to have found a  variant which doesn&#8217;t install a rootkit, but only installs itself dynamically in apache processes.  <!-- Of note, it turns out that a user running as the same user as apache (easy in a shared hosting environment where php runs as apache) can load a dynamic apache module into apache processes.  We'll probably be seeing this method used more, as it allows a lot of control without gaining root access. --> </li>
<li><a href=http://servertune.com/kbase/entry/258/ rel=nofollow> Servertune </a> &#8212; A good overview of the issue</li>
<li><a href=http://www.webhostingtalk.com/showthread.php?t=651748 rel=nofollow> Web Hosting Talk Thread </a> A highly trafficked message board thread on the issue</li>
<li><a href="http://www.cpanel.net/security/notes/random_js_toolkit.html" rel=nofollow>cPanel&#8217;s analysis of the issue </a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/01/24/0day-linux-exploit-on-the-loose/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Clusterssh:  Run the same commands simultaneously on multiple servers</title>
		<link>http://erek.blumenthals.com/blog/2008/01/21/clusterssh-run-simultaneous-commands-on-multiple-servers/</link>
		<comments>http://erek.blumenthals.com/blog/2008/01/21/clusterssh-run-simultaneous-commands-on-multiple-servers/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 18:51:50 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Computer Related]]></category>

		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/01/21/clusterssh-run-simultaneous-commands-on-multiple-servers/</guid>
		<description><![CDATA[I&#8217;ve recently discovered clusterssh, a tool that opens up many xterm sessions and binds them all to one keyboard input.  I use it for updating my servers or reconfiguring them all in the same way.  For example, since most of my boxes run the same OS version, they all need package updates at [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently discovered <a href="http://clusterssh.wiki.sourceforge.net/">clusterssh</a>, a tool that opens up many xterm sessions and binds them all to one keyboard input.  I use it for updating my servers or reconfiguring them all in the same way.  For example, since most of my boxes run the same OS version, they all need package updates at the same time, so after I get a flurry of &#8220;Update available&#8221; emails I have a quick look at an eratta site to see what problems I&#8217;m fixing, and then I fire up clusterssh and run (for example) sudo yum update.  Here&#8217;s a quick screenshot to show it in action:<br />
<a href='http://erek.blumenthals.com/blog/wp-content/uploads/2008/01/cssh.png' title='Clusterssh'><img src='http://erek.blumenthals.com/blog/wp-content/uploads/2008/01/cssh.thumbnail.png' alt='Clusterssh' /></a><br />
It works with clusters of servers, so you&#8217;ll have a configuration file like (~/.csshrc):<br />
<code><br />
clusters = web-servers all-servers special-servers<br />
all-servers = erek@libra.blumenthals.com erek@aquarius.blumenthals.com erek@scorpio.blumenthals.com erek@webserver1.blumenthals.com erek@webserver2.blumenthals.com<br />
web-servers = erek@webserver1.blumenthals.com erek@webserver2.blumenthals.com<br />
special-servers = erek@libra.blumenthals.com erek@aquarius.blumenthals.com erek@scorpio.blumenthals.com<br />
</code><br />
Obviously, it works best if you have ssh keys set up to all of your servers.  Then you can just run cssh <clustername>, and it pops up ssh sessions with each of those servers.  A simple tool that saves you a lot of time.</p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/01/21/clusterssh-run-simultaneous-commands-on-multiple-servers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Thoughts about Sun&#8217;s MySQL acquisition</title>
		<link>http://erek.blumenthals.com/blog/2008/01/17/thoughts-about-suns-mysql-acquisition/</link>
		<comments>http://erek.blumenthals.com/blog/2008/01/17/thoughts-about-suns-mysql-acquisition/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 22:49:31 +0000</pubDate>
		<dc:creator>Erek Dyskant</dc:creator>
		
		<category><![CDATA[Business Issues]]></category>

		<category><![CDATA[Computer Related]]></category>

		<guid isPermaLink="false">http://erek.blumenthals.com/blog/2008/01/17/thoughts-about-suns-mysql-acquisition/</guid>
		<description><![CDATA[By now it&#8217;s been reported all  over   the   internet  that Sun is buying MySQL, AB for approximately $1 billion.  This is either the largest or smallest news of the new year.  As of 2005, MySQL&#8217;s revenue was $40 million, and according to Sun&#8217;s press release, they have [...]]]></description>
			<content:encoded><![CDATA[<p>By now it&#8217;s been reported <a href="http://www.linuxscrew.com/2008/01/16/sun-acquires-mysql-ab/">all</a> <a href="http://blogs.sun.com/jonathan/entry/winds_of_change_are_blowing"> over </a> <a href="http://datadoghouse.typepad.com/data_doghouse/2008/01/why-did-sun-buy.html"> the </a> <a href="http://www.sun.com/aboutsun/media/presskits/2008-0116/index.jsp?intcmp=hp2008jan16_mysql_learn"> internet </a> that Sun is buying MySQL, AB for approximately $1 billion.  This is either the largest or smallest news of the new year.  As of 2005, MySQL&#8217;s revenue was $40 million, and according to Sun&#8217;s press release, they have about 400 employees.  To me, this doesn&#8217;t seem that it justifies the $1 billion price tag, so Sun is buying them for reasons other than a straight return potential.
</p>
<p>
On the cynical side, they could be looking to build it up to a second oracle, with a small free version and requiring a purchase for any of the newer enterprise features.  I doubt this is the case, as Sun should recognize that much of the MySQL appeal comes from its image as an open free program with the availability of rock solid support.  However, I wouldn&#8217;t be surprised if we see MySQL Enterprise&#8217;s base prices (currently $600-$4000/server/year or $40,000/year for a site license ) go up a bit to help pay off Sun&#8217;s investment and close the gap with Oracle (~$40,000/CPU).
</p>
<p>First of all, quite a few online disucssions have centered around &#8220;Why not postgres?&#8221;  I think that this is the easiest question to answer:  Regardless of the technical merits of each system, MySQL is currently the web application leader.  Furthermore, Postgres isn&#8217;t a company, so it can&#8217;t be bought.  Sure, Sun could announce that they are putting serious development resources behind postgres, and offering paid support options, or they could go the EnterpriseDB route and fork postgres into a commercial and commercially supported product, but neither of those give them the same control of a stable and highly adopted database product that  owning MySQL AB does for them.  More importantly, it doesn&#8217;t expose them to MySQL&#8217;s impressive customer portfolio.
</p>
<p>
By buying MySQL, Sun is showing that they&#8217;re interested in becoming more like Oracle and IBM, the enterprise consulting company.  Since many of the larger and data intensive technology companies (Baidu, Google, Facebook, Ticketmaster, Dunn &#038; Bradstreet) use MySQL, they are buying themselves ins to the who&#8217;s-who of technology, and just the companies that wouldn&#8217;t have previously been Sun customers  (none have a need for Java, they tend to use whitebox clusters, etc)  However, now that Sun owns MySQL, there&#8217;ll be the opportunity to sell complete solutions to enterprises based upon the LAMP stack.
</p>
<p>
Several concerns come to mind:  Since Sun has a vested interest in Solaris and their own hardware, optimizations and new features may come to Solaris and Sun storage systems before it makes it to the other platforms, or we may end up with a whole set of features that only work with Solaris and/or on Sun hardware.  Also, Mysql AB was a known.  We could count on them to provide a steady stream of new features for both the paid and unpaid versions, reasonably responsive unpaid support via mailing lists, and excellent (if verbose) documentation.  With Sun, we can expect all these things and more to be provided to paying customers, but it remains to be seen what will happen to the community version.
</p>
<p>
I&#8217;m actually happy to see Sun emerging as one more of the behemoth consulting companies, as that was starting to become somewhat of a duopoly, but I just hope it doesn&#8217;t come at the expense of fixing something that wasn&#8217;t broken (MySQL AB).</p>
]]></content:encoded>
			<wfw:commentRss>http://erek.blumenthals.com/blog/2008/01/17/thoughts-about-suns-mysql-acquisition/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
