


<?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>Abesto&#039;s woes</title>
	<atom:link href="http://abesto.net/feed" rel="self" type="application/rss+xml" />
	<link>http://abesto.net</link>
	<description>Adventures in LAMP-land and beyond</description>
	<lastBuildDate>Mon, 14 May 2012 09:02:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
	<atom:link rel='hub' href='http://abesto.net/?pushpress=hub'/>
		<item>
		<title>I&#8217;m writing an IRC server</title>
		<link>http://abesto.net/im-writing-an-irc-server</link>
		<comments>http://abesto.net/im-writing-an-irc-server#comments</comments>
		<pubDate>Sun, 13 May 2012 20:23:32 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[python-ircd]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=250</guid>
		<description><![CDATA[Yes, really, in 2012. See here, it&#8217;s on GitHub. You can connect to a running instance at abesto.net:6667 Why, in the name of all that is 8-bit? For one, it&#8217;s fun.&#160;The core protocol is well defined by the RFCs. &#160;In the web development world you don&#8217;t often get to program to specifications like that; it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, really, in 2012. See here, it&#8217;s on <a href="https://github.com/abesto/python-ircd">GitHub</a>. You can connect to a running instance at abesto.net:6667</p>
<h3>Why, in the name of all that is 8-bit?</h3>
<p>For one, it&#8217;s fun.&nbsp;The core protocol is well defined by the RFCs. &nbsp;In the web development world you don&#8217;t often get to program to specifications like that; it&#8217;s a nice change of pace. There&#8217;s no need for any front-end work either. I get to write Python, which I haven&#8217;t done for a while. And finally, it&#8217;s my own free time, nowgetoffmydamnlawn <span style="font-size: xx-small;">grumblegrumble</span></p>
<h3>Networking</h3>
<p>I wrote basically zero networking code &#8211; <a href="http://www.gevent.org/">gevent</a> does all the hard work.</p>
<blockquote><p>gevent is a&nbsp;<a href="http://en.wikipedia.org/wiki/Coroutine" rel="nofollow">coroutine</a>-based&nbsp;<a href="http://www.python.org/" rel="nofollow">Python</a>&nbsp;networking library that uses&nbsp;<a href="http://codespeak.net/py/0.9.2/greenlet.html">greenlet</a>&nbsp;to provide a high-level synchronous API on top of the&nbsp;<a href="http://monkey.org/~provos/libevent/">libevent</a>&nbsp;event loop.</p>
</blockquote>
<p>Pure goodness. It&#8217;s also ridiculously easy to use. &nbsp;Note the mention of coroutines &#8211; gevent&nbsp;abstracts away not only the bit pushing of low-level networking, it also takes care of the handler <del datetime="2012-05-13T20:19:10+00:00">threads</del> <ins datetime="2012-05-13T20:19:10+00:00">greenlets</ins>. Here&#8217;s the networking code of the IRC server, all four lines of it:</p>
<pre class="prettyprint ">
def handle(socket, address):
    fileobj = socket.makefile('rw')
    # From here on, I can just use fileobj as a simple file object.
    # Yes, fileobj.close() will close the socket.

server = gevent.server.StreamServer(('127.0.0.1', 6667), handle)
server.serve_forever()
</pre>
<h3>Design and implementation</h3>
<p>The server has four main components at the moment:</p>
<ul>
<li>abnf.py: Parses and checks the ABNF grammars specified in the RFCs. No regular expressions, but not a full-fledged ABNF parser either; just some helper functions that can be considered to be a semi-complete DSL. Pretty strict syntax checking.</li>
<li>dispatcher.py: loads and calls command handlers as needed. Uses some <code>importlib</code> trickery to load handlers based on the incoming commands.</li>
<li>commands: Command handlers. They get and return abstract Message objects, and operate on the server database.</li>
<li>db: Contains the server state: users, channels, other servers when I get to that. Currently just a simplistic implementation with dictionaries, but it&#8217;s probably enough for this project.</li>
</ul>
<p>Currently enough commands are implemented to allow irssi to connect, join a channel, and have a conversation in a channel or in private (no user lists yet though). Adding new commands is pretty simple, so I hope to have a mostly functional server soon. I&#8217;m not too optimistic about how the current parser can be extended to support less compliant clients; it&#8217;ll probably have to be replaced with a more robust design.</p>
<p>Anyway, go ahead and make it crash :D I know you want to.</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/im-writing-an-irc-server/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The sad case of the HP Pavilion g6, OpenGL and AMD switchable graphics</title>
		<link>http://abesto.net/the-sad-case-of-the-hp-pavilion-g6-opengl-and-amd-switchable-graphics</link>
		<comments>http://abesto.net/the-sad-case-of-the-hp-pavilion-g6-opengl-and-amd-switchable-graphics#comments</comments>
		<pubDate>Sat, 28 Apr 2012 06:59:43 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=239</guid>
		<description><![CDATA[TL;DR No, it doesn&#8217;t work (as of 2012. April 28). This post is just to save you some time. But I&#8217;ll buy you a beer if you manage to get it to work, and tell me how. The facts HP has released the Pavilion g6 series in two (correct me if I&#8217;m wrong) versions; I [...]]]></description>
			<content:encoded><![CDATA[<p><strong>TL;DR</strong> No, it doesn&#8217;t work (as of 2012. April 28). This post is just to save you some time. But I&#8217;ll buy you a beer if you manage to get it to work, and tell me how.</p>
<h1>The facts</h1>
<p>HP has released the Pavilion g6 series in two (correct me if I&#8217;m wrong) versions; I can only comment on the one with the AMD/Intel switchable graphics. But I could keep commenting on that all day.</p>
<p>The specs look good, but they don&#8217;t mention that the switchable graphics only work with DirectX applications. You don&#8217;t get to use the beefy AMD card for OpenGL apps and games &#8211; that includes any WebGL apps, Minecraft and SpaceEngine, just to name a few.&nbsp;Also, the only supported operating system seems to be 64-bit Windows 7 (see <a href="http://h10025.www1.hp.com/ewfrf/wc/softwareCategory?cc=us&amp;lc=en&amp;dlc=en&amp;product=5078476" target="_blank">here</a>).</p>
<h1>The story so far</h1>
<p>Poeple have been complaining; there&#8217;s even&nbsp;<a href="http://h30434.www3.hp.com/t5/Notebook-Display-and-Video/HP-What-is-wrong-with-your-support-g-series-switchable-graphics/td-p/964099" target="_blank">this support question</a>&nbsp;that lists all the previously unanswered questions. A possible workaround, which has been released for the some other lines (dv* and envy), is disabling switchable graphics from the BIOS and always using the dedicated video card. No such BIOS update has been released for the Pavilion g6 yet.</p>
<p>There&#8217;s a <a href="http://leshcat.blogspot.com/" target="_blank">third-party driver project</a> for AMD/Intel switchable graphics that releases with the newest versions of both drivers. This <em>might</em>&nbsp;be a solution, but it didn&#8217;t work for me. What&#8217;s more, after fooling around with three different versions of it, Windows 7 now reboots after a split-second BSOD &#8211; even in safe mode. Good thing I only use Windows to play games.</p>
<p>HP doesn&#8217;t release Linux drivers. Switchable graphics via vga_switcheroo get as far as powering the discrete graphics card up or down, but my up-to-date Arch Linux system freezes when I actually try to switch to the AMD card. The official proprietary Linux AMD drivers (fglrx 12.3 and 12.4) supposedly support switchable graphics. The newest version of Xorg is not supported yet, but let&#8217;s downgrade to an older version, and what do we find? The drivers don&#8217;t want to make friends with the hardware and complain loudly, saying &#8220;Invalid ATI BIOS from int10, the adapter is not VGA-enabled&#8221;. After which they don&#8217;t recognize the screen as usable; X11 fails to start.</p>
<h1>Conclusion</h1>
<p>There is no way to use the main selling point of the notebook with OpenGL applications, or at all on Linux. Not good.</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/the-sad-case-of-the-hp-pavilion-g6-opengl-and-amd-switchable-graphics/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Morning project: NetPincér menu filter</title>
		<link>http://abesto.net/morning-project-netpincer-menu-filter</link>
		<comments>http://abesto.net/morning-project-netpincer-menu-filter#comments</comments>
		<pubDate>Sun, 08 Apr 2012 11:07:56 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Client]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[user-script]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=232</guid>
		<description><![CDATA[NetPincér is an online food ordering service in Hungary. The website has quite a few problems, but one of the most annoying ones is that there&#8217;s no way to filter the menu of a restaurant based on what&#8217;s in the food. Even though most of the restaurants list some ingredients as the description of the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.netpincer.hu" target="_blank">NetPincér</a> is an online food ordering service in Hungary. The website has quite a few problems, but one of the most annoying ones is that there&#8217;s no way to filter the menu of a restaurant based on what&#8217;s in the food. Even though most of the restaurants list some ingredients as the description of the course.</p>
<p>Solution: a user script that adds whitelist and blacklist filtering. It looks like this:</p>
<div id="attachment_233" class="wp-caption aligncenter" style="width: 698px"><a href="http://abesto.net/wp-content/uploads/2012/04/snapshot1.png"><img class="size-full wp-image-233" title="NetPincér menu filter" src="http://abesto.net/wp-content/uploads/2012/04/snapshot1.png" alt="" width="688" height="330" /></a><p class="wp-caption-text">NetPincér menu filter</p></div>
<p>It works in both Chrome as a user script and as a Gresemonkey script in Firefox. You can get it from userscripts.org: <a href="https://userscripts.org/scripts/show/130399" target="_blank">https://userscripts.org/scripts/show/130399</a></p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/morning-project-netpincer-menu-filter/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weekend project: Mastermind</title>
		<link>http://abesto.net/weekend-project-mastermind</link>
		<comments>http://abesto.net/weekend-project-mastermind#comments</comments>
		<pubDate>Sun, 18 Mar 2012 10:12:52 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Client]]></category>
		<category><![CDATA[coffee-script]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=218</guid>
		<description><![CDATA[We just had a national holiday, which meant a longish weekend with my parents. We played some board games, and as a result I hacked up a Mastermind game in CoffeeScript that runs entirely in the browser. It took about six-eight hours, and it was actually quite fun. The model was done in an hour [...]]]></description>
			<content:encoded><![CDATA[<p>We just had a national holiday, which meant a longish weekend with my parents. We played some board games, and as a result I hacked up a Mastermind game in CoffeeScript that runs entirely in the browser. It took about six-eight hours, and it was actually quite fun.</p>
<p>The model was done in an hour or so, but without any tests. I decided to do only manual testing, which added some time at the end, but whatever. The UI took a bit longer, and it doesn&#8217;t look as good as it could. It&#8217;s also not optimal, but it&#8217;s good enough. It&#8217;d be great if someone could spend some time polishing it&#8230; *nudge-nudge, wink-wink*</p>
<p>Anyway, here&#8217;s the game: <a href="http://static.abesto.net/mastermind" target="_blank">http://static.abesto.net/mastermind</a></p>
<p>And the GitHub repo: <a href="https://github.com/abesto/mastermind" target="_blank">https://github.com/abesto/mastermind</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/weekend-project-mastermind/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure is fun</title>
		<link>http://abesto.net/clojure-is-fun</link>
		<comments>http://abesto.net/clojure-is-fun#comments</comments>
		<pubDate>Mon, 12 Mar 2012 00:16:13 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=210</guid>
		<description><![CDATA[It was time to try it out. Here&#8217;s the result &#8211; 67 lines of Clojure code for an RPN calculator with the basic operators. Also, Seesaw (GUI lib for Clojure) rocks. GitHub repository Google Prettify doesn&#8217;t provide highlighting for Clojure. GitHub does, go there for pretty colors. (ns net.abesto.calc_clj.core (:gen-class) (:use seesaw.core)) (native!) (def stack-size [...]]]></description>
			<content:encoded><![CDATA[<p>It was time to try it out. Here&#8217;s the result &#8211; 67 lines of Clojure code for an RPN calculator with the basic operators. Also, <a title="Seesaw" href="https://github.com/daveray/seesaw" target="_blank">Seesaw</a> (GUI lib for Clojure) rocks.</p>
<p><a href="https://github.com/abesto/calc-clj" target="_blank">GitHub repository</a></p>
<p><small>Google Prettify doesn&#8217;t provide highlighting for Clojure. GitHub does, go there for pretty colors.</small></p>
<pre>(ns net.abesto.calc_clj.core
  (:gen-class)
  (:use seesaw.core))

(native!)

(def stack-size 4)
(def stack (ref []))
(def gui-stack (ref []))

(defn push [x] (dosync (ref-set stack (concat (next (deref stack)) [x]))))
(defn popn [n]
  (dosync
   (let [ret (take-last n (deref stack))]
     (ref-set stack (take stack-size (concat (repeat n 0) (deref stack))))
     ret)))

(defn sync-gui [] (dorun (map value! (deref gui-stack) (map str (deref stack)))))

(defn number [n]
  (action
   :handler
   (fn [e]
     (dosync (push (+ n (* 10 (first (popn 1))))))
     (sync-gui))
   :name (str n)
   ))

(defn operator [label operator operand-count]
  (action
   :handler (fn [e]
              (let [operands (popn operand-count)]
                (push (apply operator operands)))
              (sync-gui))
   :name label))

(defn -main [&#038; args]
  (invoke-later
   (dosync
    (ref-set gui-stack (take stack-size (repeatedly #(text :editable? false))))
    (ref-set stack (repeat stack-size 0)))

   (sync-gui)
   (-> (frame
        :title "Hello",
        :content
        (vertical-panel
         :items [
                 (vertical-panel :items (deref gui-stack))
                 (horizontal-panel :items [
                                           (action :name "Enter" :handler (fn [e] (push 0) (sync-gui)))
                                           (operator "+/-" - 1)
                                           ])
                 (grid-panel
                  :rows 4
                  :columns 4
                  :items [(number 7) (number 8) (number 9) (operator "+" + 2)
                          (number 4) (number 5) (number 6) (operator "-" - 2)
                          (number 1) (number 2) (number 3) (operator "*" * 2)
                          (number 0) ""         ""         (operator "/" / 2)
                          ])
                 ])
        :on-close
        :exit)
       pack!
       show!)
   ))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/clojure-is-fun/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick fix: Bring back the scroll buttons to GMail</title>
		<link>http://abesto.net/bringing-back-the-scroll-buttons-to-gmail</link>
		<comments>http://abesto.net/bringing-back-the-scroll-buttons-to-gmail#comments</comments>
		<pubDate>Mon, 26 Dec 2011 09:48:09 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Client]]></category>
		<category><![CDATA[Desktop]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=199</guid>
		<description><![CDATA[There&#8217;s been some noise on the &#8216;net about missing scroll up/down buttons in the new Google design. Note that this only affects the browsers based on WebKit (Chrome, Safari and some KDE browsers, to name a few). Here&#8217;s a way to fix that. Why are the buttons gone? As IE before, WebKit has introduced styleable scroll-bars. (Whether that&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been <a href="http://www.google.gg/support/forum/p/gmail/thread?tid=0d5d7ea34ac7f5da&amp;hl=en" target="_blank">some</a> <a href="http://www.google.gg/support/forum/p/gmail/thread?tid=0052f4d2c7e2ab88&amp;hl=en" target="_blank">noise</a> <a href="http://www.google.gg/support/forum/p/gmail/thread?tid=7072d994efc061ad&amp;hl=en" target="_blank">on the &#8216;net</a> about missing scroll up/down buttons in the new Google design. Note that this only affects the browsers based on WebKit (Chrome, Safari and some KDE browsers, to name a few). Here&#8217;s a way to fix that.</p>
<h2>Why are the buttons gone?</h2>
<p>As IE before, WebKit has introduced styleable scroll-bars. (Whether that&#8217;s a good idea or not is not the point of this article.) The new Google design uses this new feature in a lot of places. This has two effects: 1) the scroll-bars fit in nicely and 2) the scroll buttons are gone. The special CSS selectors provide a very detailed, if verbose, way for making sure the scroll-bars on the site match the design; there&#8217;s a great article explaining them at <a href="http://css-tricks.com/custom-scrollbars-in-webkit/" target="_blank">CSS-Tricks</a>.</p>
<h2>The solution</h2>
<p>I haven&#8217;t managed to find a way to disable this feature in Chromium; there&#8217;s no way to disable these customized scroll-bars. The best solution I could find is creating visible elements via a user stylesheet where the buttons should be. We can do anything with them, but in this example we&#8217;ll just make simple gray boxes.</p>
<h3>1. Find the file / text box for custom stylesheets</h3>
<p>For Chrome (and Chromium) you&#8217;ll need to find a file. The changes will be applied as soon as you save it &#8211; there&#8217;s no need to restart the browser.</p>
<p><strong>Windows:</strong><br />
<code>%LOCALAPPDATA%\Google\Chrome\User Data\Default\User StyleSheets\Custom.css</code><br />
(<code>%LOCALAPPDATA%</code> is usually <code>C:\Users\username\AppData\Local</code>, where <code>AppData</code> is a hidden folder)</p>
<p><strong>Mac:</strong><br />
<code>/Users/username/Library/Application Support/Google/Chrome/Default/User StyleSheets/Custom.css</code><br />
<strong>Linux:</strong><br />
<code>~/.config/chrom(e|ium)/Default/User\ StyleSheets/Custom.css</code></p>
<p>In Safari you don&#8217;t even have to leave your browser: you can create stylesheets in the Preferences → Advanced tab. Note that by default you&#8217;ll have to restart your browser for changes to take effect. Check out <a href="http://hints.macworld.com/article.php?story=20060715042932352" target="_blank">this Macworld hint</a> if you want to work around that.</p>
<h3>2. Add custom styles</h3>
<p>Any CSS  you enter here will be applied to all pages loaded in the browser. The following snippet makes sure that the scroll up/left button at the start and the scroll down/right button at the end of the scroll-bar are visible as a gray box. It does not contain anything to apply it to only Google applications, but chances are that if you want the scroll buttons here, you&#8217;ll want them everywhere.</p>
<pre class="prettyprint ">::-webkit-scrollbar-button:start:decrement,
::-webkit-scrollbar-button:end:increment {
  background-color: #ddd;
  height: 16px !important;
  width: 16px !important;
  border: 1px outset silver;
  display: block !important;
}</pre>
<p class="prettyprint">This is really unacceptable from a design perspective (read: it looks bad). It&#8217;s also ridiculous that we have to resort to hacks like this to have scroll buttons&#8230; Still, this is the only way I could come up with (other than disabling this extension in the Chromium/WebKit source and compiling).</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/bringing-back-the-scroll-buttons-to-gmail/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mostly shiny: vector graphics with MVVM in the browser</title>
		<link>http://abesto.net/vector-graphics-with-mvvm-in-the-browser</link>
		<comments>http://abesto.net/vector-graphics-with-mvvm-in-the-browser#comments</comments>
		<pubDate>Tue, 13 Dec 2011 12:18:15 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Client]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[knockout]]></category>
		<category><![CDATA[raphael]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=183</guid>
		<description><![CDATA[I&#8217;d like to show you how to make two great libraries work together: Raphael and Knockout. I&#8217;ve built the basics of a purely browser-based application for creating simple graphs (as in &#8220;graph theory&#8221;). This article was supposed to be a longish explanation of how it all works, but unfortunately I&#8217;m really short on time. The working [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to show you how to make two great libraries work together: Raphael and Knockout. I&#8217;ve built the basics of a purely browser-based application for creating simple graphs (as in &#8220;graph theory&#8221;). This article was supposed to be a longish explanation of how it all works, but unfortunately I&#8217;m really short on time.</p>
<ul>
<li>The working example is <a href="http://abesto.net/kor/index.html">here</a></li>
<li>And the docco-annotated source code is <a href="http://abesto.net/kor/docs/script.html">here</a></li>
</ul>
<h3>Some links and introductions are in order</h3>
<p><strong><a href="http://raphaeljs.com/" target="_blank">Raphaël</a>:</strong> &#8221;a small JavaScript library that should simplify your work with vector graphics on the web&#8221;. It also includes a handy light-weight event framework called &#8220;eve&#8221; (yes, another one; yes, its good enough to exist). It&#8217;s a very useful common interface to SVG and VML (which is what IE supports instead of SVG).</p>
<p><strong><a href="http://knockoutjs.com/" target="_blank">Knockout</a>:</strong> a library implementing MVVM for the browser, with dependency tracking and template support using <a href="http://api.jquery.com/jquery.tmpl/" target="_blank">jquery.tmpl</a>.</p>
<p><strong><a href="http://en.wikipedia.org/wiki/Model_View_ViewModel" target="_blank">MVVM</a></strong>: a design pattern that can be considered an alternative to MVC in some respects. The idea is that view-models (VM) and views (the first V) are bound once, and they automatically update anything connected to them when they change, while updating some kind of storage (the first M). The storage is neglected in the example, but it&#8217;s supported just fine by Knockout.</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/vector-graphics-with-mvvm-in-the-browser/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux server security tips</title>
		<link>http://abesto.net/linux-server-security-tips</link>
		<comments>http://abesto.net/linux-server-security-tips#comments</comments>
		<pubDate>Tue, 06 Dec 2011 11:20:50 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=123</guid>
		<description><![CDATA[The obvious Always keep your system up to date with security patches. No amount of configuration can save you if your version of sshd allows anyone born before 1970-01-01 to log in as root. Always employ the Principle of least privilege: give users only the permissions they strictly need. Check that your system doesn&#8217;t run [...]]]></description>
			<content:encoded><![CDATA[<h2>The obvious</h2>
<ul>
<li>Always keep your system up to date with security patches. No amount of configuration can save you if your version of sshd allows anyone born before 1970-01-01 to log in as root.</li>
<li>Always employ the <a href="http://en.wikipedia.org/wiki/Principle_of_least_privilege" rel="nofollow">Principle of least privilege</a>: give users only the permissions they strictly need.</li>
<li>Check that your system doesn&#8217;t run a telnet daemon by default.</li>
<li>Use a firewall to <del>close all unused ports</del> <ins>manage ports available for local applications to listen on</ins>.<sup>[<a href="#footer-2">2</a>]</sup> See <a href="https://help.ubuntu.com/community/UFW" rel="nofollow">ufw</a> (Uncomplicated Firewall) for a simple iptables-based solution.</li>
</ul>
<h2>The less obvious</h2>
<ul>
<li>Disable administrative interfaces like PhpMyAdmin, the Nagios web GUI and cPanel when not used. You may also consider disabling the web-based interfaces of Cacti, Munin and friends; they should be password-protected at the least.</li>
<li><ins>Even when you use them, they should be behind strict firewall rules</ins><sup>[<a href="#footer-1">1</a>]</sup> and HTTPS. A self-signed certificate will work just fine for the HTTPS part. The nginx manual has a simple procedure for setting this up <a href="http://wiki.nginx.org/HttpSslModule" rel="nofollow">here</a>. The configuration options for apache are listed <a href="http://httpd.apache.org/docs/2.0/ssl/ssl_howto.html">here</a>&nbsp;(you might want to follow the key creation procedure from the nginx manual; it&#8217;s summed up rather nicely).</li>
</ul>
<h2>SSH</h2>
<p>The goal of many attackers is to gain shell access to your box. Hardening your sshd configuration is an important step in preventing this. Everything you&#8217;ll find below is tested with OpenSSH. The configuration options must be added to the sshd configuration file, usually&nbsp;<code>/etc/ssh/sshd_config</code>. Changes to this file will take effect after you restart the sshd server or reload the configuration options with <code>/etc/init.d/sshd reload</code> (replace <code>init.d</code> with <code>rc.d</code> if needed :))</p>
<h3>Restrict remote login to users that really need it</h3>
<h4>Why:</h4>
<p>Less users mean less targets, obviously. Specially, root <em>never</em>&nbsp;needs SSH access. Note that disabling login by setting the login shell to /bin/false prevents only a subset of the attacks handled by this solution.</p>
<h4>How:</h4>
<p>Use the <code>AllowUsers</code> and/or <code>AllowGroups</code> directives. Users not covered by either directive are not allowed to log in via SSH.</p>
<h4>Example:</h4>
<pre class="prettyprint ">AllowUsers user1 user2 user3
AllowGroups group1 group2
PermitRootLogin no</pre>
<h3>Disable password authentication</h3>
<h4><strong>Why:</strong></h4>
<p><strong></strong>Password based authentication is inherently less secure than the public-key alternative. You can find an easy to follow comparison at <a href="http://rongchaua.net/blog/ssh-password-vs-public-key/">Rongchaua&#8217;s blog</a>.</p>
<h4>How:</h4>
<ol>
<li>If you don&#8217;t have a <del>GPG</del> <ins>SSH</ins><sup>[<a href="#footer-3">3</a>]</sup> key yet, you&#8217;ll have to create one. <del>See this <a href="http://www.madboa.com/geek/gpg-quickstart/">GPG Quick Start</a> guide</del> <ins>On Unix-based systems <code>ssh-keygen</code> will create your SSH keypair after you answer a few simple questions</ins><sup>[<a href="#footer-1">1</a>]</sup>, or see <a href="http://unixwiz.net/techtips/putty-openssh.html#keypair">this guide</a>&nbsp;for PuTTY on Windows.</li>
<li>Once you have the private and public keys, paste the public key into the file $HOME/.ssh/authorized_keys on the server. OpenSSH is quite picky about the permissions of files, so make sure that only you can access it (&#8220;<code>chmod 0600 $HOME/.ssh/authorized_keys</code>&#8220;&nbsp;should be good enough).</li>
<li><em>Make sure you can log in without entering your login password.</em>&nbsp;If you disable password authentication without setting this up correctly, you can lock yourself out of the system.</li>
<li>Disable password login and other unsecure login methods:</li>
</ol>
<pre class="prettyprint ">ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no</pre>
<h3>Force the usage of SSH-2</h3>
<h4>Why:</h4>
<p><strong></strong>&nbsp;The older protocol, SSH-1 is less secure, and all modern clients support the new protocol. <ins>Using only SSH-2 in sshd is also the default in modern servers</ins><sup>[<a href="#footer-1">1</a>]</sup>.</p>
<h4>How:</h4>
<pre class="prettyprint ">Protocol 2</pre>
<h3>Use a non-standard port</h3>
<h4>Why:</h4>
<p>Running the SSH daemon on a random port requires little effort, for <del>a little security through obscurity</del> <ins>decreasing the number of attackers a bit<sup>[<a href="#footer-1">1</a>]</sup>.</ins></p>
<h4>Why not:</h4>
<p>A decent port scan will usually still find the service. It might not be worth the effort; decide for yourself.</p>
<h4><strong>How:</strong></h4>
<p><ins>The port number should probably be below 1024, because binding to these ports require root privileges, thus reducing the risk of port hijacking. Make sure you choose a port not already associated with an application (eg. by checking that it&#8217;s not in the <a href="http://nmap.org/book/nmap-services.html" rel="nofollow">nmap-services</a> file).</ins><sup>[<a href="#footer-1">1</a>]</sup></p>
<pre class="prettyprint ">port $PORT</pre>
<p>You can then log in via the command-line client using the -p switch:</p>
<pre class="prettyprint ">$ ssh -p $PORT user@host</pre>
<p>Take this a few steps further, and we get port knocking. It&#8217;s a technique not universally accepted as a useful solution in production environments. Setting up port knocking is out of the scope of this article, but there are plenty of resources out there.</p>
<h2>Monitoring tools</h2>
<p>The steps outlined above make it harder for an attacker to gain access to your system. It should be noted that this is far from being a complete guide on setting up a secure server; there are whole books dedicated to the topic for a reason.</p>
<p>Anyway, when a bad guy manages to access your system, you want to know about it, fast. Finding out about the problem from a request to stop brute-forcing another server does <em>not</em> qualify as fast.</p>
<p><a href="http://www.fail2ban.org/wiki/index.php/Main_Page" rel="nofollow">fail2ban</a>&nbsp;&#8221;scans log files like&nbsp;<code>/var/log/pwdfail</code>&nbsp;or&nbsp;<code>/var/log/apache/error_log</code>&nbsp;and bans IP that makes too many password failures. It updates firewall rules to reject the IP address.&#8221; This will stop brute-force attacks, but not DDoS attacks. Dealing with denial of service attacks is still not a completely solved issue; see <a href="http://thenextweb.com/media/2011/05/02/ddos-attacks-prevention-and-mitigation/" rel="nofollow">this article</a>&nbsp;for some of the problems and solutions.</p>
<p><a href="http://www.ossec.net/" rel="nofollow">ossec</a>&nbsp;is &#8220;an Open Source Host-based Intrusion Detection System. It performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response.&#8221; Chances are it will pick up the side-effects of most intrusions. Be sure to configure at least the notification address where alert emails are delivered, even if you leave other options on their default.</p>
<h2>&nbsp;IANAD</h2>
<p>(I am not a disclaimer. Oh wait, yes I am.)</p>
<p>I&#8217;m not a system administrator by training. All of this information can be found online; this is only a collection that I hope may come in handy for someone. Let me emphasize that <em>you don&#8217;t necessarily get a secure system just by following these instructions.</em>&nbsp;That said, I&#8217;ve listed all the security measures I&#8217;ve taken to protect the server running this blog at the time of writing; this setup is good enough for me. Still, the server has no sensitive information, and I&#8217;m not a sysadmin.</p>
<p><strong>Update:</strong> Coming out and stating that this is the setup I use is not acceptable from a security perspective. I accept the risk, and the potential<em> fun</em> it will bring. What I really want to say is: I eat my own dogfood. Even if stating this makes said dogfood less tasty for me.</p>
<p><a name="footer-1"></a>[1] Thanks to kdorf for pointing this out in <a href="http://www.reddit.com/r/linux/comments/n2g2n/basic_linux_server_security_tips/c35qx08" rel="nofollow">this comment on reddit</a><br />
<a name="footer-2"></a>[2] Thanks to ngroot for pointing this out in <a href="http://www.reddit.com/r/linux/comments/n2g2n/basic_linux_server_security_tips/c35tetr" rel="nofollow">this comment on reddit</a><br />
<a name="footer-3"></a>[3] Thanks to mowrawn for pointing this out in <a href="http://www.reddit.com/r/linux/comments/n2g2n/basic_linux_server_security_tips/c35u3yr" rel="nofollow">this comment on reddit</a></p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/linux-server-security-tips/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Proposal: a community-powered collection of PHP best practices</title>
		<link>http://abesto.net/proposal-for-community-powered-php-best-practices</link>
		<comments>http://abesto.net/proposal-for-community-powered-php-best-practices#comments</comments>
		<pubDate>Tue, 29 Nov 2011 11:54:47 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://abesto.net/?p=69</guid>
		<description><![CDATA[Scott Griepentrog kindly rented a domain to use for this purpose and set up a publicly accessible Google Sites page. All that&#8217;s missing now is great content (actually, maybe not, if you&#8217;re from the future). You can find the wiki at http://phpfu.org Why? We all know the old argument on why PHP is often seen [...]]]></description>
			<content:encoded><![CDATA[<div class="info">Scott Griepentrog kindly rented a domain to use for this purpose and set up a publicly accessible Google Sites page. All that&#8217;s missing now is great content (actually, maybe not, if you&#8217;re from the future). You can find the wiki at <a href="http://phpfu.org" title="PHP FU">http://phpfu.org</a></div>
<h3>Why?</h3>
<p>We all know the old argument on why PHP is often seen as a &#8220;bad&#8221; language: the barrier of entry is low, so lots of people will write PHP code without learning the fundamentals. However, the arguments usually stop there. Known fact, there&#8217;s nothing we can do. But maybe there is?</p>
<h3>What?</h3>
<p>Let me be clear: I don&#8217;t want to teach design patterns to everyone who makes a worship site for their dog. What I&#8217;d like to see, and what I&#8217;m really missing, is a central repository of best practices for solving common middle to high-level problems. Ideally in a wiki format. What would this bring to the table? It would tell you that is, indeed, thoroughly solved, and also how it&#8217;s done. It can also be thought of as a FAQ of sorts, or a collection of best practices (emphasis on best).</p>
<p>Yes, Google is usually your friend. What Google doesn&#8217;t do is code review of blogs and tutorials. Let me give a trivial example: I&#8217;ve googled really hard when I needed to implement a secure authentication scheme. What I found was tens of &#8220;simple login script with PHP and SQL&#8221;. What I finally ended up with is basically what Phpass is doing &#8211; dynamic and static salts, bcrypt, you know the drill. It&#8217;s not as extensible or general, but the theory (and <em>probably</em> the security) is there. What I didn&#8217;t know was that Phpass existed. My Google-fu must have been weak that day or something.</p>
<p>I just looked until I found something good enough and went with it. I feel this is characteristic of a lot of development, and not always a bad thing. On the other hand it takes real experience to know what&#8217;s good enough, and this experience can come at a high price (especially when considering security).</p>
<blockquote><p>So what would this proposed wiki say on the topic of secure password storage?</p></blockquote>
<p>Probably something like: &#8220;Use Phpass&#8221;. There, it&#8217;s not that complicated. Probably include a few good samples of using it, and we&#8217;re golden. A full framework-independent example of a complete secure authentication scheme would be killer. Mention OpenID as a full-fledged alternative, probably.</p>
<blockquote><p>Yes but this still assumes that the developer who needs the information realizes that s/he needs it!</p></blockquote>
<p>Indeed. However, by making it explicit that such-and-such information can be found here, it&#8217;ll be constantly at the back of the developers mind. If it&#8217;s easy to reach, maybe we&#8217;ll start looking even when we have a full solution in mind. You know, just in case. We can do that now, but (a) making sure we don&#8217;t miss a good resource because it&#8217;s three pages down in DuckDuckGo and (b) making it really quick to check on a topic instead of reading several articles can only be a good thing.</p>
<blockquote><p>Why is it that only PHP need such a resource?</p></blockquote>
<p>This is a valid question. I&#8217;m pretty sure some languages/frameworks already have this (probably called a manual or somesuch). It&#8217;s usually the documentation of a framework, so of course the documentation of PHP-the-language can&#8217;t be expected to contain these things.</p>
<h3>Why doesn&#8217;t this exist already?</h3>
<p>I can probably be convinced that not even PHP needs this. Or is there such a site out there already, and I just missed it? If there isn&#8217;t, why not? Is it redundant, not worth it? Does everyone just go with &#8220;good enough&#8221;?</p>
<p>Is this feasible? Let&#8217;s start one!</p>
<p><strong>PS.</strong></p>
<p>Phpass being the bestestest password storage solution is not the point of the post. Feel free to name alternatives. Also, most of this rant is based not on any statistical data, only my &#8220;gut feeling&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/proposal-for-community-powered-php-best-practices/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Node.js, Express and CoffeeScript</title>
		<link>http://abesto.net/node-js-express-and-coffeescript</link>
		<comments>http://abesto.net/node-js-express-and-coffeescript#comments</comments>
		<pubDate>Sat, 26 Nov 2011 10:38:06 +0000</pubDate>
		<dc:creator>Zoltán Nagy</dc:creator>
				<category><![CDATA[Client]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[coffee-script]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://178.79.182.101/?p=48</guid>
		<description><![CDATA[The solution oultlined here uses the compiler Connect middleware, which was removed in Connect 1.7 (and therefore in newer Express.js versions). The new alternative is connect-assets.Thanks to Marcel Miranda for pointing this out. I’ve been working on a moderately complex hobby project for a while using Node.js and CoffeeScript. This is the first of a [...]]]></description>
			<content:encoded><![CDATA[<div class="error">The solution oultlined here uses the compiler Connect middleware, which was removed in Connect 1.7 (and therefore in newer Express.js versions). The new alternative is <a href="https://github.com/TrevorBurnham/connect-assets">connect-assets</a>.<br />Thanks to <a href="http://reaktivo.com">Marcel Miranda</a> for pointing this out.</div>
<p>I’ve been working on a moderately complex hobby project for a while using <a href="http://nodejs.org/">Node.js</a> and <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>. This is the first of a few posts on what I’ve learned so far. This time: using CoffeeScript on the client- <strong>and</strong> the server-side and auto-compiling client side scripts on the fly with <a href="http://expressjs.com/">Express</a>.</p>
<p>The goal of the project is, by the way, to illustrate some common algorithms in the browser. You can check it out at GitHub: <a href="https://github.com/abesto/algo" target="_blank">https://github.com/abesto/algo</a>, or see a running version at <a href="http://algo-abesto.dotcloud.com/" target="_blank">http://algo-abesto.dotcloud.com</a>. The blank area next to the controls is where you can draw your graph.</p>
<h2>Server side</h2>
<p>The theory is simple: CoffeeScript code is equivalent to JavaScript code. Node.js can thus be programmed in CoffeeScript. In practice, things turn out to be just as simple: write your code in CoffeeScript, use the file extension .coffee, and use <code>coffee app.coffee</code> to start your application. Even <code>require</code> works out of the box. You can see an example <a href="https://github.com/abesto/algo/blob/nodejs/app.coffee">here</a> (using <a href="http://expressjs.com/">Express</a>)</p>
<h2>Client side</h2>
<p>This section assumes you’re using the Express web framework.</p>
<p>Express has support for <em>compilers</em>, and a compiler is shipped for <code>CoffeeScript</code>. Setting up the paths is not well documented, unfortunately. Here’s how it works: for each compiler you’ll specify a <code>src</code> and a <code>dest</code> folder, without a trailing <code>/</code>. The request path sent by the browser is appended to this.</p>
<p><code>http://localhost:9000/js/foo/bar.js</code> will map to the source file <code>src/foo/bar.coffee</code> and the compiled file <code>dest/foo/bar.js</code>. If the compiled file doesn’t exist or is older than the source file then it will be (re)compiled. If there’s an error during compilation, then the browser will receive a 500 error.</p>
<p>What will <strong>NOT</strong> be done is:</p>
<ul>
<li>Express won’t remove the compiled file if the source file is removed</li>
<li>Express won’t create any missing directory structure. If <code>dest/foo</code> doesn’t exist, then Express will return a 404 error to the browser. If you know how to work around this, please write a few lines :)</li>
</ul>
<p>Note: this was originally posted to a previous version of this blog on 01. November 2011.</p>
]]></content:encoded>
			<wfw:commentRss>http://abesto.net/node-js-express-and-coffeescript/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using apc
Database Caching using disk: basic
Object Caching 696/790 objects using disk: basic

Served from: abesto.net @ 2012-05-20 15:55:17 -->
