
<?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>M &#8211; Mark&#039;s Website</title>
	<atom:link href="https://kram.nz/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>https://kram.nz</link>
	<description>Solution Architect - Healthcare IT</description>
	<lastBuildDate>Tue, 06 Jun 2023 09:42:17 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.3</generator>

<image>
	<url>https://kram.nz/wp-content/uploads/2016/04/cropped-M-32x32.png</url>
	<title>M &#8211; Mark&#039;s Website</title>
	<link>https://kram.nz</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>NHI Validation</title>
		<link>https://kram.nz/2019/02/nhi-validation/</link>
					<comments>https://kram.nz/2019/02/nhi-validation/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Wed, 20 Feb 2019 11:01:10 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Healthcare]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[NHI]]></category>
		<category><![CDATA[NHI Generator]]></category>
		<category><![CDATA[NHI Validator]]></category>
		<guid isPermaLink="false">https://kram.nz/?p=433</guid>

					<description><![CDATA[Here is a National Health Index (NHI) validator and generator that I created. NHIs are healthcare identifiers used in New Zealand[1][2][3]. NHI Validator NHI: Generate NHIs Generate random NHIs Generate The current Id. structure only allows for around 13.8 million NHI's. With a population of around 5 million in 2019 and the possibility of a [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Here is a National Health Index (NHI) validator and generator that I created. NHIs are healthcare identifiers used in New Zealand<a class="reflink" href="#ref-nhi-wiki">[1]</a><a class="reflink" href="#ref-nhi-gov">[2]</a><a class="reflink" href="#ref-nhi-midcentral">[3]</a>.</p>



<form id="nhi-validator"> <fieldset> <legend>NHI Validator</legend> <div><label for="nhinumberfield">NHI:</label> <input id="nhinumberfield" type="text" maxlength="7" placeholder="ABC1234" pattern="[A-HJ-NP-Z]{3}\d{4}" onload="validateNhi(this)" onkeydown="validateNhi(this)" title="Three letters (without I or O) and 4 numbers" required="" autofocus=""> </div><div id="validation-result"></div> </fieldset></form><form id="nhi-generator"> <fieldset> <legend>Generate NHIs</legend> <p>Generate random NHIs</p> <button name="generate-nhi-button" type="button" onclick="generateNhis(this)">Generate</button> <ul id="generated-nhis"></ul> </fieldset></form><script>function generateNhis(){for(var e=document.getElementById("generated-nhis");e.hasChildNodes();){e.removeChild(e.lastChild)}for(var t=0;t<20;t+=1){var n=document.createElement("li"),a=document.createTextNode(generateRandomNhi());n.appendChild(a),e.appendChild(n)}}function generateRandomNhi(){for(var e="",t=0;t<6;t+=1){e+=t<3?randomNhiCharacter():getRandomInteger(0,10)}return e+=generateChecksum(e)}function getRandomInteger(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e))+e}function randomNhiCharacter(){var e=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"];return e[getRandomInteger(0,e.length)]}function validateNhi(e){setTimeout(function(){e.value=cleanNHI(e.value),7==e.value.length&#038;&#038;validateChecksum(e.value)?(e.setCustomValidity(""),document.getElementById("validation-result").innerHTML="This is a valid NHI!"):(e.setCustomValidity("Invalid NHI"),proposePossibleNhis(e.value))},1)}function proposePossibleNhis(invalidNhi){var ul=document.createElement("ul");if(invalidNhi.length==7){for(var index=0;index<7;index+=1){var alternativeNhi=findValidNhiAt(invalidNhi,index);if(alternativeNhi){var n=document.createElement("li");var a=document.createTextNode(alternativeNhi);n.appendChild(a);ul.appendChild(n)}}}var resultNode=document.getElementById("validation-result");for(;resultNode.hasChildNodes();){resultNode.removeChild(resultNode.lastChild)}var message=document.createElement("p");message.appendChild(document.createTextNode("Could it be one of the following?"));resultNode.appendChild(message);resultNode.appendChild(ul)}function findValidNhiAt(invalidNhi,index){if(index<3){var alphabet=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"];for(var i=0;i<alphabet.length;i+=1){var proposedNhi=invalidNhi.substr(0,index)+alphabet[i]+invalidNhi.substr(index+1);if(validateChecksum(proposedNhi)){return proposedNhi}}}for(var i=0;i<10;i+=1){var proposedNhi=invalidNhi.substr(0,index)+i+invalidNhi.substr(index+1);if(validateChecksum(proposedNhi)){return proposedNhi}}return null}function cleanNHI(e){return e.toUpperCase().replace("I","").replace("O","").substring(0,7)}function validateChecksum(e){return generateChecksum(e)==valueOf(e.charCodeAt(6))}function generateChecksum(e){for(sum=0,i=0;i<6;i+=1){sum+=valueOf(e.charCodeAt(i))*(7-i)}if(sum%11==0){return "Invalid"}return(11-sum%11)%10}function valueOf(e){return 47<e&#038;&#038;e<58?e-48:64<e&#038;&#038;e<73?e-64:73<e&#038;&#038;e<79?e-65:79<e&#038;&#038;e<91?e-66:void 0}</script><style>#generated-nhis,#validation-result ul{column-count:2;-webkit-column-count:2;-moz-column-count:2;font-family:monospace}#nhinumberfield:focus:required:invalid{background-color:pink;color:white}#nhinumberfield:required:valid{background-color:white;color:black}#nhinumberfield:invalid{border-color:red}#nhinumberfield,#nhinumberfield:valid{border-color:green}</style>



<ul>
<li>NHI's uses the letters A-Z without I or O.</li>



<li>NHI's start with three letters and end with four numbers.</li>



<li>The last digit is a checksum.</li>



<li>NHI's are assigned randomly. I believe hospitals have distinct sets ready to be assigned.</li>



<li>Its possible for somebody to have multiple NHIs (first alphabetically is the primary).</li>
</ul>



<p>The current Id. structure only allows for around 13.8 million NHI's. With a population of around 5 million in 2019 and the possibility of a single person being associated to multiple Id.s, I suspect NHIs in their current form wont be around very long.</p>



<h2 class="wp-block-heading">References</h2>



<p>(last checked 2023-06-06)</p>



<ol><li><a href="https://en.wikipedia.org/wiki/NHI_Number" target="_blank" rel="noopener noreferrer" id="ref-nhi-wiki">https://en.wikipedia.org/wiki/NHI_Number</a></li><li><del><a href="https://www.health.govt.nz/our-work/health-identity/national-nhi-gov" target="_blank" rel="noopener noreferrer" id="ref-nhi-gov">https://www.health.govt.nz/our-work/health-identity/national-health-index</a></del></li><li><a href="http://www.midcentraldhb.govt.nz/PatientsandVisitors/GeneralInformation/Pages/NHI.aspx" target="_blank" rel="noopener noreferrer" id="ref-nhi-midcentral">http://www.midcentraldhb.govt.nz/PatientsandVisitors/GeneralInformation/Pages/NHI.aspx</a></li></ol>



<p>[EDIT]: Thanks to Chris W for pointing out a bug in my previous implementation. If the checksum is a '0' before being subtracted from 11, the NHI number is deemed to be invalid. This is now fixed in the generator.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2019/02/nhi-validation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Brisbane Webcam</title>
		<link>https://kram.nz/2019/02/brisbane-webcam/</link>
					<comments>https://kram.nz/2019/02/brisbane-webcam/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sun, 17 Feb 2019 06:10:06 +0000</pubDate>
				<category><![CDATA[Photos]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[Brisbane]]></category>
		<category><![CDATA[N900]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Timelapse]]></category>
		<category><![CDATA[Webcam]]></category>
		<category><![CDATA[Website]]></category>
		<guid isPermaLink="false">https://kram.nz/?p=543</guid>

					<description><![CDATA[Using an old phone (Nokia N900) I have set up a webcam to take a photo every 5 minutes during the day and upload it to my website. You can see the latest photo on: Webcam I have set my computers desktop background to sync with the latest photo too. So far I have a [&#8230;]]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure><img fetchpriority="high" decoding="async" width="1024" height="569" src="https://kram.nz/wp-content/uploads/2019/02/20181231-134001-Brisbane-1024x569.jpeg" alt="" class="wp-image-552 aligncenter" srcset="https://kram.nz/wp-content/uploads/2019/02/20181231-134001-Brisbane-1024x569.jpeg 1024w, https://kram.nz/wp-content/uploads/2019/02/20181231-134001-Brisbane-300x167.jpeg 300w, https://kram.nz/wp-content/uploads/2019/02/20181231-134001-Brisbane-768x427.jpeg 768w, https://kram.nz/wp-content/uploads/2019/02/20181231-134001-Brisbane-1568x871.jpeg 1568w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Brisbane Webcam</figcaption></figure></div>



<p>Using an old phone (Nokia N900) I have set up a webcam to take a photo every 5 minutes during the day and upload it to my website. You can see the latest photo on: <a href="/webcam/">Webcam</a></p>



<div class="wp-block-image"><img decoding="async" width="640" height="480" src="https://kram.nz/wp-content/uploads/2019/02/BrisbaneWebcam.jpg" alt="" class="wp-image-548 aligncenter" srcset="https://kram.nz/wp-content/uploads/2019/02/BrisbaneWebcam.jpg 640w, https://kram.nz/wp-content/uploads/2019/02/BrisbaneWebcam-300x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>N900 set up as a webcam</figcaption></figure></div>



<p>I have set my computers desktop background to sync with the latest photo too. So far I have a years worth of images and have made a few time-lapses. Here is one over a couple of days:</p>



<div class="wp-block-media-text alignwide"><figure class="wp-block-media-text__media"><video controls src="https://kram.nz/wp-content/uploads/2019/02/timelapse.webm"></video></figure><div class="wp-block-media-text__content">
<p style="text-align:center" class="has-large-font-size">Timelapse from the webcam</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2019/02/brisbane-webcam/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://kram.nz/wp-content/uploads/2019/02/timelapse.webm" length="1903113" type="video/webm" />

			</item>
		<item>
		<title>Webcam Security System</title>
		<link>https://kram.nz/2019/02/webcam-security-system/</link>
					<comments>https://kram.nz/2019/02/webcam-security-system/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sat, 16 Feb 2019 07:50:39 +0000</pubDate>
				<category><![CDATA[Photos]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[AIML]]></category>
		<category><![CDATA[ALICE]]></category>
		<category><![CDATA[hping3]]></category>
		<category><![CDATA[Motion]]></category>
		<category><![CDATA[Nmap]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[Telegram]]></category>
		<category><![CDATA[Webcam]]></category>
		<guid isPermaLink="false">https://kram.nz/?p=353</guid>

					<description><![CDATA[A while ago I set up an old webcam / Raspberry Pi to serve as a security camera. Using Motion[1], its easy to set up a system that will record any movement and can be manually enabled or set to run on a simple schedule such as while I am away at work. Eventually I [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>A while ago I set up an old webcam / Raspberry Pi to serve as a security camera. Using Motion<a class="reflink" href="#ref-seccam-motion">[1]</a>, its easy to set up a system that will record any movement and can be manually enabled or set to run on a simple schedule such as while I am away at work.</p>



<ul class="wp-block-gallery columns-2 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img decoding="async" width="640" height="480" src="https://kram.nz/wp-content/uploads/2019/02/Webcam.jpg" alt="" data-id="519" data-link="https://kram.nz/?attachment_id=519" class="wp-image-519" srcset="https://kram.nz/wp-content/uploads/2019/02/Webcam.jpg 640w, https://kram.nz/wp-content/uploads/2019/02/Webcam-300x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Webcam</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="640" height="480" src="https://kram.nz/wp-content/uploads/2019/02/MotionRPi.jpg" alt="" data-id="522" data-link="https://kram.nz/?attachment_id=522" class="wp-image-522" srcset="https://kram.nz/wp-content/uploads/2019/02/MotionRPi.jpg 640w, https://kram.nz/wp-content/uploads/2019/02/MotionRPi-300x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Raspberry Pi</figcaption></figure></li></ul>



<p>Eventually I made the system a bit smarter to automatically turn on when I leave home and turn off as soon as I get back. Added to that, if anything moves while I am out, I get a message with a photo sent to my phone.</p>



<p>For fun, I also added an AI to my messaging system so if I get bored I can have a chat or ask it to do some pre-programmed tasks (such as shutting down systems on the network, taking a photo or changing its settings).</p>



<p>The whole system is built using:</p>



<ul><li>Motion<a class="reflink" href="#ref-seccam-motion">[1]</a></li><li>Python</li><li>Nmap<a class="reflink" href="#ref-seccam-nmap">[2]</a> / hping3<a class="reflink" href="#ref-seccam-hping">[3]</a></li><li>Telegram<a class="reflink" href="#ref-seccam-telegram">[4]</a></li><li>PHP / SQL</li></ul>



<h2 class="wp-block-heading">Python Process</h2>



<p>The heart of the system is written in Python and is set to run as a systemd process. It mostly sleeps and wakes up every so often (~10 seconds) to check for new motion events or messages from telegram. </p>



<h2 class="wp-block-heading">Network presence detection</h2>



<p>It turns out that its not easy to detect the presence of iPhones on a network. In order to save power they can be come rather quiet and uncommunicative to network chatter. </p>



<p>At first I tried to build something in Python but after it became clear it was no small task, I decided to delegate to a subprocess and run a system tool. Next, I went with a script using hping3<a class="reflink" href="#ref-seccam-hping">[3]</a>  and arp tables. This still wasn&#8217;t fantastic so at the moment I am just using an nmap<a class="reflink" href="#ref-seccam-nmap">[2]</a> ping. From my tests, this seems to work better than hping3 at finding the iPhone but my tests weren&#8217;t very scientific.</p>



<h3 class="wp-block-heading">Monitoring</h3>



<p>I set up a database to log network presence and created a small PHP script to graph phones on the network. In the example below, you can see the blue graph for my phone, pink for my girlfriends and green shows when one of us are at home (and the system is turned off).</p>



<h4>2019-02-13</h4><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0%" width="6.912037037037%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="7.4918981481481%" width="9.9525462962963%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="18.337962962963%" width="1.3252314814815%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="27.991898148148%" width="22.493055555556%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="51.212962962963%" width="2.0324074074074%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="55.68287037037%" width="29.296296296296%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="88.976851851852%" width="7.2083333333333%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="96.792824074074%" width="1.5347222222222%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="99.016203703704%" width="-98.601851851852%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="2.212962962963%" width="1.6261574074074%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="6.3611111111111%" width="0.99189814814815%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="9.5173611111111%" width="0.77083333333333%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="11.368055555556%" width="0.62037037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="13.862268518519%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="16.118055555556%" width="2.6481481481481%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="32.064814814815%" width="1.3900462962963%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="37.119212962963%" width="1.6203703703704%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="40.616898148148%" width="5.5798611111111%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="47.28125%" width="9.6354166666667%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="57.743055555556%" width="21.042824074074%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="79.650462962963%" width="7.8923611111111%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="88.903935185185%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="91.109953703704%" width="1.6458333333333%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="94.032407407407%" width="1.1296296296296%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="96.229166666667%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="98.299768518519%" width="0.57870370370371%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0%" width="19.663194444444%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="27.991898148148%" width="59.550925925926%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="88.903935185185%" width="11.096064814815%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><h4>2019-02-14</h4><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="1.2256944444444%" width="1.3125%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="3.1851851851852%" width="6.5983796296296%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="10.571759259259%" width="64.081018518519%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="75.534722222222%" width="2.4375%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="78.635416666667%" width="16.696759259259%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="95.935185185185%" width="1.0115740740741%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="97.614583333333%" width="2.3854166666667%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0.49768518518519%" width="0.59259259259259%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="2.46875%" width="1.4236111111111%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="6.619212962963%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="9.8553240740741%" width="1.3564814814815%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="14.584490740741%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="17.484953703704%" width="1.3541666666667%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="19.835648148148%" width="0.97800925925926%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="22.327546296296%" width="1.7071759259259%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="25.109953703704%" width="0.99305555555556%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="28.662037037037%" width="3.5358796296296%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="34.517361111111%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="35.997685185185%" width="3.4074074074074%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="40.283564814815%" width="0.59143518518518%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="42%" width="10.75462962963%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="54.045138888889%" width="8.75%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="64.155092592593%" width="0.6886574074074%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="65.71875%" width="0.98032407407408%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="67.408564814815%" width="10.591435185185%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="78.614583333333%" width="1.150462962963%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="81.966435185185%" width="3.1122685185185%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="85.908564814815%" width="4.9282407407407%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="91.489583333333%" width="0.57870370370371%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="93.454861111111%" width="4.724537037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="99.084490740741%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0%" width="78%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="78.614583333333%" width="21.385416666667%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><h4>2019-02-15</h4><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0%" width="22.28587962963%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="23.274305555556%" width="1.0277777777778%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="25.075231481481%" width="5.2384259259259%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="31.153935185185%" width="12.158564814815%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="43.987268518519%" width="5.0844907407407%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="50.298611111111%" width="2.9791666666667%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="54.133101851852%" width="41.005787037037%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="95.835648148148%" width="4.0300925925926%" height="15" style="fill:rgb(51, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="7.6828703703704%" width="0.59259259259259%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="11.170138888889%" width="1.6261574074074%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="13.747685185185%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="17.537037037037%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="21.679398148148%" width="1.4594907407407%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="24.025462962963%" width="0.90972222222222%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="25.519675925926%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="27.847222222222%" width="3.7337962962963%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="32.653935185185%" width="0.5787037037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="34.074074074074%" width="2.5138888888889%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="37.758101851852%" width="8.8599537037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="47.277777777778%" width="3.0196759259259%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="51.238425925926%" width="30.755787037037%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="82.988425925926%" width="1.1342592592593%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="84.768518518519%" width="3.5104166666667%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="89.568287037037%" width="2.6550925925926%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="92.803240740741%" width="0.59259259259258%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="95.24537037037%" width="0.57870370370371%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="96.960648148148%" width="0.60648148148148%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect><rect x="98.318287037037%" width="0.57870370370371%" height="15" style="fill:rgb(255, 204, 255);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg><svg width="100%" height="15"><rect width="100%" height="15" style="fill:rgb(255,255,255);stroke-width:3;stroke:rgb(0,0,0)"></rect><rect x="0%" width="99.865740740741%" height="15" style="fill:rgb(0, 204, 102);stroke-width:1;stroke:rgb(0,0,0)"></rect></svg>



<h2 class="wp-block-heading">Messaging</h2>



<p>Initially I build a messaging component using the free Telstra API<a class="reflink" href="#ref-seccam-telstra">[5]</a>. This provided an API allowing me to send SMS messages to my phone when the system started up or movement was captured. I ripped this out when Telstra added more limits on the API and put more of a push to their priced model.</p>



<ul class="wp-block-gallery columns-2 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="180" height="320" src="https://kram.nz/wp-content/uploads/2019/02/IMG_7072.png" alt="" data-id="525" data-link="https://kram.nz/?attachment_id=525" class="wp-image-525" srcset="https://kram.nz/wp-content/uploads/2019/02/IMG_7072.png 180w, https://kram.nz/wp-content/uploads/2019/02/IMG_7072-169x300.png 169w" sizes="(max-width: 180px) 100vw, 180px" /><figcaption>Phone Disconnected</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="180" height="320" src="https://kram.nz/wp-content/uploads/2019/02/IMG_7073.png" alt="" data-id="526" data-link="https://kram.nz/?attachment_id=526" class="wp-image-526" srcset="https://kram.nz/wp-content/uploads/2019/02/IMG_7073.png 180w, https://kram.nz/wp-content/uploads/2019/02/IMG_7073-169x300.png 169w" sizes="(max-width: 180px) 100vw, 180px" /><figcaption>Phone Connected</figcaption></figure></li></ul>



<h3 class="wp-block-heading">Telegram</h3>



<p>After looking for a better way to do push notifications to my phone, I eventually settled on creating a Telegram<a class="reflink" href="#ref-seccam-telegram">[4]</a>  bot. This allayed my cost aversion, provided the push notification behaviour that I was after and opened up easier two way communication. </p>



<ul class="wp-block-gallery columns-2 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="375" height="667" src="https://kram.nz/wp-content/uploads/2019/02/telegram.png" alt="" data-id="538" data-link="https://kram.nz/2019/02/webcam-security-system/telegram/" class="wp-image-538" srcset="https://kram.nz/wp-content/uploads/2019/02/telegram.png 375w, https://kram.nz/wp-content/uploads/2019/02/telegram-169x300.png 169w" sizes="(max-width: 375px) 100vw, 375px" /><figcaption>Telegram commands</figcaption></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="375" height="667" src="https://kram.nz/wp-content/uploads/2019/02/ALICE.png" alt="" data-id="529" data-link="https://kram.nz/2019/02/webcam-security-system/alice/" class="wp-image-529" srcset="https://kram.nz/wp-content/uploads/2019/02/ALICE.png 375w, https://kram.nz/wp-content/uploads/2019/02/ALICE-169x300.png 169w" sizes="(max-width: 375px) 100vw, 375px" /><figcaption>ALICE</figcaption></figure></li></ul>



<h3 class="wp-block-heading">AI</h3>



<p>I took an old copy of the A.L.I.C.E. AIML<a class="reflink" href="#ref-seccam-aiml">[6]</a> bot and plugged it into my Telegram bot. Its hardly going to convince anybody in a Turing test but is still quite a bit of fun to chat to.</p>



<h2 class="wp-block-heading">Image Capture<br></h2>



<p>Motion provides a very easy to set up frame/video capture process on Linux. It has the ability to trigger actions when motion is detected but I have instead chosen to go with periodically polling its output for events and archiving captures.</p>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="640" height="480" src="https://kram.nz/wp-content/uploads/2019/02/motion.jpg" alt="" class="wp-image-527" srcset="https://kram.nz/wp-content/uploads/2019/02/motion.jpg 640w, https://kram.nz/wp-content/uploads/2019/02/motion-300x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Capture from Motion</figcaption></figure></div>



<h2 class="wp-block-heading">References</h2>



<p> (last checked 2019-02-16) </p>



<ol><li><a href="https://motion-project.github.io/" target="_blank" rel="noopener noreferrer" id="ref-seccam-motion">https://motion-project.github.io/</a></li><li><a href="https://nmap.org/" target="_blank" rel="noopener noreferrer" id="ref-seccam-nmap">https://nmap.org/</a></li><li><a href="http://www.hping.org/" target="_blank" rel="noopener noreferrer" id="ref-seccam-hping">http://www.hping.org/</a></li><li><a href="https://telegram.org/" target="_blank" rel="noopener noreferrer" id="ref-seccam-telegram">https://telegram.org/</a></li><li><a href="https://dev.telstra.com/" target="_blank" rel="noopener noreferrer" id="ref-seccam-telstra">https://dev.telstra.com/</a></li><li><a href="https://en.wikipedia.org/wiki/AIML" target="_blank" rel="noopener noreferrer" id="ref-seccam-aiml">https://en.wikipedia.org/wiki/AIML</a></li></ol>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2019/02/webcam-security-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Remotely Initiated Reverse SSH Tunnel</title>
		<link>https://kram.nz/2018/01/remote-ssh-tunnel/</link>
					<comments>https://kram.nz/2018/01/remote-ssh-tunnel/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Wed, 10 Jan 2018 07:20:03 +0000</pubDate>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[passwd]]></category>
		<category><![CDATA[shadow]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SSH Tunnel]]></category>
		<guid isPermaLink="false">https://kram.nz/?p=430</guid>

					<description><![CDATA[This article lays out the steps to set up an SSH tunnel[1] so that you can connect to a server hidden behind a firewall/router.&#160;Cron is used on the server to maintain a connection from the hidden remote server to my local server, that I can use to connect to the remote server. Problem To highlight [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This article lays out the steps to set up an SSH tunnel<a class="reflink" href="#ref-ssh-sshtunnel">[1]</a> so that you can connect to a server hidden behind a firewall/router.&nbsp;Cron is used on the server to maintain a connection from the hidden remote server to my local server, that I can use to connect to the remote server.</p>
<h2>Problem</h2>
<p>To highlight what this setup does lets pretend we have the following scenario; Mr. Bond wants to connect to a server running on Dr. No&#8217;s private island:<br />
<a id="ref-ssh-figure1"></a></p>
<figure class="aligncenter"><img decoding="async" class="size-full wp-image-434 aligncenter" src="https://kram.nz/wp-content/uploads/2018/01/SSHTunnelBlocked.svg" alt=""><figcaption class="aligncenter">Figure 1 &#8211; Blocked SSH Connection</figcaption></figure>
<p>When Mr. Bond tries to connect, he hits the firewall put up by Dr. No and can&#8217;t see the SSH Server <a class="reflink" href="#ref-ssh-figure1">[Figure 1]</a>.</p>
<h2>Goal</h2>
<p>In order to get pass this and connect any time Mr. Bond is in the mood, he needs to sneak onto Dr. No&#8217;s island and set up an SSH tunnel back to MI6 <a class="reflink" href="#ref-ssh-figure2">[Figure 2]</a>.<br />
<a id="ref-ssh-figure2"></a></p>
<figure class="aligncenter"><img decoding="async" class="size-full wp-image-438 aligncenter" src="https://kram.nz/wp-content/uploads/2018/01/SSHTunnelEstablished.svg" alt="">&nbsp;<figcaption class="aligncenter">Figure 2 &#8211; SSH Tunnel Established</figcaption></figure>
<p>With this established, Mr. Bond can connect to the SSH tunnel open on a port in his local machine. This will then pass traffic back to Dr. No&#8217;s server <a class="reflink" href="#ref-ssh-figure3">[Figure 3]</a>.</p>
<p>&nbsp;</p>
<figure class="aligncenter"><img decoding="async" class="size-full wp-image-436 aligncenter" src="https://kram.nz/wp-content/uploads/2018/01/SSHTunnelConnected.svg" alt="">&nbsp;<figcaption class="aligncenter">Figure 3 &#8211; Connected through SSH Tunnel</figcaption></figure>
<h2>Solution Setup</h2>
<p>These instructions consist of:</p>
<ul>
<li>Create an account for SSH to connect with</li>
<li>Set up key based authentication for the tunnel</li>
<li>Use cron / shell script to re-establish the connection if it drops.</li>
</ul>
<p>With these steps, we make sure that Dr. No&#8217;s server is only able to open a port for SSH on the MI6 computer and doesn&#8217;t have access to run any commands on Mr. Bonds machine.</p>
<p>Using key based authentication means bots crawling the net wont be able to guess a password, but more vitally, will allow us to imitate the SSH tunnel from cron without having to pass through a password.</p>
<p>Cron will periodically run a shell script that opens the SSH tunnel (if there isn&#8217;t already one open). An alternative here could be to use autossh if that is available <a class="reflink" href="#ref-ssh-autossh">[7]</a>.</p>
<p>The command to connect from the remote server is fairly straight forward:</p>
<pre>ssh -R 62222:localhost:22 drno-ssh@mi6.example.com -N</pre>
<p>Breakdown:</p>
<ul>
<li>ssh : Here we are using OpenSSH. More details &#8216;man ssh&#8217;<a class="reflink" href="#ref-ssh-manssh">[2]</a>.</li>
<li>-R : Indicates that the next value is the connection to send to the remote server.</li>
<li>62222: This is the port that we want to set up on our local machine for the tunnel to appear on.</li>
<li>localhost: This is the loopback of the remote machine &#8211; could open a tunnel to a different machine on the remote network if we wanted to.</li>
<li>22: The port on the remote machine where ssh is running.</li>
<li>drno-ssh: This is the account we will connect to our local machine with.</li>
<li>mi6.example.com: This is the address/IP where SSH can connect to our local machine.</li>
<li>-N :&nbsp; Do not execute a remote command. This is useful for just forwarding ports (protocol version 2 only).</li>
</ul>
<h3>Connection Test</h3>
<p>To start with, we can check that this works by running it on the remote server (substitute drno-ssh@mi6.example.com with your username and hostname):</p>
<pre>drno@island$ ssh -R 62222:localhost:22 drno-ssh@mi6.example.com -N</pre>
<p>This should open the SSH tunnel. Now from your local server:</p>
<pre>bond@mi6$ ssh localhost -p 62222</pre>
<p>This should let you connect past the firewall. The next steps are to create a locked down user for the connection and to set up the automated connection.</p>
<h3>User Setup</h3>
<p>In this scenario, we are going to create an account on the local (mi6) server for the remote server to log in with. We will name this user &#8220;drno-ssh&#8221;:</p>
<pre>bond@mi6$ sudo adduser drno-ssh --system --shell=/bin/false
Adding system user `drno-ssh' (UID 111) ...
Adding new user `drno-ssh' (UID 111) with group `nogroup' ...
Creating home directory `/home/drno-ssh' ...
bond@mi6$ sudo passwd -l drno-ssh
passwd: password expiry information changed.</pre>
<p>The first command adduser creates the account; the &#8216;&#8211;system&#8217; option indicates that this is a &#8216;system account&#8217; and the &#8216;&#8211;shell=/bin/false&#8217; prevents commands from being run by preventing a shell from loading after a login<a class="reflink" href="#ref-ssh-manuseradd">[3]</a>.</p>
<p>After this, the &#8216;passwd&#8217; command is used with the &#8216;-l&#8217; option to disable the accounts password.</p>
<p>We can check this worked by running the flollowing commands:</p>
<pre>bond@mi6$ less /etc/passwd | grep drno-ssh
drno-ssh:x:111:65534::/home/drno-ssh:/bin/false
bond@mi6$ sudo less /etc/shadow | grep drno-ssh
drno-ssh:!*:17540:0:99999:7:::</pre>
<p>The result of the first command shows us that the shell is set to &#8216;/bin/false&#8217; and the password for the account is managed in the shadow file (the &#8216;x&#8217;)<a class="reflink" href="#ref-ssh-passwd">[4]</a>.</p>
<p>In the result from the second command you can see the row in the shadow file. The shadow file stores user passwords and the key thing that we want to see is the &#8216;!*&#8217;. This means that the users password is disabled<a class="reflink" href="#ref-ssh-shadow">[5]</a>.</p>
<p>As an additional check, we can try using root permission to jump into the account. If we try the following, we shouldn&#8217;t get anywhere and be bounced back to our current user:</p>
<pre>bond@mi6$ sudo su drno-ssh
bond@mi6$</pre>
<h3>Setup Key-Based Authentication</h3>
<p>These steps store the SSH key in the home directory of the user we created above. It&#8217;s possible to use directives in &#8216;ssh_config&#8217; to avoid having a home directory as well as using a user other than root for the connection but I am not covering these here. By setting up key-based authentication instead of a password, we are able to create the ssh tunnel form the remote server without having to set a password for the account we are connecting to on our local machine. This is a bit more secure as well as allowing us to create the ssh connection from a cron job easily.</p>
<p>Create a folder to store the private key on your local server:</p>
<pre>bond@mi6$ sudo mkdir -p /home/drno-ssh/.ssh
bond@mi6$ sudo chmod 0777 /home/drno-ssh/.ssh/</pre>
<p>Important: don&#8217;t do this if you already have a private key you are using for root as it will destroy the existing key:</p>
<p>The next step is to generate a key pair on the remote server (press return to accept each default).</p>
<pre>drno@island$ sudo ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
9b:57:26:d0:cb:0e:a0:2a:c6:b1:a5:d0:c6:1e:a5:58 root@mi6
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|         .       |
|  E . . . .      |
| = o . . o .     |
|o.*..   S + o    |
|oo=o     = +     |
|.=o     o o      |
|..       .       |
|                 |
+-----------------+</pre>
<p>After this, we need to send the public key that was generated to the remote server. This will recognise our private key when we try to connect and let us in<a class="reflink" href="#ref-ssh-sshkey">[6]</a>.</p>
<pre>drno@island$ sudo cat /root/.ssh/id_rsa.pub | ssh drno@island "cat &gt; /home/drno-ssh/.ssh/authorized_keys"</pre>
<p>On your local server, we will update the public SSH key to include some options limiting what the connection is able to do. In this case, only open port 62222 on the localhost. Its also possible to limit the connecting IP here by adding something like from=&#8221;1.2.3.4&#8243;.</p>
<pre>bond@mi6$ echo -n "command=\"echo 'This account can only be used to create an SSH tunnel'\",no-agent-forwarding,no-X11-forwarding,permitopen=\"localhost:62222\" " &gt; /home/drno-ssh/.ssh/ssh_options &amp;&amp; cat /home/drno-ssh/.ssh/authorized_keys &gt;&gt; /home/drno-ssh/.ssh/ssh_options &amp;&amp; mv /home/drno-ssh/.ssh/ssh_options /home/drno-ssh/.ssh/authorized_keys</pre>
<p>Tidy up the file permissions and restart:</p>
<pre>bond@mi6$ sudo chmod 700 /home/drno-ssh/.ssh &amp;&amp; sudo chmod 640 /home/drno-ssh/.ssh/authorized_keys
bond@mi6$ sudo chown drno-ssh:nogroup -R /home/drno-ssh/.ssh/
bond@mi6$ sudo systemctl restart ssh.service
</pre>
<h3>Cron Connection</h3>
<p>With the key based login setup, we should be able to open a connection from the remote machine with the following (password may be required for sudo but should be needed for drno-ssh@mi6.example.com):</p>
<pre>drno@island$ sudo ssh -R 62222:localhost:22 drno-ssh@mi6.example.com -N</pre>
<p>Now from the local machine:</p>
<pre>bond@mi6$ ssh localhost -p 62222
The authenticity of host '[localhost]:62222 ([::1]:62222)' can't be established.
ECDSA key fingerprint is SHA256:A7lSIQz/J9N2l7kvlKxz4QxxxF+vi8uhx2lvxdxxQ.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:62222' (ECDSA) to the list of known hosts.
bond@islands's password:
** Unauthorised use of this computer  **
** Will result in being fed to sharks **
Last login: Wed Jan 10 15:51:13 2018</pre>
<p>The next step is to set up a cron job to keep this connection alive. Here is a shell script to do this. I will check for a running process containing our SSH username before opening the connection:<br />
Create this by running the following on the remote server:</p>
<pre>drno@island$ sudo nano /home/drno-ssh/ssh_tunnel.sh</pre>
<p>Paste in the following script (after updating the &#8216;drno-ssh&#8217;s and mi6.example.com):</p>
<pre>#!/bin/bash
# Set up an SSH Tunnel if it isn't running
PROCESS_NUM=$(ps -ef | grep "drno-ssh" | grep -v "grep" | wc -l)
if [ "$PROCESS_NUM" == "0" ];
then
 ssh -R 62222:localhost:22 drno-ssh@mi6.example.com -N
fi</pre>
<p>Press CTRL+x to exit and &#8216;Y&#8217; to save.<br />
Make the script executable:</p>
<pre>drno@island$ sudo chmod +x /home/drno-ssh/ssh_tunnel.sh</pre>
<p>Set the script to run hourly using cron:</p>
<pre>drno@island$ sudo crontab -e</pre>
<pre>Add the following line:</pre>
<pre>@hourly /home/drno-ssh/ssh_tunnel.sh #Set up an SSH Tunnel to MI6 every hour if it isn't running.</pre>
<h2>Checking that it works</h2>
<p>With the cron job above enabled, the tunnel will be checked / initiated every hour on the hour. We can check if the tunnel is active with the following command on the remote server:</p>
<pre>drno@island$ ps -ef | grep "drno-ssh"
root     18945 18917  0 21:00 ?        00:00:00 ssh -R 62222:localhost:22 drno-ssh@mi6.example.com -N
bond     22081 20036  0 23:15 pts/5    00:00:00 grep --color=auto drno-ssh</pre>
<p>And on the local server with:</p>
<pre>bond@mi6$ ssh localhost -p 62222
bond@islands's password:</pre>
<p>This will let us log in with one of our normal SSH users over the SSH tunnel.</p>
<p>Mission Accomplished!</p>
<h2>References</h2>
<p>(last checked 2018-01-10)</p>
<ol>
<li><a id="ref-ssh-sshtunnel" href="https://en.wikipedia.org/wiki/Tunneling_protocol" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Tunneling_protocol</a></li>
<li><a id="ref-ssh-manssh" href="https://man.openbsd.org/ssh" target="_blank" rel="noopener noreferrer">https://man.openbsd.org/ssh</a></li>
<li><a id="ref-ssh-manuseradd" href="https://man.openbsd.org/useradd" target="_blank" rel="noopener noreferrer">https://man.openbsd.org/useradd</a></li>
<li><a id="ref-ssh-passwd" href="https://en.wikipedia.org/wiki/Passwd#Password_file" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Passwd#Password_file</a></li>
<li><a id="ref-ssh-shadow" href="https://en.wikipedia.org/wiki/Passwd#Shadow_file" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Passwd#Shadow_file</a></li>
<li><a id="ref-ssh-sshkey" href="https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2" target="_blank" rel="noopener noreferrer">https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys&#8211;2</a></li>
<li><a id="ref-ssh-autossh" href="https://linux.die.net/man/1/autossh" target="_blank" rel="noopener noreferrer">https://linux.die.net/man/1/autossh</a></li>
<li>SVG Icons &#8211; <a id="ref-ssh-svgbond" href="https://pixabay.com/en/james-bond-agent-black-suit-bow-tie-2026107/" target="_blank" rel="noopener noreferrer">[bond]</a><a id="ref-ssh-svgisland" href="https://pixabay.com/en/sand-beach-island-palm-sun-tree-304525/" target="_blank" rel="noopener noreferrer">[island]</a><a id="ref-ssh-svgserver" href="https://pixabay.com/p-159837/?no_redirect" target="_blank" rel="noopener noreferrer">[server]</a><a id="ref-ssh-svgfirewall" href="https://pixabay.com/en/firewall-fire-wall-computer-153179/" target="_blank" rel="noopener noreferrer">[firewall]</a><a id="ref-ssh-svgcloud" href="https://pixabay.com/p-159946/?no_redirect " target="_blank" rel="noopener noreferrer">[cloud]</a><a id="ref-ssh-svgbuilding" href="https://pixabay.com/en/building-multistoreyed-architecture-311016/" target="_blank" rel="noopener noreferrer">[building]</a></li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2018/01/remote-ssh-tunnel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hide OpenSSH Version Banner</title>
		<link>https://kram.nz/2018/01/hide-openssh-version-banner/</link>
					<comments>https://kram.nz/2018/01/hide-openssh-version-banner/#comments</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sat, 06 Jan 2018 08:41:28 +0000</pubDate>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Banner Leak]]></category>
		<category><![CDATA[Hexedit]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SSH]]></category>
		<guid isPermaLink="false">https://kram.nz/?p=368</guid>

					<description><![CDATA[Here is a quick and dirty method for hiding some of the banner information advertised by OpenSSH[1]. This article focuses on how to use hexedit[2] to update your sshd binary to reduce information leakage. Hiding the version information from OpenSSH is not supported by configuration[3]. This may have been added in some versions[4] and could [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Here is a <em>quick</em> and <em>dirty</em> method for hiding some of the banner information advertised by OpenSSH<a class="reflink" href="#ref-sshban-openssh">[1]</a>. This article focuses on how to use hexedit<a class="reflink" href="#ref-sshban-hexedit">[2]</a> to update your <em>sshd</em> binary to reduce information leakage.</p>
<p>Hiding the version information from OpenSSH is not supported by configuration<a class="reflink" href="#ref-sshban-sshconfig">[3]</a>. This may have been added in some versions<a class="reflink" href="#ref-sshban-debsetting">[4]</a> and could be achieved by compiling your own version from source or switching to port knocking &#8211; these approaches are not covered. Be aware that this is only a temporary change to obfuscate what you are running and the following change will revert whenever OpenSSH is updated.</p>
<h2>Problem</h2>
<p>SSH Servers such as OpenSSH advertise information such as protocol support, build version and host operating system. For example:</p>
<pre>$ nc example.local 22
 SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2</pre>
<p>Would be attackers scan the internet<a class="reflink" href="#ref-sshban-webscan">[5]</a> and create large databases to search for servers running software with known vulnerabilities<a class="reflink" href="#ref-sshban-shodan">[6]</a>. While this may have somewhat legitimate uses such as research into market share of SSH servers or for system admins monitoring their network for machines requiring patches; its generally not a good idea to give away such information freely to the Internet.</p>
<p>You can also use telnet or nmap to snoop on the same information e.g:</p>
<pre>$ nmap -A -T4 -p 22 example.local

Starting Nmap 7.60 ( https://nmap.org ) 
Nmap scan report for example.local (1.2.3.4)
Host is up (0.0044s latency).
rDNS record for 1.2.3.4: 1-2-3-4.kram.nz

PORT STATE SERVICE VERSION
22/tcp open ssh (protocol 2.0)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2</pre>
<pre>$ telnet example 22
Trying ::1...
Connected to example.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2</pre>
<h2>Removing the Banner</h2>
<p>Warning: Doing this while connected via SSH is risky as you can lock yourself out. If you are, set up a way to recover the original binary (i.e. set up another way to connect to the machine or a cron job to restore a copy of the original).</p>
<p>These steps use the hexedit<a class="reflink" href="#ref-sshban-hexedit">[2]</a> tool which is light weight and should be in your package manager. The goal is to write over the existing version string with text of your choice. The instructions are written for Debian / Systemd from steps followed on a Raspberri Pi running Raspbian.</p>
<ol>
<li>Check the current banner:
<pre>$ echo "Hello" | nc localhost 22
SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2
Protocol mismatch.</pre>
<p>In this case, the part of the banner we want to hide is &#8220;OpenSSH_7.4p1 Raspbian-10+deb9u2&#8221; which is broadcasting the versions of my SSH server and operating system. Hiding the protocol is a bit harder and not covered here.<br />
We can see this in the binary too:</p>
<pre>$ strings /usr/sbin/sshd | grep Rasp
OpenSSH_7.4p1 Raspbian-10+deb9u2</pre>
</li>
<li>Escalate to a root session:
<pre>$ sudo su</pre>
</li>
<li>Install hexedit:
<pre># apt-get update &amp;&amp; apt-get install hexedit</pre>
</li>
<li>Back up your sshd binary and create an editable working copy (as root):
<pre># cp /usr/sbin/sshd /tmp/sshd.backup
# cp /tmp/sshd.backup /tmp/sshd.new</pre>
</li>
<li>Update the binary with hexedit:
<pre># hexedit /tmp/sshd.new</pre>
<p>Press TAB to switch from the HEX are to the ASCII area<br />
Use <strong>CTRL+S</strong> to bring up the search prompt and search for the text in your banner than you want to hide e.g. &#8216;OpenSSH_7.4&#8217;. You should see something like:</p>
<pre>0007DA54   61 67 65 6E  74 00 00 00  4F 70 65 6E  agent...Open
0007DA60   53 53 48 5F  37 2E 34 70  31 20 52 61  SSH_7.4p1 Ra
0007DA6C   73 70 62 69  61 6E 2D 31  30 2B 64 65  spbian-10+de
0007DA78   62 39 75 32  00 00 00 00  4F 70 65 6E  b9u2....Open</pre>
<p>Use the arrow keys to highlight the start of the string that you want to update and type your replacement. Be careful to stay within the bounds of the length of the original banner. You can also press <strong>TAB</strong> to switch back to the HEX area if you wanted to just null out the string setting each word to &#8217;00&#8217;.<br />
Your change should look something like:</p>
<pre>0007DA54   61 67 65 6E  74 00 00 00  48 65 72 65  agent...Here
0007DA60   20 62 65 20  64 72 61 67  6F 6E 73 2E   be dragons.
0007DA6C   20 54 75 72  6E 20 42 61  63 6B 00 00   Turn Back..
0007DA78   00 00 00 00  00 00 00 00  4F 70 65 6E  ........Open</pre>
<p>Save your changes with <strong>CTRL+x</strong> and a <strong>Y</strong>.</li>
<li>Check if there are any instances that we missed (we expect no output now):
<pre># strings /tmp/sshd.new | grep Rasp</pre>
</li>
<li>Update sshd and restart the service for good measure:
<pre># rm /usr/sbin/sshd
# cp /tmp/sshd.new /usr/sbin/sshd
# systemctl restart ssh.service</pre>
</li>
<li>Check that you can still SSH in (otherwise restore the backup or reinstall OpenSSH from your package manager!):
<pre># ssh user@localhost</pre>
</li>
</ol>
<p>This change will only be temporary as any time you update OpenSSH, the binary will be replaced.</p>
<h2>Result</h2>
<p>The process above will result in something like the following:</p>
<pre>$ nc localhost 22
SSH-2.0-Here be dragons. Turn Back</pre>
<p>Where before this would be along the lines of:</p>
<pre>$ nc localhost 22 
SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u2</pre>
<p>Which makes the version you are running just a little bit more obscure and and also adds bit of fun.</p>
<h2>References</h2>
<p>(last checked 2018-01-06)</p>
<ol>
<li><a id="ref-sshban-openssh" href="https://www.openssh.com/" target="_blank" rel="noopener noreferrer">https://www.openssh.com/</a></li>
<li><a id="ref-sshban-hexedit" href="https://sourceforge.net/projects/hexedit/" target="_blank" rel="noopener noreferrer">https://sourceforge.net/projects/hexedit/</a></li>
<li><a id="ref-sshban-sshconfig" href="https://man.openbsd.org/sshd_config.5" target="_blank" rel="noopener noreferrer">https://man.openbsd.org/sshd_config.5</a></li>
<li><a id="ref-sshban-debsetting" href="https://scottlinux.com/2011/06/14/disable-debian-banner-suffix-on-ssh-server/" target="_blank" rel="noopener noreferrer">https://scottlinux.com/2011/06/14/disable-debian-banner-suffix-on-ssh-server/</a></li>
<li><a id="ref-sshban-webscan" href="http://resources.infosecinstitute.com/masscan-scan-internet-minutes/" target="_blank" rel="noopener noreferrer">http://resources.infosecinstitute.com/masscan-scan-internet-minutes/</a></li>
<li><a id="ref-sshban-shodan" href="https://www.shodan.io/" target="_blank" rel="noopener noreferrer">https://www.shodan.io/</a></li>
<li><a id="ref-sshban-servfault" href="https://serverfault.com/questions/81690/how-to-hide-web-server-name-and-openssh-version-on-linux-when-scanning-server-po" target="_blank" rel="noopener noreferrer">https://serverfault.com/questions/81690/how-to-hide-web-server-name-and-openssh-version-on-linux-when-scanning-server-po</a></li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2018/01/hide-openssh-version-banner/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Gerbil Time Tracker</title>
		<link>https://kram.nz/2011/10/gerbil-time-tracker/</link>
					<comments>https://kram.nz/2011/10/gerbil-time-tracker/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sun, 30 Oct 2011 04:45:12 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Gerbil]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Time Tracker]]></category>
		<guid isPermaLink="false">https://kram.no-ip.com?p=307</guid>

					<description><![CDATA[Hamster is a cool little Linux tool that I have recently started to use and its made my time tracking a breeze. In the past, at the end of each week, I would have to try and remember how much time I spent doing different activities at work, so that I could record my time and [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="http://projecthamster.wordpress.com/" target="_blank" rel="noopener noreferrer">Hamster</a> is a cool little Linux tool that I have recently started to use and its made my time tracking a breeze.</p>
<p><img loading="lazy" decoding="async" class="alignleft size-full wp-image-308" style="border-style: initial; border-color: initial;" title="Gerbil" src="https://kram.no-ip.com/wp-content/uploads/2011/10/gerbil2.png" alt="Gerbil Time Tracker Logo" width="200" height="200" srcset="https://kram.nz/wp-content/uploads/2011/10/gerbil2.png 200w, https://kram.nz/wp-content/uploads/2011/10/gerbil2-150x150.png 150w" sizes="(max-width: 200px) 100vw, 200px" /></p>
<p>In the past, at the end of each week, I would have to try and remember how much time I spent doing different activities at work, so that I could record my time and bill the correct customers. This was a painful chore and sometimes required a bit of email archaeology, Skype log trawling and black-magic. Hamster allowed me to track my current activity with easy integration to my desktop and proactively record time instead of using retroactive sorcery.</p>
<p>I love the tool so much I thought I&#8217;d create my own PHP web based version which would allow me to use it from my phone and create all sorts of graphs. I have begun development on my tool and it is already usable. When I have a comparable set of features to Hamster, I plan to migrate my data across and open it up for other people to use!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2011/10/gerbil-time-tracker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Password Puzzle Trail</title>
		<link>https://kram.nz/2010/05/password-puzzle-trail/</link>
					<comments>https://kram.nz/2010/05/password-puzzle-trail/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sat, 15 May 2010 06:46:38 +0000</pubDate>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Cryptography]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Logic]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[Puzzle]]></category>
		<category><![CDATA[Steganography]]></category>
		<guid isPermaLink="false">https://kram.no-ip.com?p=232</guid>

					<description><![CDATA[I have created a puzzle trail where the goal is to find the cleverly hidden password and get to the next puzzle. The puzzles start out fairly easy and get more difficult as you solve them. I have tried to make them fairly obtainable however they will test logic and as you get further your [&#8230;]]]></description>
										<content:encoded><![CDATA[<form action="/puzzle/index.php" method="post">
<p style="text-align: center;"><input maxlength="15" name="solution" size="15" type="text" value="secret" /> <input type="submit" value="Enter" /></p>
</form>
<p>I have created a puzzle trail where the goal is to find the cleverly hidden password and get to the next puzzle. The puzzles start out fairly easy and get more difficult as you solve them. I have tried to make them fairly obtainable however they will test logic and as you get further your knowledge of the internet, cryptography, steganography, control of temper etc. Its still very much a work in progress (although I can assure you they all do work, and there <strong>is</strong> a solution). You should never have to guess a password.</p>
<p>Inspiration for this has  come from many sites such as <a  target="_blank" rel="nofollow noopener noreferrer" href="http://www.hackquest.com/">Hack Quest</a> and <a target="_blank" rel="noopener noreferrer" href="http://www.projecteuler.net/">Project  Euler</a> which I have played around on for years. I have many ideas and the trail should be growing all the time. If you have any suggestions let me know! To get started and dive into the rabbit hole, you can use the form above or start <a  target="_blank" href="/puzzle/">here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2010/05/password-puzzle-trail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Twitter Bot</title>
		<link>https://kram.nz/2010/05/twitter-bot/</link>
					<comments>https://kram.nz/2010/05/twitter-bot/#respond</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sat, 15 May 2010 03:14:43 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bot]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sunrise]]></category>
		<category><![CDATA[Sunset]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Twitter]]></category>
		<guid isPermaLink="false">https://kram.no-ip.com?p=226</guid>

					<description><![CDATA[For fun, I decided to create a bot that randomly tweets bird noises such as &#8216;cheep&#8217; &#8216;tweet&#8217; &#8216;quack&#8217; etc. I can imagine it would get annoying incredibly quickly so I have thought about making it tweet very infrequently (once a week-ish maybe?). There is some generation with the bird call i.e. sometimes one or two [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>For fun, I decided to create a bot that randomly tweets bird noises such as &#8216;cheep&#8217; &#8216;tweet&#8217; &#8216;quack&#8217; etc. I can imagine it would get annoying incredibly quickly so I have thought about making it tweet very infrequently (once a week-ish maybe?). There is some generation with the bird call i.e. sometimes one or two calls and a large list of calls to choose from (although getting something other than &#8216;Tweet&#8217; should be uncommon).<a target="_blank" rel="noopener noreferrer" href="http://twitter.com/kiwi_tweeter"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-242" title="Twitter Icon" src="https://kram.no-ip.com/wp-content/uploads/2010/05/twitter_icons_2561.png" alt="" width="128" height="128" /></a></p>
<p>It was suggested that I make the bot tweet at sunrise/sunset which I thought was a cool idea and I may pursue it. I have looked for existing library&#8217;s to calculate these times on a day by day basis but all the (Java) librarys I found were not even close to accurate. It looks like its easiest to implement my own sunrise/sunset library; for the moment and I have an algorithm to implement and I could make use of some existing code I just need to convert.</p>
<p>If you want to follow my bot, it would love to have some friends and you can do so <a target="_blank" rel="noopener noreferrer" title="Twitter Bots Twitter Page" href="http://twitter.com/kiwi_tweeter">here</a>. The Twitter Bots wiki page is <a target="_blank" title="Twitter Bot Wiki Page" href="/wiki/index.php/2010:TwitterBot">here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2010/05/twitter-bot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Desktop Wallpaper Image Scraper</title>
		<link>https://kram.nz/2009/06/desktop-wallpaper-image-scraper/</link>
					<comments>https://kram.nz/2009/06/desktop-wallpaper-image-scraper/#comments</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sun, 21 Jun 2009 04:59:44 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scraper]]></category>
		<category><![CDATA[Wallpaper]]></category>
		<category><![CDATA[Watir]]></category>
		<category><![CDATA[WebSpider]]></category>
		<guid isPermaLink="false">https://kram.no-ip.com?p=121</guid>

					<description><![CDATA[Some time ago I came across a great desktop background website, InterfaceLift.com. When I first went to it, there weren&#8217;t that many images, but the number of background images they have seems to be steadily growing. I decided it would be nice to get a copy of all the images for myself so I built [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a target="_blank" rel="noopener noreferrer" href="http://interfacelift.com/"><img loading="lazy" decoding="async" class="alignright size-full wp-image-120" title="InterfaceLift Home Page" src="/wp-content/uploads/2009/06/nterfacelifpage.jpg" alt="nterfacelifpage" width="200" height="150" /></a>Some time ago I came across a great desktop background website, <a target="_blank" rel="noopener noreferrer" href="http://interfacelift.com/">InterfaceLift.com</a>. When I first went to it, there weren&#8217;t that many images, but the number of background images they have seems to be steadily growing.</p>
<p>I decided it would be nice to get a copy of all the images for myself so I built a little scraper to do the job for me. I wrote it ruby so that I could take advantage of a great ruby gem called <a target="_blank" rel="noopener noreferrer" href="http://wtr.rubyforge.org/">Watir</a>. The script works by going through all desktop backgrounds, selecting the largest available and making a nice link in a separate text file. Afterwards a download manager like <a target="_blank" rel="noopener noreferrer" href="http://www.downthemall.net/">DownThemAll</a> can be used to download all of them.</p>
<p>At the moment the script works in Windows with Internet Explorer but I am working on making it work with FireFox 3 in Linux. Its wiki page is <a target="_blank" rel="noopener noreferrer" href="/wiki/index.php/2008:WebsiteDesktopDownloader">here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2009/06/desktop-wallpaper-image-scraper/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>The Galaxy Game</title>
		<link>https://kram.nz/2009/06/the-galaxy-game/</link>
					<comments>https://kram.nz/2009/06/the-galaxy-game/#comments</comments>
		
		<dc:creator><![CDATA[M]]></dc:creator>
		<pubDate>Sun, 14 Jun 2009 02:29:22 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Progamming]]></category>
		<category><![CDATA[Puzzle]]></category>
		<guid isPermaLink="false">https://kram.no-ip.com?p=104</guid>

					<description><![CDATA[While at uni and coming to terms with the exciting world of programming I made the galaxy game. Feel free to play it here. The rules of the game are rather unique and confusing, but it is somewhat similar to Minesweeper and has an amount of luck involved with it. Late last year I decided [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>While at uni and coming to terms with the exciting world of programming I made the galaxy game. Feel free to <a target="_blank" href="/index.php/games/galaxy-game/">play it here</a>.</p>
<p><figure id="attachment_105" aria-describedby="caption-attachment-105" style="width: 221px" class="wp-caption alignleft"><a target="_blank" href="/index.php/games/galaxy-game/"><img loading="lazy" decoding="async" class="size-full wp-image-105" title="GalaxyGame" src="/wp-content/uploads/2009/06/GalaxyGame.png" alt="Galaxy Game" width="221" height="222" srcset="https://kram.nz/wp-content/uploads/2009/06/GalaxyGame.png 221w, https://kram.nz/wp-content/uploads/2009/06/GalaxyGame-150x150.png 150w" sizes="(max-width: 221px) 100vw, 221px" /></a><figcaption id="caption-attachment-105" class="wp-caption-text">Galaxy Game</figcaption></figure></p>
<p>The rules of the game are rather unique and confusing, but it is somewhat similar to Minesweeper and has an amount of luck involved with it. Late last year I decided (it was suggested to me) to make a solver for this game and  I had a few iterations of working solvers, going from fairly naive to what I felt was pretty good. I have decided to start over again with a nicer version of the game and a boast worthy solver. Stay tuned or watch the <a target="_blank" href="/wiki/index.php/2008:GalaxyGameSolver">wiki page</a> for progress.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kram.nz/2009/06/the-galaxy-game/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
