一。回顧#
1.1 ssh#
ssh
secure shell
- 遠程登錄連接,控制主機
- 數據的傳輸都是加密的
- 基於非對稱加密技術
1.2 加密技術#
加密技術
對稱加密
-
雙方共同擁有一把鑰匙,其中一方拿著加密,另外一方就拿著解密
-
弊端:這個公鑰的鑰匙很容易被有心人獲取
非對稱加密
- 使用公鑰對進行加解密
- 生成一對鑰匙,其中一方作為私鑰,另一方就是公鑰
- 私鑰是只有自己知道,私鑰保存在本地
- 公鑰是給需要通信的人,公鑰可以給其他人
- 使用公鑰加密,私鑰解密,一般用在數據加密傳輸
(A、B 2 個人,B 給 A 用加密的方式傳輸數據,私鑰在 A 手裡,B 用 A 的公鑰對數據加密) - 使用私鑰加密,公鑰解密,一般用於認證
(A 向 B 發送數據,B 用於確認是不是 A 發送的數據,客戶端 A 用 A 的私鑰對數據進行加密,服務端 B 拿 A 的公鑰進行解密。只管認證,不管加密性)
1.3 ssh 登錄#
ssh 登錄
登錄方式
- 密碼登錄
流程
1、客戶端發送登錄請求
2、服務器發送機器的公鑰發送給客戶端
3、客戶端用服務器的公鑰對密碼進行加密,發送給服務端
4、服務器收到密文之後,用私鑰進行解密,與 /etc/shadow 進行驗證
5、返回驗證結果 - 密鑰登錄,公鑰認證
1、客戶端生成公鑰對
2、將客戶端的用戶公鑰發送給服務器,保存在目標用戶~/.ssh/authorized_keys
3、客戶端發送請求,服務器返回 1 個隨機字符串
4、客戶端收到隨機字符串之後,用自己的私鑰加密,發送給服務器
5、服務器收到密文之後,用客戶端的公鑰進行解密,拿到隨機字符串與生成的字符串比較。返回認證結果 (隨機字符串其他人拿到了就拿到了,沒有任何關係,因為 A 的公鑰很多人都可以有) - 弊端
- 第三方攻擊
- A 無法判定收到的這個公鑰是不是 B 的
- 為了解決這個問題
- 第一次登錄的時候會進行人為確認
- 確認了之後,將 B 機器主機公鑰存放在~/.ssh/known_hosts,以後每次登錄都會進行對比 (如果系統重裝後,登錄不上,提示 known_hosts……,將 known_hosts 刪掉)
公鑰認證
1、使用命令生成公鑰對
ssh-keygen
-t 選項 指定生成的加密算法
默認是 rsa 算法加密,過程中一直敲回車就可以了
2、客戶端將公鑰發送給服務器
保存在目標用戶的~/.ssh/authorized_keys
3、檢測權限
authorized_keys 600 權限
.ssh 以及家目錄都給 755 以下權限
或者 允許密碼驗證登錄時 (前提條件) # ssh-copy-id wy@192.168.0.39 -p 2233 把公鑰發送過去
[root@cPen_python ~]# ssh-copy-id wy@192.168.0.39 -p 2233 # 注:需要可以支持密碼登錄
1.4 ssh 遠程操作工具#
ssh 遠程操作工具
- ssh
- 遠程執行命令,遠程登錄
- 登錄方式
- ssh 服務器 ip 地址
- 使用當前用戶和默認端口登錄
- 使用客戶端的當前用戶名,登錄到遠端服務器的同名用戶下,默認端口 22
(沒有同名用戶,登錄失敗)- ssh 用戶名 @服務器 ip 地址
- 登錄到遠端服務器的指定用戶下,使用默認端口 22 登錄
- ssh 服務器地址 -l 用戶名 -p 端口號
- 指定用戶名和端口去登錄
- ssh -o 接一些配置選項 服務器的 ip 地址
#無序輸入 yes,自動保存 hostkey
ssh -o StrictHostKeyChecking=no 192.168.0.132 -p 223- ssh -i /tmp/id_rsa 指定私鑰認證文件
默認情況在~/.ssh/ 這下面找私鑰- ssh -vvv
打印登錄過程的詳細信息
1.5 服務配置#
服務配置
- 服務安裝包
-
oepnssh#
[root@cPen_python ~]# which ssh
/usr/bin/ssh
[root@cPen_python ~]# rpm -qf /usr/bin/ssh
openssh-clients-7.4p1-21.el7.x86_64
-
- 配置文件
- /etc/ssh/sshd_config 服務端配置文件
- /etc/ssh/ssh_config 客戶端配置
- 主程序
服務端 /usr/sbin/sshd
客戶端 /usr/bin/ssh - 重新加載配置
重啟服務 service sshd restart/reload
kill -1 sshd 的 pid
kill -HUP sshd 的 pid 號
1.6 查看 ssh 服務啟動情況#
查看 ssh 服務啟動情況
1、ps -aux/-ef
2、pidof sshd
3、netstat -autpln 所有接口 (a) 的 udp tcp 連接,顯示出所有程序 (p) 監聽狀態 (l) n 數字顯示端口號
# 注:查看網絡連接狀態
# ps -eo pid,uid,comm|grep sshd # 注:-eo 查看特定字段信息
4、lsof -i:22 打印出程序所需要的文件
[root@localhost ~]# ps aux |grep sshd
root 1066 0.0 0.1 112924 4316 ? Ss 09:41 0:00 /usr/sbin/sshd -D
root 1608 0.0 0.1 158928 5608 ? Ss 09:43 0:00 sshd: root@pts/0
root 9546 0.0 0.0 112824 980 pts/0 S+ 11:26 0:00 grep --color=auto sshd
[root@localhost ~]# ps -ef |grep sshd
root 1066 1 0 09:41 ? 00:00:00 /usr/sbin/sshd -D
root 1608 1066 0 09:43 ? 00:00:00 sshd: root@pts/0
root 9550 1612 0 11:26 pts/0 00:00:00 grep --color=auto sshd
[root@localhost ~]# ps -eo pid,uid,comm|grep sshd # 注:-eo查看特定字段信息
1066 0 sshd
1608 0 sshd
1.7 ssh-agent#
ssh-agent
管理密鑰
在你自己的機器上開啟這個服務
配置: xshell--> 主機屬性 --》ssh --》勾選 使用 xagent 進行身份驗證;勾選 使用代理轉發
#注:自己的機器是 Windows,在 Windows 上開啟 ssh-agent 服務,現在有 A、B 2 台機器,A、B 兩台機器都有 Windows 的公鑰,這種情況開啟 ssh-agent (xshell 裡面開啟),A 登錄 B 時默認情況會拿 windows 的公鑰進行加密,B 機器用 Windows 的私鑰進行解密 必須在 xshell 裡進行操作,這都是 xshell 的行為
二。跳板機#
#注:跳板機給辦公人員用的 跳板機 / 堡壘機 為了保護系統的安全
#注:使用 ssh-agent 訪問跳板機和想要訪問的主機
#注:使用場景 阿里的業務 本來有 10 萬台主機 (在局域網裡面,沒有外網,外部不能訪問),我在家裡,十萬台機器撈出一台,這 1 台主機可以訪問外網 (跳板機 / 堡壘機),這 1 台跳板機的配置尤其重要
開啟 ssh-agent,把自己主機的公鑰添加到目標主機和堡壘機下 (目標主機的權限和堡壘機的權限)
#注:連到 A 上,從 A 跳到 B 上,B 不一定有當前主機的公私鑰
#跳板機 安全加固:
不能使用 root 直接登錄,使用 sudo 賦予相應權限
不能使用默認端口登錄
不能使用密碼登錄,都使用公鑰登錄
添加防火牆配置
總結:
#跳板機
#安全加固
1、不能使用密碼登錄
2、不能使用 root 登錄
3、修改默認端口
4、添加防火牆配置
5、使用跳板機登錄
示例1:查看路由 ip r
--------------------------------------------------------------------------------------------
[root@cPen_python ~]# ip r # 注:查看路由
default via 192.168.0.1 dev ens33 proto dhcp metric 100
192.168.0.0/24 dev ens33 proto kernel scope link src 192.168.0.32 metric 100
[root@cPen_python ~]# ip r delete default via 192.168.0.1 # 注:刪除網關
[root@cPen_python ~]# ip r
192.168.0.0/24 dev ens33 proto kernel scope link src 192.168.0.32 metric 100
[root@cPen_python ~]# ping www.baidu.com # 注:刪除後ping不通外網
connect: 網絡不可達
[root@cPen_python ~]# ping 8.8.8.8
connect: 網絡不可達
[root@cPen_python ~]# ip r add default via 192.168.0.1 # 注:還原
============================================================================================
示例2:A機器登錄到B機器(簡化登錄) vim .ssh/config
#以後會遇到很多機器,ip地址是記不住的
--------------------------------------------------------------------------------------------
#A機器登錄到B機器,操作前需要先把A機器公鑰放到B機器上 進行授權
#不修改全全局配置,只修改個人配置:在用戶家目錄下創建.隱藏文件
#在客戶端上配置(配到自己的主機上)
#注:意思是將機器root@192.168.0.31 -p 2233 取個別名叫B
#ForwardAgent yes # 注:轉發 開啟
#StrictHostKeyChecking no # 注:不需要輸入yes 直接把key保存在known_hosts裡面
#ServerAliveInterval 60 # 注:存活狀態,檢測服務存活狀態
#IdentityFile ~/.ssh/id_rsa # 注:指定認證私鑰
#示例如下
[root@cPen_python ~]# vim .ssh/config
###############################################
ForwardAgent yes
StrictHostKeyChecking no
ServerAliveInterval 60
IdentityFile ~/.ssh/id_rsa
###############################################
Host B
HostName 192.168.0.31
User cPen
Port 2233
[root@cPen_python .ssh]# chmod 600 config # 注:授予權限 不執行這條語句 可能會報錯
[root@cPen_python .ssh]# ssh B
Last login: Mon Nov 23 15:05:16 2020 from 192.168.0.32 # 注:登錄成功
[root@cPen_centos8 ~]#
#注:即簡化 # ssh 192.168.0.31 -l root -p 2233 操作 (比如登錄到ftp服務器 ssh ftp)
============================================================================================
示例3:查看端口連接狀態 (客戶機想訪問服務器的時候使用 客戶機上telnet) telnet 192.168.0.31 2233
#注:這個命令只能測tcp的 udp的測不了,但是大部分服務都是tcp的
#查看端口是否可以訪問(即服務是否可達) telnet 192.168.0.31 2233
--------------------------------------------------------------------------------------------
#ping命令 是查看2台機器網絡是否連通
#查看服務是否可達使用 telnet命令
#示例:查看端口是否可達(服務是否可達)
[root@cPen_python .ssh]# yum install telnet -y
[root@cPen_python .ssh]# telnet 192.168.0.31 2233
Trying 192.168.0.31...
Connected to 192.168.0.31. # 注:服務可達
Escape character is '^]'.
SSH-2.0-OpenSSH_8.0
============================================================================================
示例4:提示主機不被信任 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
--------------------------------------------------------------------------------------------
#注:提示WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
將~/.ssh/known_hosts 刪掉
============================================================================================
示例5:永久修改主機名 hostnamectl set-hostname "A"
--------------------------------------------------------------------------------------------
#方法1
[root@cPen_python .ssh]# hostnamectl set-hostname "A"
#注:其實是修改 /etc/hostname
[root@A ~]# less /etc/hostname
#方法2
#或者直接修改 /etc/hostname
#臨時修改主機名
[root@B ~]# hostname cp
============================================================================================
示例6:查看進程數 pstree -p
--------------------------------------------------------------------------------------------
#注:看程序樹狀結構 pstree -p
[root@cPen_python .ssh]# pstree -p |grep sshd
|-sshd(1065)-+-sshd(3782)---bash(3784)
| |-sshd(3980)---bash(3982)-+-grep(4318)
| |-sshd(4059)---bash(4061)
| `-sshd(4288)---bash(4290)
#注:前面是父程序,後面是父程序創造出來的子程序,子程序分配新的bash環境,bash環境在操作命令grep
#注:父進程創造出子進程,子進程有創造出一個子進程,子進程創造出一個新的bash環境
#-------------------------------------------------------------------------------------------
#注:連接到B機器後bash環境多了個ssh子進程去處理B機器
[root@a ~]# ssh B
Last login: Mon Nov 23 15:52:16 2020 from 192.168.0.32
[root@a .ssh]# pstree -p |grep sshd
|-sshd(1065)-+-sshd(3782)---bash(3784)
| |-sshd(3980)---bash(3982)-+-grep(4325)
| |-sshd(4059)---bash(4061)---ssh(4323)
| `-sshd(4288)---bash(4290)
============================================================================================
示例7:修改客戶端配置 ~/.ssh/config
#配置文件:~/.ssh/config
#工作中使用跳板機代理登錄 (客戶端的配置,方便開發配置)
--------------------------------------------------------------------------------------------
#注:假設現在有A、B、C三台機器,B是跳板機,假設A C不通,A通B,B通C,B通D,B通E…………
#注:B機器當做跳板機,A是自己的本地機,A機器做代理,B機器自動做轉發
#注:在本地機A機器中操作
[root@a ~]# vim ~/.ssh/config
###############################################
ForwardAgent yes
StrictHostKeyChecking no
ServerAliveInterval 60
IdentityFile ~/.ssh/id_rsa
###############################################
Host B
HostName 192.168.0.31
User sanchuang
Port 2233
Host 192.168.0.54
User sanchuang
Port 2233
ProxyCommand ssh 192.168.0.31 -W %h:%p -l sanchuang -p 2233
#注:ProxyCommand表示 A通過跳板機(192.168.0.31)B登錄到
#-------------------------------------------------------------------------------------------
Host * /ftp* /10.* 以10網段開頭的ip地址 ssh 10.0.0.1 跳到這個配置執行
User sanchuang
Port 2233
ProxyCommand ssh B nc %h %p -w 10 2>/dev/null
#注:上課時衝突 前面寫Host *與ssh B衝突
============================================================================================
示例8:遠程執行命令 ssh B
--------------------------------------------------------------------------------------------
#不登錄B機器,執行B機器上的命令 (一般用於腳本)
[root@a ~]# ssh B ifconfig # 注:登錄到B執行 ifconfig命令
[root@a ~]# ssh B ip a # 注:登錄到B執行 查看ip地址 命令 ;命令的返回是B機器給的
[root@a ~]# ssh B "/usr/sbin/ip a" # 注:腳本裡建議使用命令的絕對路徑
============================================================================================
示例9:遠程傳輸 scp (前提ssh可以連接)
--------------------------------------------------------------------------------------------
#注:傳輸文件
[root@a ~]# touch ahost
[root@a ~]# scp ahost B:/tmp # 注:將A機器 當前路徑ahost文件cp到B機器下的/tmp路徑下
ahost 100% 0 0.0KB/s 00:00
[root@a ~]# scp B:/tmp/bhost ./ # 注:將B機器 /tmp/bhost文件cp到當前路徑
bhost 100% 0 0.0KB/s 00:00
[root@a ~]# scp B:tmp/testhost ./ # 注:將B機器 家目錄下 tmp/testhost文件cp到當前路徑
#注:傳輸目錄
[root@a ~]# scp -r adir B: # 注:將A機器當前路徑下 adir文件夾 cp到B機器家目錄下
[root@a ~]# scp -r adir B:bdir # 注:複製文件夾並改名
[root@a ~]# scp -r adir B:bdir/ # 注:和上面的沒有區別
============================================================================================
示例10:sftp傳輸文件 (前提ssh可以連接)
--------------------------------------------------------------------------------------------
#注:ftp文件傳輸
#注:sftp 傳輸文件 本地和異地傳輸文件
#注:格式 sftp 用戶名@主機名
[sanchuang@a ~]$ sftp B
Connected to B.
sftp> ls # 注:顯示遠程目錄列表
2q aa adir bb bdir testdir testdir2 testhost
sftp> get bdir
Fetching /home/sanchuang/bdir/ to bdir
Cannot download non-regular file: /home/sanchuang/bdir/
sftp> mget bdir
Fetching /home/sanchuang/bdir/ to bdir
Cannot download non-regular file: /home/sanchuang/bdir/
sftp> get 2q # 注:get 遠程路徑 下載文件
Fetching /home/sanchuang/2q to 2q
/home/sanchuang/2q 100% 226 107.5KB/s 00:00
sftp> exit
============================================================================================
示例11:pssh pscp命令 (前提ssh可以連接)
--------------------------------------------------------------------------------------------
#批量處理
pssh
-h 指定主機文件列表,內容格式”[user@]host[:Port]”
-i 指定每個服務器的處理信息
[root@a ~]# yum install pssh -y # 注:沒有的話需要安裝epel源
[root@a ~]# cat ip.txt
192.168.0.31:2233
192.168.0.54:22
[root@a ~]# pssh -h ip.txt -i "/usr/sbin/ip a"
[1] 17:18:13 [FAILURE] 192.168.0.54:22 Exited with error code 255、
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
…… # 注:需要保證ssh能不能過去
[2] 17:18:13 [SUCCESS] 192.168.0.31:2233 # 注:返回SUCCESS表示執行成功
……
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
……
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen
……
#-------------------------------------------------------------------------------------------
#ip.txt裡面可以這樣寫
[root@a ~]# vim ip.txt
sanchuang@192.168.0.31:2233
sanchuang@192.168.0.54:2233
============================================================================================
示例12:pscp.pssh 批量傳輸文件 (前提ssh可以連接)
--------------------------------------------------------------------------------------------
[root@a ~]# pscp.pssh -h ip.txt pscptest /tmp
# 注:把當前目錄下的pscptest文件傳送到目標主機的/tmp目錄下
[root@a ~]# vim ip.txt
sanchuang@192.168.0.31:2233
sanchuang@192.168.0.54:2233
[root@a ~]# pscp.pssh -h ip.txt pscptest /tmp
[1] 17:41:31 [FAILURE] sanchuang@192.168.0.54:2233 Exited with error code 1
[2] 17:41:31 [SUCCESS] sanchuang@192.168.0.31:2233
============================================================================================
示例13:fping 批量ping(前提ssh可以連接)
--------------------------------------------------------------------------------------------
#注:批量ping 使用fping命令
[root@a ~]# yum install fping -y
[root@a ~]# fping -g 192.168.0.1/24 # 注:-g 根據網段去ping
192.168.0.1 is alive
……
192.168.0.254 is unreachable
[root@a ~]# fping -f ip.txt # 注:-f根據文件指定ip去ping
192.168.0.31 is alive
192.168.0.54 is alive
三. ssh 服務補充#
3.1 ssh#
ssh --> secure shell
作用:遠程登錄和操作遠程的服務器 --> 信息加密 --> 非常安全的遠程登錄協議
#注:遠程登錄遠程操控 省成本
ssh 協議 屬於應用層的協議
Linux:openssh --> centos7/8 自帶
Windows 沒有 ssh 協議
3.2 命令#
命令:
ssh
scp # 注:遠程 copy
sftp
ssh-keygen
ssh-copy-id
3.3 登錄方式#
登錄方式:
Xshell # 注:不開源
putty # 注:開源
secureCRT # 注:開源
- 用戶名和密碼
/etc/passwd # 注:放用戶名
/etc/shadow # 注:放密碼
- 密鑰
公鑰和私鑰
public key --> 公开 # 注:給別人
private key # 注:自己所有
3.4 安全加固措施#
安全加固措施:
修改端口號 22
nmap # 注:端口掃描
nc # 注:端口掃描
禁用 root
su # 注:su 切換到 root
密碼複雜性
啟用密鑰 # 注:禁止密碼認證
打補丁 或者 安裝最新版本的 ssh 軟件
iptables 防火牆
#注:免密通道(密鑰登錄)
3.5 免密通道#
免密通道:
單向信任 # 注:把密鑰給其他主機
雙向信任 # 注:雙方互給公鑰
#注:一般用 root 用戶,為了安全起見用普通用戶
3.6 ansible#
ansible:自動化運維的工具:批量管理和操作
#注:ansible 批量管理 批量部署的軟件;底層用的 ssh 協議,推薦建立免密通道
#注:ansible 軟件 用 Python 寫的
3.7 日誌文件:/var/log/secure#
日誌文件:/var/log/secure
[root@cPen_centos8 ssh]# vim /etc/ssh/sshd_config
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV # 注:日誌類型 認證類型 AUTHPRIV 設置
#LogLevel INFO
日誌文件:
/var/log/secure
[sanchuang@cPen_centos8 ~]$ ps aux|grep rsyslog # 注:外包日誌的進程
ssh將自己的日誌功能外包給rsyslog服務去幫它記錄日誌
[sanchuang@cPen_centos8 ~]$ vim /etc/rsyslog.conf
# The authpriv file has restricted access.
authpriv.* /var/log/secure
3.8 ssh 服務登錄不了,如何排除?#
ssh 服務登錄不了,如何排除?
檢測網絡是否通暢
ping
檢測 ssh 服務是否啟動,檢查端口,selinux
ssh 的配置:是否禁用 root,是否禁用密碼認證
檢查防火牆 iptables
service firewalled stop
黑白名單 # 注:centos6、7 裡面用,8 裡面沒有
3.9 ssh 免密通道#
ssh 免密通道
生成密鑰對
ssh-keygen
ssh-keygen -t ecdsa
上傳公鑰
ssh-copy-id -i id_ecdsa.pub root@192.168.0.35
ssh-copy-id -p 2299 -i id_ecdsa.pub root@192.168.0.35
遠程連接
ssh -p '2299' 'root@192.168.0.39'
免密通道的建立步驟:
[root@localhost .ssh]# ssh-keygen -t ecdsa
[root@localhost .ssh]# ssh-copy-id -p 2299 -i id_ecdsa.pub root@192.168.0.39
[root@localhost .ssh]# ssh -p '2299' 'root@192.168.0.39'
known_hosts:存放我們曾經ssh連接過的機器的公鑰
scp 就是在2台機器之間底層使用ssh協議來拷貝文件或者文件夾
[root@cPen_centos8 ssh]# ssh root@192.168.0.24 # 注:遠程登錄
[root@cPen_centos8 ssh]# ssh root@192.168.0.24 df -Th # 注:遠程執行命令
[root@cPen_python ssh]# scp echo.sh root@192.168.0.35:/root # 注:傳文件 (源文件 远程)
[root@cPen_python ssh]# scp -r /boot root@192.168.0.35:/root # 注:傳文件夾
[root@cPen_python ssh]# scp -r root@192.168.0.35:/etc/passwd # 注:拿文件夾
[root@cPen_python ssh]# ssh root@192.168.0.35 bash /root/echo.sh feng zhang wang
scp 就是在2台機器之間底層使用ssh協議來拷貝文件或者文件夾
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_centos8 ssh]# getenforce # 注:查看selinux
Disabled
[root@cPen_centos8 ssh]# setenforce 0 # 注:臨時關閉selinux
setenforce: SELinux is disabled
---------------------------------------------------------------------------------------------------------------------------------
[sanchuang@cPen_centos8 ~]$ ifdown ens33
[sanchuang@cPen_centos8 ~]$ ifup ens33
#注:禁用root用戶登錄後,本地可以用root用戶登錄