一、命令简介
ssh
命令用于安全登录远程主机,以便在远程机上执行命令或传输数据。
例如登录远程主机 169.10.222.23
上的 soulio
用户:
ssh soulio@169.10.222.23
更多示例参考第三章。
了解背景知识:ssh 加密
1. 加密类型
- 对称加密: 在数据传输过程中使用相同的密钥进行加密和解密。常见的对称加密算法包括 AES(高级加密标准)、Blowfish 和 3DES(Triple Data Encryption Standard)。
- 非对称加密: 使用一对密钥(公钥和私钥)来加密和解密数据。公钥可以公开,而私钥则应保密。常见的非对称加密算法包括 RSA 和 DSA。
- 哈希函数: 用于确保数据完整性,防止数据在传输过程中被篡改。常见的哈希算法包括 SHA-256 和 SHA-1。
2. SSH 加密过程
- 密钥交换: 在连接开始时,客户端和服务器通过非对称加密交换公钥,以安全地生成共享的会话密钥。
- 会话密钥生成: 一旦密钥交换成功,双方生成一个对称的会话密钥,后续的通信将使用这个会话密钥进行加密。
- 数据加密: 使用会话密钥加密所有发送的数据,包括命令、输出和文件传输。
- 数据完整性检查: 在传输过程中,SSH 使用哈希函数确保数据的完整性,防止数据被篡改。
3. SSH 密钥管理
- 密钥对生成: 用户可以使用
ssh-keygen
工具生成 SSH 密钥对(公钥和私钥)。 - 公钥分发: 将公钥添加到远程主机的
~/.ssh/authorized_keys
文件中,以便通过私钥进行身份验证。 - 私钥安全性: 私钥应妥善保管,通常加密存储,并在使用时输入密码。
4. SSH 加密的优点
- 安全性高: SSH 加密保护了数据传输过程中的机密性和完整性,防止窃听和数据篡改。
- 身份验证: SSH 支持多种身份验证方式,包括密码、密钥对和基于证书的认证,提供了灵活的安全选项。
- 远程管理: SSH 使得系统管理员能够安全地管理远程服务器,执行命令和文件传输。
5. 总结
SSH 加密是保护远程连接和数据传输的关键技术,广泛应用于网络管理和安全通信。通过对称和非对称加密、密钥交换和数据完整性检查,SSH 确保了用户在使用网络时的数据安全。
除了 ssh
命令外,stfp
和 scp
这两个文件传输命令也建议在 SSH 加密之上。
二、命令参数
命令格式
ssh [选项] [用户名@]主机名或IP地址 [命令]
常用参数
-
-p port
: 指定连接的端口号,默认是 22。 -
-i identity_file
: 指定私钥文件用于身份验证。 -
-v
: 启用详细模式,显示连接过程中的调试信息。 -
-X
: 启用 X11 转发,以便在本地显示远程 GUI 应用程序。 -
-C
: 启用压缩,提高传输速度。
选项太多,这里仅做收集,方便用时查阅。此刻的你不用记,甚至不用看。
更多选项
-
-p
: 指定端口(例如:ssh -p 2222 user@example.com
)。 -
-i
: 指定私钥文件(例如:ssh -i /path/to/private/key user@example.com
)。 -
-l
: 指定登录用户名(例如:ssh -l user example.com
)。 -
-o
: 指定自定义 SSH 选项(例如:ssh -o "OptionName Value" user@example.com
)。 -
-4
: 强制使用 IPv4 地址(例如:ssh -4 user@example.com
)。 -
-6
: 强制使用 IPv6 地址(例如:ssh -6 user@2001:db8::1
)。 -
-C
: 启用压缩(例如:ssh -C user@example.com
)。 -
-c
: 指定加密算法(例如:ssh -c blowfish,user@example.com
)。 -
-D
: 动态端口转发(例如:ssh -D 1080 user@example.com
)。 -
-L
: 本地端口转发(例如:ssh -L 8080:localhost:80 user@example.com
)。 -
-R
: 远程端口转发(例如:ssh -R 8080:localhost:80 user@example.com
)。 -
-N
: 不执行远程命令,用于端口转发(例如:ssh -N -L 8080:localhost:80 user@example.com
)。 -
-f
: 后台执行(例如:ssh -f -L 8080:localhost:80 user@example.com
)。 -
-g
: 允许远程主机连接到转发的端口(例如:ssh -g -L 8080:localhost:80 user@example.com
)。 -
-T
: 禁用伪终端分配(例如:ssh -T user@example.com
)。 -
-t
: 分配伪终端(例如:ssh -t user@example.com
)。 -
-v
: 详细模式(例如:ssh -v user@example.com
)。 -
-X
: 启用 X11 转发(例如:ssh -X user@example.com
)。 -
-Y
: 信任的 X11 转发(例如:ssh -Y user@example.com
)。
三、命令示例
1 最简单登录
1.命令格式
ssh user@example.com
- user:要登录的用户
- example.com:要登录的主机,可以是一个
域名
,也可以是一个ip
,还可以是一个别名
。最终都会指向某台主机。
对于未指定的信息,将会使用默认配置,比如端口使用 22
2.开始登录
登录会验证用户密码,密码验证成功后进入远程主机的终端。
现在你可以管理这台远程主机:执行命令,传输文件等操作。
3.退出登录
输出 exit
退出登录,将会回到本地主机的终端中。
2 指定端口登录
ssh -p 2222 user@example.com
通常 SSH 使用默认端口 22 进行通信,但是有些管理员可能会修改默认端口号,以避免网络攻击。如果你不知道正确的端口号,就无法与远程主机建立 SSH 连接。如果你知道正确端口号,可以使用 -p
指定,如上所示:-p 2222
指定连接远程主机的 2222 端口,而非 22 端口。
3 让远程计算机执行一条命令
ssh user@example.com 'ls'
需要让远程计算机执行的命令,写在 ssh 命令的最后。通常命令执行后会有一个输出,输出会直接返回到当前终端中。这个例子将会返回在远程计算机上执行 ls
的结果,也就是列出远程计算机 example.com 的 user 用户的家目录列表。
4 秘钥管理
如果你经常登录某个远程主机,每次都要输密码就会显得很麻烦。有没有方法,让我们不需要输入密码就可以登录远程主机?有。
方法一:使用 SSH 客户端
比如 Termius
将登录信息保存到客户端中
下次登录时,客户端会调用你的配置(用户名、主机、密码)。从而用户无需输入。
方法二:使用公钥
将本地计算机的公钥发送远程计算机上,下次登录就不需要输入密码。真正的免密登录。
1.生成秘钥
如果新装的系统,可能还没有生成秘钥信息,使用以下命令生成秘钥:
ssh-keygen
中间会有两三次提示,不用管,直接按回车键。看到类似提示就成功了。
2.把公钥部署到远程主机
ssh-copy-id user@example.com
- user 换成你在远程主机上的用户名
- example.com 换成你的远程主机,可以是域名,可以是 ip,还可以是别名。最终都会指向你的主机。
tips:如果你有多个公钥,可以在命令中加上 -i 目录
部署指定公钥。
执行命令,成功会有类似输出
现在登录远程主机就不会再验证密码了。
5 使用别名
例如用 armbian
作为 soulio@192.168.10.36
的别名,这样用 ssh armbian
就可以登录指定主机,输入起来更友好。
实现步骤:
第一步,修改本地 ~/.ssh/config
文件,添加主机别名:
Host armbian
HostName 192.168.10.36
User soulio
Port 22 #可选的配置
IdentityFile ~/.ssh/id_rsa #可选的配置
第二步,使用别名登录远程主机:
ssh armbian
6 端口转发
在 SSH 中,端口转发和代理转发是两种非常有用的功能,它们允许用户通过 SSH 会话来转发网络流量,从而绕过防火墙、访问内网资源或保护网络通信。
SSH 端口转发是通过 SSH 通道安全地传输 TCP 流量的功能,可以分为三种类型:本地端口转发、远程端口转发和动态端口转发。它们分别允许将本地端口、远程端口或任意的流量通过 SSH 通道进行转发。
本地端口转发 (远程发到本地)
本地端口转发将本地计算机的一个端口绑定到远程服务器上的某个端口。这种方式常用于从本地访问远程服务器上的内部资源。
语法:
ssh -L [local_port]:[remote_host]:[remote_port] [user@ssh_server]
-
local_port
: 本地机器上将绑定的端口。 -
remote_host
: 远程主机地址,可以是服务器的内部 IP 或域名。 -
remote_port
: 远程主机的端口号。 -
ssh_server
: 用于建立 SSH 连接的服务器。
示例:
ssh -L 8080:intranet.example.com:80 user@ssh_server.com
这个命令将本地机器的 8080
端口与远程服务器 ssh_server.com
上的内部主机 intranet.example.com
的 80 端口相连。你可以通过在浏览器中访问 http://localhost:8080
来访问远程内网的资源。
在局域网中实验:
ssh -L 8080:localhost:32769 soulio@192.168.10.63
- 源:在 192.168.10.63:32769 上搭建 web 页面
- 转发:转发到本地 8080
远程端口转发 (本地发到远程)
远程端口转发允许将远程服务器上的一个端口绑定到本地计算机或另一个远程机器的端口上,通常用于将外部网络的请求转发到本地计算机上。
语法:
ssh -R [remote_port]:[local_host]:[local_port] [user@ssh_server]
-
remote_port
: 远程服务器上的端口。 -
local_host
: 本地计算机的地址。 -
local_port
: 本地机器上的端口。
示例:
ssh -R 8080:localhost:3000 user@ssh_server.com
此命令将远程服务器 ssh_server.com
的 8080
端口绑定到本地机器的 3000
端口。任何对 ssh_server.com:8080
的请求都会转发到你本地计算机的 3000
端口。
设置-允许远程转发:
编辑远程主机 sudo nano /etc/ssh/sshd_config
GatewayPorts yes
GatewayPorts 默认为 no,不允许远程转发。必须开启。修改配置后重启 ssh 服务使其生效。
在局域网中实验:
ssh -R 8081:localhost:16601 soulio@192.168.10.63
- 源:在本地 3000 端口搭建一个 web 页面
这里源不局限于本地主机,只要是本地主机可以访问到的页面都可以,比如 192.168.10.55:16601
- 转发:转发到 192.168.10.63:8080
动态端口转发
动态端口转发是一种灵活的方式,它将本地机器的一个端口用作 SOCKS 代理,可以转发任意的网络请求。这种方式允许你通过 SSH 通道代理所有网络流量,类似于 VPN 的效果。
语法:
ssh -D [local_port] [user@ssh_server]
-
local_port
: 用于 SOCKS 代理的本地端口。
示例:
ssh -D 1080 user@ssh_server.com
此命令将本地端口 1080
设置为 SOCKS 代理端口。你可以在浏览器或其他应用中设置 SOCKS 代理为 localhost:1080
,通过 SSH 服务器转发所有网络流量。
使用体验:但不好用。用了几分钟就开始报错,超时。建议用其他简单、稳定的工具呢。也可能是我未能掌握关键。
设置-允许动态转发:
编辑远程主机 sudo nano /etc/ssh/sshd_config
AllowTcpForwarding yes #默认是yes
PermitTunnel yes #默认是no 改为yes
确保这些选项被设置为 yes
,然后重启 SSH 服务:
sudo systemctl restart ssh
7 代理转发
- 代理转发,例如本地端口 1080
ssh -D 1080 user@example.com
- SSH 代理转发 (Agent Forwarding)
SSH 代理转发是一种允许在远程服务器上使用本地 SSH 代理功能的机制。通过代理转发,你可以在远程服务器上使用本地的 SSH 私钥进行身份验证,而不需要将私钥复制到远程服务器上。这对于通过中间跳板服务器访问更多服务器时非常有用。
- 工作原理
SSH 代理转发通过 SSH 代理 (ssh-agent
) 进程,将本地机器的 SSH 代理功能转发到远程服务器。这样,远程服务器上的应用程序可以通过本地 SSH 代理进行密钥认证,而不会暴露私钥。
- 使用方式
使用 -A
选项启用 SSH 代理转发。
语法:
ssh -A user@ssh_server
示例:
ssh -A user@jump_server
假设你通过 jump_server
访问另一台服务器 server2
,你可以在 jump_server
上通过 SSH 代理连接到 server2
,而无需在 jump_server
上存储私钥:
ssh user@server2
总结
- 端口转发允许你通过 SSH 通道安全地转发本地或远程的网络流量,支持本地、远程和动态端口转发。
- 代理转发允许在远程服务器上使用本地 SSH 代理进行身份验证,避免在远程服务器上存储私钥,增加了安全性和灵活性。
这两种功能在网络安全和远程访问方面提供了极大的便利,尤其是在访问内网资源或通过跳板服务器进行管理时。
注意事项
如果你使用 WSL 环境,可能在某些环节遇到网络问题。
远程转发时,WSL 无法将 localhsost:xxx 转发到远程端口。在纯 Linux 环境则成功。