Yearly Archives: 2011

Three new SSH client features in Go weekly.2011-11-18

Over the last few weeks the exp/ssh package has been bubbling away quietly.

Firstly, the Client has finally grown support for publickey authentication. In place of handing over your username and password to the ClientConfig, now you can specify a number of ClientAuth implementations that will be negotiated with the remote server.

To use publickey authentication you need to supply your own type that implements the ClientKeyring interface. Here is a simple example, but more complicated intergrations with operating system keyrings is possible.

// keyring implements the ClientKeyring interface
type keyring struct {
        keys []*rsa.PrivateKey
}

func (k *keyring) Key(i int) (interface{}, error) {
        if i < 0 || i >= len(k.keys) {
                return nil, nil
        }
        return k.keys[i].PublicKey, nil
}

func (k *keyring) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
        hashFunc := crypto.SHA1
        h := hashFunc.New()
        h.Write(data)
        digest := h.Sum()
        return rsa.SignPKCS1v15(rand, k.keys[i], hashFunc, digest)
}

func (k *keyring) loadPEM(file string) error {
        buf, err := ioutil.ReadFile(file)
        if err != nil {
                return err
        }
        block, _ := pem.Decode(buf)
        if block == nil {
                return errors.New("ssh: no key found")
        }
        r, err := x509.ParsePKCS1PrivateKey(block.Bytes)
        if err != nil {
                return err
        }
        k.keys = append(k.keys, r)
        return nil
}

Because of the change to ClientAuth, if you want to use password authentication you will need to pass a type that implements ClientPassword.

// password implements the ClientPassword interface
type password string

func (p password) Password(user string) (string, error) {
        return string(p), nil
}

Tying it all together, Client authentication now looks like this:

func main() {
        k := new(keyring)
        err := k.LoadPEM("/path/to/your/privatekey")
        if err != nil { ... }
        config := &ssh.ClientConfig {
                User: "yourusername",
                Auth: []ssh.ClientAuth {
                        // ClientAuthPassword wraps a ClientPassword implementation
                        // in a type that implements ClientAuth.
                        ssh.ClientAuthPassword(password("yourpassword")),

                        // ClientAuthPublickey wraps a ClientKeyring implementation 
                        // in a type that implements ClientAuth.
                        ssh.ClientAuthPublickey(k),
                }
        }
        conn, err := ssh.Dial("tcp", "yourserver:22", config)
        if err != nil { ... }
}

Secondly, John Beisley has committed the first of a series of CLs that improves cipher handling in both the Client and Server. The commit includes support for AES and ARC4 ciphers and lays the groundwork for adding additional ciphers.

No changes are needed in client code to take advantage of these cipher improvements, the zero value for CryptoConfig in the ClientConfig struct defaults to a list of secure modern ciphers.

Finally, experimental support has been added to the ClientConn type for initiating direct-tcpip connections over SSH connections. The interface matches net.Dial and returns a net.Conn implementation. This allows the SSH clients, where supported, to tunnel TCP connections via the server.

// Dial an SSH server running on yourserver.com
c1, err := ssh.Dial("tcp", "yourserver.com:22", ... )
if err != nil { ... } 

// Dial news.yc via a tunnel to yourserver.com  
c2, err := c1.DialTCP("tcp", "news.ycombinator.org:80")
if err != nil { ... }

All of these are available in the current Go weekly, weekly.2011-11-18. Thanks to the intrepid souls who have already begun to explore the the exp/ssh package. I look forward to hearing about your adventures on golang-nuts.


But wait, there’s more. If you’re keen to live right on the bleeding +tip, this commit has made some improvements to the way interactive Sessions work. The goal is to follow the os/exec API, making Sessions more akin the to exec.Cmds. This features is very new, so I hope to post more as it solidifies after the next weekly.

Scratching my own itch, or how to publish multicast DNS records in Go

DHCP handles allocating IP addresses to the devices on my home network, but that leaves me with the problem of mapping IP addresses to names. The Macs and Linux hosts sort this out with Bonjour and Avahi, but annoyingly two devices, my router and my NAS don’t support it.

Now, I could hack my /etc/hosts file for those two hosts, but that doesn’t work well for embedded devices like iPad. Alternatively, I could install Avahi on my NAS, which is running Debian Sid armel, but space on it’s tiny root file system is always at a premium.

Fortunately, my NAS is also one of my Go development systems, so after some prodding from +Brian Ketelsen, I wrote a package to replicate the parts of Avahi that I needed. Here it is

https://github.com/davecheney/mdns/

Here is a simple example of how to use the package.

import (
        "net"
        "github.com/davecheney/mdns"
)

func main() {
        // Publish a SVR record for ssh running on port 22 for my home NAS.

        // Publish an A record for the host
        mdns.PublishA("stora.local.", 3600, net.IPv4(192, 168, 1, 200))

        // Publish a PTR record for the _ssh._tcp DNS-SD type
        mdns.PublishPTR("_ssh._tcp.local.", 3600, "stora._ssh._tcp.local.")

        // Publish a SRV record typing the _ssh._tcp record to an A record and a port.
        mdns.PublishSRV("stora._ssh._tcp.local.", 3600, "stora.local.", 22)

        // Most mDNS browsing tools expect a TXT record for the service even if there
        // are not records defined by RFC 2782.
        mdns.PublishTXT("stora._ssh._tcp.local.", 3600, "")

        select{}
}

So that’s it. This package has scratched my itch and I hope it is useful for others. I’d love to hear feedback and suggestions you’ve found it to be useful.

updated 16/10/2011 Thanks to @eneff for the select{} tip.

OS X has a built in WiFi scanner

Did you know that OS X has a built in WiFi survey tool? Nope, neither did I, but here it is

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport

This won’t be in your path, so to make things easier you could add the following to your ~/.profile

% alias airport=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport

Here is an example of the output.

% airport -s
SSID BSSID RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
fibble 00:26:de:ad:be:ef -59 9 Y -- WEP
flobble 00:60:ca:fe:ba:be -66 6 N AU WPA(PSK/TKIP,AES/TKIP) WPA2(PSK/TKIP,AES/TKIP)
wibble 94:44:51:51:51:51 -62 6,+1 Y -- WPA(PSK/AES,TKIP/TKIP) WPA2(PSK/AES,TKIP/TKIP)
wobble 00:21:af:af:af:af -60 3 N US WPA(PSK/TKIP/TKIP)
ftang 00:18:3b:00:b1:15 -73 11 N -- NONE

For the nitpickers, this data is also available in WIFi icon on the menu, with the important distinction that you can only find out the channel and signal strength if you associate with the AP. Using this tool you can easily do a quick WiFi survey to pick a good channel to avoid side lobe interference (hat tip to Matt Ryall).

Simple extended attribute support for Go

This afternoon I sat down and polished up the extended attribute library I have been working on for a while. You can find the code and readme on Github.

https://github.com/davecheney/xattr

This has been tested on linux (should work under 5g, 6g and 8g) and darwin (tested under Snow Leopard).

Installation

goinstall github.com/davecheney/xattr

Documentation

godoc github.com/davecheney/xattr

Usage

A example program is provided with the source. The simplest way to compile and install it is

make -C $GOROOT/src/pkg/github.com/davecheney/xattr/example clean install

This will install it to your $GOBIN directory. If you have trouble running this example, make sure there isn’t another xattr somewhere higher in your $PATH.

Before you start

All extended attributes need a file to be associated with. In this example I’m going to create an empty file in my home directory.

touch ~/testfile

Setting an attribute

% $GOBIN/xattr -w username dave ~/testfile

Listing known attributes

% $GOBIN/xattr ~/testfile
username

Printing attribute values

% $GOBIN/xattr -p username ~/testfile
dave

Listing names and values

% $GOBIN/xattr -l ~/testfile
 username: dave

Bash trick ‘o the day

Bash supports the += operator

% echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
% PATH+=:$HOME/bin
% echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/dave/bin

A new take on artificial scarcity

P34

Sometime in the last week, not one but two of these billboards appeared in the front yards of blocks of units on a street in Ashfield. Surprisingly spartan on details, the board implies that the wizards at Brough Real Estate have made two sets of sellers, buyers and a themselves very happy, an increasingly difficult task in the current climate. Less believable is the fact these properties are directly opposite each other.

Clearly this is a ruse.

With a reported 350,000 properties on the market across the country, the question becomes, who is the audience for this call to action?

Nobody rings a bell at the top of the market

To steal a quote from Liaquat Ahamed’s Lords of Finance the best days of Australian housing bubble may be behind it. As an amateur economist and armchair property speculator I wanted to share my views on this subject.

During the 60s and 70s Ashfield, the formerly Polish, now Chinese migrant, inner west suburb of Sydney succumbed to vast swathes of development which saw the majority of Colonial and Fediterania bungalows replaced by two and three story apartment blocks. Due of their ubiquity and near identical layout, these properties provide an opportunity to study the effects of the Australian housing boom on a particular class of asset; the quintessential two bedroom flat.

Skipping forward a few decades to October 2009, it was a heady time for the Sydney housing market, and it was no different for Vendors in Ashfield. Landlords were dumping unrenovated 2 bedroom units onto the private market for $400,000 a pop. Saturday mornings saw Agents, weighed down with keys, leading platoons of eager DINKYs from inspecting to inspection. Estate agents, banks and solicitors were doing a roaring trade on the back of the dying months of the final extension of the First Home Buyers grant. Those who waited for the governments handouts to cease in the hope that the market would cool were out of luck, twelve months later I watched a 2br flat sell at auction for over $520,000.

However the present day in Ashfield reveals a different picture. The previous weekend I attended two auctions with similar outcomes. The first apartment, a ground floor flat sold for $370,000 to the first, and only bidder. The second, with rubberneckers spilling onto the stairs, was passed in at $451,000 after the vendor bid failed to push the lacklustre bidding above the reserve.

Much has been written about the Australian housing bubble, and I believe the diagnosis to be accurate. Clearly my shoulder surfing a brace of sales does not represent a trend, and more data is needed before I can say the age of the half million dollar Ashfield flat is over.

What is, however, less clear to me, is the prognosis for the price of 70 square meters of real estate in Ashfield.

  • Will the reported 350,000 properties on the Australian market drive down prices, or will they be quietly be withdrawn to await more favourable conditions ?
  • Does the US example of Federally insured non redress loans provide an accurate model for the future of the Australian property market, or should we look to Spain or Portugal for clues ?
  • Which way will interest rates move in the next few quarters ? Would raising them cause a firesale of properties, or would homeowners instead retreat further from the retail market ? Would lowering them continue to support this over inflated market, driving prices higher and with it, increased wage claims ?

 

Netgear Stora as an ARM development platform

About a week ago I posted a request for recommendations for ARM based systems that could be used for Go development. There were some great responses, including the BeagleBoard and the Guru Plug. Being impatient, and in Australia, I ended up getting a Netgear Stora which has turned out to be a great home NAS, and a capable ARM5 development system. This is the same hardware, albeit with less RAM, that ships in the ShivaPlug.

axentraserver(~/go/src) % export MAKEFLAGS=-j1
axentraserver(~/go/src) % hg identify 
546b1fc95dcc+ tip
axentraserver(~/go/src) % time ./make.bash > /dev/null
hg not installed
conflicts: 3 shift/reduce

real    10m48.889s
user    9m15.380s
sys     0m52.480s

Not too shabby, my 8g host (2.8Ghz Celeron) turns around the same build in just under 12 minutes.

Pros

  • Very good value. For less thatn $200 AUD you get a 1.2Ghz Marvel ARM5 CPU, 128mb of ram and a 1Tb Seagate 3.5″ drive (and a slot for a second drive). Online Computer have the 1Tb units for $185.
  • Very hackable. SSH is enabled out of the box, if you know the magic suffix that Netgear, and all users created via the web interface are in /etc/sudoers. The fantastic ipkg system will close the gap between the slimmed down RedHat distribution that Netgear Axentra ship and a GNU buildchain that can bootstrap Go.

Cons

  • 128mb of ram, non expandable. This actually turns out to not be a big deal. The stock install has ~75mb of RAM free while running. Turing off a few options and trimming the daemons Netgear installs can get another 10-15mb back.