Linux ssh協定

2022-08-01 12:12:42

基礎知識

  • ssh:secure shell protocol,安全的遠端登入

  • 作用:是建立在應用層基礎上的安全協定,實現資料傳輸過程中資料的加密,代替telent協定

  • 使用tcp協定,埠號為22

ssh服務具體的軟體實現:

  • openSSH

  • dropbear

OpenSSH:ssh協定的開源實現,linux(centos、ubuntu等)預設使用的是openssh來實現ssh這個服務的

dropbear:另一個ssh協定的開源專案的實現

ssh的通訊過程:

第一次連線的時候就要進行公鑰的交換

  • 使用者端發起請求

  • 伺服器端返回給使用者端自己的公鑰,以及生成一個對談ID

  • 使用者端生成金鑰對:將自己的公鑰和對談ID做互斥或運算,然後再使用伺服器端的公鑰來加密互斥或運算的到的值

  • 伺服器端的到這個加密的資料後使用自己的私鑰解密得到資料

  • 伺服器端使用解密後得到的資料和對談ID進行互斥或運算得到使用者端的公鑰(伺服器得到使用者端公鑰)

最終:雙方各自持有三個祕鑰,分別為自己的一對公、私鑰,以及對方的公鑰,之後的所有通訊都會被加密

伺服器的公鑰表現為一個磁碟檔案

使用者端的公鑰是臨時生成的(在連線的時候自動生成一個公鑰)

ssh加密通訊原理

假如A和B通訊,A是使用者端,B是伺服器端
A--->B
使用者端A使用伺服器端B的公鑰來加密資料,伺服器端B使用自己的私鑰來解密資料

B--->A
流程和A--->B的流程是一樣的

#第一次連線的時候會把目標主機的公鑰利用雜湊演演算法生成一個摘要,需要手動確認目前連線的機器是想要連線的目標主機
#確認以後會自動把對方的公鑰下載下來,下次再連線的時候就能確保是否和第一次是同一個主機。

#對方公鑰存放位置:
當前使用者的家目錄下面一個叫做ssh的隱藏資料夾,裡面有個叫做known_hosts的檔案,裡面記錄了遠端主機的公鑰。

#拿到公鑰的好處:
如果下次存取的時候有一個假冒的主機(同樣的ip地址等資訊),系統是能夠發現的。

#新的機器地址和舊地址一樣,只需要刪除舊機器對應的公鑰檔案就可以重新連線上去了 .ssh/known_hosts裡面

openssh服務

OpenSSH是SSH(Secure SHell)協定的免費開源實現,一般在各種Linux版本中會預設安裝,基於C/S結構

Openssh軟體相關包組成:

  • openssh

  • openssh-clients:伺服器的組態檔帶D,使用者端的組態檔不帶D

  • openssh-server:這個包定義了伺服器的組態檔

#可以使用rpm -ql 包名 :檢視軟體包中的內容

伺服器端:
[root@Centos8 CA]# rpm -ql openssh-server
/etc/pam.d/sshd  #伺服器端程式
/etc/ssh/sshd_config #伺服器端組態檔
/etc/sysconfig/sshd
...
伺服器端對應的unit檔案:/usr/lib/systemd/system/sshd.service


使用者端:
[root@Centos8 ~]# rpm -ql openssh-clients
/etc/ssh/ssh_config  #使用者端的組態檔,可以更改預設埠,公鑰檢查等
/etc/ssh/ssh_config.d
/etc/ssh/ssh_config.d/05-redhat.conf
/usr/bin/scp
/usr/bin/sftp
/usr/bin/ssh
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan
...

使用者端:openssh-clients

Linux Client: ssh, scp, sftp,slogin  #linux的openssh-clients經常使用的工具

Windows Client: xshell, MobaXterm, putty, securecrt, sshsecureshellclient

使用者端 ssh命令

ssh命令:是ssh使用者端的一個工具,允許實現對遠端系統經驗證地加密安全存取

#ssh使用者端組態檔:
/etc/ssh/ssh_config

ssh命令使用格式

ssh [user@]host [COMMAND] 或者 ssh -l user host [COMMAND]
#後面加COMMAND,在遠端主機上執行對應的命令

選項:
-p port    #指定openssh-server使用的埠

-X          #支援x11轉發(遠端顯示的圖形介面在本機顯示(前提是雙方都是圖形介面))

-t          #強制偽tty分配,通過間接的方式連線到目標主機
            #如:ssh -t remoteserver1 ssh -t remoteserver2   ssh remoteserver3 

-o option   #如:-o StrictHostKeyChecking=no #表示登入的時候不用確認,直接下載公鑰

-i <file>   #指定私鑰檔案路徑,實現基於key驗證,預設使用檔案: ~/.ssh/xxx
範例: 利用windows 顯示 Linux 的圖形工具
使用到了x協定,x協定是用來實現圖形處理的。
#windows的圖形介面和作業系統綁在一起的,linux裡面圖形介面只是一個元件,不輸入作業系統本身。
	x_server元件:一個伺服器,是真正畫圖的元件
	x_client元件:圖形介面使用者端,比如firefox等

	x_client代指圖形工具,執行一個x_client的時候,藉助x協定把請求傳送給x_server。
	x_server再連線圖形顯示卡進行介面的顯示。
	#兩者可以屬於不同的主機,可以使用不同的協定。

#利用windows 顯示 Linux 的圖形工具
在linux上裝x_client,在windows上裝x_server。
在linux執行使用者端軟體,通過x協定傳送給windows的伺服器,實現了windows顯示linux上的影象。

#windeows的x_server軟體: xmanager(用的比較多)
#linux的x_client:firefox

ssh登入驗證的方式

  • 口令驗證

  • 金鑰驗證

口令驗證
1. 使用者端發起ssh請求,伺服器會把自己的公鑰傳送給使用者

2. 使用者會根據伺服器發來的公鑰對密碼進行加密

3. 加密後的資訊回傳給伺服器,伺服器用自己的私鑰解密,如果密碼正確,則使用者登入成功
金鑰驗證實現方式

在每次連線對方的時候就不用在輸入密碼了,可以直接連線

1. 首先在使用者端生成一對金鑰(ssh-keygen)(公鑰、私鑰)

2. 使用者端的公鑰通過ssh-copy-id命令拷貝到伺服器端,存放在(authorized_keys)這個檔案中

3. 使用者端再次傳送連線請求,用使用者端公鑰加密並傳給使用者端

4.使用者端接接收到這個加密的檔案後用私鑰解密,將解密的字元用伺服器的公鑰(第一次登入得到的)加密發給伺服器端

5.伺服器端用自己的私鑰解密得到結果。通過對比字串來實現免密登入
實現基於金鑰的登入方式實現過程
  • 1.使用者端生成金鑰對

  • 2.使用者端把公鑰拷給伺服器端

1.ssh-keygen:直接回車預設使用rsa這種非對稱加密演演算法生成一個公鑰私鑰對檔案

-f:指定公鑰私鑰存放的路徑,不指定預設存放在家目錄下的ssh這個隱藏檔案 .ssh/xxx
-t:指定加密演演算法
-p: 指定密碼

2.ssh-copy-id -i 公鑰檔案的路徑  目標主機

會自動拷到目標主機額度.ssh目錄下的authorized_keys這個檔案中(不存在會自動建立)

範例

#使用sshpass工具實現非互動式登入:(一般用在指令碼裡面)

sshpass:實現口令的提交

前提:要實現和對方遠端通訊,需要先將對方的公鑰加到自己的.ssh/known_hosts檔案中

[root@centos8 ~]# sshpass -p 123456 ssh -o StrictHostKeyChecking=no [email protected] #在存取對方的時候就不需要輸入密碼了


#非互動式實現公鑰的拷貝
sshpass -p 123456 ssh-copy-id -i 本機的公鑰 -o StrictHostKeyChecking=no 10.0.0.8(需要複製到的遠端主機)
#範例:批次部署多臺主機基於key驗證指令碼
#!/bin/bash  #新增shebang機制
HOSTS="  #指定需要遠端連線到的主機ip地址
10.0.0.6
10.0.0.7
10.0.0.18
10.0.0.28
"
PASS=redhat #用於儲存這幾臺主機的密碼
[ -f /root/.ssh/id_rsa ] || ssh-keygen  -P ""  -f /root/.ssh/id_rsa &> /dev/null #如果有私鑰了就不用再建立了
apt -y install sshpass &> /dev/null #如果沒有安裝sshpass就安裝
for i in $HOSTS;do #迴圈ip地址
{
   sshpass  -p $PASS ssh-copy-id  -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub $i &> /dev/null #使用非互動式的方式來將自己的公鑰拷貝過去  -i:指定私鑰的路徑
}& #後臺並行執行
done
wait
#實現多臺主機之間彼此都能基於Key驗證
1.生成金鑰對 ssh-keygen #預設儲存在.ssh下面

2.將自己的私鑰檔案儲存到自己的authorized_keys檔案中。 ssh-copy-id 127.0.0.1

3.使用rsync工具將.ssh檔案整個複製到目標所有主機

#例如:rsync -av .ssh serverhost/.ssh/root


#原理就是所有人共用一個公鑰私鑰對。 因為使用ssh-keygen生成一個金鑰對是放在/.ssh裡面的且authorized_keys存放自己的公鑰(自己信任自己)
如果生成金鑰對的時候指定了密碼:ssh-keygen -P 。下次遠端的時候不想輸入這個密碼,
可以使用ssh-agent bash 來開啟一個代理,然後把私鑰的密碼託管給代理

ssh-keygen -p

ssh-agent bash #是一個後臺執行的程式
ssh-add #將要密碼託管給agent,下次就不需要手動輸入密碼了

其他ssh使用者端工具

他們都是基於ssh協定開發的ssh_client工具

  • scp

  • rsync

  • stfp

scp:實現跨主機的遠端拷貝

格式:
scp [選項] 原始檔 目標檔案
scp [選項]  /source_file [user@]remote_houst/dest_file
scp [選項]  [user@]remote_houst/dest_file /source_file

選項:
-r:複製資料夾
-P PORT 指明remote host的監聽的埠

#複製目錄檔案後面有無斜線的區別
	有斜線:複製資料夾裡面的內容
	無斜線:複製整個資料夾

rsync:實現資料的更新(增量備份)

主要用來實現資料的增量備份、資料的更新。

工具來源:rsync包
#通訊雙方都需要安裝rsync這個工具

#選項:
-a:保留原始檔的屬性,但是無法保留acl和selinux屬性  -a選項自帶遞迴的功能
-v:顯示詳細的過程
--delete:保證兩邊的資料一樣,如果目標檔案存在某個原始檔沒有的檔案,就會把目標檔案的這個檔案刪除掉

rsync  -av /etc server1:/tmp #複製目錄和目錄下檔案
rsync  -av /etc/ server1:/tmp #只複製目錄下檔案 和scp一樣

rsync -av --delete source_file host:/dest_file | dest_file  #可以跨主機備份也可以本地備份

sftp:互動式檔案傳輸工具

用法和ssh工具差不多。

ssh伺服器端設定

伺服器端對應的程式名稱:sshd

伺服器端的組態檔: /etc/ssh/sshd_config

伺服器端的組態檔幫助:man 5 sshd_config
Port        #埠號,生產建議修改
ListenAddress ip
LoginGraceTime 2m
PermitRootLogin yes #預設ubuntu不允許root遠端ssh登入
StrictModes yes   #檢查.ssh/檔案的所有者,許可權等
MaxAuthTries   6     #pecifies the maximum number of authentication
attempts permitted per connection. Once the number of failures reaches half this
value, additional failures are logged. The default is 6.
MaxSessions  10         #同一個連線最大對談
PubkeyAuthentication yes     #基於key驗證
PermitEmptyPasswords no      #空密碼連線
PasswordAuthentication yes   #是否支援密碼驗證
GatewayPorts no
ClientAliveInterval 10 #單位:秒
ClientAliveCountMax 3 #預設3
UseDNS yes #改為no,一般用不到,可以讓ssh連線速度加快
GSSAPIAuthentication yes #提高速度可改為no
MaxStartups    #未認證連線最大值,預設值10
Banner /path/file
#以下可以限制可登入使用者的辦法:
AllowUsers user1 user2 user3
DenyUsers user1 user2 user3
AllowGroups g1 g2
DenyGroups g1 g2
ssh服務設定的最佳實踐
建議使用非預設埠
禁止使用protocol version 1
限制可登入使用者
設定空閒對談超時時長
利用防火牆設定ssh存取策略
僅監聽特定的IP地址
基於口令認證時,使用強密碼策略,比如:tr -dc A-Za-z0-9_ < /dev/urandom | head -c 12| xargs
使用基於金鑰的認證
禁止使用空密碼
禁止root使用者直接登入
限制ssh的存取頻度和並行線上數
經常分析紀錄檔

範例:

#設定 ssh 空閒60s 自動登出
Vim /etc/ssh/sshd_config

	ClientAliveInterval   60
	ClientAliveCountMax   0
Service sshd restart
#注意:新開一個連線才有效
#解決ssh登入緩慢的問題
vim /etc/ssh/sshd_config
	UseDNS no
	GSSAPIAuthentication no
#在 ubuntu 上啟用 root 遠端ssh登入
#修改sshd服務組態檔
vim /etc/ssh/sshd_config 
	#PermitRootLogin prohibit-password 註釋掉此行
	PermitRootLogin yes 修改為下面形式

ssh使用者端的設定

使用者端名稱:ssh

組態檔:
/etc/ssh/ssh_config  #使用者端的組態檔,可以更改預設埠,公鑰檢查等

輕量自動運維化工具

  • sshfs

  • pssh

  • sshpass

掛載遠端ssh目錄:

sshfs:由EPEL源提供,目前CentOS8 還沒有提供,可以利用ssh協定掛載遠端目錄
輕量級自動化運維工具 pssh
#範例
sshfs 10.0.0.8:/data /mnt #將遠端主機的data目錄掛載到原生的mnt目錄

pash

pssh:批次管理目標主機,需要提前做好基於key驗證。,可在多臺伺服器上執行命令的工具,也可實現檔案複製,提供了基於ssh和scp的多個並行工具


選項:
-H:指定要遠端管理的主機地址
-h file:主機列表檔案,內容格式」[user@]host[:port]」
-A :手動輸入密碼模式
-i:每個伺服器內部處理資訊輸出
範例
#預設使用ssh的key認證,通過 -A選項,使用密碼認證批次執行指令
pssh -H "192.168.1.10"   -A   hostname

#多臺主機
pssh -H "192.168.1.10 192.168.1.20"  -i   hostname

#多臺主機
cat hosts.txt 
10.0.0.8
10.0.0.6
pssh -h hosts.txt  -i   hostname

#將標準錯誤和標準正確重定向分別儲存至本地主機的/data/stdout和/data/stderr目錄下
pssh -H 192.168.1.10 -o /data/stdout -e /data/stderr   -i 「hostname」

-o:輸出的檔案目錄
-e:錯誤輸出檔案

#使用pssh的時候 變數 *號等萬用字元需要使用單引號括起來

pscp.pssh命令

是將本地檔案批次複製到遠端主機

#選項:
-v 顯示覆制過程
-r 遞迴複製目錄

#將本地curl.sh 複製到/app/目錄
pscp.pssh -H 192.168.1.10 /root/test/curl.sh   /app/
pscp.pssh -h host.txt /root/test/curl.sh   /app/

#將本地多個檔案批次複製到/app/目錄
pscp.pssh -H 192.168.1.10 /root/f1.sh /root/f2.sh   /app/

#將本地目錄批次複製到/app/目錄
pscp.pssh -H 192.168.1.10  -r /root/test/   /app/

pslurp命令

將遠端主機的檔案批次複製到本地

#批次下載目標伺服器的passwd檔案至/app下,並更名為user
pslurp -H 192.168.1.10 -L /app /etc/passwd user

#選項
-L 指定從遠端主機下載到本機的儲存的目錄,local是下載到本地後的名稱
-r 遞迴複製目錄