ssh各种使用方式的基础介绍,使vps管理更方便

ssh使用证书登录,sshd配置,端口转发,多个ssh管理。配置ssh免密登录。scp命令,ssh Agent转发

yuniee
yuniee   Follow

# ssh各种使用方式的基础介绍,使vps管理更方便

# 🐡前言

​ 使用linux操作系统的人会经常用到ssh(Secure Shell ),这是个非常强大的工具,并且ssh的连接非常可靠安全。ssh的可用功能有很多,平时我们可以使用到的却只有一小部分。甚至大部分人只会用root和密码连接ssh。下面我会介绍一些比较实用且常用的ssh使用方法,当然你如果对ssh感兴趣可以去深入了解更多。ssh的玩法之多远超想象。

# 🐙基础使用方法

1.安装

OpenSSH 是 SSH协议的流行的免费开源实现,OpenSSH提供了服务端程序(openssh-server)和客户端工具(openssh-client)。

通常各个系统自带不需要安装。

sudo apt install openssh-server openssh-client -y  #ubuntu,debian

安装后可以使用以下命令检查一下:

netstat -tlp | grep ssh

输出:

root@ca:~# netstat -tlp | grep ssh
tcp        0      0 0.0.0.0:1011            0.0.0.0:*               LISTEN      373056/sshd: /usr/s 
tcp6       0      0 [::]:1011               [::]:*                  LISTEN      373056/sshd: /usr/s

2.ssh连接

ssh [email protected] #用户名和IP地址,默认端口为22
ssh -p 22 [email protected] #-p可指定端口

更详细参数可见这里ssh命令参数

  • user远程服务器登录的用户名,默认为当前用户
  • hostname远程服务器地址。可以是IP/域名/别名
  • exitlogout命令均可退出当前登录

# 🐚/etc/ssh/sshd_config常用配置介绍

SSH服务端配置文件默认为/etc/ssh/sshd_config,可以按需修改默认22端口等配置。这里介绍几个常用的选项。

修改端口:Port 22

建议修改!这个非常重要,最好是修改默认ssh端口为其他端口,这样可以增强一些安全性。

启用密钥登录:PubkeyAuthentication yes

禁用密码登录:PasswordAuthentication no

建议禁用!这个在密钥登录成功后再禁用,禁用密码登录可以大大增强安全性。开启密钥登录见ssh密钥登陆

禁用dns解析:UseDNS no

建议设置为no!在SSH配置中将 UseDNS 设置为 no 可以带来一些性能上的优势,特别是在网络环境较差或者DNS解析较慢的情况下。

SSH默认情况下会尝试通过 DNS 解析客户端的 IP 地址来获取其反向解析域名。这个过程在连接时会导致一定的延迟,特别是当 DNS 解析服务器响应较慢或不可用时,这可能会导致 SSH 连接的建立变慢。

允许tcp转发:AllowTcpForwarding yes

如果使用ssh隧道时需要使用。

设置仅允许本地端口转发:GatewayPorts no

设置为yes之后ssh隧道转发的内容可以被其他人访问。

ssh服务器允许代理转发:AllowAgentForwarding yes

AllowAgentForwarding选项用于控制SSH服务器是否允许代理转发。将其设置为yes允许通过SSH连接时进行代理转发。

代理转发允许在通过SSH连接到远程主机时,使用本地计算机上的SSH代理(通常是SSH密钥)进行身份验证和访问其他主机,而无需在远程主机上保存私钥或重新进行身份验证。这对于在多个主机之间进行安全访问和身份验证非常方便。

通常情况下,将AllowAgentForwarding设置为yes是合理且方便的选择,因为它提供了一种方便的方法来在多个主机之间共享身份验证信息,而不必在每台主机上都维护和管理私钥。但是,需要谨慎使用,确保仅将其应用于可信任的主机和环境,以防止私钥被滥用或泄露。

允许 SSH 客户端在 TCP 层启用保持活动功能: TCPKeepAlive yes

这个选项的作用在于防止底层 TCP 连接因为网络中间设备的连接超时而断开。有些网络设备或防火墙会在一段时间没有活动的连接上关闭连接,这可能导致 SSH 连接意外中断,尤其是在长时间的闲置后。

启用 TCPKeepAlive 可以确保即使在 SSH 会话长时间闲置时,底层的 TCP 连接也保持活动状态。这样一来,即使在 SSH 会话空闲时,底层的 TCP 连接仍然保持,防止了连接超时断开的情况发生,从而提高了连接的可靠性和稳定性。

启用PAM身份验证 :UsePAM yes

启用 UsePAM 选项可以允许 SSH 服务器使用操作系统上配置的 PAM 模块进行用户身份验证。这样可以实现更灵活、更强大的身份验证机制,例如使用 LDAP、Kerberos、双因素身份验证等。

# 🗝️ssh密钥登录

ssh,scp等)每次都需要提供用户密码保证安全,使用密钥不仅更安全还可以免密登录。

一定要在信任的机器上生成密钥,最好是在本地。window powershell等也可以生成密钥。且私钥一定要保存在信任的地方,最好保存在本地

1.生成密钥

ssh-keygen [-options]

参数:

-t:指定加密类型,默认为非对称加密(rsa), 所有可选项[dsa,ecdsa,ed25519,rsa]

-f: 密钥文件名。

-C: 注释,将附加在密钥文件尾部

使用方式实例:

ssh-keygen -t rsa -f ~/.ssh/[KEY_FILENAME] -C [USERNAME]  #-f和-C是可选的选项,为了使各个密钥可区分,可以不配置

生成密钥后要将私钥的权限修改为600:

chmod 600 ~/.ssh/[KEY_FILENAME]

2.各种ssh加密类型简介

在 SSH 中,常见的密钥类型包括以下几种:

  1. RSA:这是最早的 SSH 密钥类型之一,使用 RSA 加密算法。RSA 密钥在 SSH 中被广泛使用,并且是许多 SSH 工具和协议的默认密钥类型。
  2. DSA:这是另一种早期的 SSH 密钥类型,使用 DSA 加密算法。DSA 密钥已被广泛使用,但现在已不建议使用。
  3. ECDSA:这是一种基于椭圆曲线加密算法的 SSH 密钥类型,通常比 RSA 和 DSA 密钥更安全和高效。
  4. ed25519:这是一种基于椭圆曲线加密算法的公钥加密方案,它被广泛应用于 SSH 密钥认证。ed25519 密钥具有更高的安全性和更好的性能,因此在许多情况下被认为是最佳选择。

需要注意的是,不同的 SSH 工具和平台可能会支持不同的密钥格式和类型。在使用 SSH 密钥时,需要确保 SSH 工具支持使用的密钥类型。尽管ECDSA在许多情况下仍然是安全的,但它可能需要更长的密钥长度才能提供相同级别的安全性,并且可能受到特定类型的攻击(如侧信道攻击)的影响。如果系统支持的话,ED25519密钥是一个很好的选择,因为它提供了出色的性能和安全性。如果需要更广泛的兼容性,RSA密钥仍然是一个稳定的选择

总结:最推荐的是ed25519,安全性和性能最高,但兼容性差。rsa兼容性好。

3.各种加密类型密钥生成方法

ssh-keygen -t rsa -b 4096 #该命令将生成一个长度为 4096 位的 RSA 密钥,并要求您输入密钥文件名和密码。该命令还将提示您将公钥文件复制到远程主机上。
ssh-keygen -t dsa -b 1024 #该命令将生成一个长度为 1024 位的 DSA 密钥,并要求您输入密钥文件名和密码。该命令还将提示您将公钥文件复制到远程主机上。
ssh-keygen -t ecdsa -b 521 #该命令将生成一个长度为 521 位的 ECDSA 密钥,并要求您输入密钥文件名和密码。该命令还将提示您将公钥文件复制到远程主机上。
ssh-keygen -t ed25519 #该命令将生成一个 ed25519 密钥,并要求您输入密钥文件名和密码。该命令还将提示您将公钥文件复制到远程主机上。

4.将公钥文件复制到远程主机

当生成密钥对后我们想将自己的公钥添加到每一个我想要密钥连接的vps上。使用以下命令就能快速将公钥文件复制到vps。

ssh-copy-id -f -i /root/.ssh/id_rsa.pub -p 22  [email protected]    #这里将id_rsa.pub修改为你的公钥文件名称,端口修改为你的ssh端口。

输入命令后需要输入密码来确认。然后公钥就自动上传到你的远程vps内了。会在远程vps的~/.ssh下生成authorized_keys文件。

也可以在远程主机中直接用

echo '你的公钥'>> ~/.ssh/authorized_keys #填入公钥文件内容,可以追加填入多个公钥,使用多个密钥对登录同一台主机

5.使用密钥连接ssh

接下来可以在本机或有私钥的主机通过私钥连接ssh了。

ssh -i /root/.ssh/id_rsa  -p 22 [email protected] #-i指定密钥路径,-p可指定端口

# 🪼ssh登录简化方式一,配置~/.ssh/config

~/.ssh下可以创建一个config文件。这可以用来持久化的配置ssh登录参数。可以让ssh登录极其简单。类似以下的方式连接所有服务器。

1.配置~/.ssh/config

首先在这之前需要先配置密钥登陆,可参考这里:ssh密钥登录

然后使用文本编辑器创建并编辑一个~/.ssh/config文件。

vim ~/.ssh/config

编辑器打开文件后按i进入编辑模式,输入以下配置:

Host host1    #这里可以随意改成你觉得好记的主机名
  HostName 192.168.6.6  #IP地址
  User root            #用户名
  Port 22              #端口,改成你的ssh端口
  IdentityFile ~/.ssh/id_ed25519   #私钥文件地址
Host host2                     #可以添加多个服务器。
  HostName 192.168.6.7
  User root
  Port 9999
  IdentityFile ~/.ssh/id_ed25519

:wq保存退出后就可以在本地主机上直接使用ssh host1来直接进入上面ip为192.168.6.6的主机了。进入之后如果想退出,可以使用exit命令。连接第二台主机时只需要输入ssh host2即可,根据喜好命名。

# 🐙ssh登录简化方式二,配置alias别名

很简单,在本地主机一行命令就可以实现:

alias host1='ssh -i /root/.ssh/id_ed25519  -p 22 [email protected]'

这样就可以在本地主机中直接输入host1即可连接服务器

但是以上方式只在本次会话生效,所以可以写入~/.bashrc文件使之持久生效。

使用编辑器编辑~/.bashrc

编辑器打开文件后按i进入编辑模式,然后在文件最后一行添加

alias host1='ssh -i /root/.ssh/id_ed25519  -p 22 [email protected]'

:wq保存退出后使用

source ~/.bashrc即可应用设置。接着就可以使用host1登录远程主机了,同样的,想要添加多台主机就添加多个alias记录

# 🦀SCP命令

scpsecure copy缩写,它基于SSH实现远程文件拷贝。scp命令只能在UNIX内核系统(如Linux/mac OS) 中运行。Windows可用ftp。

scp [-options] user@host1:file1  user@host2:file2  #两个远程主机之间
scp [-options]  /file   user@host2:file2  #本地和远程主机之间,可互换,既可以本地传到远程主机,也可以远程主机传到本地
options 含义
-r 远程拷贝文件或递归拷贝目录
-P 指定远程服务器端口号,默认22端口可以省略

实例:

scp -P 22 -r /root/localfile   [email protected]:/root/  #既可以传输文件也可以传输目录,路径可以替换为任何你想要的

2.使用SSH Agent使两个远程主机更方便传输

当我需要本地主机使用ssh连接主机A之后,想在主机A中使用scp传输文件给主机B,A连接主机B时使用密钥的方式认证会更方便。

可以直接使用scp -r /file/test B:/flie而不需要密码或指定私钥路径。比如:

scp -P 22 -r  /opt/file/  [email protected]:/opt 

3.~/.ssh/config配置后两个远程主机之间传输

scp -r host1:/opt/file  host2:/opt

# 🦞SSH Agent转发

这是个非常好用的工具。SSH Agent Forwarding 是一种 SSH 功能,允许您通过 SSH 连接从本地系统转发 SSH Agent 到远程系统。为了安全,我们需要把私钥存储在本地,但有时我们需要一台远程主机使用ssh密钥连接到另一台远程主机。比如达到实现多层跳板机的目的。这时候如果把私钥传到A服务器会非常不安全且麻烦。所以我们可以使用SSH Agent。这使得在远程系统上可以使用本地系统的 SSH 私钥,而不需要将私钥直接暴露在远程系统上

1.启用本地系统上的 SSH Agent

Linux系统可以使用:

eval $(ssh-agent)

来开启ssh agent。

2.将本地 SSH 私钥添加到 SSH Agent 中

ssh-add

这个命令会自动添加本地私钥。

但是如果私钥存放在非默认路径下可以使用:

ssh-add ~/opt/id_rsa  #你的私钥路径和私钥文件名称

3.在连接远程系统时启用 Agent 转发

在本地连接远程主机时添加-o ForwardAgent=yes参数即可开启agent转发。也可以在/etc/ssh/sshd_config中修改AllowAgentForwarding yes

例如:

ssh -i /root/.ssh/id_rsa  -p 22 [email protected]  -o ForwardAgent=yes

配置过~/.ssh/config的本地主机可以直接使用:

ssh host1 -o ForwardAgent=yes

当然也可以写入config文件中:

Host host2
  HostName 192.168.6.7
  User root
  Port 22
  IdentityFile ~/.ssh/id_ed25519
  ForwardAgent yes

4.远程主机中查看SSH Agent是否生效

在进入后远程主机后输入以下命令:

ssh-add -L

来查看当前的私钥。可以看到出现了本地主机的私钥。这样就可以直接使用本地的私钥了。既安全又方便👍。

# 🐠SSH 端口转发/ssh隧道

ssh端口转发可以实现端口流量转发以及搭配公网ip主机实现内网穿透的效果,ssh也可以科学上网,感兴趣自行研究。

转发之前要在sshd_config设置AllowTcpForwarding yes

GatewayPorts参数用于控制SSH隧道中端口转发的行为。当设置为no时,表示只允许本地端口转发(即仅允许连接到SSH客户端的本地端口)。而当设置为yes时,表示允许远程主机连接到SSH服务器上的转发端口。

–D [bind_address:]port

指定一个本地的动态应用程序级别端口转发。该操作可以通过分配套接字以侦听本地端上的端口来实现,也可以选择绑定到指定的 bind_address。每当与此端口建立连接时,该连接就会通过安全通道转发。然后,使用应用程序协议确定从远程计算机连接到的位置。目前,支持 SOCKS4SOCKS5 协议,ssh 可充当 SOCKS 服务器。只有具有足够特权的用户才能转发特权端口。动态端口转发也可以在配置文件中进行指定。

指定 IPv6 地址时,可以通过备用语法 [bind_address/]port 或将该地址括在方括号中。缺省情况下,本地端口将根据 GatewayPorts 设置进行绑定。但是,可以使用显式 bind_address 将连接绑定到特定地址。localhost 的 bind_address 表示侦听端口仅供本地使用,而空地址或 * 则表示所有接口均可使用该端口。

如果要在本地计算机上创建一个 SOCKS 代理服务器,并将其绑定到本地的 1080 端口,并通过 SSH 连接到名为 user 的远程服务器 example.com,命令是:

ssh -D 1080 [email protected]

执行这个命令后,本地计算机上的 1080 端口就会成为一个 SOCKS 代理服务器,可以配置浏览器或其他应用程序使用该代理服务器进行网络连接,从而实现安全的网络传输。

–L [bind_address:]port:host:hostport

指定将本地(客户机)主机上的指定端口转发到远程端上的指定主机和端口。该操作可以通过分配套接字以侦听本地端上的端口来实现,也可以选择绑定到指定的 bind_address。然后,一旦与该端口建立连接,该连接就会通过安全通道进行转发,并与远程计算机上的主机端口 hostport 建立连接。端口转发也可以在配置文件中进行指定。只有具有足够特权的用户才能转发特权端口。指定 IPv6 地址时,可以通过备用语法 [bind_address/]port/host/hostport 或将该地址括在方括号中。

缺省情况下,本地端口将根据 GatewayPorts 设置进行绑定。但是,可以使用显式 bind_address 将连接绑定到特定地址。localhost 的 bind_address 表示侦听端口仅供本地使用,而空地址或 * 则表示所有接口均可使用该端口。

例:

  1. 将本地端口 8888 转发到远程主机 example.com 的端口 80 上
ssh -L 8888:localhost:80 [email protected]
  1. 常用参数组合,参数解释见下方
ssh -fgCNL 5566:127.0.0.1:5566  192.168.6.5

–R [bind_address:]port:host:hostport

指定将远程(服务器)主机上的指定端口转发到本地端上的指定主机和端口。该操作可以通过分配套接字以侦听远程端上的端口来实现。然后,一旦与该端口建立连接,该连接就会通过安全通道进行转发,并与本地计算机上的主机端口 hostport 建立连接。端口转发也可以在配置文件中进行指定。只有以具有足够特权的用户身份登录到远程计算机上时,才能转发特权端口。

IPv6 地址可以通过将地址括在方括号中或使用备用语法 [bind_address/]host/port/ hostport 来指定。

缺省情况下,服务器上的侦听套接字仅绑定到回送接口。通过指定 bind_address 可以覆盖此选项。空的 bind_address 或地址 * 表示远程套接字应在所有接口上侦听。只有在启用了服务器的 GatewayPorts 选项时,指定远程 bind_address 才会成功。请参见 sshd_config(4)

ssh -R 9999:127.0.0.1:80  -C -T -N root@公网地址 -P 22

将远程的9999端口转发到本地的80端口上

转发端口后公网访问; 客户端打开:GatewayPorts yes 服务端打开:AllowTcpForwarding yes

常用参数

  • “-L选项”:local,表示使用本地端口转发创建 ssh 隧道
  • “-R选项”:remote,表示使用远程端口转发创建 ssh 隧道
  • “-D选项”:dynamic,表示使用动态端口转发创建 ssh 隧道
  • “-N选项”: 表示创建隧道以后不连接到 sshServer端,通常与”-f”选项连用
  • “-f选项”:表示在后台运行ssh隧道,通常与”-N”选项连用
  • “-g选项”:表示 ssh 隧道对应的转发端口将监听在主机的所有IP中,不使用”-g选项”时,转发端口默认只监听在主机的本地回环地址中,”-g” 表示开启网关模式,远程端口转发中,无法开启网关功能

# 配置ssh隧道保活

为了避免长时间空闲导致ssh连接被断开,我们可以通过配置保活选项来定期发送心跳包保活。可以通过修改配置文件的方式,也可以在建立ssh链接时通过命令的-o选项指定。如:-o ServerAliveInterval=60,每60秒向ssh server发送心跳信号。

  1. 修改配置文件保活

第一种方法: 修改ssh server主机的/etc/ssh/sshd_config配置文件

ClientAliveInterval 60	#server每隔60秒,向client发送一次请求,然后client响应,从而保持连接。
ClientAliveCountMax 40	#client超过40次无响应就断开链接。

还有一个TCPKeepAlive选项的作用是类似的,但是不如ServerAliveInterval 好,因为TCPKeepAlive在TCP层工作,发送空的TCP ACK packet,有可能会被防火墙丢弃;而ServerAliveInterval 在SSH层工作,发送真正的数据包,更可靠。

第二种方法: 修改ssh client主机的/etc/ssh/ssh_config配置文件

ServerAliveInterval 60 #client每隔60秒发送一次请求给server,然后server响应,从而保持连接。
ServerAliveCountMax 3  #client发出请求后,服务器端没有响应得次数达到3,就自动断开连接,正常情况下,server不会不响应。

以上两种方法,任选一种即可。修改配置文件后记得重启服务。

  1. -o参数指定配置保活

在建立链接的命令参数里通过-o ServerAliveInterval=60保活, 这样只会在当前建立的连接中保持持久连接, 其他链接不受影响。毕竟不是所有连接都要保持持久的。

$ ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 [email protected] 

这里要提醒的是ServerAliveInterval 和 TCPKeepAlive 区别

  • TCPKeepAlive 在 TCP 层上运行。 它发送一个空的 TCP ACK 数据包。 防火墙可以配置为忽略这些数据包,因此如果您通过丢弃空闲连接的防火墙,这些可能无法保持连接活动。
  • ServerAliveInterval 操作在 ssh 层。 它实际上会通过 ssh 发送数据,因此 TCP 数据包已加密数据,防火墙无法判断它是保活数据包还是合法数据包,因此这些数据包效果更好。
  • ClientAliveInterval是配置在ssh服务端的,如果启用这个配置项则建议禁用 TCPKeepAlive。 此选项将通过加密通道发送消息以请求客户端的响应(默认为 0,因此ssh服务器端不会向客户端发送消息)。

# 🐧ssh命令参数

选项 描述
-1 强制 ssh 仅尝试协议版本 1。
-2 强制 ssh 仅尝试协议版本 2。
-4 强制 ssh 仅使用 IPv4 地址。
-6 强制 ssh 仅使用 IPv6 地址。
-a 禁用验证代理连接转发。
-A 启用验证代理连接转发。也可以在配置文件中按主机指定此选项。启用代理转发时应谨慎。如果用户能够绕过远程主机上的文件权限(有代理的 UNIX 域套接字),则可以通过转发的连接访问本地代理。攻击者无法从代理获取密钥材料。但是,攻击者可以对密钥执行操作,从而可以使用已装入代理的标识进行验证。
-b bind_address 在具有多个接口或别名地址的计算机上指定要从中传输数据的接口。
-c cipher_spec 选择用于为会话加密的加密算法规范。
-C 请求压缩所有数据。
-D [bind_address:]port 指定一个本地的动态应用程序级别端口转发。
-e ch | ^ch | none 使用 pty 为会话设置转义符。
-f 请求 ssh 在命令执行之前进入后台。
-F configfile 指定每个用户的备用配置文件。
-g 允许远程主机连接到本地转发端口。
-i identity_file 选择用于读取 RSA 或 DSA 验证所使用的标识(私钥)的文件。
-I PKCS#11-URI 与存储在 PKCS#11 令牌中的证书和私钥一起使用。
-l login_name 指定远程计算机上的登录用户。
-L [bind_address:]port:host:hostport 指定将本地主机上的指定端口转发到远程端上的指定主机和端口。
-m mac_spec 对于协议版本 2,也可以按优先顺序指定以逗号分隔的 MAC 算法列表。
-n 从 /dev/null 重定向 stdin。
-N 不执行远程命令(仅适用于协议版本 2)。
-o option 以配置文件中使用的格式指定选项。
-p port 指定所要连接的远程主机上的端口。
-P 过时选项,不支持从特权端口发起的 SSHv1 连接。
-q 静默模式,隐藏所有警告和诊断消息。
-R [bind_address:]port:host:hostport 指定将远程主机上的指定端口转发到本地端上的指定主机和端口。
-s 请求调用远程系统上的子系统。
-t 强制分配伪 tty。
-T 禁用伪 tty 分配(仅适用于协议版本 2)。
-v 详细模式,打印调试消息。
-x 禁用 X11 转发。
-X 启用 X11 转发,也可以在配置文件中按主机指定此选项。启用 X11 转发时应谨慎。

# 🦠后记

ssh还有更多的使用方式,我介绍的只是其中一些常用的基础部分。每个部分还有更多的应用场景,感兴趣的也可以研究一下。

记录一些基础但有用的玩机指南,还有我随心分享的各种内容,希望你能在这里找到你想要的