在一个列表里选定主机名后直接 SSH 登陆

标题真拗口,详细一点应该是,在一个文本文件里有一个主机名(和 IP 地址)列表,通过 vi/vim 的上下键选择某个主机名(IP 地址)后,点击回车键就可以完成相应的 SSH 登陆。

不管 chef/puppet/salt/ansible 这类自动化配置工具多么智能,我们总有需要登陆到单台服务器上找问题的时候。总不能每次去翻 doc/txt 文档找相应的 IP 地址和用户名吧,找到 IP 地址和用户名后、copy 出来、切换窗口、再 ssh?有点累~~

机械的工作总是能找到替代的工具来完成,warp 就是这样一个小工具,确切的说是一个小 bash 脚本,warp 从 .warp 文本文件里读取主机名(IP 地址)信息,然后自动连上 ssh.

$ wget https://raw.githubusercontent.com/jpalardy/warp/master/warp
$ chmod +x warp

我们可以看到这个 .warp 文件格式很自由,只要保证第一列是主机名和 IP 地址(执行 ssh 命令格式的后半部分)就可以了,还可以用 — 和 # 当作注释方便我们区分和归类不同的服务器:

$ vi ~/.warp
# VIRTUAL MACHINE HOSTS

-- production servers

host101.vpsee.com -- xen host
host102.vpsee.com
root@host103.vpsee.com -- kvm host
user@host104.vpsee.com

-- development servers

172.20.2.101
172.20.2.102
root@172.20.2.103
user@172.20.2.104

# SUN GRID ENGINE HOSTS

sge101
sge102.cluster.vpsee.com
192.168.2.15 -- local datacenter

执行 warp 后会自动打开 vi/vim,然后使用 kj 键选择某行后回车即可:

$ ./warp

如果选择多行,warp 还支持 csshx 哦~

服务器批量执行工具 PSSH

操作一台服务器的时候可以 ssh,操作多台服务器可以开多个窗口多个 ssh,那操作很多台服务器呢?

我们的一个 Oracle Gird Engine 集群上大概有60多台 Ubuntu 服务器作执行节点,这些服务器操作系统和软件配置完全一样(上线后由 puppet 统一配置),有时候我们需要在这些服务器上做同样的操作,这个时候特别适合使用 PSSH 这种 ssh 批量操作工具。

当然,如果对 Python 不恐惧的话也可以用 Fabric 批量执行服务器任务

下载和安装 pssh:

$ git clone http://code.google.com/p/parallel-ssh/
$ cd parallel-ssh/
$ sudo python setup.py install

批量执行

首先新建一个服务器列表文件,把需要操作的服务器的 hostname(或者 IP 地址)加进去,然后就可以批量执行 uptime 命令了,-l 指定登录用户名,-A 询问密码,-h 指定服务器列表文件:

$ vi grids
grid01
grid02
grid03
grid04
grid05

$ pssh -i -l root -A -h grids 'uptime'
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 05:42:09 [SUCCESS] grid01
 11:42:09 up 620 days, 20:30,  0 users,  load average: 6.09, 6.14, 6.13
[2] 05:42:09 [SUCCESS] grid03
 11:42:09 up 620 days, 20:29,  0 users,  load average: 9.01, 9.04, 9.05
[3] 05:42:09 [SUCCESS] grid05
 11:42:09 up 620 days, 20:10,  0 users,  load average: 8.46, 8.18, 8.10
[4] 05:42:09 [SUCCESS] grid04
 11:42:09 up 620 days, 20:25,  0 users,  load average: 6.00, 6.01, 6.05
[5] 05:42:10 [SUCCESS] grid02
 11:42:10 up 606 days,  2:07,  0 users,  load average: 6.03, 6.02, 6.01

批量上传

批量上传本地文件 linux-3.14.3.tar.xz 到服务器上的 /tmp 目录:

$ pscp -l root -A -h grids linux-3.14.3.tar.xz /tmp/
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 05:56:16 [SUCCESS] grid01
[2] 05:56:16 [SUCCESS] grid03
[3] 05:57:04 [SUCCESS] grid05
[4] 05:57:04 [SUCCESS] grid04
[5] 05:57:05 [SUCCESS] grid02

批量下载

批量下载服务器上的某文件到本地,不用担心重名问题,因为 pssh 已经建立了 grid01, grid02, …, grid05 目录来存放下载的文件:

$ pslurp -l root -h grids -A /tmp/linux-3.14.3.tar.xz .
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 06:06:01 [SUCCESS] grid01
[2] 06:06:01 [SUCCESS] grid03
[3] 06:06:06 [SUCCESS] grid04
[4] 06:06:06 [SUCCESS] grid02
[5] 06:06:06 [SUCCESS] grid05

$ ls
grid01  grid02  grid03  grid04  grid05  grids  linux-3.14.3.tar.xz  parallel-ssh

批量同步

有时候我们需要保持开发机上(某目录里)的数据和服务器上的数据一致:

$ prsync -l root -h grids -A -r develop/ /tmp/production/
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 06:12:52 [SUCCESS] grid05
[2] 06:12:52 [SUCCESS] grid01
[3] 06:12:52 [SUCCESS] grid04
[4] 06:12:52 [SUCCESS] grid02
[5] 06:12:52 [SUCCESS] grid03

如何的退出无响应的 SSH 连接

大家有时候会发现 ssh 挂在那里没有响应了,可能是客户端的问题,也可能是服务器端的问题,也可能是客户端和服务器之间的网络问题;可能是客户端电脑休眠后连接断了、可能是网络断了、可能是 WiFi 信号不好、可能是网络延迟大了、可能是服务器挂了、也可能是服务器上的 sshd 进程挂了,…,可能是技术问题,也可能是非技术问题,可以找出无数可能。

我常遇到或者说每天都遇到的情形是,离开办公桌前忘了退出 ssh 会话。工作的时候长时间 ssh 到服务器上,工作完盖上 Mac 走人,回家后发现那些没退出的 ssh 会话还挂在那里,无法退出、无法 Ctrl+C、无法做任何操作。我的粗暴做法通常是直接关闭 Terminal 后重新开一个新的;如果用的不是图形系统,没有窗口可以关闭,那还要启用另一个终端找到相关进程后 kill 掉,如果每天都要搞这么几次还是挺烦人的。今天无意中从同事那里学到了一个小技巧,在那些没退出的 ssh 会话里用 ~. “优雅” 的断开连接。

~.

查看一下 man 帮助文件发现已经有说明,惭愧的是用了这么多年 ssh 才发现有这么一招:

$ man ssh
...
ESCAPE CHARACTERS
     ...

     The supported escapes (assuming the default `~') are:

     ~.      Disconnect.

使用浏览器访问 Linux 终端

wssh 可以让我们通过 HTTP 来调用远程的一个 shell,也就是说我们可以用浏览器来访问某个 Linux 服务器/虚拟机的终端(只要这个服务器上运行了 wsshd 服务器端)。wssh 客户端通过 ssh 帐号连接到 wsshd 服务器端。wssh 更多的是当作库来开发一些应用,比如开发云计算、虚拟机后台控制面板的虚拟机控制台等等。我们先来玩一下简单的~

安装一些必要软件:

$ sudo apt-get install git gcc python libevent-dev python-dev python-pip

安装 wssh 需要的各种 Python 库:

$ sudo pip install gevent gevent-websocket paramiko flask

下载并安装 wssh:

$ git clone https://github.com/aluzzardi/wssh.git
$ cd wssh
$ sudo python setup.py install

运行 wsshd:

$ wsshd
wsshd/0.1.0 running on 0.0.0.0:5000

从浏览器打开 http://IP:5000 后会看到如下登陆界面:
wssh

使用 ssh 帐号登陆后就可以看到终端了:
wssh

解决 /dev/null is not a character device! 问题

昨天我们一个客户无法 ssh 到他的 VPS,但是可以 ping 通。从控制台上看没有异常,登陆进去后发现 ssh 服务没有启动,企图启动(重启)这个服务时报错 /dev/null is not a character device!:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd failed!
/dev/null is not a character device!.

解决办法是,删除 /dev/null 后重建一个字符设备:

# rm -f /dev/null
# mknod /dev/null c 1 3

然后启动(重启)ssh 就可以了:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd.

同步管理多个 SSH 会话

当我们管理数十台或更多 Linux 服务器的时候,往往需要在每台服务器上执行同样的命令,比如我们想一次查看10台 Xen 服务器(node)上系统负载情况,或者想知道哪台 Xen 服务器有剩余内存可以分给新客户,又或者想执行 df 命令看看哪个服务器上还有多的硬盘空间等等,除了可以用脚本或工具统一收集这些信息外,我们还可以考虑使用一些同步管理多个 SSH 会话的小工具来帮助管理多台服务器,节省时间提高管理效率。在 Linux 上可以用 pdsh、ClusterSSH 和 mussh;在 Mac 上可以用 csshX.

使用 csshX 很简单,下载解压后就可以运行,如果要同时 ssh 到4个服务器的话:

$ ./csshX 192.168.0.1 192.168.0.2 192.168.0.3 192.168.0.4

也可以把这些要 ssh 管理的 IP 写到一个文件里,然后加载这个文件:

$ vi xenhosts
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4

$ ./csshX --hosts xenhosts

csshX

开启 VMware ESXi 的 SSH 服务

昨天收到一位 VPS 客户邮件问到一个不相关 VPS 业务的问题(这个问题已经发到相关文章的评论里),请大家把与我们 VPS 业务不相关的技术问题直接发到博客上,这样大家都可以看见和搜索到,我们也不必重复回复类似的问题和邮件了:)问题是这样的,如何把 VMware ESXi 上的虚拟机镜像文件拷贝出来?一种简单的解决办法就是用 ssh 登录 VMware ESXi 服务器,然后到相关目录直接把镜像文件拷贝出来。VMware ESXi 默认是关闭 ssh 的,那么如何开启呢?

在 VMware ESXi 3.5 控制台上直接按 “ALT + F1″ 就可以到 console,输入 “unsupported” 后回车进入 Tech Support Mode 模式,输入 root 用户名和密码登录就进入 console 了,然后编辑 inetd.conf 文件、去掉 ssh 那行注释、保存、然后重启服务就可以了:

~# vi /etc/inetd.conf
ssh stream tcp ...

~# /sbin/services.sh restart

如果是 VMWare ESXi 3.5 Update 2 版本,需要找到 inetd 进程并用 kill 带上 -HUP 选项重启这个服务进程:

~ # ps | grep inetd
5031 5031 busybox              inetd

~# kill –HUP 5031

在 VMware ESXi 4.1 上开启 ssh 功能和 VMware ESXi 3.5 不同,如果直接按 “ALT + F1″ 的话会看见以下提示信息:

Tech support mode has been disabled by your administrator

所以需要先把 Tech support mode 打开,在 VMware ESXi 4.1 上输入密码后进入界面控制台,选择 “Troubleshooting Options”,继续选择 “Enable Local Tech Support” 和 “Enable Remote Tech Support (SSH)”,这样就可以同时开启本地 console 和远程 ssh 登录。

在 VMware ESXi 5.0 上开启 ssh 功能就简单多了,直接在操作界面里 enable 就可以了。

用 ssh 登录 VMware ESXi 后就可以随心所欲了,根目录下就这么些文件和目录,层次清晰,很容易找出虚拟机镜像文件在哪,需要的话把这些镜像文件 scp 拷出来就可以了。

~ # ls /vmfs/volumes/datastore1/minix01/
minix01-d76c0df1.vswp  minix01.nvram      minix01.vmsd       minix01.vmxf
minix01-flat.vmdk      minix01.vmdk       minix01.vmx        vmware.log

Debian 上 /var/run/sshd/ 的所属问题导致 SSH 不能启动

前天有位客户的 Debian VPS 的 ssh 出现问题,无法正常连接,ssh IP 地址后出现如下错误:

ssh_exchange_identification: Connection closed by remote host

找客户要了 root 密码后登录检查 /etc/ssh/sshd_config 配置文件没有发现问题、防火墙关闭状态、sshd 进程也在,企图重启 sshd 出现如下报错:

# /etc/init.d/ssh restart
Error: Starting OpenBSD Secure Shell server: sshd/var/run/sshd must be owned
by root and not group or world-writable.

原因是 /var/run/sshd/ 运行时环境目录出现权限所属问题,删除这个目录后重启 sshd 就可以了:

# rm -rf /var/run/sshd/
# invoke-rc.d ssh restart

Linux 上最常用的用户名和密码

如果打开 VPS 的 ssh 登录日志(/var/log/secure)就一定会发现有无数无聊的人无数次的试探 ssh 密码,对付这种 brute force 密码探测,用一个特殊字符、大小写字母加数字混合的无规律12位密码就能搞定,所以对安全很在意的用户不用太担心自己 VPS 被黑,用一个好密码就基本可以解决这类问题。VPSee 最近常遇到客户被自己 iptables 或错误的 sshd 配置锁在外面的事情,比如有客户用了很复杂的 ssh 配置文件,加上一些辅助工具比如 fail2ban, sshdfilter 等,并且用 iptables 来过滤,把一个很简单的事情搞得很复杂,结果不小心把自己锁在外面了。注重安全性是好的,太过就不必了,简单就好。安全是一大块,甚至是一个大的研究方向,非常复杂,需要综合考虑,真正容易出问题的地方在应用,比如 PHP 程序、WordPress 插件等,比如上次 “备份 WordPress 博客到 Dropbox” 的一个 WordPress 插件就有安全问题。所以应该多花精力在应用程序的安全性上,应用的安全性问题最多,黑客也多是从应用下手的。

Dragon Research Group 发布了一个 Linux/SSH 密码认证的报告, 统计了一些最常用的 Linux/SSH 用户名和密码,下图截取自 DRG SSH Username and Password Authentication Tag Clouds,看看有没有自己常用的密码,有的话赶快换吧。

most popular usernames

most popular passwords

如果对 ssh 还不放心的话可以采用下面几个简单做法来进一步增强 ssh 的安全性,不过要记住的是下面的技巧不能替代一个好的密码:

  • 修改和配置 DenyUsers, AllowUsers, DenyGroups, AllowGroups 只允许相关人员登录 ssh;
  • 生成 public/private key,修改 AuthorizedKeysFile,采用 ssh key 的方式登录 ssh;
  • 禁止 PasswordAuthentication no;
  • 禁止 root 直接登录,PermitRootLogin no;
  • 修改 ssh 的默认端口 22 为其他数字(比如 2012)。

Mac 通过代理服务器 ssh

在学校、公司大多时候都需要通过代理服务器上网,想在 Mac 下通过代理服务器 ssh 的话可以使用 Corkscrew 小工具。Corkscrew 也支持 Linux。

下载 corkscrew-2.0.tar.gz 后解压编译,然后拷贝编译生成的 corkscrew 到用户的主目录下的 .ssh 中:

$ tar zxvf corkscrew-2.0.tar.gz
$ cd corkscrew-2.0
$ ./configure --host=apple
$ make
$ cp corkscrew $HOME/.ssh/

打开 .ssh/config,增加以下几行:

$ vi .ssh/config

Host vpsee.com 67.203.229.22
ProxyCommand /Users/vpsee/.ssh/corkscrew proxy.server.address 3128 %h %p
TCPKeepAlive yes
ServerAliveInterval 5

注意:把上面的 vpsee.com 67.203.229.22 换成要 ssh 的服务器地址(可以有多个,可以是域名也可以是 IP 地址);把 proxy.server.address 3128 换成相应的代理服务器地址和端口号;TCPKeepAlive 用来与 ssh 服务器保持连接。

ssh 服务器为了安全考虑发现客户端长时间闲置的话会主动断开 ssh 连接,如果不想 ssh 自动断开,ssh 客户端需要打开 TCPKeepAlive 选项定时给服务器发 TCP 包来欺骗服务器,让 ssh 服务器感觉客户端还在 “活动” 中。同时 ssh 服务器端也需要打开 TCPKeepAlive 选项(也就是说,ssh 客户端配置和 ssh 服务器端配置都要打开 TCPKeepAlive):

# vi /etc/ssh/sshd_config

TCPKeepAlive yes