首頁 > 軟體

Linux命令ssh-copy-id

2020-06-16 17:31:55

在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)退出當前視窗,重新登入驗證,是否可以無密碼通訊

最近還是看到ssh-copy-id這個神器,看完之後有一種全然一新的感覺,感覺我們之前的處理似乎還是有些老套了。ssh-copy-id可以直接執行這一個命令即可完成上面的步驟,所以這個命令確實是個好東西,難得的是這個命令本身是個shell指令碼,所以索性拿來學學。

指令碼的內容如下:

#!/bin/sh

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

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

if [ "-i" = "$1" ]; then
  shift
  # check if we have 2 parameters left, if so the first is the new ID file
  if [ -n "$2" ]; then
    if expr "$1" : ".*.pub" > /dev/null ; then
      ID_FILE="$1"
    else
      ID_FILE="$1.pub"
    fi
    shift # and this should leave $1 as the target name
  fi
else
  if [ x$SSH_AUTH_SOCK != x ] ; then
    GET_ID="$GET_ID ssh-add -L"
  fi
fi

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

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

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

{ 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

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

  .ssh/authorized_keys

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

EOF

其實看完之後,發現裡面確實有不少的內容,命令格式,新的命令都值得學習。

shift是個蠻有意思的命令,可以在不知道位置變數個數的情況下,還能逐個把引數一一處理。
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到目標端的引數值呼叫
 所以這個過程也完全可以自己定義命令來完成。
 明白了這些,很多工具就會脫離開神聖的外衣,而對於我們來說,明白了核心的部分,就需要學習哪些場景沒有考慮周到,不斷去補充,不斷完善。

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-09/135532.htm


IT145.com E-mail:sddin#qq.com