自动化检测工具之如何免密登录服务器

你好 我是懂java的测试

前言
前段时间开发了一款自动化检测工具,主要针对Swift集群新加入服务器进行对象存储基本功能、配置文件、服务器时间同步、Swift集群网络连通性等方面的验证。
工具开发的背景

Swift是什么?云计算OpenStack项目里关键的对象存储技术,也是公司云产品之一,目前线上50+台服务器集群,有时遇到业务高峰期,扩容至少10台服务器才能缓解,为了让这10台服务器融入到整个Swift服务集群中,每台服务器必须进行Swift组件安装、下发配置文件和网络连通性的检查。由于服务器较多,又加上手工肉眼检查服务器相关信息,难免会有遗漏之处,造成生产问题频发。

为了解决这么一个问题,我用Java语言、Testng框架等技术开发了一款线上自动化检测工具,主要针对新加入Swift集群的每个服务器,进行以下几个方面检测,

自动化检测工具之如何免密登录服务器_第1张图片

过程很曲折,收获却很多,目前已投入使用,既丰富了线上验证的内容,也提高了新服务器交付的效率。

近期打算用几篇文章详细聊聊开发这款工具遇到的问题和解决方案,希望对大家开发工具有所帮助,后期也会考虑开源这个工具源码。

怎么获取服务器相关的数据?
1到6项,自动化检测工具必须要先登录新交付服务器,获取相关的数据,才能进行检测,但是怎么登录呢?第一个方案是提前配置好待测服务器的账号、密码,使用ganymed-ssh2 jar包,登录服务器,代码如下:

public static Connection getConn(String ip, String userName, String pwd, int port) {

    Connection conn = new Connection(ip);
    boolean blag = true;
    try {
        conn.connect();
        blag = conn.authenticateWithPassword(userName, pwd);
        if (!blag) {

throw new IOException("Authentication failed.文件scp到数据服务器时发生异常");

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
   if (blag) {
      return conn;
    } else {
       return null;
    }
}

但是,让线上服务器的密码明文裸奔多少有点不讲究,要是被人拿到线上服务器的账号、密码,进行非法操作,必将是一场生产灾难,于是采用了第二种方案SSH免密登录。

SSH免密登录是什么?
SSH免密登录是什么意思?简单说两台服务器之间不输入密码,用ssh+对方的ip就能登录,这个就得详细聊一聊ssh登录的原理,一般服务器用户目录使用以下命令ssh-keygen -t rsa会生成几个文件。

id_rsa(私钥)
服务器上经过RSA算法生成的私钥。

id_rsa.pub(公钥)
服务器上经过RSA算法生成的公钥,和私钥是一对的密钥对,用于连接其他服务器用,例如:将主机名001的id_rsa.pub内容追加到主机名002的authorized_keys文件中,这样001主机就能用ssh 002的ip登录。

known_hosts
ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告, 避免你受到DNS Hijack之类的攻击

SSH远程连接是什么原理?

工具自动化登录服务器源码长啥样?
部分源码如下:host 是要登录服务器ip,userName要登录服务器的用户名
public static Session getSession(String host, String userName) throws JSchException {

    Session session = null;
    #privateKeyPath 本地私钥路径。
    String privateKeyPath ="~/.ssh/id_rsa";
    
    JSch jsch = new JSch();
    jsch.addIdentity(privateKeyPath);
    session = jsch.getSession(userName, host, 22);
    session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    session.connect();
    return session;
}

command :是登录服务器要执行的命令;

public static String printInfo(Session session, String command) throws IOException, JSchException {

    Channel channel = session.openChannel("exec");
    ((ChannelExec) channel).setPty(false);
    ((ChannelExec) channel).setCommand(command);
    channel.setInputStream(null);
    ((ChannelExec) channel).setErrStream(System.err);
    channel.connect();
    //打印成功信息
    InputStream in = channel.getInputStream();
    String result = "";
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String buf;
    while ((buf = reader.readLine()) != null) {
        result += new String(buf.getBytes(StandardCharsets.UTF_8)) + ",";
    }
    log.info("result" + result.length());
    channel.disconnect();
    log.info("返回的结果:" + result);
    if (result.length() <= 0) {
        return "";
    }
    return result.substring(0, result.length() - 1);
}

返回的result是命令执行的结果。

总结

本篇文章主要分享了SSH密码登录的原理、Java代码中自动登录服务器的两种方法,Python中paramiko库也可以远程操控服务器。

代码自动登录服务器,执行linux命令或上传、下载文件,可以在一些自动化场景中帮我们解决很多问题。

加我微信lvceshikaifa,免费面试辅导、学习资料、简历模板获取、加入学习群。

你可能感兴趣的:(后端java)