<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arricc &#187; Hosting</title>
	<atom:link href="http://www.arricc.net/tags/hosting/feed" rel="self" type="application/rss+xml" />
	<link>http://www.arricc.net</link>
	<description>50% IT snippets that I couldn&#039;t readily find existing help on. 50% drivel.</description>
	<lastBuildDate>Wed, 02 Mar 2011 23:44:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Drupal HTTPS images</title>
		<link>http://www.arricc.net/drupal-https-images.php</link>
		<comments>http://www.arricc.net/drupal-https-images.php#comments</comments>
		<pubDate>Wed, 02 Mar 2011 23:44:34 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://www.arricc.net/?p=96</guid>
		<description><![CDATA[I was involved with a project for a while which was using Drupal as the CMS. The entire site was being served over HTTPS, which was quite annoying as a large pile of the images that were being posted were being served over HTTP from their respective webservers. Naturally, this resulted in everyone getting very [...]]]></description>
			<content:encoded><![CDATA[<p>I was involved with a project for a while which was using <a href="http://drupal.org">Drupal</a> as the CMS. The entire site was being served over HTTPS, which was quite annoying as a large pile of the images that were being posted were being served over HTTP from their respective webservers. Naturally, this resulted in everyone getting very annoyed at their browser warning about loading unsecured content on a secure page.</p>
<p>So, I came up with this module. I&#8217;ve been meaning to release it for ages, but as I need to clear down the server it was running on it&#8217;s made me take the five minutes to write this post. Still needs a bit of work, but does what it says on the tin.</p>
<p>It identifies non-local images in content, downloads them and serves them from a local cache.</p>
<p>Download the module here: <a href='http://www.arricc.net/wp-content/uploads/img_proxy.tar.gz'>img_proxy.tar.gz</a></p>
<p>If you use Drupal, you should already know the drill &#8211; extract the file to your modules directory and enable it in the modules page. The module is implemented as an input filter, so you will then have to add it to the appropriate input formats at http://your.site.com/admin/settings/filters </p>
<p><strong>Notes</strong></p>
<ul>
<li>Licenced under the GPL version 2.</li>
<li><strong>*** There is nothing in the code that verifies the file being proxied is an image!! ***</strong> (that&#8217;ll be in the next version!)</li>
<li>May not work with sites that check the referer of the request for images.</li>
<li>I&#8217;ve been meaning to release this for ages, but there is sill a lot of debug code thats just commented out.</li>
</ul>
<p>Hopefully I&#8217;m not the only webmaster that ever had this issue and somebody will find this handy.</p>
<p>Maybe one day I&#8217;ll tidy up the code and submit it to the Drupal Module repository!</p>
<p>Enjoy.</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for Drupal HTTPS images" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+Drupal+HTTPS+images" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/drupal-https-images.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User VHosting</title>
		<link>http://www.arricc.net/user-vhosting.php</link>
		<comments>http://www.arricc.net/user-vhosting.php#comments</comments>
		<pubDate>Tue, 29 Aug 2006 23:05:50 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Wintermute]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.arricc.net/user-vhosting.php</guid>
		<description><![CDATA[So, previously, I detailed how to do web virtual hosting to directories on the file system. This is all well and good, but I want to have users pidgeon holed into their own directories, plus I want users own websites to be stored under their own directories in a similar format to that used in [...]]]></description>
			<content:encoded><![CDATA[<p>So, <a href="/vwebhosting.php">previously</a>, I detailed how to do web virtual hosting to directories on the file system. This is all well and good, but I want to have users pidgeon holed into their own directories, plus I want users own websites to be stored under their own directories in a similar format to that used in the previous article (eg. /home/user/web/example.org/subdomain)</p>
<p>The problem lies with mapping domain names (example.org) onto user accounts (Alice? Bob?). This is where Apache and mod_rewrite come to the rescue again. On Wintermute I&#8217;ve installed Apache 2, but this recipe will work just as well with Apache 1.3.<span id="more-24"></span></p>
<p>First, we create a file with domain names to username mappings:<br />
/etc/apache2/map.hosted<br />
<div class="codeblock"><code>wintermute:/etc/apache2# cat map.hosted<br />xeno-phon.co.uk: jimsin<br />starfallonline.co.uk: stillborn<br />ryanroberts.co.uk: stillborn<br />witchhunter.co.uk: stillborn<br />flushedphoenix.co.uk: flushedphoenix<br />shawree.co.uk: shawree<br />theballswinger.co.uk: the_ball_swinger<br />the-hearse.com: hobgoth<br /></code></div><br />
The pattern is &#8220;website.com: username&#8221; with one per line.<br />
Each of these usernames must also exist in the Xoops database (or as system users), but I&#8217;ll be covering the links to that DB in a later article.</p>
<p>Coming up with that file was the easy bit. The next bit was the major pain in the hole. I searched for aaaages to try and work out how to do this in php ( my php is significantly better than my Perl), but all the examples I could find were written in Perl. So, here are some keywords for search engines: how to write a mod_rewrite map in php not perl. php apache rewritemap.</p>
<p><div class="codeblock"><code>#!/usr/bin/php<br /><span class="synSpecial">&lt;?</span><br /><span class="synComment">//Optional log file.</span><br /><span class="synComment">#$log = fopen (&quot;/tmp/rwlist&quot;,'a');</span><br /><span class="synComment">//Map file</span><br /><span class="synStatement">$</span><span class="synIdentifier">mapIn</span> <span class="synStatement">=</span> <span class="synIdentifier">fopen</span><span class="synSpecial">(</span>&quot;<span class="synConstant">/etc/apache2/map.hosted</span>&quot;, &quot;<span class="synConstant">r</span>&quot;<span class="synSpecial">)</span>;<br /><span class="synComment">//Read in the file.</span><br /><span class="synComment">//NB: This is only done at startup, so if you change the file you have to reload Apache to get the changes recognised.</span><br /><span class="synStatement">while</span> <span class="synSpecial">((</span><span class="synStatement">$</span><span class="synIdentifier">data</span> <span class="synStatement">=</span> <span class="synIdentifier">fgetcsv</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">mapIn</span>, <span class="synConstant">1000</span>, &quot;<span class="synConstant">:</span>&quot;<span class="synSpecial">))</span> <span class="synStatement">!==</span> <span class="synConstant">FALSE</span><span class="synSpecial">)</span> <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">map</span><span class="synSpecial">[</span><span class="synStatement">$</span><span class="synIdentifier">data</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">]]</span> <span class="synStatement">=</span> <span class="synIdentifier">trim</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">data</span><span class="synSpecial">[</span><span class="synConstant">1</span><span class="synSpecial">])</span>;<br /><span class="synSpecial">}</span><br /><span class="synIdentifier">fclose</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">mapIn</span><span class="synSpecial">)</span>;<br /><span class="synComment">//Recursive function. Starts with the full domain name and gradually pops off segments until it finds an owner (or not).</span><br /><span class="synComment">//eg. www.sub.example.org - first checks for www.sub.example.org, then sub.example.org, then example.org and finally org.</span><br /><span class="synPreProc">function</span> checkUser<span class="synSpecial">(</span><span class="synStatement">&amp;$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span><br /><span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synType">global</span> <span class="synStatement">$</span><span class="synIdentifier">map</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">uname</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">map</span><span class="synSpecial">[</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">uname</span> <span class="synStatement">&lt;&gt;</span> &quot;&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">uname</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">else</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">host</span> <span class="synStatement">=</span> <span class="synIdentifier">explode</span><span class="synSpecial">(</span>&quot;<span class="synConstant">.</span>&quot;,<span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/</span>&quot;<span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">unset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">[</span><span class="synConstant">0</span><span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> <span class="synIdentifier">implode</span><span class="synSpecial">(</span>&quot;<span class="synConstant">.</span>&quot;,<span class="synStatement">$</span><span class="synIdentifier">host</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">&lt;&gt;</span> &quot;&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checkUser<span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br /><span class="synSpecial">}</span><br /><span class="synStatement">do</span><br /><span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">in</span> <span class="synStatement">=</span> <span class="synIdentifier">trim</span><span class="synSpecial">(</span><span class="synIdentifier">fgets</span><span class="synSpecial">(</span>STDIN,<span class="synConstant">8096</span><span class="synSpecial">))</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">strlen</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span><span class="synSpecial">)</span> <span class="synStatement">&gt;</span><span class="synConstant">0</span><span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br /><span class="synComment">//Log request</span><br /><span class="synComment">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  fputs($log, &quot;$in\n&quot;);</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">unset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">])</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">substr</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span>,<span class="synConstant">0</span>,<span class="synConstant">1</span><span class="synSpecial">)</span> <span class="synStatement">&lt;&gt;</span> &quot;<span class="synConstant">/</span>&quot;<span class="synSpecial">)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">in</span> <span class="synStatement">=</span> &quot;<span class="synConstant">http://</span><span class="synStatement">$</span><span class="synIdentifier">in</span>&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span> <span class="synStatement">=</span> <span class="synIdentifier">parse_url</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">in</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">path</span> <span class="synStatement">=</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">=</span> &quot;&quot;;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checkUser<span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//If we find an owner</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span><span class="synSpecial">(</span><span class="synStatement">isset</span><span class="synSpecial">(</span><span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]))</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//This bit is slightly legacy before I moved the hosting files about a bit. Kept for posterity mainly.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> &quot;<span class="synConstant">.elizium.net/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synIdentifier">file_exists</span><span class="synSpecial">(</span>&quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span><span class="synSpecial">))</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">{</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span> <span class="synStatement">=</span> &quot;<span class="synConstant">/home/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">hostedUser</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span>&quot;<span class="synConstant">/web/</span>&quot; <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">host</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">url</span><span class="synSpecial">[</span>&quot;<span class="synConstant">path</span>&quot;<span class="synSpecial">]</span> <span class="synStatement">.</span> <span class="synStatement">$</span><span class="synIdentifier">path</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synComment">//Otherwise just return this file as 99% chance its some automated script looking for exploitable webapps.</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">else</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synStatement">$</span><span class="synIdentifier">out</span><span class="synStatement">=</span> &quot;<span class="synConstant">/var/www/monkey.txt</span>&quot;;<br /><span class="synComment">//Log resulting path</span><br /><span class="synComment">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  fputs($log, &quot;$out\n&quot;);</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="synIdentifier">fputs</span><span class="synSpecial">(</span>STDOUT, &quot;<span class="synStatement">$</span><span class="synIdentifier">out</span><span class="synSpecial">\n</span>&quot;<span class="synSpecial">)</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synSpecial">}</span><br /><span class="synComment">//Just keep doing it forever.</span><br /><span class="synSpecial">}</span> <span class="synStatement">while</span> <span class="synSpecial">(</span><span class="synConstant">true</span><span class="synSpecial">)</span>;<br /><span class="synSpecial">?&gt;</span><br /></code></div></p>
<p>The only improvement I may make to that is to get the users home directory info as opposed to assuming its under /home.</p>
<p>Now we just need put that script somewhere, make it executable by the Apache user and tell Apache to use it. Thats done like so:<br />
<div class="codeblock"><code><span class="synIdentifier">RewriteEngine</span> <span class="synConstant">on</span><br /><span class="synComment">#Use this program to do the mappings</span><br /><span class="synIdentifier">RewriteMap</span>&nbsp; &nbsp; &nbsp; hosted&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prg:/etc/apache2/<span class="synConstant">map</span>.hosted.php<br /><span class="synComment">#This is for allowing www.user.elizium.net type urls as they're outwith the scope of the rewrite script as they're easy to map.</span><br /><span class="synComment">#See http://forum.modrewrite.com/viewtopic.php?t=1652&amp;postdays=0&amp;postorder=asc&amp;start=10</span><br /><span class="synIdentifier">RewriteCond</span> %{HTTP_HOST} !^(www\.)?elizium\.net$ [NC]<br /><span class="synIdentifier">RewriteCond</span> %{ENV:REDIRECT_STATUS} ^$<br /><span class="synIdentifier">RewriteCond</span> %{HTTP_HOST} ^([^\.]+\.)?([^.]+)\.elizium\.net$ [NC]<br /><span class="synIdentifier">RewriteRule</span> .*&nbsp; /home/%2/web/%2\.elizium.net%{REQUEST_URI}&nbsp; &nbsp; &nbsp; [QSA,L]<br /><span class="synComment">#Ignore *.elizium.net</span><br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{HTTP_HOST}&nbsp; &nbsp; !elizium.net$ [NC]<br /><span class="synComment">#Use the full request</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^(.+)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  %{HTTP_HOST}$1&nbsp; [C]<br /><span class="synComment">#Throw the request through the map program</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^(.*)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ${hosted:$1}&nbsp; &nbsp; [L,C]<br /></code></div></p>
<p>I hope this is of use to people. Especially those folk looking for a php based rewrite script for Apache. Theres a lot of scope to expand the script. For example, the file data could be retrieved from a database and then stored in something like <a href="http://www.danga.com/memcached/">memcached</a> if you were performing this sort of thing on a larger scale. Much better than having a large webserver config file that means the webserver has to be reloaded for each change.</p>
<p>The only problem I have with this, and I know its not insurmountable, is that the webserver user has to be able to read the files that users are storing. To allow this I&#8217;ve made the www-data user a member of the group all the users are members of. This also means that users can read each others files. So if somebody was to hardcode a password in a php file (for example) then it would be open to being read by any other user.</p>
<p>I also want to mention <a href="http://www.suphp.org">suPHP</a>, it really does merit an article to itself, but as I&#8217;m not intending to cover it in depth (you can read all about it at the website) I&#8217;ll just say that I&#8217;ve enabled it on Wintermute to prevent users being able to do things like kill the web server processes via a php script. To do that, I installed the suphp-common Debian package. The default configs are all you need. For the non-Debian user, they look like this when taken together:<br />
<div class="codeblock"><code><span class="synIdentifier">LoadModule</span> suphp_module /usr/lib/apache2/modules/mod_suphp.so<br /><span class="synStatement">&lt;IfModule</span><span class="synConstant"> mod_suphp.c</span><span class="synStatement">&gt;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; suPHP_Engine <span class="synConstant">on</span><br />&nbsp; &nbsp; &nbsp; &nbsp; <span class="synIdentifier">AddHandler</span> x-httpd-php .php .php3 .php4 .phtml<br /><span class="synComment"># # Use a specific php config file (a dir which contains a php.ini file)</span><br />&nbsp; &nbsp; &nbsp; &nbsp; suPHP_ConfigPath /etc/php4/cgi/<br /><span class="synStatement">&lt;/IfModule&gt;</span><br /></code></div></p>
<p>As usual comments on the above are most welcome. Especially quick links about solving my security issue!</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for User VHosting" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+User+VHosting" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/user-vhosting.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VWebhosting</title>
		<link>http://www.arricc.net/vwebhosting.php</link>
		<comments>http://www.arricc.net/vwebhosting.php#comments</comments>
		<pubDate>Fri, 07 Jul 2006 19:18:04 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Wist]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.arricc.net/vwebhosting.php</guid>
		<description><![CDATA[So, to reiterate &#8211; the main server (Wist) will hold all my own stuff, then I&#8217;ll be creating a user Virtual Server (Wintermute) on top of that for users to play with and/or break. All the user stuff is backended in a Xoops database using Xoops groups. Wist is installed with Debian Sarge using a [...]]]></description>
			<content:encoded><![CDATA[<p>So, to reiterate &#8211; the main server (Wist) will hold all my own stuff, then I&#8217;ll be creating a user Virtual Server (Wintermute) on top of that for users to play with and/or break. All the user stuff is backended in a <a href="http://www.xoops.org">Xoops</a> database using Xoops groups.</p>
<p>Wist is installed with Debian Sarge using a custom kernel including the vserver patches from Debian. This sort of thing is detailed elsewhere so I won&#8217;t go over it again here.</p>
<p>The core server software (all from the Debian archive) will include: Apache 1.3 with PHP4, Apache-SSL, Bind, MySQL 4.1, Exim4, ClamAV and Dovecot (I&#8217;ll be detailing the email setup seperately)<span id="more-17"></span></p>
<p>The installation of the Bind9 DNS server is very straight forward and only hosts a few domains, most of which are served from either Wist or Wintermute using a handfull of A/CNAME records and wildcard dns.</p>
<p>The Apache-SSL server is only going to host https for www.elizium.net so the only changes from the stock install for that is to install the appropriate certificate. I tend to buy certificates from <a href="https://ssl.ev1servers.net/?SslType=QuickSSL">EV1Servers</a> which I find very affordable.</p>
<p>The magic for this article happens in the config file for Apache 1.3 hosting plain http traffic.<br />
To allow me to easily add arbitrary domains and subdomains without extra config of the DNS server, I&#8217;ve used wildcard DNS. This means that all DNS requests for any subdomain of a domain (eg. www.example.org and sub.example.org) will be directed to the same server unless there is a specific DNS record for that particular subdomain. Clear? Probably not but thats the best I can do just now.</p>
<p>I wanted to be able to create a directory structure which would let me map out the web sites. Lets say I&#8217;ve created a root folder at /var/http and domains under that will be at /var/http/example.org then the subdomains will reside at /var/http/example.org/www /var/http/example.org/sub following me? Good. </p>
<p>On Wist, the first part of the domain name is stripped to become the subdomain. This means that if a request for http://example.org is recieved it will go to /var/http/org/example. I tend to create redirects in each of those folders to www.example.org etc as the vanity www has been overly popular for the last million years.</p>
<p>How did I manage to do this? Using mod_rewrite! Much as I hate regex (well, to be honest, I don&#8217;t use it enough to easily remember its quirks) this is clearly the way forward in this case.</p>
<p>Concentrate, here comes the science bit:<br />
<div class="codeblock"><code><span class="synIdentifier">RewriteEngine</span> <span class="synConstant">on</span><br /><span class="synComment">#Ignore requests for server wide directories</span><br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{REQUEST_URI}&nbsp; !^/mailman/.*<br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{REQUEST_URI}&nbsp; !^/pipermail/.*<br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{REQUEST_URI}&nbsp; !^/cgi-bin/.*<br /><span class="synIdentifier">RewriteCond</span>&nbsp; &nbsp;  %{REQUEST_URI}&nbsp; !^/icons/.*<br /><span class="synComment">#Rewrite the full request to include the host instead of just the path</span><br /><span class="synComment">#eg. /dir/index.html -&gt; www.example.org/dir/index.html</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^(.+)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  %{HTTP_HOST}$1&nbsp; [C]<br /><span class="synComment">#Rewrite the url to a file in a directory</span><br /><span class="synComment">#www.example.org/dir/index.html -&gt; /var/http/example.org/www/dir/index.html</span><br /><span class="synIdentifier">RewriteRule</span>&nbsp; &nbsp;  ^([^.]+)\.([^/]+)\/(.*)$&nbsp; &nbsp; &nbsp; &nbsp; /var/http/$2/$1/$3 [L]<br /></code></div></p>
<p>Good, eh? I have to add my thanks to the guys in <a href="irc://chat.freenode.net/#regex">#regex</a> when I was struggling to come up with this.</p>
<p>Apache handles all the rest &#8211; default directory indexes and the variety of options itself.</p>
<p>The one last addition to the whole bundle is logging. First I started with this:<br />
<div class="codeblock"><code><span class="synIdentifier">LogFormat</span> <span class="synConstant">&quot;%{Host}i %h %l %u %t \&quot;%r\&quot; %&gt;s %b \&quot;%{Referer}i\&quot; \&quot;%{User-Agent}i\&quot;&quot;</span> vfull<br /><span class="synIdentifier">CustomLog</span> /var/log/apache/access.log vfull<br /></code></div></p>
<p>Which is the same as a standard Apache log file line but with the hostname (eg. www.example.org) as the first field.</p>
<p>Good, but we can do better.<br />
<div class="codeblock"><code><span class="synIdentifier">CustomLog</span> <span class="synConstant">&quot;|/sbin/vlogger -s access.log -u www-data -g www-data&nbsp; -t %Y%m%d-access.log /var/log/apache&quot;</span> vfull<br /></code></div></p>
<p>I&#8217;ve installed the <a href="http://n0rp.chemlab.org/vlogger/">vlogger</a> package. This spits out a directory per hostname with dated YYYY-MM-DD-access.log files and a symlink called access.log to the current days logs. Priceless if you want to do per host webstats withouth pre-precessing a big monolithic log file for specific domains.</p>
<p>Hopefully some folk will find that useful. After I&#8217;ve detailed the webhosting setup on Wintermute &#8211; more regex, some the same, mostly different &#8211; I&#8217;ll tell you how I automatically generate my webstats.</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for VWebhosting" /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+VWebhosting" target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/vwebhosting.php/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Migratory changes&#8230;</title>
		<link>http://www.arricc.net/migratory-changes.php</link>
		<comments>http://www.arricc.net/migratory-changes.php#comments</comments>
		<pubDate>Sat, 01 Jul 2006 23:46:00 +0000</pubDate>
		<dc:creator>Fizzgig</dc:creator>
				<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Wist]]></category>
		<category><![CDATA[Xev]]></category>

		<guid isPermaLink="false">http://wp.arricc.net/migratory-changes.php</guid>
		<description><![CDATA[Over the last 12 months I&#8217;ve become increasingly disenchanted with the value for money of the colo server I rent (xev.arricc.net) from Serversure. When I first took out the contract, it was the best there was, and as my bandwidth at the time was very low, 5Gb/month was an acceptable limitation. Since then my bandwidth [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last 12 months I&#8217;ve become increasingly disenchanted with the value for money of the colo server I rent (xev.arricc.net) from <a href="http://www.serversure.net">Serversure</a>. When I first took out the contract, it was the best there was, and as my bandwidth at the time was very low, 5Gb/month was an acceptable limitation.</p>
<p>Since then my bandwidth has gone over that fairly regularly. So I went shopping about. After a lot of time spend trying to convert € and $ into £ I eventually settled on the basic root server offering from <a href="http://www.1and1.co.uk/?k_id=10500082">1&#038;1 Internet</a> (wist.arricc.net). The benefits? <em>unlimited</em> bandwidth and serial console access to the server &#8211; not to mention the spec is about double the memory and Mhz of Xev!</p>
<p>I&#8217;ve made a number of changes to the setup of Wist over Xev, with (hopefully!) no loss of services. Not least is the implementation of <a href="http://www.linux-vserver.org">virtual servers</a>. This has allowed me to let users run <a href="http://www.php.net">PHP</a> scripts in a sandbox which won&#8217;t affect my own projects. </p>
<p>I&#8217;m going to attempt to detail the setup in stages as there are a number of things to cover &#8211; vservers, webservers &#038; virtual hosting,  database server, host access(ssh, ftp, etc.) &#8211; so hopefully I&#8217;ll be able to break them down in meaningful stages!</p>
<p class="buymebeer"><form action="https://www.paypal.com/cgi-bin/webscr" target="paypal" method="post"><input type="hidden" name="cmd" value="_xclick" /><input type="hidden" name="business" value="mark@arricc.net" /><input type="hidden" name="return" value="http://www.arricc.net/pp-thanks.php" /><input type="hidden" name="item_name" value="Buy Me a Beer for Migratory changes..." /><input type="hidden" name="currency_code" value="GBP" /><input type="hidden" name="amount" value="5" /><input type="image" src="http://www.arricc.net/wp-content/plugins/buy-me-beer/icon_beer.gif" align="left" alt="" title="" hspace="3" /></form><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=mark@arricc.net&amp;currency_code=GBP&amp;amount=5&amp;return=http://www.arricc.net/pp-thanks.php&amp;item_name=Buy+Me+a+Beer+for+Migratory+changes..." target="paypal">If you find this article useful, buy me a beer!</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.arricc.net/migratory-changes.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

