Linux命令ssh-copy-id

jeanron100發表於2016-09-13
    在N多年前,搭建Oracle RAC環境的時候,其中有一項非常艱鉅的任務就是配置節點伺服器的互信關係,每次到了這個部分的時候就有點暈,因為檔案需要在兩個節點間拷過來,拷過去。每次到了這個部分,就需要開啟我的攻略筆記,然後嚴格按照上面的步驟來完成。到了OCM考試的時候,當時Oracle是提供了一個建立互信關係的指令碼,直接執行即可。搭建的過程省事不少。到了11g的RAC搭建中,在檢查項中有一個就是建立互信關係,只需要在介面上點選即可完成。可見互信關係的建立過程是越來越簡化了。
    當然回到工作環境中,如果兩臺伺服器需要建立互信關係,那麼需要做的就是複製秘鑰資訊,這個工作就得手工來完成,有時候感覺真是麻煩,但是又無可奈何。
一般建立單向信任關係的步驟如下:
    1)檢查是否有秘鑰生成,如果沒有則使用ssh-keygen -t rsa來生成即可。
    2)複製id_rsa.pub的資訊,稍後使用。
    3)  ssh連線到目標伺服器,然後到.ssh/authorized_keys檔案中新增複製的id_rsa.pub的內容即可
    4)退出當前視窗,重新登入驗證,是否可以無密碼通訊
最近還是看《Linux大棚》裡面有講到ssh-copy-id這個神器,看完之後有一種全然一新的感覺,感覺我們之前的處理似乎還是有些老套了。ssh-copy-id可以直接執行這一個命令即可完成上面的步驟,所以這個命令確實是個好東西,難得的是這個命令本身是個shell指令碼,所以索性拿來學學。
指令碼的內容如下:

點選(此處)摺疊或開啟

  1. #!/bin/sh

  2. # Shell script to install your public key on a remote machine
  3. # Takes the remote machine name as an argument.
  4. # Obviously, the remote machine must accept password authentication,
  5. # or one of the other keys in your ssh-agent, for this to work.

  6. ID_FILE="${HOME}/.ssh/id_rsa.pub"

  7. if [ "-i" = "$1" ]; then
  8.   shift
  9.   # check if we have 2 parameters left, if so the first is the new ID file
  10.   if [ -n "$2" ]; then
  11.     if expr "$1" : ".*\.pub" > /dev/null ; then
  12.       ID_FILE="$1"
  13.     else
  14.       ID_FILE="$1.pub"
  15.     fi
  16.     shift # and this should leave $1 as the target name
  17.   fi
  18. else
  19.   if [ x$SSH_AUTH_SOCK != x ] ; then
  20.     GET_ID="$GET_ID ssh-add -L"
  21.   fi
  22. fi

  23. if [ -z "`eval $GET_ID`" ] && [ -r "${ID_FILE}" ] ; then
  24.   GET_ID="cat ${ID_FILE}"
  25. fi

  26. if [ -z "`eval $GET_ID`" ]; then
  27.   echo "$0: ERROR: No identities found" >&2
  28.   exit 1
  29. fi

  30. if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
  31.   echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2
  32.   exit 1
  33. fi

  34. { eval "$GET_ID" ; } | ssh $1 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)" || exit 1

  35. cat <<EOF
  36. Now try logging into the machine, with "ssh '$1'", and check in:

  37.   .ssh/authorized_keys

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

  39. EOF
其實看完之後,發現裡面確實有不少的內容,命令格式,新的命令都值得學習。
shift是個蠻有意思的命令,可以在不知道位置變數個數的情況下,還能逐個把引數一一處理。
restorecon命令用來恢復SELinux檔案屬性即恢復檔案的安全上下文。

來自:

restorecon命令用來恢復SELinux檔案屬性即恢復檔案的安全上下文。

來自:
restorecon命令用來恢復SELinux檔案屬性即恢復檔案的安全上下文。

來自:
restorecon命令用來恢復SELinux檔案屬性即恢復檔案的安全上下文。
整個指令碼中花了大篇幅來處理輸入引數,可以手工指定秘鑰檔案,還有副檔名補全的功能。比如呼叫指令碼的方式如下:
ssh-copy-id -i aaa  test@test.com
這種情況下,指令碼會把aaa自動補全副檔名,指令碼就會查詢aaa.pub的秘鑰檔案。
裡面最核心的是下面的一句,執行後會提示輸入密碼。
$ { eval "$GET_ID" ; } |  ssh 10.127.133.125 "umask 077;test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)" || exit 1
oracle@10.127.133.125's password:
可以看到整個指令碼有很多需要考慮的細節,值得玩味。
當然大道至簡,這個指令碼的本質就是傳輸id_rsa.pub並不會自動幫你去生成id_rsa.pub,最核心的功能就是把秘鑰資訊寫入.ssh/authorized_keys中。
所以整個過程的簡化版思路就是下面的一個類似的命令形式。
$ echo "aaaaa"|ssh 10.127.133.125 "cat"
oracle@10.127.133.125's password:
aaaaa
echo "aaaaa"會輸出秘鑰資訊,然後透過管道作為ssh到目標端的引數值呼叫
所以這個過程也完全可以自己定義命令來完成。
明白了這些,很多工具就會脫離開神聖的外衣,而對於我們來說,明白了核心的部分,就需要學習哪些場景沒有考慮周到,不斷去補充,不斷完善。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2124939/,如需轉載,請註明出處,否則將追究法律責任。

相關文章