Linux系統root用戶無密碼訪問腳本(ssh)

半年前寫的腳本,等有時間就加注釋(滑稽)

前言

腳本無非就是寫給電腦的記事本,記事本上告訴電腦你要干什么(買二斤白菜,一斤豬肉,倆饅頭·······),所以在寫腳本前要清楚自己要做什么,才能給計算機描述清楚,前端后端皆是如此。

手動實現無密碼訪問

先手動的方式來實現無密碼訪問,再去研究如何寫腳本。

SSH驗證:從客戶端來看,SSH提供兩種級別的安全驗證。

第一種級別(基于口令的安全驗證)

只要你知道自己帳號和口令,就可以登錄到遠程主機。所有傳輸的數據都會被加密,但是不能保證你正在連接的服務器就是你想連接的服務器??赡軙袆e的服務器在冒充真正的服務器,也就是受到“中間人”這種方式的攻擊。

第二種級別(基于密匙的安全驗證)

需要依靠密匙,也就是你必須為自己創建一對密匙,并把公用密匙放在需要訪問的服務器上。如果你要連接到SSH服務器上,客戶端軟件就會向服務器發出請求,請求用你的密匙進行安全驗證。服務器收到請求之后,先在該服務器上你的主目錄下尋找你的公用密匙,然后把它和你發送過來的公用密匙進行比較。如果兩個密匙一致,服務器就用公用密匙加密“質詢”(challenge)并把它發送給客戶端軟件??蛻舳塑浖盏健百|詢”之后就可以用你的私人密匙解密再把它發送給服務器。

用這種方式,你必須知道自己密匙的口令。但是,與第一種級別相比,第二種級別不需要在網絡上傳送口令。

說白了一種場景是:

  • 服務器A: 密碼是什么
  • 服務器B:******

一種場景是:

  • 服務器A:天王蓋地虎
  • 服務器B:寶塔鎮河妖

而我們要做的就是第二種校驗。
實現步驟
(因為要做root無密碼訪問,所以所有執行全在root下,普通用戶原理是一樣的,不過是認證文件位置不同罷了,sudo su -sudo su的區別大家都知道的吧。

  • 首先執行ssh-keygen -t rsa生成密鑰對
  • 將密鑰拷貝至需要無密碼訪問的機器scp id_rsa.pub(key訪問加-i)
  • 去無密碼訪問的機器將拷貝來的密鑰寫入授權列表cat id_rsa.pub >> /root/.ssh/authorized_keys
  • 文件授權chmod 600 authorized_keys 至于為什么是這個權限忘記了
  • 上述步驟中拷貝key的地方可替換為ssh-copy-id -i /root/.ssh/id_rsa.pub

上腳本文件

腳本需要服務器安裝expect命令,atp-get或yum install就行,需要bash來執行入口文件

  • 入口文件startAuthorize.sh
#!/bin/bash
path=$(cd "$(dirname "$0")"; pwd)
sshPath="/root/.ssh/authorized_keys"
if [ ! -f "$sshPath" ]; then
echo "密鑰不存在,正在生成密鑰"
expect productKey.exp
cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
echo "密鑰生成完成,正在修改服務器配置"
else
echo "密鑰已經存在,正在修改服務器配置"
fi

for i in `awk '{print $1}' ${path}/pwdconfig`
do
u=`awk -v I="$i" '{if(I==$1)print $2}' ${path}/pwdconfig`
p=`awk -v I="$i" '{if(I==$1)print $3}' ${path}/pwdconfig`
rp=`awk -v I="$i" '{if(I==$1)print $4}' ${path}/pwdconfig`
echo "開始修改ip為 $i 的服務器配置"
expect ${path}/initServer.exp $i $p $u $rp >/dev/null 2>&1
if [ "$?" = 0 ]; then
echo "正在為ip為 $i 的服務器授權"
expect ${path}/authorize.exp $i $rp >/dev/null 2>&1
if [ "$?" = 0 ]; then
echo "服務器 $i 授權成功"
fi
else
echo "\033[31m無法為ip為 $i 的服務器進行授權 請重新修改服務器配置 \033[0m"
fi
done
echo "所有服務器配置修改完成"
sh ${path}/confirmServer.sh
  • 生成密鑰productKey.exp
#!/bin/expect
set timeout 30
spawn -noecho ssh-keygen -t rsa
expect {
    "Enter file in which to save the key" {
        send "\r"
        expect {
                        "Overwrite" {
                                send "y\r"; exp_continue;
                         }
                "Enter passphrase" {
                    send "\r"
                    expect "Enter same passphrase again:"
                    send "\r"
                }
        }
    }
}
expect eof
  • 初始化服務器(啟用root用戶腳本)initServer.exp
#!/bin/expect
set serverIp [lindex $argv 0]
set passwd [lindex $argv 1]
set user [lindex $argv 2]
set rootPasswd [lindex $argv 3]
set timeout 30
spawn -noecho ssh -l $user $serverIp
expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" {
        send "$passwd\r"
            expect "$user"
            send "sudo su -\r"
            expect "password"
            send "$passwd\r"
            expect "root"
            send "sed -i 's/PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config\r"
            expect "root"
            send "service ssh restart\r"
            expect "root"
            send "passwd\r"
            expect "UNIX"
            send "$rootPasswd\r"
            expect "UNIX"
            send "$rootPasswd\r"
            expect "root"
            send "exit\r"
            expect "$user"
            send "exit\r"
        send_user "服務器 $serverIp 配置修改成功"; exit 0
     }
    timeout { puts "服務器 $serverIp 連接超時"; exit 1 }
}
exit 1
  • 開始授權authorize.exp
#!/bin/expect
set timeout 30
set serverIp [lindex $argv 0]
set passwd [lindex $argv 1]
spawn -noecho ssh-copy-id -i /root/.ssh/id_rsa.pub root@$serverIp
expect {
            "Are you sure you want to continue connecting (yes/no)?" {
                send "yes\r"; exp_continue;
            }
            "password:" {
                send "$passwd\r"; exp_continue;
            }
        eof { exit 0 }
}
expect eof
  • 確認授權狀態confirmServer.sh
#!/bin/bash
path=$(cd "$(dirname "$0")"; pwd)
echo "正在檢測所有服務器連接訪問狀態"
for i in `awk '{print $1}' ${path}/pwdconfig`
do
echo "開始檢測服務器${i}的連接狀態。。。"
ssh -o NumberOfPasswordPrompts=0 $i "date" > /dev/null 2>&1
if [ $? = 0 ]; then
        echo "服務器${i}無密碼訪問 [\033[32m  成功  \033[0m]"
else
        echo "服務器${i}無密碼訪問 [\033[31m  失敗  \033[0m]"
fi
done
  • 配置文件 (ip,用戶名,密碼,期望修改的root密碼) pwdconfig
192.168.20.109 cloud rd123456 123456
192.168.20.214 cloud rd123456 123456
192.168.20.104 cloud rd123456 123456
192.168.20.100 cloud rd123456 123456
192.168.20.212 cloud rd123456 123456

針對于我們公司部署情況寫的(ubuntu14),如有需求,可適配更改,原理都是一樣的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,915評論 18 139
  • SSH 為 Secure Shell 的縮寫,由 IETF 的網絡小組(Network Working Group...
    shuff1e閱讀 1,801評論 1 11
  • SSH全稱Secure SHell,顧名思義就是非常安全的shell的意思,SSH協議是IETF(Internet...
    StarShift閱讀 2,557評論 0 7
  • 姓名:樂仁華 學號:16140220023 轉載自:http://m.blog.chinaunix.net/uid...
    小樂雜貨鋪閱讀 1,325評論 0 0
  • 1 今天早晨參加了本周的檢視,感覺自己,通過分析能夠看到自己的不足,得到了小伙伴們的贊揚! 2 今天中午做了家鄉...
    LiHongxi閱讀 145評論 0 0