一、SSH 概述
1.1 SSH 概述
SSH(安全外壳协议)是一种在不安全的网络中通过加密来实现安全连接的网络协议,用于以加密方式远程登录其它计算机系统,通过SSH,用户可以安全地在远程服务器上进行文件传输和命令执行等操作。除了基本的远程终端功能外,SSH还提供了诸如远程命令执行、端口转发、数据隧道等高级功能。
Tips: sshd 是应用层和传输层的 SSH 服务
1.2 SSH相关各种文件分布
以主机A连接主机B为例,主机A为SSH客户端,主机B为SSH服务端。
在服务端即主机B上:
- /etc/ssh/sshd_config :ssh服务程序sshd的配置文件。
- /etc/ssh/ssh_host_* :服务程序sshd启动时生成的服务端公钥和私钥文件。如ssh_host_rsa_key和ssh_host_rsa_key.pub。
- 其中.pub文件是主机验证时的host key,将写入到客户端的~/.ssh/known_hosts文件中。
- 其中私钥文件严格要求权限为600,若不是则sshd服务可能会拒绝启动。
- ~/.ssh/authorized_keys:保存的是基于公钥认证机制时来自于客户端的公钥。在基于公钥认证机制认证时,服务端将读取该文件。
|
|
在客户端即主机A上:
- /etc/ssh/ssh_config :客户端的全局配置文件。
- ~/.ssh/config :客户端的用户配置文件,生效优先级高于全局配置文件。一般该文件默认不存在。该文件对权限有严格要求只对所有者有读/写权限,对其它人完全拒绝写权限。
- ~/.ssh/known_hosts :保存主机验证时服务端主机host key的文件。文件内容来源于服务端的ssh_host_rsa_key.pub文件。
- /etc/ssh/known_hosts:全局host key保存文件。作用等同于~/.ssh/known_hosts。
- ~/.ssh/id_rsa :客户端生成的私钥。由ssh-keygen生成。该文件严格要求权限,当其他用户对此文件有可读权限时,ssh将直接忽略该文件。
- ~/.ssh/id_rsa.pub :私钥id_rsa的配对公钥。对权限不敏感。当采用公钥认证机制时,该文件内容需要复制到服务端的 ~/.ssh/authorized_keys 文件中。
- ~/.ssh/rc :保存的是命令列表,这些命令在ssh连接到远程主机成功时将第一时间执行,执行完这些命令之后才开始登陆或执行ssh命令行中的命令。
- /etc/ssh/rc :作用等同于~/.ssh/rc。
1.3 基于公钥认证机制实现双机互信
实现基于公钥认证的实现步骤:
- 在客户端使用ssh-keygen生成密钥对,存放路径按照配置文件的指示,默认是在 ~/.ssh/ 目录下。
|
|
- 将生成的公钥 id_rsa.pub 使用 ssh-copy-id 分发(即复制)到远程待信任主机上。
ssh-copy-id用法很简单,只需指定待信任主机及目标用户即可。如果生成的公钥文件路径不是 ~/.ssh/id_rsa.pub,则使用 -i
选项指定要分发的公钥。
|
|
Tips: ssh-copy-id的作用是在目标主机的指定用户的家目录下,检测是否有~/.ssh目录,如果没有,则以700权限创建该目录,然后将本地的公钥追加到目标主机指定用户家目录下的~/.ssh/authorized_keys文件中。
ssh-copy-id 唯一需要注意的是,如果ssh服务端的端口不是22,则需要给 ssh-copy-id 指定传递端口号,传递方式为 “-p port_num [user@]hostname” (注意加上双引号),例如:ssh-copy-id “-p 22222 root@172.16.10.6”。
二、SSH 常用命令
2.1 SSH基本用法 - 远程登录
|
|
参数:
- -p:指定端口号。
- user:登录的用户名,(连同@)省略时用户名与本地主机用户名相同。
- host:登录的主机。
SSH服务端(sshd)默认的端口号为22,当端口号为22的时候,可以省略,直接使用如下方式:
|
|
2.2 SSH的远程操作
在远程的机器上面执行操作,格式如下:
|
|
command: 为 要执行的 shell 命令
案例1:在机器A(192.168.13.148)中查看机器B(192.168.13.149)的操作系统类型。
在A机器上面执行如下代码:
|
|
案例2:将机器A(192.168.13.148)中test文件夹复制到B机器(192.168.13.149)。
在A机器上面,执行如下命令:
|
|
三、SSH 端口转发
3.1 SSH端口转发的概念
SSH端口转发是一种通过SSH协议在本地和远程主机之间建立安全通道,实现端口之间的数据转发,也称为SSH隧道。它允许在不直接访问目标主机的情况下,通过安全的SSH连接来访问该主机上的服务。通过SSH端口转发,可以将本地端口与远程主机上的服务端口相关联(映射),使得在本地主机上运行的应用程序能够通过SSH隧道与远程主机上的服务进行通信。
SSH端口转发通常被用来绕过防火墙等设备穿透到内网,或用于保护TCP连接等。
SSH端口转发有三种常见的类型:本地端口转发(Local Port Forwarding)、远程端口转发(Remote Port Forwarding) 和 动态端口转发(Dynamic Port Forwarding)。
SSH端口转发是一种强大而灵活的功能,通过安全的SSH连接,可以将流量从一个端口转发到另一个端口。
SSH端口转发常用参数:
- -C:压缩数据
- -f:后台认证用户/密码,通常和-N连用,不用登录到远程主机。
- -N:不执行脚本或命令,通常与-f连用。
- -g:在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。
- -L: 本地端口:目标IP:目标端口
- -D: 动态端口转发
- -R: 远程端口转发
- -T:不分配 TTY 只做代理用
- -q:安静模式,不输出 错误/警告 信息
3.2 本地端口转发
本地端口转发(local port forwarding) 是最常用的SSH端口转发类型之一。它允许将本地主机上的一个端口(local_port)转发到远程主机上的另一个端口(remote_port)。当需要通过SSH访问位于防火墙后面或者只能在远程主机上访问的服务时,本地端口转发非常有用。通过本地端口转发,可以在本地主机上创建一个监听指定端口(local_port)的SSH隧道,将该端口(local_port)上的流量转发到远程主机上的指定端口(remote_port)。这样,就可以通过本地主机上的端口(local_port)与远程主机上的服务进行通信。即 访问本地主机端口(local_port),实际上是访问远程主机(remote_host)的端口(remote_port)。
Tips: 我们把执行本地转发命令的设备称为本地主机。
命令格式:
|
|
- -f -N 参数设置 命令后台运行
- local_ip 可以省略(省略时默认值为:localhost/127.0.0.1),也可指定为本机网口的 IP 或 0.0.0.0(全部网口)
- ssh_server 可以是 本机 或 任意 本机可通过 ssh 访问的 远程主机
- remote_host 可以是 ssh_server 或 任意 ssh_server 主机可 访问的 远程主机
流量转发流程:
- SSH 客户端会监听本地的端口 local_port,把所有发给该端口的 TCP 报文都 通过 ssh 发给指定的 ssh_server 服务
- ssh_server服务 收到这类报文 后再转发到目标主机服务(remote_host:remote_port)
- 在目标机器看来,这个请求来自 ssh_server。
原型图:
示例:
|
|
3.3 远程端口转发
远程端口转发(remote port forwarding) 是另一种常见的SSH端口转发类型。它允许将远程主机上的一个端口(remote_port)的流量通过SSH隧道传输(转发)到本地主机上的另一个端口(local_port)。将远程主机(remote)上的端口流量 通过 ssh 转发到本地(ssh 客户端)机器上的端口,本机(ssh 服务器)再转发到目标机器上的端口。
当需要将远程主机上的某个服务映射到本地主机上,或者需要远程主机上的其它计算机访问本地主机上的服务时,远程端口转发非常有用。通过远程端口转发,可以在远程主机上创建一个监听指定端口(remote_port)的SSH隧道,将该端口(remote_port)上的流量转发到本地主机上的指定端口(local_port)。这样,远程主机上的流量就可以通过SSH隧道传输到本地主机上的指定端口(port1),实现服务的访问。
- 用户 A 发起连接:用户A在本地主机上使用SSH命令发起远程转发连接。示例命令为:
- 建立 SSH 连接:本地主机与 SSH 服务器之间建立 SSH 连接。这一步骤确保所有数据都通过安全的 SSH 隧道传输。
- 用户 B 访问服务:远程主机上的用户 B 试图通过 SSH 服务器访问本地主机上的服务。
- 请求转发:SSH 服务器接收到用户 B 的请求后,通过已建立的 SSH 隧道将请求转发到用户 A 的本地主机上的端口。
- 响应返回:本地主机将响应通过 SSH 隧道发送回 SSH 服务器,SSH 服务器再将响应转发回远程主机。
命令格式:
|
|
远程转发应用场景:
假设在本地计算机上运行了一个 Web 服务器(例如:localhost:80),希望通过中转服务器 sshserver.com 让远程用户访问该 Web 服务器。
|
|
执行上述命令后,远程用户可以通过访问 sshserver.com:8080 来连接到本地计算机上的 Web 服务器。
- 在本地计算机上运行
ssh -R 8080:localhost:80 user@sshserver.com
。 - SSH 服务器在 sshserver.com:8080 上监听。
- 当远程用户连接到 sshserver.com:8080 时,SSH 服务器通过 SSH 隧道将请求转发到本地计算机上的 localhost:80。
- 本地计算机返回的响应通过相同的路径返回到远程用户。
3.4 动态端口转发
SSH 动态转发(SSH Dynamic Port Forwarding)是一种通过 SSH 隧道实现的代理功能,它允许在本地计算机上创建一个 SOCKS 代理服务器,从而使得所有通过这个代理的流量都通过 SSH 隧道加密并转发到远程服务器。与本地转发和远程转发不同,动态转发不需要预先指定目标主机和端口,而是可以动态地决定目的地,这使其更加灵活。
动态端口转发 是SSH端口转发的另一种类型,也称为SSH动态代理。与本地端口转发和远程端口转发只能将一个端口进行转发不同,动态端口转发可以创建一个动态代理通道,将本地主机上的多个端口转发到远程主机上。通过动态端口转发,可以在本地主机上创建一个监听指定端口的SSH隧道,将本地主机上的流量通过SSH通道转发到远程主机上,然后再由远程主机发送到最终的目标地址。动态端口转发通常用于代理服务器或通过中间节点访问特定网络资源。
- 用户发起连接:用户在本地主机上使用 SSH 命令发起动态转发连接。示例命令为:
- 建立 SSH 连接:本地主机与 SSH 服务器之间建立 SSH 连接。这一步确保所有数据都通过安全的 SSH 隧道传输。
- 设置本地 SOCKS 代理:本地计算机在指定端口(例如 8080)上启动一个 SOCKS 代理。任何发送到该端口的流量都会通过 SSH 隧道转发到远程服务器。
- 用户配置应用程序:用户配置需要通过代理访问网络的应用程序(如浏览器),使其使用本地 SOCKS 代理端口(例如 8080)。
- 应用程序发出请求:用户在应用程序中访问某个远程服务器(例如访问某个网站)。应用程序的请求首先发送到本地 SOCKS 代理端口。
- 请求转发:本地计算机捕获通过 SOCKS 代理端口的请求,通过已建立的 SSH 隧道将请求加密并转发到 SSH 服务器。
- SSH 服务器处理请求:SSH 服务器接收到请求后,根据请求中的目标地址和端口访问远程服务器。
- 远程服务器处理请求并返回响应:远程服务器接收请求后进行处理,生成响应数据,并将其返回给 SSH 服务器。SSH 服务器将响应数据通过 SSH 隧道加密并发送回本地主机。
那么我们都有了远程转发和本地转发,为什么还需要动态转发呢?
那么我们思考这样一个问题,如果我们本地转发的目的端口为443,对端是一个HTTPS服务,在我们通过浏览器访问时,由于本地监听的地址为localhost,则会出现证书无法被验证的问题。还有假设这个Web服务器将我们重定向至另一个URL,很有可能将连接失败,例如在使用单点登录时(SSO),这种情况很可能出现问题。
使用动态转发则能够解决这个问题,动态转发的实现是SSH通过在本地建立Socks代理,然后通过SSH转发到远程主机,然后远程主机再将SSH内的数据包转发至内网主机。
命令格式:
|
|
3.5 SSH端口转发的用途
SSH端口转发具有广泛的用途,以下是其中一些常见的应用场景:
- 安全远程访问
通过SSH端口转发,您可以安全地访问位于防火墙后面的远程主机或仅在内部网络中可访问的服务。通过建立SSH隧道,您可以将本地主机上的某个端口转发到远程主机上,然后通过SSH连接进行访问。这样,您就可以使用SSH协议的加密和身份验证功能来保护远程访问的安全性。
- 跨越网络限制
在某些情况下,您可能面临着网络限制,无法直接访问某些服务或资源。使用SSH端口转发,您可以绕过这些限制,通过建立安全的SSH通道将流量转发到允许访问的网络上。这对于跨越防火墙或访问受限制的网络资源非常有用。
- 加密流量传输
SSH端口转发不仅仅用于访问远程服务,还可以用于加密流量传输。通过将本地主机上的流量通过SSH隧道转发到远程主机上,然后再由远程主机发送到最终的目标地址,您可以确保数据在传输过程中受到SSH协议的加密保护。这对于传输敏感数据或在不受信任的网络上操作非常重要。
- 跨越 NAT 网络
NAT(Network Address Translation)是一种常见的网络配置,用于在私有网络和公共网络之间转换IP地址。当您需要在私有网络中访问公共网络上的服务时,NAT可能会导致问题。通过使用SSH端口转发,您可以将本地主机上的流量通过SSH隧道转发到公共网络上的服务。这样,您可以绕过NAT限制,实现私有网络与公共网络之间的通信。
- 安全代理
动态端口转发可以用作安全代理,通过建立动态代理通道将本地主机上的流量转发到远程主机上。这对于通过中间节点访问受限制的网络资源非常有用。通过SSH端口转发,您可以在本地主机上配置代理设置,使得所有的网络流量都通过SSH隧道转发到远程主机上,然后再由远程主机发送到最终的目标地址。