<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Webtatic.com</title>
	
	<link>http://www.webtatic.com</link>
	<description>Just another technical blog</description>
	<lastBuildDate>Tue, 07 Sep 2010 20:15:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BlogWebtaticcom" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="blogwebtaticcom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://www.webtatic.com/?pushpress=hub" /><item>
		<title>Page-level caching with Nginx</title>
		<link>http://www.webtatic.com/blog/2010/04/page-level-caching-with-nginx/</link>
		<comments>http://www.webtatic.com/blog/2010/04/page-level-caching-with-nginx/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 10:49:40 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Server Admin]]></category>
		<category><![CDATA[Web Optimisation]]></category>
		<category><![CDATA[Nginx]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=566</guid>
		<description><![CDATA[Since my last post on using Nginx to cache proxied content, they have added proper cache handling via their proxy_cache* directives. These are much more suitable for use, as they capture the HTTP response headers and also use more advanced Cache-Control checks. To start, install the latest stable Nginx avaliable at http://wiki.nginx.org/NginxInstall. Next edit your [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F04%2Fpage-level-caching-with-nginx%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F04%2Fpage-level-caching-with-nginx%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Since my <a href="http://www.webtatic.com/blog/2008/04/page-level-caching-with-nginx/">last post</a> on using <a href="http://wiki.nginx.org/Main">Nginx</a> to cache proxied content, they have added proper cache handling via their proxy_cache* directives. These are much more suitable for use, as they capture the HTTP response headers and also use more advanced Cache-Control checks.</p>
<p>To start, install the latest stable Nginx avaliable at <a href="http://wiki.nginx.org/NginxInstall">http://wiki.nginx.org/NginxInstall</a>.</p>
<p>Next edit your nginx.conf and add the proxy_cache_path directive to define a named cache storage. These are independant of servers and locations, and can be reused inside each later on.</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">...
http {
    ...
&nbsp;
    proxy_cache_path /var/cache/nginx keys_zone=anonymous:10m;
&nbsp;
    include vhosts/*.conf
}</pre></div></div>

<p>Next create the directory for the cache:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>nginx</pre></div></div>

<p>Next define your server configuration, which can be done for example in conf/vhosts/example.com.conf if you defined the include above.</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">server {
    listen            80;
    servername        example.com;
&nbsp;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  Host       $host;
&nbsp;
    location / {
        proxy_pass    http://localhost:8080/;
        proxy_cache   anonymous;
    }
&nbsp;
    # don't cache admin folder, send all requests through the proxy
    location /admin {
        proxy_pass    http://localhost:8080/;
    }
&nbsp;
    # handle static files directly. Set their expiry time to max, so they'll
    # always use the browser cache after first request
    location ~* (css|js|png|jpe?g|gif|ico)$ {
        root          /var/www/${host}/http;
        expires       max;
    }
}</pre></div></div>

<p>As we don&#8217;t want the nginx worker processes to have root permissions when in use, add to the start of conf/nginx.conf:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">user nginx
&nbsp;
...</pre></div></div>

<p>Then sort out the user and permissions:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">useradd nginx
<span style="color: #c20cb9; font-weight: bold;">chown</span> nginx:nginx <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>cache<span style="color: #000000; font-weight: bold;">/</span>nginx <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>nginx<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>fastcgi_temp,logs,proxy_temp<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>To start nginx on bootup, add the following to the end of /etc/rc.local:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">/usr/local/nginx/sbin/nginx</pre></div></div>

<p>Then also run this command to start nginx now.</p>
<p>That is all that is needed, no patches this time. There are several more proxy_cache* directives avaliable that you can use to tweak its behaviour, see the <a href="http://wiki.nginx.org/NginxHttpProxyModule#proxy_cache">proxy module documentation</a> for more details.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2010/04/page-level-caching-with-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mpm-itk on CentOS – run Apache virtual hosts as different users</title>
		<link>http://www.webtatic.com/blog/2010/04/mpm-itk-on-centos/</link>
		<comments>http://www.webtatic.com/blog/2010/04/mpm-itk-on-centos/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 18:49:44 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Server Admin]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[httpd]]></category>
		<category><![CDATA[mpm-itk]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=553</guid>
		<description><![CDATA[mpm-itk is a fork of mpm-prefork (ironically in both process and project sense), which allows you to configure individual Apache vhosts to run as specified users and groups. This makes it extremely secure if used in a shared hosting environment. I have provided a CentOS RPM for this in the Webtatic yum repository. This should [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F04%2Fmpm-itk-on-centos%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F04%2Fmpm-itk-on-centos%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://mpm-itk.sesse.net/">mpm-itk</a> is a fork of mpm-prefork (ironically in both process and project sense), which allows you to configure individual <a href="http://httpd.apache.org/">Apache</a> vhosts to run as specified users and groups. This makes it extremely secure if used in a shared hosting environment.</p>
<p>I have provided a CentOS RPM for this in the <a href="http://www.webtatic.com/projects/yum-repository/">Webtatic yum repository</a>. This should work with your existing httpd installation, as it is installed as a separate mpm to be selected just as the worker or event mpms can.</p>
<p><span id="more-553"></span></p>
<p>To install, first add the Webtatic repository to your Yum configuration:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rpm <span style="color: #660033;">-ivh</span> http:<span style="color: #000000; font-weight: bold;">//</span>repo.webtatic.com<span style="color: #000000; font-weight: bold;">/</span>yum<span style="color: #000000; font-weight: bold;">/</span>centos<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span><span style="color: #000000; font-weight: bold;">/`</span><span style="color: #c20cb9; font-weight: bold;">uname</span> -i<span style="color: #000000; font-weight: bold;">`/</span>webtatic-release-<span style="color: #000000;">5</span>-0.noarch.rpm</pre></div></div>

<p>Then install the package:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">--enablerepo</span>=webtatic httpd-itk</pre></div></div>

<p>Next, if you are currently running httpd, stop it, as the switch is done in the httpd control scripts.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">service httpd stop</pre></div></div>

<p>Then edit /etc/sysconfig/httpd and add the following line:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">HTTPD=/usr/sbin/httpd.itk</pre></div></div>

<p>Next you can add users and groups for your vhosts and configure httpd&#8217;s vhosts to use them:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">...
&lt;VirtualHost *:80&gt;
    ServerName example.com
    DocumentRoot /path/to/web/root
&nbsp;
    AssignUserId vhost-user vhost-group
&lt;/VirtualHost&gt;
...</pre></div></div>

<p>And then start up your Apache httpd:</p>

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

<p>The fun doesn&#8217;t stop there, however. You must configure websites to only be accessible to these linux users, and not to others. This can typically be done by setting the website&#8217;s root to be owned by the user, the group set to the vhost&#8217;s group, and turning off world read/write/execute, e.g.:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">chown</span> owner-user:vhost-group <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>webroot
<span style="color: #c20cb9; font-weight: bold;">chmod</span> o-rwx <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>webroot
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-ald</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>webroot
<span style="color: #666666; font-style: italic;"># drwxr-x--- 20 owner-user vhost-group 4096 Apr  5 19:38 /path/to/webroot</span></pre></div></div>

<p>Now the only users able to access the webroot are the super user, owner-user, and any users in vhost-group. As the web server will be setuid&#8217;d to vhost-user/vhost-group it will be able to read files in the web root.</p>
<p>The reason I didn&#8217;t change the user of the directory to vhost-user is that it would give the httpd process write access, which you still should take care of, as if there are vulnerabilities in the user&#8217;s code, the files could be hacked.</p>
<h3>VirtualHost security</h3>
<p>mpm-prefork (and most of the other stable MPMs) runs under a single user and group. In a shared hosting environment using these processing models, every script that is run essentially has read access to every other vhost&#8217;s scripts, which is a frightening prospect as they can easily be compromised giving an attacker the full source to a website. Database passwords can be read, leading to additional private data being accessible.</p>
<p>There are methods to secure shared hosting, as detailed in my blog post <a href="http://andytson.com/blog/2010/01/techniques-for-creating-a-secure-shared-web-server/">&#8220;Techniques for creating a secure shared web server&#8221;</a>. However they tend to decrease performance or don&#8217;t have total protection.</p>
<h3>mpm-itk</h3>
<p>mpm-itk is an alternative which runs the prefork model as root, giving it setuid capabilities. Each time a request is established, a preforked httpd process forks itself and setuid&#8217;s to the vhost&#8217;s defined user/group (or the default if unspecified). When the request is complete, the fork is terminated, allowing the parent to fork again on a later request.</p>
<p>The reason for this is that only the super user can setuid, and once done a process cannot go back to the super user&#8217;s context. Forking a process is extremely cheap on resources, so mpm-itk should not lose much in performance when compared to mpm-prefork.</p>
<p>Yes, there is a point where if there is a vulnerability an attacker might gain root permissions, specifically in between the established connection and the setuid, however as the project&#8217;s author mentions, this would only really happen if mod_ssl had a vulnerability.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2010/04/mpm-itk-on-centos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Facebook XHP RPM on CentOS</title>
		<link>http://www.webtatic.com/blog/2010/02/facebook-xhp-rpm-on-centos/</link>
		<comments>http://www.webtatic.com/blog/2010/02/facebook-xhp-rpm-on-centos/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 22:38:47 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Server Admin]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[XHP]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=504</guid>
		<description><![CDATA[A few days ago, Facebook released XHP, a PHP extension, which allows defining XML directly in PHP blocks, allowing you to &#8220;use PHP as a stricter templating engine&#8221;. It seems a bit strange to be coding XML tags directly in PHP blocks, but it adds features such as automatic escaping, and the ability to manipuate [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F02%2Ffacebook-xhp-rpm-on-centos%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2010%2F02%2Ffacebook-xhp-rpm-on-centos%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>A few days ago, Facebook released <a href="http://wiki.github.com/facebook/xhp/">XHP</a>, a PHP extension, which allows defining XML directly in PHP blocks, allowing you to &#8220;use PHP as a stricter templating engine&#8221;.</p>
<p>It seems a bit strange to be coding XML tags directly in PHP blocks, but it adds features such as automatic escaping, and the ability to manipuate the tags, and how they render.</p>
<p>I&#8217;ve compiled <strong>experimental</strong> RPMs, and put them in the Webtatic yum repository. These are compiled against PHP 5.3, which I also have in my repository.</p>
<p>I cannot guarantee the build of the exension is stable, as I had to add a few patches of my own to the source to get it to compile, so I don&#8217;t recommend you install it on a production site.</p>
<p>To install, first upgrade your PHP to 5.3, as detailed in my <a href="http://www.webtatic.com/blog/2009/06/php-530-on-centos-5/">PHP 5.3 on CentOS post</a>.</p>
<p>Then install the extension, and then you&#8217;re done:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">yum install --enablerepo=webtatic php-xhp</pre></div></div>

<p>To test if it is set up correctly, run the following:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">php -r 'echo &quot;XHP!\n&quot;; exit; &lt;a /&gt;;'</pre></div></div>

<p>Currently XHP requires you to include a PHP file (xhp/init.php), which is installed in the include path, to define all the default elements e.g.:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'xhp/init.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$href</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://www.webtatic.com'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #339933;">&lt;</span>a href<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span><span style="color: #000088;">$href</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">&gt;</span>Webtatic<span style="color: #339933;">.</span>com<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2010/02/facebook-xhp-rpm-on-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recovering a broken Subversion working copy</title>
		<link>http://www.webtatic.com/blog/2009/12/recovering-a-broken-subversion-working-copy/</link>
		<comments>http://www.webtatic.com/blog/2009/12/recovering-a-broken-subversion-working-copy/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 13:09:16 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Code Versioning]]></category>
		<category><![CDATA[.svn]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=479</guid>
		<description><![CDATA[There are times when a Subversion working copy can mess up. This is usually due to human error, for example due to permissions problems or moving files or folders incorrectly These can usually be easily recoverable, although at times it can seem there&#8217;s no solution. Here are a few examples and their solutions. Incorrectly deleting [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F12%2Frecovering-a-broken-subversion-working-copy%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F12%2Frecovering-a-broken-subversion-working-copy%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>There are times when a Subversion working copy can mess up. This is usually due to human error, for example due to permissions problems or moving files or folders incorrectly</p>
<p>These can usually be easily recoverable, although at times it can seem there&#8217;s no solution. Here are a few examples and their solutions.<br />
<span id="more-479"></span></p>
<h3>Incorrectly deleting files/folders without using svn rm</h3>
<p>This will usually result in subversion complaining when you attempt to commit. The symptom of this is the svn status giving something like:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">!</span>       path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>missing<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">file</span></pre></div></div>

<p>To fix this, simply issue the svn rm command for the file, and Subversion will fix and mark it as deleted.</p>
<h3>Incorrectly moving files/folders without using svn mv</h3>
<p>Sometimes someone may forget to run the subversion move command, and move files/folders manually. If you attempt to add a file after this, you will lose the history of the file. If you attempt with a folder, it will give an error:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">svn</span>: warning: <span style="color: #ff0000;">'path/to/moved/folder'</span> is already under version control</pre></div></div>

<p>The symptom of this is an svn status of:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">?       path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>moved<span style="color: #000000; font-weight: bold;">/</span>folder
<span style="color: #000000; font-weight: bold;">!</span>       path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>old<span style="color: #000000; font-weight: bold;">/</span>folder</pre></div></div>

<p>The best solution for this is to simply move it back and run the svn mv command instead.</p>
<h3>Adding a folder with permission problems</h3>
<p>Sometimes either the group or permissions of a folder will be incorrect. If you add the folder, it will usually issue an error like:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">svn</span>: Can<span style="color: #ff0000;">'t create directory '</span>new<span style="color: #000000; font-weight: bold;">/</span>folder<span style="color: #000000; font-weight: bold;">/</span>.svn<span style="color: #ff0000;">': Permission denied</span></pre></div></div>

<p>Whats worse is that the working copy now registers the folder in a half-added state. The parent folder metadata says the folder is added, but the child folder is missing its .svn metadata. The symptom of this is an svn status of:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~       new<span style="color: #000000; font-weight: bold;">/</span>folder</pre></div></div>

<p>The solution is to first fix the permissions of the folder, then move the folder to a temporary location, and revert the add:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># first fix the permissions</span>
<span style="color: #666666; font-style: italic;"># ...</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mv</span> new<span style="color: #000000; font-weight: bold;">/</span>folder new<span style="color: #000000; font-weight: bold;">/</span>folder2
<span style="color: #c20cb9; font-weight: bold;">svn</span> revert new<span style="color: #000000; font-weight: bold;">/</span>folder
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mv</span> new<span style="color: #000000; font-weight: bold;">/</span>folder2 new<span style="color: #000000; font-weight: bold;">/</span>folder
<span style="color: #c20cb9; font-weight: bold;">svn</span> add new<span style="color: #000000; font-weight: bold;">/</span>folder</pre></div></div>

<h3>An .svn metadata transplant</h3>
<p>There are sometimes some cases that can&#8217;t be explained. The best solution I&#8217;ve found for this is to do a .svn folder lobotomy and restore with fresh .svn folders. To do this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># backup your project in case you run into trouble</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-Rp</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>project <span style="color: #000000; font-weight: bold;">/</span>temporary<span style="color: #000000; font-weight: bold;">/</span>location
&nbsp;
<span style="color: #666666; font-style: italic;"># strip out the old .svn folders</span>
<span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>project <span style="color: #660033;">-name</span> .svn <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># check out a clean copy</span>
<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> http:<span style="color: #000000; font-weight: bold;">//</span>repo<span style="color: #000000; font-weight: bold;">/</span>location <span style="color: #000000; font-weight: bold;">/</span>temporary<span style="color: #000000; font-weight: bold;">/</span>location2
&nbsp;
<span style="color: #666666; font-style: italic;"># move the .svn folders from the clean copy into the correct relative</span>
<span style="color: #666666; font-style: italic;"># place in the broken copy</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>temporary<span style="color: #000000; font-weight: bold;">/</span>location2
<span style="color: #c20cb9; font-weight: bold;">find</span> . <span style="color: #660033;">-name</span> .svn <span style="color: #660033;">-print0</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #660033;">-I</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #ff0000;">'{}'</span> <span style="color: #ff0000;">'/path/to/project/{}'</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># remove the clean copy</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>temporary<span style="color: #000000; font-weight: bold;">/</span>location2</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/12/recovering-a-broken-subversion-working-copy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Locked down authoritative versioned code repositories</title>
		<link>http://www.webtatic.com/blog/2009/09/locked-down-versioned-code-repository/</link>
		<comments>http://www.webtatic.com/blog/2009/09/locked-down-versioned-code-repository/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 20:32:38 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Code Versioning]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=437</guid>
		<description><![CDATA[Centralised versioning systems are inherently authoritative, but when dealing with decentralised systems, either patches are made and applied to the maintainer&#8217;s repository, or one repository should be defined as the authoritative one. If the authoritative repository requires commit access, it should be locked down as much as possible, requiring authentication, encryption, and push access without [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F09%2Flocked-down-versioned-code-repository%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F09%2Flocked-down-versioned-code-repository%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Centralised versioning systems are inherently authoritative, but when dealing with decentralised systems, either patches are made and applied to the maintainer&#8217;s repository, or one repository should be defined as the authoritative one.</p>
<p>If the authoritative repository requires commit access, it should be locked down as much as possible, requiring authentication, encryption, and push access without opening up raw file write access. If raw file write access is given, either intentionally or unintentionally, any user with access could corrupt or delete the repository.</p>
<p><span id="more-437"></span></p>
<p>Here are the protocols and methods used by <a href="http://subversion.tigris.org/">Subversion</a>(svn), <a href="http://git-scm.com/">Git</a> and <a href="http://mercurial.selenic.com/">Mercurial</a>(hg) along with their capabilities:</p>
<table>
<tbody>
<tr>
<th>name</th>
<th>authentication</th>
<th>encryption</th>
<th>push</th>
<th>raw file write</th>
</tr>
<tr>
<td>svnserve</td>
<td>Y</td>
<td>N</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>git-daemon</td>
<td>N</td>
<td>N</td>
<td>Y<sup>1</sup></td>
<td>N</td>
</tr>
<tr>
<td>hg serve</td>
<td>N</td>
<td>N</td>
<td>Y<sup>1</sup></td>
<td>N</td>
</tr>
<tr>
<td>svn+ssh</td>
<td>Y<sup>5</sup></td>
<td>Y</td>
<td>Y<sup>1</sup></td>
<td>Y<sup>2</sup></td>
</tr>
<tr>
<td>git ssh</td>
<td>Y<sup>5</sup></td>
<td>Y</td>
<td>Y</td>
<td>Y<sup>2</sup></td>
</tr>
<tr>
<td>hg ssh</td>
<td>Y<sup>5</sup></td>
<td>Y</td>
<td>Y</td>
<td>Y<sup>2</sup></td>
</tr>
<tr>
<td>mod_dav_svn<sup>4</sup></td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>git over httpd<sup>4</sup></td>
<td>Y</td>
<td>Y</td>
<td>Y<sup>3</sup></td>
<td>Y<sup>3</sup></td>
</tr>
<tr>
<td>hgweb<sup>4</sup></td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>N</td>
</tr>
</tbody>
</table>
<ol>
<li>disabled by default</li>
<li>the login shell can be changed to a shell wrapper to allow only api commands e.g. git-shell</li>
<li>with mod_dav file provider</li>
<li>with a mod_auth_* module, and mod_ssl</li>
<li>achieved by file ownership and permissions</li>
</ol>
<h3>Git clone of a Subversion repository</h3>
<p>An alternative, if you require git access, is to have a locked down Subversion repository cloned to a read-only git repository, with a svn post-commit hook running git svn fetch on the git repository.</p>
<p>Clone the Subversion repository via its publicly accessible url:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git <span style="color: #c20cb9; font-weight: bold;">svn</span> clone <span style="color: #660033;">-s</span> https:<span style="color: #000000; font-weight: bold;">//</span>example.com<span style="color: #000000; font-weight: bold;">/</span>svnrepo<span style="color: #000000; font-weight: bold;">/</span> .</pre></div></div>

<p>Create /path/to/svnrepo/hooks/post-commit with content:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
git <span style="color: #660033;">--git-dir</span>=<span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>gitrepo<span style="color: #000000; font-weight: bold;">/</span>.git <span style="color: #c20cb9; font-weight: bold;">svn</span> fetch</pre></div></div>

<p>The suggested way (in &#8220;man git-svn&#8221;) of then cloning the git repository and initialising the svn metadata is a bit complicated, but you could instead rsync the git repository and use that instead, otherwise:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git init
git remote add origin url<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>gitrepo
git config <span style="color: #660033;">--add</span> remote.origin.fetch <span style="color: #ff0000;">'+refs/remotes/*:refs/remotes/*'</span>
git fetch
git checkout <span style="color: #660033;">-b</span> master FETCH_HEAD
git <span style="color: #c20cb9; font-weight: bold;">svn</span> init <span style="color: #660033;">-s</span> https:<span style="color: #000000; font-weight: bold;">//</span>example.com<span style="color: #000000; font-weight: bold;">/</span>svnrepo<span style="color: #000000; font-weight: bold;">/</span>
git <span style="color: #c20cb9; font-weight: bold;">svn</span> rebase</pre></div></div>

<h3>Conclusion</h3>
<p>The capabilities needed by a locked down repository (authentication, encryption, no raw file write access), mean that several methods aren&#8217;t viable, and only two with push capabilities (mod_dav_svn, and hgweb). The ssh methods can, as mentioned, be limited to api access only using wrappers, but require local users and those users can&#8217;t be used for regular activities, so if your users have ssh access as well, they&#8217;ll need two accounts</p>
<p>Public repositories can forgoe these capabilities, so any of these are suitable if anonymous read-only access is required.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/09/locked-down-versioned-code-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git 1.7.2.3 on CentOS 5</title>
		<link>http://www.webtatic.com/blog/2009/09/git-on-centos-5/</link>
		<comments>http://www.webtatic.com/blog/2009/09/git-on-centos-5/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 22:11:57 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Code Versioning]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=426</guid>
		<description><![CDATA[I&#8217;ve been hearing good things about git lately, with many projects which used to use subversion converting to it, so I&#8217;ve decided to try it out myself. RPMForge only has version 1.5, so like the other software I&#8217;ve been using, I&#8217;ve converted Fedora 11&#8242;s rpm to CentOS and put it in the Webtatic repository. Update [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F09%2Fgit-on-centos-5%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F09%2Fgit-on-centos-5%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been hearing good things about <a href="http://git-scm.com/">git</a> lately, with many projects which used to use subversion converting to it, so I&#8217;ve decided to try it out myself. RPMForge only has version 1.5, so like the other software I&#8217;ve been using, I&#8217;ve converted Fedora 11&#8242;s rpm to CentOS and put it in the Webtatic repository.</p>
<p><b>Update 2010-02-14</b> &#8211; Updated Git 1.6.6 to 1.7.0</p>
<p><b>Update 2010-04-05</b> &#8211; Updated to 1.7.0.4, included all dependencies in the repository to remove any dependencies on other repositories</p>
<p><span id="more-426"></span></p>
<p>If you haven&#8217;t set up the <a href="http://www.webtatic.com/projects/yum-repository/">Webtatic repository</a> in yum, then add it in the command-line as following:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rpm <span style="color: #660033;">-ivh</span> http:<span style="color: #000000; font-weight: bold;">//</span>repo.webtatic.com<span style="color: #000000; font-weight: bold;">/</span>yum<span style="color: #000000; font-weight: bold;">/</span>centos<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span><span style="color: #000000; font-weight: bold;">/`</span><span style="color: #c20cb9; font-weight: bold;">uname</span> -i<span style="color: #000000; font-weight: bold;">`/</span>webtatic-release-<span style="color: #000000;">5</span>-1.noarch.rpm</pre></div></div>

<p>Now install git:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">--enablerepo</span>=webtatic git-all</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/09/git-on-centos-5/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Get an “A” in YSlow with Webtatic Optimizer</title>
		<link>http://www.webtatic.com/blog/2009/08/get-an-a-in-yslow-with-webtatic-optimizer/</link>
		<comments>http://www.webtatic.com/blog/2009/08/get-an-a-in-yslow-with-webtatic-optimizer/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 12:13:51 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Web Optimisation]]></category>
		<category><![CDATA[Google Page Speed]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webtatic Optimizer]]></category>
		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=359</guid>
		<description><![CDATA[The performance of a website is an important issue. Even fast responding dynamic pages can be hit with problems with sub-optimal static content such as high overhead on many HTTP requests and large javascript/css files. Tools like YSlow, and Google Page Speed help identify these problem areas. Webtatic Optimizer is a tool that can be [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F08%2Fget-an-a-in-yslow-with-webtatic-optimizer%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F08%2Fget-an-a-in-yslow-with-webtatic-optimizer%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The performance of a website is an important issue. Even fast responding dynamic pages can be hit with problems with sub-optimal static content such as high overhead on many HTTP requests and large javascript/css files. Tools like <a href="http://developer.yahoo.com/yslow/">YSlow</a>, and <a href="http://code.google.com/speed/page-speed/">Google Page Speed</a> help identify these problem areas.</p>
<p><a href="http://www.webtatic.com/projects/optimizer/">Webtatic Optimizer</a> is a tool that can be used to improve these areas, and can help get an almost perfect score.<br />
<span id="more-359"></span></p>
<h3>Make fewer HTTP requests</h3>
<p>JavaScript and Css files are naturally loaded individually. Having multiples of them being used across an entire site, e.g. including the JQuery library along with your own javascript, adds to the time the user has to wait for the files to download.</p>
<p>The Optimizer can concatenate these files and store in a new static file, so loading this instead will mean less requests, resulting in an &#8220;A&#8221; in this category. (images may decrease the score if you use many of them, but I will add in a future release the ability to easily create CSS sprites which rewrite the css file to accomidate the position of an image within its sprite).</p>
<h3>Add Expires headers</h3>
<p>Whilst you can force an expiry of X hours in apache, this means that changes to these files wont be reflected in the browser until the image has expired. However, browsers cache files based on their entire request url (including query string), so simply concatenating onto the referenced url a unique query string that changes when the contents are modified, is enough to be able to set a year&#8217;s expiry whilst changes are reflected immediately.</p>
<p>The Optimizer does this by rewriting css url() urls, calculating the last-modified date of the physical file, and appending this onto the url. There is also a php function helper to do this for static files included in dynamic pages. With this you can get an &#8220;A&#8221; in this section.</p>
<h3>Compress components with gzip</h3>
<p>Text-based http requests can be reduced in size significantly using gzip when the browser supports it as a content encoding. The Optimizer does this when creating the concatenated files, also creating a gzipped version at the same time.</p>
<p>This will give an &#8220;A&#8221; in YSlow.</p>
<h3>Minify JavaScript and CSS</h3>
<p>If a browser is not able to use the gzipped version of a file, optimized versions of the original JavaScript or CSS can be used instead. This is done at the same time as concatenating the files, using JsMin for JavaScript, and a simple CSS minifier, giving you an &#8220;A&#8221; for this category in YSlow.</p>
<h3>Example</h3>
<p>Using a configuration such as below, enables the above optimizations to be incorporated into the generated files:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">[config]
version = 1.0.0
&nbsp;
[javascript]
config.workingPath = http
defaults.output = site.js
files = &quot;
  + javascript/jquery.min.js
  + javascript/my-javascript.js
&quot;
&nbsp;
[css]
config.workingPath = http
defaults.output = site.css
files = &quot;
  + css/layout.css
  + css/global/**.css
&quot;</pre></div></div>

<p>The above configuration can passed to the optimizer command-line script:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">optimizer-compile optimizer.ini</pre></div></div>

<p>This will concatenate http/javascript/jquery.min.js and http/javascript/my-javascript.js, minimise it, and store it in http/site.js and a gzipped version in http/site.js.gz. It will also concatentate, minify, and rewrite url()&#8217;s for http/css/layout.css and any CSS files in http/css/global and sub-directories, and store it in http/site.css and a gzipped version in http/site.css.gz.</p>
<h3>Advanced features</h3>
<p>There are much more advanced features that can be configured, which you can find out more about in the documentation. The Webtatic Optimizer is a fully extensible library, using plugins and filters to achieve the above. You can enable/disable any features or can even write your own.</p>
<h3>An example in use</h3>
<p>Using each of the Webtatic Optimizer&#8217;s features above, I have managed to get the <a href="https://passport.fubra.com/">Fubra Passport</a>, an authentication gateway and payment system for the sites <a href="http://www.fubra.com/">Fubra Limited</a> runs/is affiliated with, a score of &#8220;B&#8221;. It fails at getting an &#8220;A&#8221; as it doesn&#8217;t have a CDN, and cookies are passed for static content.</p>
<p>I will address the latter, along with making it easy to automatically rewrite local static file urls to a CDN, in a future release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/08/get-an-a-in-yslow-with-webtatic-optimizer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP public key cryptography using OpenSSL</title>
		<link>http://www.webtatic.com/blog/2009/07/php-public-key-cryptography/</link>
		<comments>http://www.webtatic.com/blog/2009/07/php-public-key-cryptography/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 10:36:02 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[OpenSSL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/blog/2009/07/php-public-key-cryptography/</guid>
		<description><![CDATA[Using the PHP OpenSSL extension it is fairly easy to sort out a secure system for encrypting data with one key that only can be decrypted with another.]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F07%2Fphp-public-key-cryptography%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F07%2Fphp-public-key-cryptography%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Recently I have been handling the security of some sensitive data. I had originally been encrypting/decrypting data with a <a href="http://en.wikipedia.org/wiki/Symmetric-key_algorithm">symmetric-key system</a> using <a href="http://uk3.php.net/manual/en/function.mcrypt-encrypt.php">mcrypt</a> for PHP. This was due to the web frontend and the backend existing on the same server. However for security purposes I am now separating the frontend and backend onto different servers, so that there is no way the web accessible frontend, whether compromised or not, can get at the data it inserts into the database.</p>
<p>In order to do this, a asymmetric-key system is needed, such as <a href="http://en.wikipedia.org/wiki/Public-key_cryptography">public-key cryptography</a>. Googling for examples of this in PHP, there doesn&#8217;t seem to be any results of this other than the <a href="http://uk3.php.net/manual/en/book.openssl.php">php OpenSSL extension documentation</a>, and systems that try to reinvent the wheel with their own implementations.</p>
<p>Using the PHP OpenSSL extension it is fairly easy to sort out a secure system for encrypting data with one key that only can be decrypted with another.<br />
<span id="more-335"></span><br />
First, you need to generate your private and public keys. You can either do this yourself with the openssl command-line application:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;"># generate a 1024 bit rsa private key, ask for a passphrase to encrypt it and save to file
openssl genrsa -des3 -out /path/to/privatekey 1024
&nbsp;
# generate the public key for the private key and save to file
openssl rsa -in /path/to/privatekey -pubout -out /path/to/publickey</pre></div></div>

<p>or programatically using php-openssl:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// generate a 1024 bit rsa private key, returns a php resource, save to file</span>
<span style="color: #000088;">$privateKey</span> <span style="color: #339933;">=</span> <span style="color: #990000;">openssl_pkey_new</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'private_key_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1024</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'private_key_type'</span> <span style="color: #339933;">=&gt;</span> OPENSSL_KEYTYPE_RSA<span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">openssl_pkey_export_to_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$privateKey</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/path/to/privatekey'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$passphrase</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// get the public key $keyDetails['key'] from the private key;</span>
<span style="color: #000088;">$keyDetails</span> <span style="color: #339933;">=</span> <span style="color: #990000;">openssl_pkey_get_details</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$privateKey</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">file_put_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/path/to/publickey'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$keyDetails</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'key'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Next, you can load the public key, and encrypt the data:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$pubKey</span> <span style="color: #339933;">=</span> <span style="color: #990000;">openssl_pkey_get_public</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'file:///path/to/publickey'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">openssl_public_encrypt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sensitiveData</span><span style="color: #339933;">,</span> <span style="color: #000088;">$encryptedData</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pubKey</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// store $encryptedData ...</span></pre></div></div>

<p>When you need to get the sensitive data again, you can load the private key and decrypt:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// retrieve $encryptedData from storage ...</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// load the private key and decrypt the encrypted data</span>
<span style="color: #000088;">$privateKey</span> <span style="color: #339933;">=</span> <span style="color: #990000;">openssl_pkey_get_private</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'file:///path/to/privatekey'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$passphrase</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">openssl_private_decrypt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$encryptedData</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sensitiveData</span><span style="color: #339933;">,</span> <span style="color: #000088;">$privateKey</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Alternatively you can use the private key to encrypt data, sign data or seal it against multiple other public keys, but that is beyond the scope of this article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/07/php-public-key-cryptography/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP 5.3 on CentOS 5</title>
		<link>http://www.webtatic.com/blog/2009/06/php-530-on-centos-5/</link>
		<comments>http://www.webtatic.com/blog/2009/06/php-530-on-centos-5/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 10:13:47 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Server Admin]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=319</guid>
		<description><![CDATA[My previous articles on installing PHP on CentOS dealt with installing PHP 5.2.6. I have found this to have some bugs that kill the process without error information. One bug I found, which was on an x86_64 server, was that converting an object to a string did this. So, I have compiled the latest PHP [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F06%2Fphp-530-on-centos-5%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F06%2Fphp-530-on-centos-5%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>My <a href="http://www.webtatic.com/blog/2009/05/installing-php-526-on-centos-5/">previous articles</a> on installing PHP on CentOS dealt with installing PHP 5.2.6. I have found this to have some bugs that kill the process without error information. One bug I found, which was on an x86_64 server, was that converting an object to a string did this.</p>
<p>So, I have compiled the latest PHP version, <del datetime="2009-09-01T17:43:17+00:00">5.2.10</del> <del datetime="2009-11-20T23:00:04+00:00">5.3.0</del> 5.3.3, and put it in my own repository for easy installation. I have compiled it for CentOS 5 i386 and x86_64, and provided the <a href="http://repo.webtatic.com/yum/centos/5/SRPMS/">source RPMS</a> in the repo, if anyone wants to compile it for another OS or architecture.</p>
<p><b>Update 2009-07-03</b> &#8211; I updated the version to PHP 5.3, which was released a few days before. This includes many new features such as closures, namespaces, and packaged scripts in phar files, which I&#8217;ll blog about soon. Check out <a href="http://www.php.net/ChangeLog-5.php">PHP changelog</a> for more details.<br />
<b>Update 2009-09-01</b> &#8211; Added a note about deprecated errors, and how to silence them. Also I have included a tip that might help those of you struggling to install.<br />
<b>Update 2010-03-03</b> &#8211; I&#8217;ve added both apc 3.1.3p1 beta (php-pecl-apc in yum) and eAccelerator 0.9.6 (php-eaccelerator in yum) RPMs to the repository, they are compiled for (and work on) php 5.3.x</p>
<p><span id="more-319"></span></p>
<p>I have also included the same php extensions I mentioned in my <a href="http://www.webtatic.com/blog/2009/05/installing-php-526-extra-extensions/">other article</a>, php-mcrypt, php-mhash (in PHP 5.2), php-mssql and php-tidy</p>
<p>To install, first you must tell rpm to accept rpm&#8217;s signed by me, then add the yum repository information to yum:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rpm <span style="color: #660033;">-ivh</span> http:<span style="color: #000000; font-weight: bold;">//</span>repo.webtatic.com<span style="color: #000000; font-weight: bold;">/</span>yum<span style="color: #000000; font-weight: bold;">/</span>centos<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span><span style="color: #000000; font-weight: bold;">/`</span><span style="color: #c20cb9; font-weight: bold;">uname</span> -i<span style="color: #000000; font-weight: bold;">`/</span>webtatic-release-<span style="color: #000000;">5</span>-1.noarch.rpm</pre></div></div>

<p>Now you can install php by doing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #660033;">--enablerepo</span>=webtatic <span style="color: #c20cb9; font-weight: bold;">install</span> php</pre></div></div>

<p>Or update an existing installation of php, which will also update all of the other php modules installed:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #660033;">--enablerepo</span>=webtatic update php</pre></div></div>

<p>If this does not work correctly, try disabling all other repositories while installing/updating, by adding the &#8211;disablerepo=* option. This will stop other dependencies from being installed, so you may want to install them first.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #660033;">--disablerepo</span>=<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #660033;">--enablerepo</span>=webtatic update php</pre></div></div>

<h3>&#8220;Depsolving&#8221; problems</h3>
<p>If you get depsolving problems when updating, you may have currently installed some extensions that have been removed, e.g. php-mhash, php-ncurses.</p>
<p>You will need to remove them before upgrading.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum remove php-mhash php-ncurses</pre></div></div>

<h3>Deprecated Errors</h3>
<p>Once you are running the new version, you may get &#8220;deprecated&#8221; errors in your error logs. This isn&#8217;t bad, it just means to tell you that some of the functions you are using are no longer prefered, and may be removed in a future major release. An example of this is the ereg functions. Preg functions are prefered over these, as they are much faster and more powerful, and in all cases do at least the same thing.</p>
<p>If upgrading the functions are not an option, and you would like to hide the deprecated errors from your error log, for example on a production server, just edit your /etc/php.ini file, find the line:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">error_reporting  =  E_ALL</pre></div></div>

<p>and replace to:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">error_reporting  =  E_ALL &amp; ~E_DEPRECATED</pre></div></div>

<h3>PHP 5.2.14</h3>
<p>I am also maintaining a PHP 5.2.14 release, so should you prefer to install that (for reasons like incompatibilities or testing), you can force it to install that instead by doing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #660033;">--enablerepo</span>=webtatic <span style="color: #660033;">--exclude</span>=php<span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000;">5.3</span><span style="color: #000000; font-weight: bold;">*</span> update php</pre></div></div>

<p>Or you can add to the /etc/yum.repos.d/webtatic.repo the line:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">exclude=php*5.3*</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/06/php-530-on-centos-5/feed/</wfw:commentRss>
		<slash:comments>168</slash:comments>
		</item>
		<item>
		<title>mod_auth_mysql digest authentication patch</title>
		<link>http://www.webtatic.com/blog/2009/05/patch-for-mod_auth_mysql-to-allow-digest-authentication/</link>
		<comments>http://www.webtatic.com/blog/2009/05/patch-for-mod_auth_mysql-to-allow-digest-authentication/#comments</comments>
		<pubDate>Sun, 31 May 2009 10:59:13 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Server Admin]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[mod_auth_mysql]]></category>
		<category><![CDATA[mod_auth_mysql digest]]></category>

		<guid isPermaLink="false">http://www.webtatic.com/?p=301</guid>
		<description><![CDATA[Recently, I wrote a mod_perl module for using a database backend for basic and digest authentication in Apache, however I found it to be much slower than mod_auth_mysql. This would be due to using mod_perl and DBI. So I have written a patch for mod_auth_mysql which performs the same, which means its as fast. The [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F05%2Fpatch-for-mod_auth_mysql-to-allow-digest-authentication%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.webtatic.com%2Fblog%2F2009%2F05%2Fpatch-for-mod_auth_mysql-to-allow-digest-authentication%2F&amp;source=webtatic&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Recently, I wrote a mod_perl module for using a database backend for basic and digest authentication in Apache, however I found it to be much slower than <a href="http://modauthmysql.sourceforge.net/">mod_auth_mysql</a>. This would be due to using <a href="http://perl.apache.org/">mod_perl</a> and DBI. So I have written a patch for mod_auth_mysql which performs the same, which means its as fast.</p>
<p>The main reason why I chose to do this rather than use <a href="http://www.webtatic.com/projects/webtaticauthdbi/">Webtatic::AuthDBI</a> is because subversion checkouts were taking twice as long. A mod_perl authentication provider, even without performing authentication (just returning OK for any login details) seems to be the speed of the whole mod_auth_mysql without even establishing a mysql connection.</p>
<p>This patch seems to perform just as well as mod_auth_mysql.</p>
<p>Check it out here: <a href="http://www.webtatic.com/projects/mod_auth_mysql-auth/">/projects/mod_auth_mysql-auth/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webtatic.com/blog/2009/05/patch-for-mod_auth_mysql-to-allow-digest-authentication/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 1.739 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-07 21:48:01 --><!-- Compression = gzip -->
