背景:最近,在配置VPN的时候,SSH老是连不上国外的服务器。估计可能是由于被“墙”了,同学说I p 被封了,可能等待一段时间就好了。可是,我哪知道,什么时候会把我的I P解封啊。正好最近在学习Script脚本,于是想写一个脚本,每天定时执行,连接成功了,就通知我。
思路:本次任务的总体思路分为两个小部分。第一个部分是通过expect语言,实现自动化交互,达到自动ssh连接服务器的目的。第二个部分是将上一个部分的结果记录下来并通过邮件传递出来。
下面将详细介绍这两部分。
ssh检测部分:
#!/usr/bin/expect
#传入三个参数:用户名、主机和密码
if { $argc < 3 } {
send_user "you should input 3 para: user host and password\r\n"
exit -1 #退出
}
send_user "about to connect to ssh...\r\n"
#设置一些参数
set timeout 30 #设置超时时间
set user [lindex $argv 0] #接收第一个传入的参数
set host [lindex $argv 1]
set passwd [lindex $argv 2]
spawn ssh ${user}@${host} #开启连接进程
#处理密码
expect {
"(yes/no)" { send "yes\r\n" ; exp_continue } #第一次连接会有接收公钥操作
"password" { send "${passwd}\r\n" } #传入密码
}
expect "\[ #\\\$ ]*" { send "pwd\r" } #等待命令提示符,传入执行pwd('[' 与'$'是特殊字符,需要根据语法进行转义)
expect "\[ #\\\$ ]*" {send "exit\r"} #等待命令提示符,传入执行exit
#判断等待超时操作,若超时则会返回127
expect {
timeout { exit 127 }
}
#expect eof
基本的说明,脚本中有注释。下面简要介绍几点需要注意的部分。
1、实现ssh免交互登陆主要有两种方式:
(1). SSH无密码认证方式 客户端使用ssh-keygen生成密钥对,将公钥复制到服务端(authorized_keys),SSH提供公钥登陆,当SSH访问服务端时,服务端先在本机寻找客户端的公钥,然后把客户端发来的公钥进行比较,如果一致,则用公钥加密给客户端,客户端再用私钥进行解密,实现加密所有传输的数据。
(2)、使用expect工具自动实现交互任务。expect是一个免费的免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。(所以本脚本执行前需要安装expect工具)。基本的expect使用语法网上很多教程,在此就不赘述了。
2、对于本脚本来说,需要将连接的结果返回给调用的上层脚本,在这里如果服务器连接不通的话将会超时退出,返回127;如果成功连接,将会返回成功0。
邮件提醒部分:
#!/bin/bash
#根据传入的信息,进行日志记录及邮件提醒操作
#this file should be used to send some information by email!
log_file="/home/ubuntu/logs/ssh_log.txt" #日志文件
if [ $# -ne 1 ] ; then #保证一个输入参数,代表上一条命令的执行结果
echo "you should input one parameters"
exit 1
else
if [ $1 -ne 0 ] ; then #connect failed
echo $(date)":ssh connect failed!" >> ${log_file} #连接失败,日志记录
else
echo $(date)":ssh connect successfully!" >> ${log_file}
echo $(date)":ssh connect successfully!" | mail -s ssh_info 767480266@qq.com #连接成功,日志记录。并通过进行邮件提醒
fi
fi
exit 0
这部分总体来说很简单,即根据ssh连接的结果做出不同的操作。如果连接不成功,则记录到日志文件中。如果连接成功,则记录在日志当中并且通过mail发送结果。
这里也需要注意几点:
1、在发送邮件的时候,利用的是mail工具。当然这里并没有用自己搭建的邮件服务器,使用的是新浪的邮件服务器。使用的时候需要安装mail工具,并进行简单的配置。具体的做法可以参考 ubuntu发送邮件
在主脚本里调用执行以上两个脚本即可。
主脚本如下:
#!/bin/bash
work_dir="/home/ubuntu/scripts/" #工作目录
cd ${work_dir}
if [ $# -ne 3 ] ; then #输入3个参数:用户名 主机名和密码
echo "you should input three parameters:user host and password "
exit 1 #退出
fi
echo "test ssh connection..."
expect check_ssh.sh $1 $2 $3#执行expect程序
echo "output test result"
#执行send_email程序,返回ssh连接信息
./send_email.sh $?
最后由于需要定时操作,所以需要使用linux系统的定时任务工具crontab。使用很简单,安装完这个工具之后,写上一条任务命令即可。
30 10 * * * bash /home/ubuntu/scripts/ssh_checked.sh <用户> <主机> <密码>
完整的代码可以从下载 代码下载
到此,整个任务就结束了。虽然很简单,但还是花了不少时间呢,也学到了不少东西,还是在任务中学习比较快呢。