远程连接


Linux:
- ssh 端口:22 加密传输数据
- telnet 端口:23 明文传输数据

Windows:
- rdp 端口:3389 remote desktop protocol

抓包演示


SSH数据加密传输

SSH远程管理_密钥对

Telnet数据明文传输

SSH远程管理_密钥对_02

企业面试题


## 写出下列服务或者协议的端口
ftp 21
ssh 22
telnet 23
dns 53
mysql 3306
http 80
https 443
rsync 873

ssh相关命令及选项


## 注意:不加用户@,默认使用当前登录的用户
ssh:远程连接Linux服务器
-p:port指定端口 (默认:22)

## 不连接上服务器,直接执行命令
ssh root@10.0.0.41 'ls /'

scp:远程拷贝数据(写在前面的是源文件)
-r:递归(远程拷贝目录)
-p:拷贝的时候保持属性
-P:大写p指定port(端口)

推:scp sersync2.5.4 root@172.16.1.7:/root
拉:scp root@172.16.1.7:/root/sersync2.5.4 /opt
[root@backup ~]# scp -P 22 root@172.16.1.7:/root/sersync2.5.4.tar.gz .

# 结论:
1.scp通过ssh协议加密方式进行文件或目录拷贝。
2.scp连接时的用户作为为拷贝文件或目录的权限。(-p保持文件属性)
3.scp支持数据推送和拉取,每次都是全量拷贝,效率较低。

ssh免密连接


验证方式:

1)用户名密码验证

2)密钥对验证方式

ssh密钥对认证流程

SSH远程管理_vim_03

#### ssh-keygen:生成密钥对
[root@web01 ~]# ssh-keygen

Generating public/private rsa key pair.
## 将秘钥保存到文件中,可以指定其他路径(直接回车)
Enter file in which to save the key (/root/.ssh/id_rsa):
## 给密钥对设置密码,不需要设置(直接回车)
Enter passphrase (empty for no passphrase):
## 重复输入设置的密码(直接回车)
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:/IXBNSWKZWI5WODDeT/b8o4v7JjQIlbza1Q3yMMzDcA root@web01
The key's randomart image is:
+---[RSA 2048]----+
| o=B=.o. |
| . oo*+O=oo |
|. . =.@+O+ . |
| o o *o/.+. |
|. . E B.S . |
| . . . |
| . |
| |
| |
+----[SHA256]-----+

## 生成后的密钥对
[root@web01 ~]# ll /root/.ssh/
-rw------- 1 root root 1679 May 23 16:03 id_rsa
-rw-r--r-- 1 root root 392 May 23 16:03 id_rsa.pub

#### ssh-copy-id:发送公钥
-i:指定公钥位置
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.7
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.8
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.31
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.41

#### .ssh目录中的know_host作用
[root@m01 ~]# cat ~/.ssh/known_hosts
记录连接过的服务器,如果没有连接过(第一次连接),需要输入yes

#### 生成密钥对命令:ssh-keygen(流程)
1.在当前用户的家目录下创建了一个隐藏目录 .ssh mkdir ~/.ssh
2.将密钥对存放目录 .ssh 授权为 700 chmod 700 ~/.ssh
3.将公钥内容写入 ~/.ssh/id_rsa.pub 文件中
4.将私钥内容写入 ~/.ssh/id_rsa 文件中
5.将私钥文件授权为 600 chmod 600 ~/.ssh/id_rsa

#### 发送公钥:ssh-copy-id(流程)
[root@web01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.5
输入yes
输入密码:1
1.在远端的指定用户的家目录下创建了一个隐藏目录.ssh ssh root@172.16.1.5 'mkdir
~/.ssh'
2.将密钥对存放目录 .ssh 授权为 700 ssh root@172.16.1.5 'chmod 700 ~/.ssh'
3.先在远端~/.ssh目录下创建文件authorized_keys ssh root@172.16.1.5 'touch
~/.ssh/authorized_keys'
4.将authorized_keys文件授权为600 ssh root@172.16.1.5 'chmod 600
~/.ssh/authorized_keys'
5.将公钥内容,保存到authorized_keys文件中

ssh root@172.16.1.5 'echo ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQCgW5rliyT3oan+r4aXuOj0D0fLEFSGNJXZd5JMDY
WX2pWhC5kITeVS66+EvXM
5OvqFfr40IQcMrZym0DXk7Zqf8brgWoqxR8AZR9tqAFwV3qTb9T/QB95OM16Y+N14oUOvW
CzB9rQo54QU/INPgfhaRy
Sk4YOgv+oL2aXdD6qbIGAikPzayvh9hWFjvy/LeFUGLheYYlYTqVM7WgeNrTlmbpjG4QO/
IYe/xWESbt20l70yTIrD/
XWSZ2lsxSWQf0KXERhshRGhNkJF87hhS2cJozOHjzhjaPjDvgycjpYajQWf4gERe3sTL9f
ji/bhf8bZ3dCLp4uK/e5P
6CRpgo9V root@web01' >> ~/.ssh/authorized_keys'

免密使用场景


1)批量查看服务器信息

#!/bin/bash
[ $# -ne 1 ] && echo "请输入执行的命令" && exit 1

for i in 31 41
do
echo "#########172.16.1.$i#####"
ssh root@172.16.1.$i "$1"
done

2)跳板机

#!/bin/bash
#jumpserver
lb01=10.0.0.5
lb02=10.0.0.6
web01=10.0.0.7
web02=10.0.0.8
web03=10.0.0.9
nfs=10.0.0.31
backup=10.0.0.41
db01=10.0.0.51
m01=10.0.0.61
zabbix=10.0.0.71

menu(){
cat <<-EOF
+-------------------------+
| 1) lb01 |
| 2) lb02 |
| 3) web01 |
| 4) web02 |
| 5) web03 |
| 6) nfs |
| 7) backup |
| 8) db01 |
| 9) m01 |
| 10) zabbix |
| h) help |
+-------------------------+
EOF
}
#菜单函数
menu

#连接函数
connect(){
ping -c 1 -w 1 $1 &>/dev/null
if [ $? -eq 0 ];then
ssh root@$1
else
echo -e "\033[5;4;40;31m 别连了,我的哥,$2:$1机器都没开!!!\033[0m"
fi
}

#控制不让输入ctrl+c,z
trap "" HUP INT TSTP
while true
do
read -p "请输入要连接的主机编号:" num
case $num in
1|lb01)
connect $lb01 lb01
;;
2|lb02)
connect $lb02 lb02
;;
3|web01)
connect $web01 web01
;;
4|web02)
connect $web02 web02
;;
5|web03)
connect $web03 web03
;;
6|nfs)
connect $nfs nfs
;;
7|backup)
connect $backup backup
;;
8|db01)
connect $db01 db01
;;
9|m01)
connect $m01 m01
;;
10|zabbix)
connect $zabbix zabbix
;;
h|help)
clear
menu
;;
close)
break
;;
esac
done

SSH安全优化


## ssh配置文件
[root@m01 ~]# vim /etc/ssh/sshd_config
17 Port 52022 # 修改默认端口
115 UseDNS no # 关闭反向解析
38 PermitRootLogin no # 禁止root用户登录
65 PasswordAuthentication no # 禁止使用密码登录
79 GSSAPIAuthentication no # 关闭GSSAPI认证

## 将以下内容,直接复制到文件最后一行
Port 6666 # 变更SSH服务远程连接端口
PermitRootLogin no # 禁止root用户直接远程登录
PasswordAuthentication no # 禁止使用密码直接远程登录
UseDNS no # 禁止ssh进行dns反向解析,影响ssh连接效率参数
GSSAPIAuthentication no # 禁止GSS认证,减少连接时产生的延迟

## 重启服务
[root@m01 ~]# systemctl restart sshd

## 解决方案
如果已经优化完ssh,发现服务器上出现以下问题:
# 1.没有普通用户
useradd jinnan(无法创建,进入单用户模式)
# 2.windows上秘钥没有推送
1)在windows上生成密钥对
- 使用windows的命令行执行 ssh-keygen

2)使用Xshell生成秘钥对

生成秘钥对

SSH远程管理_vim_04

SSH远程管理_bash_05

SSH远程管理_bash_06

SSH远程管理_vim_07

SSH远程管理_密钥对_08

SSH远程管理_bash_09

SSH远程管理_密钥对_10

SSH远程管理_bash_11

## 在普通用户家目录下创建 .ssh 目录 并赋予700权限
[jinnan@m01 ~]$ mkdir .ssh
[jinnan@m01 ~]$ chmod 700 .ssh/

## 在 .ssh 目录创建authorized_keys文件并将属性中的公钥直接复制到这个文件里 保存
退出
[jinnan@m01 ~]$ vim .ssh/authorized_keys

ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEAw1uEC+QXSNa5ws0uQBSCJMbMVZl1rT9EeStalVk587
TKnl7MZwz0Vk56JWEJu9vhGad5ok3FmlIc0tNbu6U2daUcO1bkhBJaeQvyYsl0gpYhGVcz
f5uy7x4u3NgkMwfuIbTF94wNqvO57IfreaMuBY/wOl5ga8V6xc3kh30rvfdHPavop+Rmev
fzNsgVKQ6pXCUdXtbwodIrrlboLNUQXiYNG6IHrK3XHTm7R7cODyl4FZQYBx2EYSg9CnAX
gH9lc9wEhkMsH3SuoF/3f45WsOcGQlYDUdCAWQXMjwIK+hHNtnMVIwSdhwJQb0xDhBz7vP
tO64pb3NWrq9sIjwF1nQ==

## 赋予600权限
[jinnan@m01 ~]$ chmod 600 .ssh/authorized_keys

## 修改Xshell登录设置

SSH远程管理_bash_12

SSH远程管理_密钥对_13

免交互生成秘钥对


## 因为需要方便将生成密钥对写入脚本 免交互的选项
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa &>/dev/null

-t:指定加密类型
-P:空密码
-f:秘钥生成的位置

## 判断密钥对生成是否成功的方法
## 也就是查看id_rsa私钥文件是否生成的方法:
方法一:
[root@m01 ~]# test -f ~/.ssh/id_rsa
[root@m01 ~]# echo $?
0 # 0是存在 0<是不存在

方法二:
[zls@m01 ~]$ [ -f ~/.ssh/id_rsa ]
[root@m01 ~]# echo $?
0 # ↑这是test的第二种写法

方法三:
ls -l ~/.ssh/id_rsa # 这个方法是要写到脚本里的方法

免交互推送公钥


## 不会循环的lowB写法
#!/bin/bash

# 先判断 有没有生成密钥对 判断有 就执行下面的推送 否则就 免交互生成密钥对
ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f
~/.ssh/id_rsa &>/dev/null
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.31
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.41
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.5
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.7
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.8

------------------------------------------------------

## 循环的写法
[root@m01 ~]# vim 1.txt # 先将要推送的服务器ip写入一个文件中
172.16.1.31 # 然后循环中指定这个文件一行一行的去循环执行
172.16.1.41
172.16.1.7
172.16.1.8

[root@m01 ~]# vim myxx.sh
#!/bin/bash

ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f
~/.ssh/id_rsa &>/dev/null

for n in `cat /root/1.txt`;do
ssh-copy-id -i ~/.ssh/id_rsa.pub root@$n
done

------------------------------------------------------

## 解决密码交互问题
方法一:使用expect解决
# expect是一门编程语言 以下内容大概意思: 例如 "(yes/no)" {send "yes\r";
exp_continue}
# 意思为当遇到 (yes/no) 时 就输入 yes 然后回车 ( \r 就代表回车)
# 以下脚本是指定了一个服务器推送 想要多个推送 就将 set ip 变量写个循环
[root@m01 ~]# yum install -y expect # 安装 expect
[root@m01 ~]# vim expect_send_pud.exp

#!/usr/bin/expect
set ip 172.16.1.31
set pass 1
set timeout 30
spawn ssh-keygen
expect {
"id_rsa):" {send "\r"; exp_continue}
"passphrase):" {send "\r"; exp_continue}
"again:" {send "\r"}
}
expect eof
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$ip
expect {
"(yes/no)" {send "yes\r"; exp_continue}
"password:" {send "$pass\r"}
}
#expect "root@*" {send "df -h\r"}
#expect "root@*" {send "exit\r"}
expect eof

# 执行脚本
[root@m01 ~]# expect expect_send_pud.exp

------------------------------------------------------

方法二:使用sshpass解决
[root@m01 ~]# yum install -y sshpass # 安装sshpass

# ssh不需要输入yes的选项 -o 'StrictHostKeyChecking no'
[root@m01 ~]# ssh -o 'StrictHostKeyChecking no' root@172.16.1.7
# 然后再用 sshpass -p指定密码

[root@m01 ~]# sshpass -p 1 ssh-copy-id -o 'StrictHostKeyChecking no'
-i ~/.ssh/id_rsa.pub root@172.16.1.8
[root@m01 ~]# vim send_public_key.sh

#!/bin/bash
ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f
~/.ssh/id_rsa &>/dev/null

for n in `cat /root/2.txt`;do
sshpass -p 1 ssh-copy-id -o 'StrictHostKeyChecking no' -i
~/.ssh/id_rsa.pub root@$n
done

[root@m01 ~]# cat /root/2.txt
172.16.1.31
172.16.1.41
172.16.1.7
172.16.1.8

------------------------------------------------------

## 各服务器密码不一样的情况
# 先将密码写入文件 然后在脚本里拿awk截取
[root@m01 ~]# vim /root/3.txt
172.16.1.31:1
172.16.1.41:2
172.16.1.7:4
172.16.1.8:111
[root@m01 ~]# vim send_public_key.sh

#!/bin/bash


ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f
~/.ssh/id_rsa &>/dev/null
for n in `cat /root/3.txt`;do
pass=`echo $n|awk -F ':' '{print $2}'`
ip=`echo $n|awk -F ':' '{print $1}'`
sshpass -p $pass ssh-copy-id -o 'StrictHostKeyChecking no' -i
~/.ssh/id_rsa.pub root@$ip
done

------------------------------------------------------

## 优化后的脚本
[root@m01 ~]# vim send_public_key.sh
#!/bin/bash

. /etc/init.d/functions

ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa &>/dev/null

for n in `cat /root/3.txt`;do
pass=`echo $n|awk -F ':' '{print $2}'`
ip=`echo $n|awk -F ':' '{print $1}'`

sshpass -p $pass ssh-copy-id -o 'StrictHostKeyChecking no' -i ~/.ssh/id_rsa.pub root@$ip &>/dev/null
if [ $? -eq 0 ];then
action "$ip send public key " /bin/true
else
action "$ip send public key " /bin/false
fi
done

[root@m01 ~]# cat /root/1.txt
172.16.1.31:1
172.16.1.41:1
172.16.1.7:1
172.16.1.8:1

------------------------------------------------------

## 优化后不使用判断的脚本
[root@m01 ~]# vim send_public_key.sh
#!/bin/bash

. /etc/init.d/functions

ls -l ~/.ssh/id_rsa &>/dev/null || ssh-keygen -t rsa -P '' -f
~/.ssh/id_rsa &>/dev/null

for n in `cat /root/1.txt`;do
pass=`echo $n|awk -F ':' '{print $2}'`
ip=`echo $n|awk -F ':' '{print $1}'`

sshpass -p $pass ssh-copy-id -o 'StrictHostKeyChecking no' -i
~/.ssh/id_rsa.pub root@$ip
&>/dev/null && \
action "$ip send public key " /bin/true || \
action "$ip send public key " /bin/false
done

[root@m01 ~]# cat /root/1.txt
172.16.1.31:1
172.16.1.41:1
172.16.1.7:1
172.16.1.8:1