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

168 阅读4分钟

你好 我是懂java的测试


前言

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

工具开发的背景

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

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

图片

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

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

怎么获取服务器相关的数据?

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命令或上传、下载文件,可以在一些自动化场景中帮我们解决很多问题。