1. 程式人生 > >sshkey批量分發,管理方案

sshkey批量分發,管理方案

批量 分發 批量管理 sshkey

title: ssh 批量分發
tags: sshkey,批量,分發
grammar_cjkRuby: true

sshkey批量分發,管理方案

1. 批量發簡述

linux運維工程師,每天都需要維護大量的主機,特別是互聯網公司的運維工程師,需要看大量的日誌,硬件狀態信息,服務狀態信息,有時候甚至要導入大量文件或者配置文件,這樣的話,如果你還一臺一臺登錄操的話,效率低下不用說,每天的工作往往是滿滿的負荷工作,而且是機械式的一臺一臺看。但是如果你了解熟悉ssh就不一樣了,ssh可以通過主機間的互信,來免密碼登錄,還可以利用腳本完成一些重要的工作。比如給各個主機分發hosts文件等等。

2. ssh 連接原理

技術分享圖片
ssh 建立連接方式有密碼登錄驗證和 密鑰登錄驗證,我們現在用的是密鑰登錄來讓主機之間添加互信關系。其中密鑰登錄的原理圖如上圖。

  1. 客戶端和服務端建立通道連接
  2. 客戶端向服務端發送公鑰(其中公鑰和私鑰都可以用ssh-keygen生成,默認生成一次就是一對,分別是公鑰和私鑰,私鑰是保存在客戶端,公鑰是保存在服務端,其中生成公鑰私鑰可以理解為去超市買一把鎖,默認都是有鎖有鑰匙,其中鎖給服務端,鑰匙自己留著,用來去服務端開鎖)
  3. 客戶端發送過來公鑰,服務端會檢查自有的known_hosts文件進行驗證,如果服務端發現這次訪問時第一次,它會提示客戶端,讓客戶端敲yes後,服務端會把客戶端的指紋信息寫在known_hosts,然後讓客戶端輸入服務端的密碼,如果客戶端輸正確了,服務端會把該公鑰放在自己的.ssh目錄中
  4. 客戶端帶著私鑰過來要求連接服務端
  5. 服務端用公鑰質詢加密發給客戶端
  6. 客戶端拿配套的私鑰進行解密後的質詢發送回服務端
  7. 驗證通過,雙方建立連接,客戶端終於連接上了服務端

    3. scp工具解析

  8. scp命令和cp命令很像,cp是本地拷貝,scp是加密的遠程拷貝,參數的區別是,-p 是保持屬性,-P是端口號。
  9. scp可以把數據從一臺機器推送到另一臺機器,也可以從其他服務器把數據拉回本地。
  10. scp和rsync的區別是,scp不支持增量拷貝,且沒有daemon模式,每一次都是全量拷貝,效率低,適合第一用,如果是增量備份還是推薦使用rsync。舉例如下:
    推
    [root@server ~]# scp -r -p -P22  GNU-Linux-x86/  [email protected]:/tmp
    [email protected]‘s password: 
    confxml.xml                                    100% 2214     2.2KB/s   00:00    
    拉
    [root@server ~]# scp -p -P22 [email protected]:/tmp/rsync_fail_log.sh ~/
    [email protected]‘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.
[email protected]‘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 [email protected]" 
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.
[email protected]‘s password: 
Now try logging into the machine, with "ssh ‘-P22 [email protected]‘", and check in:

  .ssh/authorized_keys

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

5. 文件分發實例講解

利用ssh互信,我們可以讓主機之間免密碼登錄,發送文件給對方,這樣我們就可以通過腳本做很多事情了如下列實例:
技術分享圖片
如圖:存儲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
    ##############################################################
    # 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 [email protected].$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) [email protected].$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
    ##############################################################
    # 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) [email protected].$n:~/ &>/dev/null  &&ssh [email protected].$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
    ##############################################################
    # 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) [email protected].$n:~/ &>/dev/null  &&ssh -t [email protected].$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才是中小企業最基本實用的批量分發,管理方案。

sshkey批量分發,管理方案