linux运维工程师,每天都需要维护大量的主机,特别是互联网公司的运维工程师,需要看大量的日志,硬件状态信息,服务状态信息,有时候甚至要导入大量文件或者配置文件,这样的话,如果你还一台一台登录操的话,效率低下不用说,每天的工作往往是满满的负荷工作,而且是机械式的一台一台看。但是如果你了解熟悉ssh就不一样了,ssh可以通过主机间的互信,来免密码登录,还可以利用脚本完成一些重要的工作。比如给各个主机分发hosts文件等等。
ssh 建立连接方式有密码登录验证和 密钥登录验证,我们现在用的是密钥登录来让主机之间添加互信关系。其中密钥登录的原理图如上图。
推
[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
密钥生成就是一对,分为公钥和私钥,公钥为锁,私钥为钥匙,所以一定要清楚,是钥匙开锁,而不是锁开钥匙。因此私钥自己留着,公钥是发给对方,然后我们可以拿着私钥去登录对方(打开对方的门)。锁的定义很形象,生成密钥可以想象中是去超市买锁,因此只要有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
利用ssh互信,我们可以让主机之间免密码登录,发送文件给对方,这样我们就可以通过脚本做很多事情了如下列实例:
如图:存储C作为核心中的分发机,因为图中架构所有设备都处于内网内,为了提高各个主机的互访能力,因此/etc/hosts文件都对各个服务器的主机名和ip有解析。因此各个主机的hosts文件是保持一致的,现在要求以分发机的hosts文件为准,分发机C将最新的hosts文件定时分发到各主机,覆盖原来的hosts文件,这样让所有主机都可以及时更新到最新的hosts文件,这样如果hosts文件有更新的话就只要改一下分发机的hosts文件即可。分析解答如下:
我们可以通过脚本利用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
##############################################################
# File Name: /service/scripts/check-ssh.sh
# Version: V1.0
# Author: OuYoung
# Blog: http://blog.51cto.com/ouyangtao
# Created Time : 2018-05-23 12:49:19
# Description:
##############################################################
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
##############################################################
# File Name: /service/scripts/fengfa1.sh
# Version: V1.0
# Author: OuYoung
# Blog: http://blog.51cto.com/ouyangtao
# Created Time : 2018-05-23 13:18:25
# Description:
##############################################################
. /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
[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
##############################################################
# File Name: /service/scripts/fengfa1.sh
# Version: V1.0
# Author: OuYoung
# Blog: http://blog.51cto.com/ouyangtao
# Created Time : 2018-05-23 13:18:25
# Description:
##############################################################
. /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 ]
[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
##############################################################
# File Name: /service/scripts/fengfa1.sh
# Version: V1.0
# Author: OuYoung
# Blog: http://blog.51cto.com/ouyangtao
# Created Time : 2018-05-23 13:18:25
# Description:
##############################################################
. /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 ]
其实现在很多人批量分发都看不起sshkey,他们大都采用puppet和saltstack,诚然puppet和saltstack必然是更加专业而且更加强大,但是配置起来比起sshkey的方案难太多了,根据linux的基本原则,如果简单易用的方法可以解决需求,那请尽量选择简单易用的方案,如果不满足需求才考虑其他更优的方案,因为我们的运维法则是简单,易用,高效,毕竟ssh key才是中小企业最基本实用的批量分发,管理方案。
原文地址:http://blog.51cto.com/ouyangtao/2123158