ssh的基础使用与端口转发

发布时间 2023-04-12 22:22:54作者: 厚礼蝎

基础使用

基本连接

SSH基本的连接命令是:

ssh username@hostname

这里牵扯到了两台主机

  1. 执行命令、运行SSH客户端的主机,我们称为本地主机A【Host A】;
  2. 接收连接请求、运行SSH服务器的主机,我们称为远程主机B【Host B】。

通过密码或密钥等方式验证后,SSH连接建立,主机A可以使用命令行对主机B实施远程控制。

以上命令中,username是主机B上可登录的用户名,hostname则是主机B的设备名、域名或IP等可以在网络(局域网或互联网)上定位的名称。

登录类型

  • 密码登录: 服务器发送公钥给客户端,客户端使用公钥加密后回传给服务器,服务器解密验证密码。
    ssh abc@xxx.xxx.xxx.xxx -p 22
    
  • 公钥登录: 服务器发送一个随机字符串给客户端,客户端用私钥加密,服务器用公钥解密(rsa作为签名使用)
    ssh -i .ssh/id_rsa abc@xxx.xxx.xxx.xxx -p 22
    

相关参数

  • -A:密钥转发 这个参数在使用跳板机等场景非常有用,如果发现始终连不上需要检查下这个
  • -i:指定密钥文件
  • -p:端口号
  • -C:请求压缩所有数据;
  • -f:后台运行,一般与-f搭配使用
  • -N:不要求分配shell,有些场景下ssh禁止账号请求shell终端,比如这个账号只是作为转发
  • -g:默认这个LocalPort端口只允许本机连接,可以通过这个参数允许别的机器连接这个端口
  • -T:不要求分配终端
  • -o ServerAliveInterval=60:隔段时间发送保活消息
  • -q:抑制一些调试性的额外输出
  • -4:强制ipv4地址
  • -6:强制ipv6地址
  • -F:指定ssh客户端的配置文件
  • -q:静默模式,所有的警告和诊断信息被禁止输出

相关命令

  • ssh-keygen 用于生成密钥对
  • ssh-copy-id 用于复制公钥到服务器

相关文件

  • ~/.ssh/authorized_keys 用于保存用户的公钥文件
  • ~/.ssh/known_hosts 文件 保存的服务器用于辨别服务器的唯一散列码
  • ~/.ssh/id_dsa 用户的私钥文件
  • ~/.ssh/id_rsa.pub 默认生成的用户的公钥文件,用于将该公钥追加到需要登录的服务器authorized_keys文件
  • /etc/ssh/ssh_confi 客户端ssh配置
  • /etc/ssh/sshd_config 服务端ssh配置

端口转发

什么是端口转发?

SSH 隧道SSH 端口转发可以用来在客户端和服务器之间建立一个加密的 SSH 连接,通过它来把本地流量转发到服务器端,或者把服务器端流量转发到本地。

比如从本地访问服务器上的 MySQL 管理后台,或者把本地的服务暴露在公网上。

比如从公网上访问你家里的的NAS。

端口转发分为:

  • 本地端口转发
  • 远程端口转发.

本地端口转发

简而言之

将ssh服务器(中转服务器)上的本地端口转发到别的本地端口或者其他能连接的服务器端口

这里的本地端口就是作为中转服务器上的本地端口

本地端口转发的语法

ssh -L [LOCAL_IP:]LOCAL_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER

这时 SSH 客户端会监听本地的端口 LOCAL_PORT,把所有发给该端口的 TCP 连接都发给指定的服务器,然后再连接到目标机器。

这个目标机器通常是服务器自己,也可以是任何其他机器。

在目标机器看来,这个请求来自 SSH 服务器,相当于连到了服务器的内网。

场景1

例如你在家想连接到公司的数据库。
但是IT部门只给了你一个跳板机172.16.1.60。
你在家里用笔记本连上网就可以连上这个跳板机。
这个跳板机是通过公司防火墙NAT转换出去的。
当然跳板机是能够连接数据库的。
现在你可以连接数据库了,可是跳板机上没有你习惯使用的工具,例如navicat。
此时在不麻烦it的前提下你可以通过ssh远程端口转发来解决这个问题. (如果公司网络有堡垒机或者其他网络隔离设备可能会禁掉,这里不做讨论)

大概的架构是这样的

需要做的就是将远程的数据库3306上的服务通过对外的跳板机映射到本地,你就可以使用navicat连接数据库了。

此时,你就可以在跳板机上做一个本地端口转发的配置

ssh -N -f -L 3301:192.168.122.76:3306 172.16.1.60
  • -L: 就是本地转发的标志
  • -N:不要求分配shell,有些场景下ssh禁止账号请求shell终端,比如这个账号只是作为转发
  • -f:后台运行,一般与-f搭配使用

注意:-N一定不能是第一个参数

这个ssh命令的意思是所有跟 跳板机 上的 3301 端口的TCP数据传输都会直接通过 跳板机 的 ssh服务 转发给数据库服务器(192.168.122.76:3306)。

也就是说将本地的3301 端口映射到了内网的3306端口。

至此你就可以使用navicat连接本地的3301 端口连接远程数据库服务了.

场景2

防火墙阻止了外部主机对服务器一些端口的连接,但服务器仍有部分端口是对外开放的。
这时外部主机如果需要访问服务器上被防火墙阻挡的端口,就可以通过 SSH连接服务器+端口转发 来进行。

在服务器上配置

ssh -N -f -L 5920:localhost:5901 cloud_user@1.1.1.1

参数不再做赘述

这里的5920就是服务器上对外开放的端口
5901是被防火墙阻挡的端口,cloud_user表示服务器上的一个用户,1.1.1.1是服务器的对外ip地址(如果是经过防火墙NAT转换的,那这里的ip就是防火墙上的出口IP)

这个命令的意思就是把对5920端口的访问通过ssh服务转发到本地的5901端口上

这个时候外部就可以通过5920端口间接访问5901端口

远程端口转发

简言之

将远程ssh服务器主机的端口转发到本地端口

远程端口转发的语法

ssh -R [REMOTE:]REMOTE_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER -p [ssh_port]
  • [REMOTE:]REMOTE_PORT- 远程 SSH 服务器上的 IP 和端口号。空的REMOTE意味着远程 SSH 服务器将绑定到所有接口。
  • DESTINATION:DESTINATION_PORT- 目标机器的 IP 或主机名和端口。
  • [USER@]SERVER_IP- 远程 SSH 用户和服务器 IP 地址。
  • -p [ssh_port] 是可选项,当ssh端口被修改,就需要加上这项

场景一

外网可以访问内部的一个服务,在任何有网络的地方(而不再限制在某台主机上,应用更广泛)都可以访问你的服务啦。

注意:

在公网上需要放行安全组8888这个端口。

在10.0.0.4上执行远程端口转发命令,该主机和公网22端口可达。(其实只要求公网能ssh到10.0.0.4就可以了,企业里面一般都是出口松进口严)

ssh -N -f -R 8888:10.0.0.3:8080 44.11.22.33

场景二

OpenSSH服务器对于远程端口转发的设定,默认只接受远程主机B本机上的应用发起的请求。

想要从其他连接到B的设备发起请求,需将【sshd_config】文件中【GatewayPorts】选项后的【no】修改为【yes】
如果长时间保持连接,那么还需要将 【TCPKeepAlive】 设置为 【yes】

手头上计算机A运行着http服务,但A没有公网IP,其他设备不能使用该服务。
恰好云服务器B有公网IP(甚至域名),便于被访问。
在不将http服务迁移至云服务器B的前提下,可以使用SSH端口转发使其他设备通过访问B的方式访问A上的http服务。

(在A上)执行端口转发命令

ssh -N -f -R 8080:localhost:80 cloud_user@server.example.com

前面的8080是B上的端口
localhost:80 是A上的端口
cloud_user@server.example.com 是B上的用户和地址或者域名

于是大家可以通过访问 http://server.example.com:8080 来访问本地计算机A提供的http服务了。