sshkey批量分发,管理方案

Easter79
• 阅读 659

sshkey批量分发,管理方案

批量分发 sshkey scp 公钥 私钥 -

现在很多人批量分发都看不起sshkey,他们大都采用puppet和saltstack,诚然puppet和saltstack必然是更加专业而且更加强大,但是配置起来比起sshkey的方案难太多了,如果要简单,易用,高效,毕竟ssh key才是中小企业最基本实用的批量分发,管理方案。

    • sshkey批量分发,管理方案
      • 1. 批量发简述
      • 2. ssh 连接原理
      • 3. scp工具解析
      • 4. 密钥生成与分发
      • 5. 文件分发实例讲解
      • 6. 批量分发小结

sshkey批量分发,管理方案

1. 批量发简述

linux运维工程师,每天都需要维护大量的主机,特别是互联网公司的运维工程师,需要看大量的日志,硬件状态信息,服务状态信息,有时候甚至要导入大量文件或者配置文件,这样的话,如果你还一台一台登录操的话,效率低下不用说,每天的工作往往是满满的负荷工作,而且是机械式的一台一台看。但是如果你了解熟悉ssh就不一样了,ssh可以通过主机间的互信,来免密码登录,还可以利用脚本完成一些重要的工作。比如给各个主机分发hosts文件等等。

2. ssh 连接原理

sshkey批量分发,管理方案

ssh的连接原理

ssh 建立连接方式有密码登录验证和 密钥登录验证,我们现在用的是密钥登录来让主机之间添加互信关系。其中密钥登录的原理图如上图。

  1. 客户端和服务端建立通道连接
  2. 客户端向服务端发送公钥(其中公钥和私钥都可以用ssh-keygen生成,默认生成一次就是一对,分别是公钥和私钥,私钥是保存在客户端,公钥是保存在服务端,其中生成公钥私钥可以理解为去超市买一把锁,默认都是有锁有钥匙,其中锁给服务端,钥匙自己留着,用来去服务端开锁)
  3. 客户端发送过来公钥,服务端会检查自有的known_hosts文件进行验证,如果服务端发现这次访问时第一次,它会提示客户端,让客户端敲yes后,服务端会把客户端的指纹信息写在known_hosts,然后让客户端输入服务端的密码,如果客户端输正确了,服务端会把该公钥放在自己的.ssh目录中
  4. 客户端带着私钥过来要求连接服务端
  5. 服务端用公钥质询加密发给客户端
  6. 客户端拿配套的私钥进行解密后的质询发送回服务端
  7. 验证通过,双方建立连接,客户端终于连接上了服务端

3. scp工具解析

  1. scp命令和cp命令很像,cp是本地拷贝,scp是加密的远程拷贝,参数的区别是,-p 是保持属性,-P是端口号。

  2. scp可以把数据从一台机器推送到另一台机器,也可以从其他服务器把数据拉回本地。

  3. scp和rsync的区别是,scp不支持增量拷贝,且没有daemon模式,每一次都是全量拷贝,效率低,适合第一用,如果是增量备份还是推荐使用rsync。举例如下:

    推 [root@server ~]# scp -r -p -P22 GNU-Linux-x86/ root@192.168.50.4:/tmp root@192.168.50.4's password: confxml.xml 100% 2214 2.2KB/s 00:00
    拉 [root@server ~]# scp -p -P22 root@192.168.50.4:/tmp/rsync_fail_log.sh ~/ root@192.168.50.4's password: rsync_fail_log.sh 100% 0 0.0KB/s 00:00
    [root@server ~]# ls |grep rsync_fail_log.sh rsync_fail_log.sh

4. 密钥生成与分发

密钥生成就是一对,分为公钥和私钥,公钥为锁,私钥为钥匙,所以一定要清楚,是钥匙开锁,而不是锁开钥匙。因此私钥自己留着,公钥是发给对方,然后我们可以拿着私钥去登录对方(打开对方的门)。锁的定义很形象,生成密钥可以想象中是去超市买锁,因此只要有ssh-keygen这个工具都是可以生成密钥,密钥是不限主机的,只要分清,私钥自己拿着,公钥给别人。我们一般使用dsa的密钥对,生成密钥的步骤如下:

[root@server .ssh]# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
b8:42:03:c2:9d:ee:bf:10:83:6c:44:a5:1f:c8:39:80 root@server
The key's randomart image is:
+--[ DSA 1024]----+
|o...             |
|E = .            |
|.O.+             |
|o.=..  .         |
| + =o . S        |
|. ..o. .         |
|   o. .          |
|    o.           |
|     o.          |
+-----------------+
[root@server .ssh]# ls -a
.  ..  id_dsa  id_dsa.pub
[root@server .ssh]# ls -l
total 8
-rw-------. 1 root root 668 May 23 01:30 id_dsa
生成密钥我们用ssh-keygen,分配公钥给对方我们使用ssh-copy-id ,
[root@server .ssh]# ssh-copy-id -i 192.168.50.4
/usr/bin/ssh-copy-id: ERROR: No identities found
[root@server .ssh]# ssh-copy-id -i id_dsa.pub 192.168.50.4 
The authenticity of host '192.168.50.4 (192.168.50.4)' can't be established.
RSA key fingerprint is 41:8a:f8:19:54:e2:e1:fa:eb:9e:3a:22:d2:1f:08:00.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.50.4' (RSA) to the list of known hosts.
root@192.168.50.4's password: 
Now try logging into the machine, with "ssh '192.168.50.4'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[root@server .ssh]# 
如果对方的ssh端口号改了,不是默认端口则我们也要改
[root@server .ssh]# ssh-copy-id -i id_dsa.pub "-P22 root@192.168.50.3" 
The authenticity of host '192.168.50.3 (192.168.50.3)' can't be established.
RSA key fingerprint is 41:8a:f8:19:54:e2:e1:fa:eb:9e:3a:22:d2:1f:08:00.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.50.3' (RSA) to the list of known hosts.
root@192.168.50.3's password: 
Now try logging into the machine, with "ssh '-P22 root@192.168.50.3'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting

5. 文件分发实例讲解

利用ssh互信,我们可以让主机之间免密码登录,发送文件给对方,这样我们就可以通过脚本做很多事情了如下列实例:

sshkey批量分发,管理方案

批量分发实例

如图:存储C作为核心中的分发机,因为图中架构所有设备都处于内网内,为了提高各个主机的互访能力,因此/etc/hosts文件都对各个服务器的主机名和ip有解析。因此各个主机的hosts文件是保持一致的,现在要求以分发机的hosts文件为准,分发机C将最新的hosts文件定时分发到各主机,覆盖原来的hosts文件,这样让所有主机都可以及时更新到最新的hosts文件,这样如果hosts文件有更新的话就只要改一下分发机的hosts文件即可。分析解答如下:

  1. 我们可以通过脚本利用ssh互信免密码,将主机的hosts文件通过scp推送到各个主机,但是存在一个问题,/etc目录必须要root权限才能放进去,因此必须选择root互信才能完成需求。这样可以直接推送到/etc/下完成覆盖。

    [root@NFSserver-C .ssh]# ssh-keygen -t dsa Generating public/private dsa key pair. [root@NFSserver-C .ssh]# ls id_dsa id_dsa.pub [root@NFSserver-C .ssh]# ssh-copy-id -i id_dsa.pub "-P22 192.168.50.2" The authenticity of host '192.168.50.2 (192.168.50.2)' can't be established. [root@NFSserver-C .ssh]# ssh-copy-id -i id_dsa.pub "-P22 192.168.50.3" The authenticity of host '192.168.50.3 (192.168.50.3)' can't be established. [root@NFSserver-C .ssh]# ssh-copy-id -i id_dsa.pub "-P22 192.168.50.4" The authenticity of host '192.168.50.4 (192.168.50.4)' can't be established 确认是不是互信成功 [root@NFSserver-C .ssh]# vim /service/scripts/check-ssh.sh #!/usr/bin/env bash for n in 2 3 4 do echo "This is 192.168.50.$n" ssh root@192.168.50.$n hostname done
    [root@NFSserver-C .ssh]# sh /service/scripts/check-ssh.sh This is 192.168.50.2 MYSQL-B This is 192.168.50.3 LAMP-A1 This is 192.168.50.4 backup-D 写个简单的批发脚本,执行成功后写入crontab里,默认每30分钟执行一次分发。 [root@NFSserver-C .ssh]# vim /service/scripts/fengfa1.sh
    #!/usr/bin/env bash . /etc/init.d/functions FILE=$1 REMOUTEDIR=$2 if [ $# -ne 2 ] then echo "WARNINT: $0: LOCAL FILE AND REMOUTE DIR " exit 1; fi for n in 2 3 4 do cp -r $FILE /fengfa/ &&\ scp /fengfa/$(basename $FILE) root@192.168.50.$n:$REMOUTEDIR >/dev/null if [ $? -eq 0 ] then action "192.168.50.$n fengfa $1 is OK" true else action "192.168.50.$n fengfa $1 is fail" false fi done 执行测试脚本,先在分发机上/etc/hosts文件上改动,然后执行脚本,再看每台被分发机上是否有覆盖。 [root@NFSserver-C .ssh]# echo "# test fengfa is ok" >>/etc/hosts [root@NFSserver-C .ssh]# sh /service/scripts/fengfa1.sh /etc/hosts /etc 192.168.50.2 fengfa /etc/hosts is OK [ OK ] 192.168.50.3 fengfa /etc/hosts is OK [ OK ] 192.168.50.4 fengfa /etc/hosts is OK [ OK ] [root@MYSQL-B ~]# tail -1 /etc/hosts

    test fengfa is ok

    [root@LAMP-A1 .ssh]# tail -1 /etc/hosts

    test fengfa is ok

    [root@backup-D ~]# tail -1 /etc/hosts

    test fengfa is ok

    在分发机上的cron文件写入,每三十分钟执行一次 [root@NFSserver-C ~]# echo "*/30 * * * * sh /service/scripts/fengfa1.sh /etc/hosts /etc " >>/var/spool/cron/root [root@NFSserver-C ~]# crontab -l |grep "/etc/hosts" */30 * * * * sh /service/scripts/fengfa1.sh /etc/hosts /etc

  2. 方法1中存在安全隐患问题,如果分发机和各个主机都是root互信的话,那么分发机就拥有所有主机的root权限,那么分发机可以随时百分百的控制各个主机,这样稍有不慎就会酿成大错,非常的不安全。我们可以在选择用普通用户做互信,先将hosts文件发送到该用户的家目录,然后给rsync添加SUID权限,然后让该用户用rsync将hosts文件在推送到本地的/etc

    [root@backup-D ]# chmod u+s /usr/bin/rsync [root@backup-D ~]# ls -l which rsync
    -rwsr-xr-t. 1 root root 410536 Apr 30 2014 /usr/bin/rsync [root@LAMP-A1 ~]# chmod u+s /usr/bin/rsync [root@LAMP-A1 ~]# ls -l which rsync -rwsr-xr-x. 1 root root 410536 Apr 30 2014 /usr/bin/rsync [root@MYSQL-B ~]# chmod u+s /usr/bin/rsync [root@MYSQL-B ~]# ls -l which rsync -rwsr-xr-x. 1 root root 410536 Apr 30 2014 /usr/bin/rsync 我们把分发脚本稍微改一下,重新命名fengfa2.sh [test@NFSserver-C ~]$ vim /service/scripts/fengfa2.sh
    #!/usr/bin/env bash . /etc/init.d/functions FILE=$1 REMOUTEDIR=$2 if [ $# -ne 2 ] then echo "WARNINT: $0: LOCAL FILE AND REMOUTE DIR " exit 1; fi for n in 2 3 4 do cp -r $FILE /fengfa/ &&
    scp /fengfa/$(basename $FILE) test@192.168.50.$n:
    / &>/dev/null &&
    ssh test@192.168.50.$n "rsync ~/$(basename $FILE) $REMOUTEDIR" &>/dev/null if [ $? -eq 0 ] then action "192.168.50.$n fengfa $1 is OK" true else action "192.168.50.$n fengfa $1 is fail" false fi done 再次进行测试发现: [test@NFSserver-C ~]$ sh /service/scripts/fengfa2.sh /etc/hosts /etc 192.168.50.2 fengfa /etc/hosts is OK [ OK ] 192.168.50.3 fengfa /etc/hosts is OK [ OK ] 192.168.50.4 fengfa /etc/hosts is OK [ OK ]

  3. 当然方法二也不安全,把rsync的权限设置为SUID的话,那么任何用户执行rsync都可以像root执行rsync一样,那安全隐患也很大,我们继续限制让只有test用户才可以执行rsync,其他的普通用户依然不能执行rsync,这样安全性减少很多。因此我们利用sudo,在每个客户端上将rsync设置为test用户可以执行,如:

    [root@backup-D ]# chmod u-s which rsync [root@backup-D ~]# echo "test ALL=(ALL) NOPASSWD: /usr/bin/rsync" >>/etc/sudoers [root@backup-D ~]# tail -1 /etc/sudoers test ALL=(ALL) NOPASSWD: /usr/bin/rsync [root@backup-D ~]# visudo -c /etc/sudoers: parsed OK [root@LAMP-A1 ~]# chmod u-s which rsync [root@LAMP-A1 ~]# echo "test ALL=(ALL) NOPASSWD: /usr/bin/rsync" >>/etc/sudoers [root@LAMP-A1 ~]# tail -1 /etc/sudoers test ALL=(ALL) NOPASSWD: /usr/bin/rsync [root@LAMP-A1 ~]# visudo -c /etc/sudoers: parsed OK [root@MYSQL-B ~]# chmod u-s which rsync [root@MYSQL-B ~]# echo "test ALL=(ALL) NOPASSWD: /usr/bin/rsync" >>/etc/sudoers [root@MYSQL-B ~]# chmod u-s which rsync [root@MYSQL-B ~]# tail -1 /etc/sudoers test ALL=(ALL) NOPASSWD: /usr/bin/rsync [root@MYSQL-B ~]# visudo -c /etc/sudoers: parsed OK 分发脚本稍微改一下,重新命名fengfa23.sh [test@NFSserver-C ~]$ vim /service/scripts/fengfa3.sh #!/usr/bin/env bash . /etc/init.d/functions FILE=$1 REMOUTEDIR=$2 if [ $# -ne 2 ] then echo "WARNINT: $0: LOCAL FILE AND REMOUTE DIR " exit 1; fi for n in 2 3 4 do cp -r $FILE /fengfa/ &&
    scp /fengfa/$(basename $FILE) test@192.168.50.$n:
    / &>/dev/null &&
    ssh -t test@192.168.50.$n "sudo rsync ~/$(basename $FILE) /etc/" &>/dev/null if [ $? -eq 0 ] then action "192.168.50.$n fengfa $1 is OK" true else action "192.168.50.$n fengfa $1 is fail" false fi done [test@NFSserver-C ~]$ sh /service/scripts/fengfa3.sh /etc/hosts /etc 192.168.50.2 fengfa /etc/hosts is OK [ OK ] 192.168.50.3 fengfa /etc/hosts is OK [ OK ] 192.168.50.4 fengfa /etc/hosts is OK [ OK ]

6. 批量分发小结

其实现在很多人批量分发都看不起sshkey,他们大都采用puppet和saltstack,诚然puppet和saltstack必然是更加专业而且更加强大,但是配置起来比起sshkey的方案难太多了,根据linux的基本原则,如果简单易用的方法可以解决需求,那请尽量选择简单易用的方案,如果不满足需求才考虑其他更优的方案,因为我们的运维法则是简单,易用,高效,毕竟ssh key才是中小企业最基本实用的批量分发,管理方案。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k