<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:html="http://www.w3.org/1999/html" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
   <title>semicomplete.com - Jordan Sissel</title>
   <link>http://www.semicomplete.com/blog</link>
   <description>Projects, articles, tips, and experiences on topics ranging from AJAX to Network Security.</description>
   <language>en</language>
   <copyright>Copyright 2009 Jordan Sissel</copyright>
   <ttl>60</ttl>
   <pubDate>Sun, 08 Nov 2009 21:14 GMT</pubDate>
   <managingEditor>jls@semicomplete.com</managingEditor>
   <generator>PyBlosxom http://pyblosxom.sourceforge.net/ 1.3.2 2/13/2006</generator>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/semicomplete/main" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
   <title>new keynav version available (20091108)</title>
   <guid isPermaLink="false">geekery/keynav-20091108</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/LFwBkjAxOCo/keynav-20091108.html</link>
   <description>Hop on over to the &lt;a href="/projects/keynav"&gt;keynav project page&lt;/a&gt; and
download the new version.

&lt;p/&gt;

The changelist from the previous announced release is as follows:

&lt;pre&gt;
20091108:
  - Added xinerama support.
    * Default 'start' will now only be fullscreen on your current xinerama
    display. You can move between screens by using the move-* actions to move
    the current selection outside the border of the current screne.
  - All xdotool commands now return integers so we can forward their return
    status to the user.
  - Actually handle SIGCHLD now so the shell commands get reaped on exit.
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/keynav-20091108" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=LFwBkjAxOCo:sQrXlDG5qm8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=LFwBkjAxOCo:sQrXlDG5qm8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=LFwBkjAxOCo:sQrXlDG5qm8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=LFwBkjAxOCo:sQrXlDG5qm8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=LFwBkjAxOCo:sQrXlDG5qm8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/LFwBkjAxOCo" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Sun, 08 Nov 2009 21:14 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/keynav-20091108.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Ruby metaprogramming will cost you documentation.</title>
   <guid isPermaLink="false">geekery/metaprogramming-at-the-expense-of-documentation</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/BJzqqOE1aJw/metaprogramming-at-the-expense-of-documentation.html</link>
   <description>Ruby, like many other dynamic and modern languages, makes it easy for you to do
fun stuff like metaprogramming.

&lt;p&gt;

Ruby, also like other nice languages, comes with a builtin documentation
generator that scans your code for comments and makes them available in html
and other formats.

&lt;p&gt;

... until you start metaprogramming.

&lt;p&gt;

Take a simple example, the Fizzler! The name of the class is unimportant; this
class will simply provide a new way to define methods, simply for the sake of
showing some metaprogramming and how ruby's rdoc fails on it.

&lt;p&gt;

&lt;pre&gt;
class Fizzler
  def self.fizzle(method, &amp;block)
    self.class_eval do
      define_method method, &amp;block
    end
  end
end

class Bar &lt; Fizzler
  # Print a worldly message
  fizzle :hello do
    puts "hello world!"
  end
  
  # A simple test
  def test
    puts "testing, 1 2 3!"
  end
end

# Now some sample code, let's invoke the new 'hello' method we generated with
# 'fizzle'.
bar = Bar.new
bar.hello
&lt;/pre&gt;

The output looks like this:
&lt;pre&gt;
% ruby fizzler.rb 
hello world!
&lt;/pre&gt;

All is well! We are generating new methods on the fly, etc etc, all features of
metaprogramming. However, we can never make this 'hello' method obviously
available to the world via rdoc, at least as far as I can tell. The rdoc
generated looks like this:

&lt;p&gt;

&lt;a href="/files/blogposts/20091108/fizzler-rdoc.png"&gt; &lt;img
src="/files/blogposts/20091108/fizzler-rdoc-thumb.png"&gt; &lt;/a&gt;

&lt;p&gt;

Note the lack of any mention of 'hello' as a method. I cannot simply do what
works for lots of other normal ruby code and ask for the documentation of hello
by running 'ri Bar#hello' - because rdoc simply doesn't see it.

&lt;p&gt;

I recall in python, if you were dynamically generating methods and classes, you
could also inject their documentation by simply setting the '__doc__' property
on your class or method. Ruby doesn't appear to have such a thing.

&lt;p&gt;

Additionally, in some metaprogramming cases, the stack traces are actually
harder to read. For example, ActiveRecord makes extensive use of
'method_missing' rather than dynamically generate methods. The output is the
same, but the stacktraces are now littered with 'method_missing' and references
to files and lines you don't own, rather than containing stacktraces to
named functions and other useful pointers. This perhaps is a feature, but for
cases like method_missing, being able to add other useful data onto the stack
trace would greatly aid in debugging.

&lt;p&gt;

So, if long term necessities like documentation and easy debuggability (stack
traces, etc), are hindered by metaprogramming, at least in ruby, what are we
left to do? Metaprogramming is clearly a win in some places, but the automatic
losses seem to detract from any value it may have.


&lt;img src="/images/spacer.gif?geekery/metaprogramming-at-the-expense-of-documentation" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=BJzqqOE1aJw:Sb7l2-qJxdo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=BJzqqOE1aJw:Sb7l2-qJxdo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=BJzqqOE1aJw:Sb7l2-qJxdo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=BJzqqOE1aJw:Sb7l2-qJxdo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=BJzqqOE1aJw:Sb7l2-qJxdo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/BJzqqOE1aJw" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Sun, 08 Nov 2009 09:56 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/metaprogramming-at-the-expense-of-documentation.html?source=rss20</feedburner:origLink></item>
<item>
   <title>grok 20091103 release</title>
   <guid isPermaLink="false">geekery/grok-20091103</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/ecVphaqbICc/grok-20091103.html</link>
   <description>Lots of changes since the last announced release. Grok should get some
more activity now that I'm actually using it in a few places. If you
find bugs or have feature requests, please file them on googlecode
issue tracker (see below)

&lt;p&gt;

The largest changes are:
&lt;ul&gt;
&lt;li&gt; we ship with Ruby and C API. &lt;/li&gt;
&lt;li&gt; lots of new testing code. &lt;/li&gt;
&lt;li&gt; we now use tokyocabinet internally instead of bdb. &lt;/li&gt;
&lt;/ul&gt;

&lt;dl&gt;
&lt;dt&gt; Grok documentation: &lt;/dt&gt;
&lt;dd&gt; &lt;a href="http://code.google.com/p/semicomplete/wiki/Grok"&gt;http://code.google.com/p/semicomplete/wiki/Grok&lt;/a&gt; &lt;/dd&gt;
&lt;dt&gt; Download: &lt;/dt&gt;
&lt;dd&gt; &lt;a href="http://semicomplete.googlecode.com/files/grok-20091103.tar.gz"&gt;http://semicomplete.googlecode.com/files/grok-20091103.tar.gz&lt;/a&gt; &lt;/dd&gt;
&lt;dt&gt; File bugs/features: &lt;/dt&gt;
&lt;dd&gt; &lt;a href="http://code.google.com/p/semicomplete/issues/list"&gt;http://code.google.com/p/semicomplete/issues/list&lt;/a&gt; &lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;

This release has all tests passing in these configurations:
&lt;ul&gt;
&lt;li&gt; FreeBSD 7.1. tokyocabinet 1.4.30, pcre 8.00, libevent 1.4.12 &lt;/li&gt;
&lt;li&gt; Ubuntu 9.04. tokyocabinet 1.4.35, pcre 7.8-2, libevent 1.3e-3 &lt;/li&gt;
&lt;li&gt; CentOS 5.3. tokyocabinet 1.4.9-1, pcre 7.8-2, libevent 1.1a-3.2.1 &lt;/li&gt;
&lt;/ul&gt;

Thanks to Pete Fritchman, grok also ships with an RPM spec so you can 'rpmbuild
-tb grok-20091103.tar.gz' for simple build and deployment.  The spec builds
grok, grok-devel, and grok-ruby. 

&lt;p&gt;

I'm using this version of grok myself with good success. It's also
being used in the new logstash (log indexing tool) project for doing
log parsing.

&lt;p&gt;

Full changelist since the last announced release:

&lt;pre&gt;
20091103
 - New: ruby bindings are now really supported.
 - Change 'WORD' pattern to be word bounded (\b)
 - Move grok-patterns to patterns/base
 - update rpm spec to install patterns/base in /usr/share/grok

20091102
 - Add a bunch of tests, mostly in ruby, to exercise grok. This uncovered a
   few bugs which are fixed.
   All tests currently pass (both CUnit and Ruby Test::Unit) on:
   * FreeBSD 7.1. tokyocabinet 1.4.30, pcre 8.00, libevent 1.4.12
   * Ubuntu 9.04. tokyocabinet 1.4.35, pcre 7.8-2, libevent 1.3e-3
   * CentOS 5.3. tokyocabinet 1.4.9-1, pcre 7.8-2, libevent 1.1a-3.2.1
 - When making strings in ruby, we now make them tainted per ruby C docs.
 - "Too many replacements" error will now occur if you have cyclic patterns,
   such as defining 'FOO' to be '%{FOO}'. Max replacements is 500.

20091030
 - Make 'grok' main take a config for an argument.
 - Add grok rpm spec.
 - Updated Makefile to work on Linux and FreeBSD without modification.
 - Fixed bug introduced in 20091022 where capture_by_(name,subname) didn't
   work properly.
 - Add default values for match {} grok.conf blocks:
   shell: stdout
   reaction: "%{@LINE}"
 - Have grok exit nonzero if there were no reactions executed, akin to grep(1)
   not matching anything. 'reactions' are important here; matches with no
   reaction will not count as a reaction.

20091023
 - Fix libgrok accidentally sharing it's parser/lexer functions. Turns out,
   libgrok doesn't actually need to parse the grok.conf, so we don't build
   against it anymore for the library.

20091022:
 - Convert to using tokyocabinet instead of berkeley db.
   * Berkeley DB isn't easy to target across platforms (4.x versions vary
     wildly in bugs)
   * tokyo cabinet should be faster
   * tokyo cabinet is less code to write, and slightly more readable in the
     author's opinion.
   * we don't have to serialize with xdr anymore

20091019:
 - include pregenerated bison/flex output since gnu flex varies much from
 non-gnu flex, and many important platforms don't have gnu flex available
 easily from packages (freebsd, centos, etc) but come with the other flex.

 No functional changes.
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/grok-20091103" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ecVphaqbICc:0t5d3gN-Ws4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ecVphaqbICc:0t5d3gN-Ws4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=ecVphaqbICc:0t5d3gN-Ws4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=ecVphaqbICc:0t5d3gN-Ws4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=ecVphaqbICc:0t5d3gN-Ws4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/ecVphaqbICc" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 03 Nov 2009 09:54 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/grok-20091103.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Bringing test tools to Nagios monitoring</title>
   <guid isPermaLink="false">geekery/rspec-for-nagios-monitoring</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/cIuduyqSkvI/rspec-for-nagios-monitoring.html</link>
   <description>With all the TDD (test-driven design) and BDD (behavior-driven design) going
around these days, it'd be a shame not to use these tools on monitoring
applications.

&lt;p&gt;

You might have a boatload of tests that test your application before you roll a
new version, but do you use those tests while the application is in production?
Can you? Yes!

&lt;p&gt;

Let's take an important example of monitoring some complex interaction, like
searching google and checking the results. Simple with a mouse, but perhaps
complex in code. Even if you wrote a script to do it, using an existing testing
framework gets you pass/fail testing automatically.

&lt;p&gt;

For this example, I'll use the following ruby tools: &lt;a
href="http://rspec.info/"&gt;rspec&lt;/a&gt; and &lt;a
href="http://github.com/brynary/webrat"&gt;webrat&lt;/a&gt;. This fairly easy, though it
took me a bit to find all the right documentation bits to clue me in to the
right way.

&lt;pre&gt;
require 'rubygems'
require 'webrat'

Spec::Runner.configure do |config|
  include Webrat::Methods
end

describe "google search for my name" do
  it "should include semicomplete.com in results" do
    visit "http://www.google.com/"
    webrat.response.title.should =~ /Google/
    query = "jordan sissel"
    fill_in "q", :with =&gt; query
    field_named("btnG").click
    webrat.response.title.should == "#{query} - Google Search"
    click_link "semicomplete.com"
  end
end
&lt;/pre&gt;

Now, we run this with the 'spec' tool:

&lt;pre&gt;
% spec rspec-webrat.rb 
.

Finished in 0.578546 seconds

1 example, 0 failures
&lt;/pre&gt;

Seems ok. Let's break the test and see what happens. Change the 'visit' line to something else:

&lt;pre&gt;
    visit "http://www.yahoo.com/"
&lt;/pre&gt;

Now rerun the test, which was checking specifically for google things in the
page and will now fail on yahoo's page:

&lt;pre&gt;
 % spec rspec-webrat.rb
F

1)
'google search for my name should include semicomplete.com in results' FAILED
expected: /Google/,
     got: "Yahoo!" (using =~)
./rspec-webrat.rb:29:

Finished in 0.186847 seconds

1 example, 1 failure
&lt;/pre&gt;

This output kind of sucks. Additionally, rspec failures seem to have exit code
1, not 2 as wanted by a nagios check reporting critical. Let's fix those.
First, fixing the exit code can be hacked around directly in ruby if you want:

&lt;pre&gt;
# Nagios checks expect exit code '2' to mean CRITICAL.
# Let's make any nonzero exit attempt always exit 2 (EXIT_CRITICAL).
EXIT_CRITICAL = 2
module Kernel
  alias :original_exit :exit
  def exit(value)
    value = EXIT_CRITICAL if value != 0
    original_exit(value)
  end
end
&lt;/pre&gt;

Fixing the output just means telling spec to use a different output format. I
like the 'nested' output. Rerun that test now:

&lt;pre&gt;
% spec -f nested rspec-webrat.rb
google search for my name
  should include semicomplete.com in results (FAILED - 1)

1)
'google search for my name should include semicomplete.com in results' FAILED
expected: /Google/,
     got: "Yahoo!" (using =~)
./rspec-webrat.rb:30:

Finished in 0.017534 seconds

1 example, 1 failure

% echo $?
2
&lt;/pre&gt;

All set.

&lt;p&gt;

Even better is that you can include multiple checks in the same script, if you wanted to. RSpec lets you select any test to run alone, so your nagios checks for a given web application could be a very simple:

&lt;pre&gt;
define command {
  command_name check_google_for_semicomplete
  command_line /usr/bin/spec -f nested -e "google search for my name" mytests.rb
}
&lt;/pre&gt;

&lt;img src="/images/spacer.gif?geekery/rspec-for-nagios-monitoring" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=cIuduyqSkvI:lM7ndLrveZg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=cIuduyqSkvI:lM7ndLrveZg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=cIuduyqSkvI:lM7ndLrveZg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=cIuduyqSkvI:lM7ndLrveZg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=cIuduyqSkvI:lM7ndLrveZg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/cIuduyqSkvI" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Fri, 30 Oct 2009 09:24 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/rspec-for-nagios-monitoring.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Net-SNMP and tcp-wrappers verbosity</title>
   <guid isPermaLink="false">geekery/net-snmp-tcp-wrapper-verbosity</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/NEBwnAyJgD4/net-snmp-tcp-wrapper-verbosity.html</link>
   <description>I see this in my server logs quiet often:

&lt;pre&gt;
Oct 23 05:37:48 pww-5 snmpd[23946]: Connection from UDP: [XX.XX.XX.XX]:34650 
Oct 23 05:37:48 pww-5 last message repeated 16 times
Oct 23 05:37:48 pww-5 snmpd[23946]: Connection from UDP: [XX.XX.XX.XX]:34652 
Oct 23 05:37:48 pww-5 last message repeated 24 times
&lt;/pre&gt;

Googling points out that in snmpd.conf we should use
"dontLogTCPWrappersConnects" - but thet top search results claim that it
doesn't work (syntax errors, etc).

I tried this:
&lt;pre&gt;
dontLogTCPWrappersConnects
&lt;/pre&gt;

This makes an error of:
&lt;pre&gt;
/etc/snmp/snmpd.conf: line 29: Error: Blank line following dontLogTCPWrappersConnects token.
&lt;/pre&gt;

So I took a guess and changed it to:

&lt;pre&gt;
dontLogTCPWrappersConnects 1
&lt;/pre&gt;

This works to quiet the 'Connection from UDP: ...' messages. However, it still logs things like:
&lt;pre&gt;
Oct 22 23:17:35 pww-4 snmpd[29383]: Received SNMP packet(s) from UDP: [XX.XX.XX.XX]:42926
&lt;/pre&gt;

Fixing this requires telling snmpd to log less stuff to syslog. The '-L'
logging options support upper-case versions which set the level at which it
will log. Fixing syslog to not log the snmp packet info means setting this flag
"-LSnd". This means we'll log at 'notice' levels and above to syslog with the
daemon facility. Setting this flag seems to make snmpd less chatty in logs
about packets it gets. Setting the log level to '-LSid' (info level) will make
it once again log the packet receipts.

&lt;p&gt;

In CentOS (and other redhat variants) you'll edit this file to make this change
permanent: /etc/sysconfig/snmpd.options - just change "-Lsd" (default in my
version of net-snmp) to "-LSnd" and make sure the OPTIONS line is uncommented.

&lt;img src="/images/spacer.gif?geekery/net-snmp-tcp-wrapper-verbosity" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=NEBwnAyJgD4:FdoKW4dwdUY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=NEBwnAyJgD4:FdoKW4dwdUY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=NEBwnAyJgD4:FdoKW4dwdUY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=NEBwnAyJgD4:FdoKW4dwdUY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=NEBwnAyJgD4:FdoKW4dwdUY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/NEBwnAyJgD4" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 27 Oct 2009 03:27 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/net-snmp-tcp-wrapper-verbosity.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Ruby: Finding subclasses in your world</title>
   <guid isPermaLink="false">geekery/ruby-find-subclasses</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/n__dNujUbIQ/ruby-find-subclasses.html</link>
   <description>Use the ObjectSpace class to find all ancestors of a given class.

&lt;pre&gt;
class Foo; end
class Bar &lt; Foo; end
class Baz &lt; Foo; end

subclasses = ObjectSpace.each_object(Class).select do |klass|
  klass.ancestors.include?(Foo) and klass != Foo
end

# prints "[Baz, Bar]"
puts subclasses
&lt;/pre&gt;

Of course, you could always override Class#inherited instead, but if you don't
want to override methods, the above is a reasonable choice.

&lt;img src="/images/spacer.gif?geekery/ruby-find-subclasses" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=n__dNujUbIQ:Apu2OEY6Pgs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=n__dNujUbIQ:Apu2OEY6Pgs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=n__dNujUbIQ:Apu2OEY6Pgs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=n__dNujUbIQ:Apu2OEY6Pgs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=n__dNujUbIQ:Apu2OEY6Pgs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/n__dNujUbIQ" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 29 Sep 2009 07:54 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/ruby-find-subclasses.html?source=rss20</feedburner:origLink></item>
<item>
   <title>MySQL 5.0 'read-only' permits uncommitted writes</title>
   <guid isPermaLink="false">geekery/mysql-read-only-not-so-read-only</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/fMxIYAVFwEQ/mysql-read-only-not-so-read-only.html</link>
   <description>I recently had to do a master failover in mysql to bring up a new mysql master
to replace an older one.

&lt;p&gt;

The switchover went awry shortly after we told the old master to start slaving
off of the new master. The output of 'show slave status' indicated a halt of
replication due to foreign key constraints: an auto_increment primary key had a
duplicate insert attempt. How did this happen? I'm not sure yet, still digging.

&lt;p&gt;

This puzzle made me wonder how we got into that state given that I put the old
master in 'read only' mode before doing the switch. Turns out, there are some
edge cases that are permitted even in read-only mode. The docs have this to
say:

&lt;blockquote&gt;
When it is enabled, the server allows no updates except from users that have
the SUPER privilege or (on a slave server) from updates performed by slave
threads.
&lt;/blockquote&gt;

&lt;p&gt;

The above exceptions sound pretty reasonable, but I found an undocumented
exception: uncommitted transactions can be committed even in read-only mode.

&lt;p&gt;

This breaks my expectation that setting read_only means that as soon as this
setting goes 'true' all writes will fail. This means your backups aren't
consistent when using read_only unless you lock all your tables during the
backup. Additionally, commits made after read_only is set will bump the binlog
position, meaning if your backups do "set readonly, copy master status,
mysqldump", then you may break things because your mysqldump may have data that
includes things in the future of the master status you recorded.

&lt;p&gt;

It looks like this is fixed in MySQL &gt;=5.1.15. The docs say that later versions
will cause setting read_only to block while there's a pending  transactions.

&lt;p&gt;

Related to the original problem (replication failover), I think we should've
just locked all the tables then restart the old master in read_only mode rather
than simply setting read_only.

&lt;p&gt;

Below is an example of 'read_only' being set and a transaction commit as
non-superuser resulting in a data write. I have aligned the actions
side-by-side as they were executed chronologically.

&lt;p&gt;

Note the master status binary log position had changed after the commit. This
is expected after a normal database write. You can also see the table was
actually updated. I wasn't expecting any writes to succeed when read_only is
set:

&lt;p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;th width="50%"&gt; mysql as user 'test' &lt;/th&gt;
&lt;th width="50%"&gt; mysql as user 'root' &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;
# As a user I created 'test':
mysql&amp;gt; SET AUTOCOMMIT=0;
mysql&amp;gt; CREATE TABLE foo.foo (a int) ENGINE INNODB;
mysql&amp;gt; START TRANSACTION;
mysql&amp;gt; SELECT * FROM foo.foo;
Empty set (0.00 sec)

# So far so good, let's insert.
mysql&amp;gt; INSERT INTO foo.foo (a) VALUES (2);
mysql&amp;gt; SELECT * FROM foo.foo;
+------+
| a    |
+------+
|    2 | 
+------+
1 row in set (0.00 sec)









mysql&amp;gt; INSERT INTO foo.foo (a) VALUES (12345);
ERROR 1290 (HY000): The MySQL server is running 
with the --read-only option so it cannot execute 
this statement

# We expected the above error, but can we commit
# our previous insert before read_only was set?
mysql&amp;gt; COMMIT;
Query OK, 0 rows affected (0.01 sec)
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;

&lt;pre&gt;







# This is an empty result, since we haven't 
# yet committed.
root@mysql&amp;gt; SELECT * FROM foo.foo; 
Empty set (0.00 sec)





root@mysql&amp;gt; SET GLOBAL READ_ONLY = TRUE;
root@mysql&amp;gt; SHOW MASTER STATUS \G
*************************** 1. row ********
            File: mysql-bin.000001
        Position: 644
    Binlog_Do_DB: 
Binlog_Ignore_DB: 
1 row in set (0.00 sec)









root@mysql&amp;gt; SHOW MASTER STATUS \G
*************************** 1. row ********
            File: mysql-bin.000001
        Position: 834
    Binlog_Do_DB: 
Binlog_Ignore_DB: 
1 row in set (0.00 sec)

root@mysql&amp;gt; SELECT * from foo.foo;
+------+
| a    |
+------+
|    2 | 
+------+
1 row in set (0.00 sec)

&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;img src="/images/spacer.gif?geekery/mysql-read-only-not-so-read-only" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=fMxIYAVFwEQ:VfD5EyC7lTw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=fMxIYAVFwEQ:VfD5EyC7lTw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=fMxIYAVFwEQ:VfD5EyC7lTw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=fMxIYAVFwEQ:VfD5EyC7lTw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=fMxIYAVFwEQ:VfD5EyC7lTw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/fMxIYAVFwEQ" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Mon, 28 Sep 2009 07:41 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/mysql-read-only-not-so-read-only.html?source=rss20</feedburner:origLink></item>
<item>
   <title>Setuid bind(2) and switch!</title>
   <guid isPermaLink="false">geekery/setuid-bind-and-switch</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/yBIaLx6uFME/setuid-bind-and-switch.html</link>
   <description>Got a program that can't setuid but needs to listen on a priviledged port? I
was hacking around with Linux's capabilities(7) tonight and came up empty
trying to allow a non-priviledged user to bind to port 80 without having to
start as root - after all, not everything is capable of setuid on startup, like
many java programs.

&lt;p&gt;

Speaking of java, if you do setuid, the java hotspot monitor file thing
(/tmp/hsperfdata_&amp;lt;user&amp;gt;/&amp;lt;pid&amp;gt;) is in the original user's directory,
not the setuid'd user, so you can't jstack reliably. I might be PEBCAKing it,
but this is the behavior I observe. Unless we can fix that, and my java-fu is
weak, we'll have to find a workaround. One workaround is to run a proxy or
firewall redirector that forwards the privileged port to the real port.

&lt;p&gt;

Linux supports this process setting that allows a special non-root process to
listen on privileged ports, but I can't get it working.  I gave up trying to
use libcap's sucap, execcap, and setpcaps tools trying to allow nonroot
processes to bind to lower ports. Let's hack it with LD_PRELOAD and execve(2).

&lt;p&gt;

The trick is creating a socket and binding on the correct port, then sharing
that socket with your process. This comes with two steps, the socket creation,
and sharing.

&lt;p&gt;

The creation is easy, for simplicity, I used ruby. The sharing requires
LD_PRELOAD - we'll override bind(2) and have it dup our existing socket to
whatever socket bind(2) is being called with. The sharing is done using
environment variables to share the file descriptor number and the port number.

&lt;p&gt;

The end result looks like this, where we can now force programs that try to
bind on our specified port to use our pre-created socket instead.

&lt;pre&gt;
# id
uid=0(root) gid=0(root) groups=0(root)
# ./bindandswitch.rb
Usage: bindandswitch.rb [host]:port user group command [arg1 ...]
# ./bindandswitch.rb localhost:80 jls jls nc -l -p 80
setgid: 1000 (jls)
setuid: 1000 (jls)
Exec: ["nc", "-l", "-p", "80"]


# -- now in another terminal --
% lsof -i :80 | grep LISTEN 
 nc        27092  jls    4u  IPv4 8100070       TCP localhost:www (LISTEN)
&lt;/pre&gt;

See, now we have given 'nc' the ability to bind to privileged ports as
non-root (user 'jls' above). Sweet!

&lt;p&gt;

The ruby code takes care of creating the socket and doing setuid (I was lazy
and didn't want to write the C code). I also have a very short C library that
simply dup2()'s the original bound socket when bind(2) is called by the new
process on our specific port.

&lt;p&gt;

bind(2) calls for other ports than the one specified in the command line are handled normally. For example, this fails:

&lt;pre&gt;
# ./bindandswitch.rb localhost:33 jls jls nc -l -p 80
setgid: 1000 (jls)
setuid: 1000 (jls)
Exec: ["nc", "-l", "-p", "80"]
Can't grab 0.0.0.0:80 with bind : Permission denied
&lt;/pre&gt;

The reason for this investigation was really for seeing how we could allow
non-root java processes to bind to port 80. Maybe I'll use this at work if it
behaves well.

&lt;p&gt;

Code:
&lt;ul&gt;
&lt;li&gt; &lt;a href="http://code.google.com/p/semicomplete/source/browse/liboverride/bindandswitch.over"&gt;bindandswitch.over&lt;/a&gt; (needs &lt;a href="http://www.semicomplete.com/projects/liboverride/"&gt;liboverride&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt; &lt;a href="http://code.google.com/p/semicomplete/source/browse/liboverride/bindandswitch.rb"&gt;bindandswitch.rb&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;img src="/images/spacer.gif?geekery/setuid-bind-and-switch" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=yBIaLx6uFME:uToyHL3AjVE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=yBIaLx6uFME:uToyHL3AjVE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=yBIaLx6uFME:uToyHL3AjVE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=yBIaLx6uFME:uToyHL3AjVE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=yBIaLx6uFME:uToyHL3AjVE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/yBIaLx6uFME" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Thu, 24 Sep 2009 07:20 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/setuid-bind-and-switch.html?source=rss20</feedburner:origLink></item>
<item>
   <title>DNS Redirection and how it will break things</title>
   <guid isPermaLink="false">geekery/comcast-dns-hijack-breaks-things</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/PlqRdcMRwbk/comcast-dns-hijack-breaks-things.html</link>
   <description>There's some hot debate around the implications and rightness of service
providers to do things like traffic filtering, session hijacking, etc.

&lt;p&gt;

I'm not here to talk about that. The data below aims to focus on the technical
failures induced by dns hijacking, or dns redirection. I won't bore you with
the moral, political, or philosophical discussion around this topic.

&lt;p&gt;

Here's a summary if you don't want to read the details:
&lt;ul&gt;
&lt;li&gt; DNSBLs probably don't work anymore for Comcast users &lt;/li&gt;
&lt;li&gt; Owned domains (semicomplete.com, google.com, etc) are also subject to hijacking. Domain owners cannot opt-out. &lt;/li&gt;
&lt;li&gt; Down dns servers may result in full-domain hijacking by Comcast (due to dns search suffix and retry behavior) &lt;/li&gt;
&lt;li&gt; Privacy/security/cookie leak due to domain hijacking &lt;/li&gt;
&lt;li&gt; There is an &lt;a href="http://tools.ietf.org/html/draft-livingood-dns-redirect-00"&gt;IETF draft&lt;/a&gt; to formalize/standarize this destructive behavior that ignores consequences and impact, and neglects important points. &lt;/li&gt;
&lt;li&gt; Sometimes Domain Helper malfunctions and steals valid hostnames, like
www.google.com: &lt;a href="http://www.flickr.com/photos/jordansissel/3935640722/in/set-72157600173442944/"&gt;screenshot here&lt;/a&gt; ; &lt;a href="http://www.youtube.com/watch?v=NUDzl1Pf9Mo"&gt;or a video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; Web browsers aren't the only things using DNS. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

All of the samples below are real data I observed while digging into this issue. They are not faked.
&lt;p&gt;

Comcast recently finished rolling out their new &lt;a
href="http://networkmanagement.comcast.net/DomainHelperLogic.htm"&gt;Domain
Helper&lt;/a&gt; software. This tool intercepts responses from other DNS servers and
replaces them with forged responses that point to comcast's search portal. It
currently modifies responses that indicate 'no such hostname'; in DNS this
response is called NXDOMAIN.

&lt;p&gt;

For example, if you try to visit 'http://www.someinvalidhost12345.com', it doesn't exist, and the DNS 'NXDOMAIN' response saying so is dropped and replaced with an A  record pointing to Comcast's search site:

&lt;pre&gt;
% host http://www.someinvalidhost12345.com
http://www.someinvalidhost12345.com has address 208.68.139.38
&lt;/pre&gt;

The &lt;a href="http://networkmanagement.comcast.net/DomainHelperLogic.htm"&gt;domain
helper&lt;/a&gt; documentation explains how it works, but incorrectly describes
behavior and doesn't describe the consequences of the new behavior.

From the docs, it sounds something "must" (per above) include "www". This is
false, and is likely just out-of-date documentation, as the documentation goes
on to explain that they  "will eventually phase in the following pattern
matches to enhance this service in the future." This probably explains why
valid invalid.valid hostnames are bounced to comcast, and why invalid TLDs are
bounced to comcast:

&lt;pre&gt;
% host -t A abcdefghijklmnopww12345678.semicomplete.com
abcdefghijklmnopww12345678.semicomplete.com has address 208.68.139.38

% host -t A www.dns.is.broken
www.dns.is.broken has address 208.68.139.38
&lt;/pre&gt;

Simply having 'ww' is sufficient, even for valid domains like mine or totally
invalid TLDs like 'broken'.  Every NXDOMAIN is subject to hijacking. The IP
address above is still comcast's search redirector.

&lt;p&gt;

So, what is the hard technical impact of this change?

&lt;h4&gt; DNSBLs may be broken &lt;/h4&gt;

DNSBL is 'dns blacklist', check &lt;a
href="http://en.wikipedia.org/wiki/DNSBL"&gt;wikipedia&lt;/a&gt; for detail. Wikipedia
says this about how DNSBLs are used:

&lt;blockquote&gt;
Look up this name in the DNS as a domain name ("A" record). This will return
either an address, indicating that the client is listed; or an "NXDOMAIN" ("No
such domain") code, indicating that the client is not.
&lt;/blockquote&gt;

&lt;pre&gt;
% host -t A 111.0.168.192.bl.spamcannibal.org
111.0.168.192.bl.spamcannibal.org.home has address 208.68.139.38
% host -t A 111.111.11.11.zen.spamhaus.org
111.111.11.11.zen.spamhaus.org.home has address 208.68.139.38
&lt;/pre&gt;

&lt;p&gt;

According to DNSBL de facto behavior, I should probably get NXDOMAIN given it's
unlikely these IPs are in DNSBLs. Alternately, many DNSBLs reply with a special
'127.0.0.xxx' address to indicate what the status of the address is if it is in
the list. The responses above are neither, but are Comcast's search domain.

&lt;p&gt;

A Comcast employee on twitter pointed out that DNSBLs are only used by mail
servers. Fine, we don't run mail servers on Comcast residental, but there are
mail clients that support DNSBL for local spam filtering (thunderbird may,
evolution appears to). The point is, DNSBL is not purely for 'mail servers',
meaning this feature breaks DNSBL for clients.

&lt;p&gt;

I don't have data about how many people use DNSBL on mail clients. Point is,
it's an option not limited to mail servers.

&lt;h4&gt; Down DNS servers are fully hijacked &lt;/h4&gt;

When a DNS server is down, your DNS request generally times out and you get a
SERVFAIL response. What happens when your local DNS client gets a SERVFAIL,
though?

&lt;p&gt;

DNS resolvers support 'search suffixes'. In linux, you see this in
/etc/resolv.conf as 'search some list of domains'. At my house, I have a 'home'
dns zone managed automatically by my ddwrt router. This means I have 'search home' in my resolver.

&lt;p&gt;

If I try doing a dns query for 'some-invalid-host.something.com' and get
NXDOMAIN or SERVFAIL, my resolver will try adding a suffix, if it's configured
to do so. Here's an example of a dns server not responding and yielding
SERVFAIL and the resolver's attempt to try with a suffix 'home' resulting in
comcast NXDOMAIN hijacking me:

&lt;pre&gt;
% host -t A wwwdead.evilcouncil.org 68.87.76.182
Using domain server:
Name: 68.87.76.182
Address: 68.87.76.182#53
Aliases:

wwwdead.evilcouncil.org.home has address 208.68.139.38

Sniffing my local network traffic with tshark during this lookup:
6.755838 192.168.0.97 -&gt; 68.87.76.182 DNS Standard query A wwwdead.evilcouncil.org
6.770844 68.87.76.182 -&gt; 192.168.0.97 DNS Standard query response, Server failure
6.771264 192.168.0.97 -&gt; 68.87.76.182 DNS Standard query A wwwdead.evilcouncil.org.home
6.799348 68.87.76.182 -&gt; 192.168.0.97 DNS Standard query response A 208.68.139.38
&lt;/pre&gt;

Interesting. Here's another data point:

&lt;pre&gt;
% ping hijackmyww.evilcouncil.org
PING hijackmyww.evilcouncil.org.home (208.68.139.38) 56(84) bytes of data.
^C
&lt;/pre&gt;

Notice comcast's search portal IP repeated again and again...

&lt;p&gt;

If we use comcast's default search suffix for my area, hsd1.ca.comcast.net,
what happens?; 'www.example.com' may SERVFAIL, then we retry as
www.example.com.hsd1.ca.comcast.net, which comes back as comcast's
search2.comcast.net, again, due to their NXDOMAIN intercept.

&lt;p&gt;

Now, any SERVFAIL may automatically direct you to through their 'dns helper'
search redirect.

&lt;h4&gt; Security issues &lt;/h4&gt;

The last issue is something I noticed last night while disconnecting my VPN to
work. I had our monitoring site up in my browser - this page autorefreshes
itself every few minutes. After disconnecting, it refreshed, and dumped me at
search2.comcast.net. 

&lt;p&gt;

Since the redirect happens in DNS, the browser will believe that you are still
talking to the same server (by name) and will share cookies and http
authentication freely. What happens if you visit 'www.mail.google.com' in Firefox? Let's look at the network:

&lt;pre&gt;
snack(~) % sudo ngrep . 'port 80 and host 208.68.139.38'
[sudo] password for jls:
interface: eth0 (192.168.0.0/255.255.255.0)
filter: (ip or ip6) and ( port 80 and host 208.68.139.38 )
match: .
####
T 192.168.0.97:44422 -&gt; 208.68.139.38:80 [AP]
  GET / HTTP/1.1..Host: www.mail.google.com..User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.3) Gecko/20090824 Firefo
  x/3.5.3..Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8..Accept-Language: en-us,en;q=0.5..Accept-Encoding: gzip,
  deflate..Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7..Keep-Alive: 300..Connection: keep-alive..Cookie: PREF=ID=0cc23ef3118faec6:U=fffb...
&lt;/pre&gt;

The above shows Firefox sending Comcast my google mail login cookie. Had I been
visiting a page that uses &lt;a
href="http://en.wikipedia.org/wiki/Basic_access_authentication"&gt;basic HTTP
authentication&lt;/a&gt;, my username and password would've been sent, too.

&lt;p&gt;

Sure, cookies have a 'secure' attribute which tells the browser to only send
them over SSL connections, but does everyone use them? Nope. Bank of America,
for example, doesn't set this flag, which is a security issue itself, but is
leaked to Comcast on typoed URLs or during 'domain helper' malfunctions.

&lt;p&gt;

Firefox has no idea that 'www.mail.google.com' isn't Google, or
www1234.bankofamerica.com isn't Bank of America, and a normal user won't have
any idea they just leaked their credentials, private session info, and other
cookie data.

&lt;p&gt;

&lt;h4&gt; Domain Helper Malfunction &lt;/h4&gt;

Ofcourse, the worst part of this whole system is when the hijacking itself
misbehaves, and you get 'www.google.com' hijacked, when it's a real hostname.

&lt;p&gt;

&lt;h4&gt; Defenses and Actions &lt;/h4&gt;

How can we prevent some or all of this? Contact your ISP, help them understand
the impact of this behavior. Pushing at least to allow domain owners to opt-out
of the domain redirection might be a start or to require that providers not
hijack owned domains. Not hijacking invalid TLDs would be good too, given the
common usage of 'corp' and others as an intranet TLD.

&lt;p&gt;

If you are a comcast user and want  to opt-out of Comcast's Domain Helper, you
can visit &lt;a
href="https://dns-opt-out.comcast.net/"&gt;dns-opt-out.comcast.net&lt;/a&gt; (requires
login, only works when viewed from comcast). Alternately, you can point your
local dns caches at &lt;a
href="http://dns.comcast.net/dns-ip-addresses2.php"&gt;comcast's non-domain-helper
servers&lt;/a&gt;


&lt;img src="/images/spacer.gif?geekery/comcast-dns-hijack-breaks-things" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=PlqRdcMRwbk:tXQqMbV3KIQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=PlqRdcMRwbk:tXQqMbV3KIQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=PlqRdcMRwbk:tXQqMbV3KIQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=PlqRdcMRwbk:tXQqMbV3KIQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=PlqRdcMRwbk:tXQqMbV3KIQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/PlqRdcMRwbk" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Wed, 23 Sep 2009 03:28 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/comcast-dns-hijack-breaks-things.html?source=rss20</feedburner:origLink></item>
<item>
   <title>GDB for poking at libc to test random things</title>
   <guid isPermaLink="false">geekery/gdb-eval-libc-trickery</guid>
   <link>http://feedproxy.google.com/~r/semicomplete/main/~3/1OMnaBvZfFY/gdb-eval-libc-trickery.html</link>
   <description>I wanted to test something quickly out in C, but didn't want to write the 5
line of code to do it. Having done some fun ruby debugging with gdb recently, I
decided to go with that.

&lt;pre&gt;
% gdb -q `which sleep` --args `which sleep` 60000
(gdb) break nanosleep
(gdb) run
Starting program: /bin/sleep 60000
[Thread debugging using libthread_db enabled]
[New Thread 0x7f8c40bc46f0 (LWP 6504)]
[Switching to Thread 0x7f8c40bc46f0 (LWP 6504)]

Breakpoint 1, 0x00007f8c404f7ce0 in nanosleep () from /lib/libc.so.6
(gdb) call strcspn("hello world", "w")
$1 = 6
&lt;/pre&gt;

I don't know why I didn't think about this before. This is nicely useful, allowing me to easily test any simple function call unrelated.

&lt;img src="/images/spacer.gif?geekery/gdb-eval-libc-trickery" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=1OMnaBvZfFY:QN4_Z1ZOnx4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=1OMnaBvZfFY:QN4_Z1ZOnx4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=1OMnaBvZfFY:QN4_Z1ZOnx4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/semicomplete/main?a=1OMnaBvZfFY:QN4_Z1ZOnx4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/semicomplete/main?i=1OMnaBvZfFY:QN4_Z1ZOnx4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/semicomplete/main/~4/1OMnaBvZfFY" height="1" width="1"/&gt;</description>
   <category domain="http://www.semicomplete.com/blog">geekery</category>
   <pubDate>Tue, 22 Sep 2009 03:22 GMT</pubDate>
<feedburner:origLink>http://www.semicomplete.com/blog/geekery/gdb-eval-libc-trickery.html?source=rss20</feedburner:origLink></item>
</channel>
</rss>
