Python Tech

ssh连接并获取服务器信息

Perface

SSH(Secure Shell)是一种安全协议,运作于应用层和传输层,特点是对传输数据进行加密(FTP、Telnet是明文传输),有效防止信息泄露问题,而且传输的数据是经过压缩的,可以加快传输的速度。最初的SSH协议由一家芬兰公司开发,现在多使用OpenBSD 计划组提供的OpenSSH。

在Linux下通常使用SSH都是基于密钥的连接:本机提供用户名、密码连接远程服务器,并申请用密匙进行安全验证。服务器收到请求之后,先根据连接时提供的用户名,在服务器的用户根目录下寻找公有密匙,然后把它和本机存储的公有密匙进行比较。如果两个密匙一致,服务器就用公有密匙加密信息(Challenge)并把它发送给客户端软件。本文介绍用Python的paramiko模块进行ssh操作,通过默认模式和pystatgrab模块返回服务器信息的步骤。

Install

在Python中使用SSH,最简单的方法是使用paramiko模块,paramiko支持Python2.2以上版本,在RedHat,CentOs,Ubuntu都可以直接通过安装源安装。

#Redhat\CentOS
yum -y install python-paramiko
#ubuntu
sudo apt-get install python-paramiko


或者直接下载压缩包进行安装:

#Sourceforge上是1.7.6版,官方的是1.7.4
wget http://www.lag.net/paramiko/download/paramiko-1.7.4.tar.gz
cd paramiko-1.7.4
python setup.py install

windows可能会提示ImportError:No module named Crypto.Util.randpool,通常需要先安装pycrypto。找到对应的版本,下载后运行exe文件,选择Python路径安装即可。

windows下运行setup.py时,要先把目录切换到当前目录下,比如把paramiko解压在C盘,就必须在C:\paramiko目录下执行setup.py install,否则会提示’paramiko\__init__.py’ not found

Use

首先导入paramiko模块,可能会提示:

RandomPool_DeprecationWarning: This application uses RandomPool, which is BROKEN in older releases. See http://www.pycrypto.org/randpool-broken

就是警告这个应用会使用随机数池(RandomPool),在较低的发行版中不支持这一功能,这个提示不会影响正常的使用。以下操作都在Python解释器中完成:

>>> import paramiko
>>> client = paramiko.SSHClient()
>>> client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> client.load_system_host_keys()
>>> cilent.connect(‘服务器地址’,port=22,username=’登录用户名’,password=’登录密码’)
>>> output = client.exec_command(‘ls’)

如果找不到密钥,通常会提示:paramiko.SSHException: Unknown server 服务器地址。在每次成功进行SSH连接服务器之后,系统都会将密钥保存到本地。但如果是首次连接,或者是在windows系统下,就无法使用client.load_system_host_keys() 来读取密钥,所以需要client.set_missing_host_key_policy(paramiko.AutoAddPolicy())自动添加并保存密钥。
这样就连接到远程服务器了。每执行一个命令(比如上文的ls命令),会打开一个新的通道(Channel),命令输出的结果会被发送到一个多元组(Tuple)中,这个多元组有3个对象,这三个对象的类型都是file,分别是stdinstdoutstderr。上文输入的命令(ls)是正确的,所以我们只用关注他的命令输出,也就是这个多元组的第二个对象,这个:

>>> output[1].read()
‘apache.py\nsystem.py\n’

输出了目录下的文件,ls命令执行成功。

Proc

在linux根目录下有个名为proc的文件夹,和其他文件夹不同,它只存在于内存中,以文件系统的方式为访问系统内核数据的操作提供接口。除了以PID命令的文件夹(都是数字)以外,还有一些用来存储系统信息的文件,只要读取这些文件,就可以获得一些简单的信息了:

>>> meminfo = client.exec_command(‘cat /proc/meminfo’)
>>> meminfo[1].read()
MemTotal: 2060100 kB
MemFree: 67332 kB
Buffers: 50836 kB
Cached: 732768 kB
SwapCached: 1620 kB
….more

显示的各项依次表示:

  • MemTotal: 内存总量
  • MemFree: 系统保留未使用的内容,LowFree+HighFree的总和(这个暂时没研究清楚)
  • Buffers: 磁盘缓存大小
  • Cached: 高速缓存使用的内存部分 twiddling thumbs
  • SwapCached: 高速缓存用于Swap的部分

同理,只要利用ssh执行相应的命令(比如top),通过输出的内容就可以获得服务器信息了。

pystatgrab

上面的方法虽然可以获得系统信息,但是用的是linux自带的方法,本文主要关注的是Python,所以还是要提一下用Python中的模块来获取系统信息的方法。

libstatgrab是一个提供平台统计信息的库,用C语言编写,可以统计CPU、内存、磁盘、进程、网络的数据。pystatgrab是一个绑定libstatgrab的模块,使用它可以直接调用libstatgrab获得系统信息。

首先在服务器上安装libstatgrab,然后下载pystatgrab并安装:

#Redhat\CentOS
yum -y install libstatgrab-dev
#ubuntu
sudo apt-get install libstatgrab-dev
wget http://ftp.uk.i-scream.org/sites/ftp.i-scream.org/pub/i-scream/pystatgrab/pystatgrab-0.5.tar.gz
cd pystatgrab-0.5/
python setup.py install

运行Python解释器:

>>> import statgrab
>>> statgrab.sg_get_cpu_stats()
{‘kernel’: 994006L, ‘iowait’: 0L, ‘user’: 780906L, ‘idle’: 4028311L, ‘swap’: 0L, ‘systime’: 1290677515, ‘total’: 6277335L, ‘nice’: 474112L}
>>> statgrab.sg_get_mem_stats()
{‘cache’: 468209664L, ‘total’: 2109542400L, ‘free’: 55771136L, ‘used’: 2053771264L}
>>>

使用sg_get_cpu_stats()和statgrab.sg_get_mem_stats()两个方法,分别获得CPU和内存的信息。statgrab常用方法如下:

  • sg_get_cpu_stats():返回操作系统的ticks总数
  • sg_get_disk_io_stats():返回磁盘IO总数
  • sg_get_fs_stats():返回内存使用状况,在FreeBSD下需要root权限才能返回swap的值
  • sg_get_host_info():返回系统信息,包括设备名,内核版本等
  • sg_get_mem_stats():返回内存使用状况,在FreeBSD下需要root权限才能返回swap的值
  • sg_get_network_iface_stats(parama):返回某个网络接口的信息
  • sg_get_network_io_stats():

最终在服务器上安装了pystatgrab,然后通过paramiko连接到服务器上,再执行一个Python脚本,获得服务器信息。

Leave a Reply

Your email address will not be published. Required fields are marked *