Pages

Monday, 29 August 2016

mosh 的安装和使用

ssh服务器如果延迟比较大的话, 还是比较痛苦的.
今天发现了这个东西: mosh
它是为了解决两个问题:
  1. 线路不稳定, 丢包率高.
  2. 线路延迟大, 操作延迟大.
简单的讲, 它使用普通的ssh协议认证, 然后传输使用udp协议.
使用udp协议的好处是不用总是保持连接, 用来解决第一个问题, 就是高丢包率. 就算丢包,也不会断,因为本来就是 udp , 没有连接.
为了处理延迟大的问题, 它在客户端做了优化, 包括输入回显预测机制,让你感觉到输入流畅了. 以及打包及拆包发送等等. 实测效果比较流畅.大有改观.
目前的缺陷就是只支持交互式shell环境, 不支持X转发,和端口转发等.
简单说一下安装方法.
  1. 安装服务端.
服务端已经支持了几乎所有的平台. 安装也很简单:
https://mosh.mit.edu/#getting
apt-get install mosh
服务端默认使用 udp 60001 端口传输, 所以可能需要你打开防火墙端口:
iptables -I INPUT -p udp --dport 60001 -j ACCEPT
  1. 安装客户端.
    如果是linux, 也使用同样的命令安装:
apt-get install mosh
我是windows, 官方客户端只支持cygwin. 所以要先安装cygwin.
mosh已经进入cygwin的仓库, 但是默认没有安装.
在cygwin安装时, 需要搜索添加mosh.
如果已经安装过cygwin了, 再次运行安装程序, 然后在安装时搜索找到mosh 安装即可.
mosh 只能在 纯的 utf-8 环境下工作. 所以在运行 mosh之前, 要改cygwin的语言.
找到 cygwin的 C:\cygwin64\home\neil.bashrc 文件.
在文件末尾加入如下两行.
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
  1. 使用方法.
启动cygwin的shell.
直接输入命令:
mosh  root@myserver.com

如果ssh的端口改了.
mosh -ssh="ssh -p 1234"  root@myserver.com
更新:
发现有官方的 chrome 插件 客户端. 可以在浏览器里直接连接vps了.
https://chrome.google.com/webstore/detail/mosh/ooiklbnjmhbcgemelgfhaeaocllobloj
---------------
mosh的安装和使用
如果用过 ssh 连接远程电脑,就会发现,无论是哪个系统,Ubuntu,或者 Windows,输入都会有很大的延迟。你输入了好多文字,它却要缓上好一会儿才显示得出来。
这是折腾 Mosh(Mobile shell) 的初衷。
首先,要使用 Mosh,需要在客户端及服务器端都安装它,或者在服务器端至少安装 mosh-server。Ubuntu 下可以通过 ppa 安装的:
$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:keithw/mosh
$ sudo apt-get update
$ sudo apt-get install mosh
因为 Mosh 使用的是 UDP 端口,所以服务器上需要打开某 UDP 端口。
假设 Mosh 使用 60001 UDP 端口,则在服务器上运行:
$ sudo iptables -I INPUT -p udp --dport 60001 -j ACCEPT
这样就在服务器上打开 60001 UDP 端口。当然,最好是把上一条命令写入服务器 firewall 的规则中,这样不必要每次都手动打开这个端口。
接下来就是从客户端连接:
$ mosh -p 60001 sam@server_ip
p 参数用于指定 UDP 端口。
假如你的 SSH 连接 设置公钥/私钥连接,比如 ssh zfanw 即可直接连接服务器而无需输入密码,则 mosh 命令也可以以 mosh zfanw 的形式连接,基本上,可以把它当作 ssh 命令的替换,只不过 ssh 开的是 TCP 口,mosh 开的是 UDP 口。
效果如何?开两个窗口,一个直接 ssh 登录,一个通过 mosh 登录,对比输入一下就知道了 – 当然是 mosh 的输入流畅。
Mosh 有很多强于 ssh 的特性,比如连接不会掉,你可以盖上笔记本电脑让它休眠,然后再打开,mosh 的连接还在,而如果是 ssh 的话,直接就断掉。
不过折腾过程中真是碰上不少问题,比如 locale 问题,后来莫名地就折腾好了 – 本来还想写一篇关于 Locale 的内容,现在省了。
----------------------

Mosh是MIT最近新出的一款类似SSH的软件,全称是mobile shell,官网GitHub

优点

相对于SSH,Mosh有两个强大之处
  1. Mosh支持漫游和间歇性链接,假如你断网了,或者网络不稳定IP变了(比如在移动蜂窝之间漫游),仍旧可以连接上原来的会话,而不是像ssh那样网络一断,就直接丢了(直接合上笔记本,下次再打开重新联网,这个链接不会断)
  2. Mosh可以在客户端即时显示击键的结果,原始的SSH,每当用户敲击一下键盘,就要和server通信一次,但是Mosh会做一个预测,比如用户输入一个单词,在单词输入完之前很可能不必和server交互,等完全输入之后再一起发给server,返回结果
这两点,非常明显,这货就是为了一个目的:在移动端SSH链接服务器啊。。

缺点?

有可能的缺点:如果在终端看log的话,由于上面第二点,client这边看到的log实时刷新会不会有问题?这个我稍后研究下

原理

内部的细节我还在了解中,根据介绍,原理也非常简单,事实上,这货仍旧是通过SSH先链接到服务器,然后再服务器端唤起Mosh-server建立会话,再返回信息给Mosh-client

安装

linux下(Ubuntu,Debian)只要 sudo apt-get install mosh 就可以了,当然不同的发行版略有区别,Gentoo,Arch,Fedora,BSD可以参考官网的说明
Mac下推荐HomeBrew来安装 brew install mobile-shell

使用

连接服务器和SSH一样 mosh [yourname@]yourserver.com
指定server目录
当然,Mosh非常人性的一点就是,你可以把mosh-server装到任何目录下,就算你不是server的管理员,你也可以把它安装到自己的目录下,这样连接的时候,只要指定目录就可以了 mosh --server=/home/yourname/mosh/ r2d2 [yourname@]yourserver.com
指定UDP端口
当server在防火墙之后的时候,默认端口不可用的时候,你可以自己指定UDP端口 mosh -p 1234
指定SSH端口
上面说了,事实上mosh还是走SSH链接的,可以指定ssh端口 mosh --ssh="ssh -p 2222"
其他SSH选项
mosh --ssh="~/bin/ssh -i ./identity"
立即输出
mosh -n #关闭 或者 mosh --predict=never
mosh -a #开启 或者 mosh --predict=always
关闭连接
一般,调用logout或者exit将直接断开会话

注意

Mosh要求在client端有一个纯净的UTF-8交互环境,如果不是,则拒绝启动
在我的Mac上刚装好Mosh,启动连接server的时候报错如下:
MOSH IP 127.0.0.1
mosh-server needs a UTF-8 native locale to run.

Unfortunately, the local environment ([no charset variables]) specifies
the character set "US-ASCII",

The client-supplied environment ([no charset variables]) specifies
the character set "US-ASCII".

LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Connection to localhost closed.
你可以在本地locale来查看哪些设置不是UTF-8,然后在.bashrc或者.zshrc修改他们成UTF-8
我在我的.zshrc中设置下面这两项:
export LC_CTYPE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
如果服务器端有问题,可以ssh到server上,修改server的相应环境参数
如果不能ssh到服务器上,你也可以使用mosh remotehost --server="LANG=en_US.UTF-8 mosh-server"这种命令

Amazon EC2?

Yes, it works great, but please remember to open up UDP ports 60000–61000 on the EC2 firewall.