Wednesday, April 11, 2012

Mosh - the great new SSH replacement

I'm regularly connecting to servers at the other side of the planet, frequently with latencies of 280-300ms.  While you do get used to the slow response of such connections any improvement is welcome, to the extent that I was pleased to hear that a 60ms improvement would be on the cards soon.

I heard about the mosh project today and made time to get it working this evening.  The initial impression is great.  In addition to the improvements in the feeling of latency it's fantastic to be able to switch between wired and wireless connectivity without losing the terminal session.

I can definitely see this becoming an essential tool.

Installation on Mac OSX

On my OSX 10.7 client installation was as simple as:
sudo port install mosh

Installation on Debian Squeeze

Update: It appears mosh has arrived in Debian squeeze backports: https://github.com/keithw/mosh/issues/75#issuecomment-5067129

On the Debian Squeeze server it was a little more involved.  I tried to use the debian testing repository with apt preferences for Pin-Priority.  Unfortunately trying to install mosh wanted to upgrade around 20 packages to the testing versions.  Not something I want to do on production servers.

Fortunately building and install mosh was easier than expected using the standard squeeze packages:
sudo aptitude install build-essential autoconf protobuf-compiler libprotobuf-dev libboost-dev libutempter-dev libncurses5-dev zlib1g-dev pkg-config
git clone https://github.com/keithw/mosh
cd mosh
./autogen.sh
./configure
make
sudo make install

Following this it was necessary to open up the relevant ports in the firewall:

$ sudo iptables -A INPUT -p udp -m multiport --dports 60000:61000 -j ACCEPT

Locale configuration

The Mosh developers have decided to only go down the path of supporting UTF-8, which doesn't seem like such a bad idea, however it does mean you'll have to ensure both ends of your connection properly support the UTF-8 locales.  To do this the following conditions need to be met.

On the server ensure you have the following line in your sshd_config.  On debian this is located at /etc/ssh/sshd_config:

Server /etc/ssh/sshd_config
...
AcceptEnv LANG LC_*
... 

OSX client ~/.ssh/config or /etc/ssh_config. Thanks to srmadden for this snippet.
...
Host *
    SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
  SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
  SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
...

Now confirm the locales are correct.  Initially running locale on both client and server reported the locales were all correctly UTF-8, however checking the server locale via the ssh one liner "ssh remotehost locale" was returning POSIX. After adding the above config the correct locales were returned.

On the local workstation:
user@workstation $ locale  
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8" 

And a regular connection to the remote host.
user@workstation $ ssh remotehost locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8

Now go ahead and enjoy the low latency "feeling" and the ability to seamlessly move between connections.

Last but not least a big thank you to all the people that made the mosh project a reality!

No comments: