ssh — OpenSSH 远程登录客户端
概要
ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
[-i identity_file] [-J destination] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd]
[-o option] [-P tag] [-p port] [-R address] [-S ctl_path] [-W host:port]
[-w local_tun[:remote_tun]] destination [command [argument ...]]
ssh [-Q query_option]
描述
ssh(SSH 客户端)是一个用于登录到远程机器并执行远程机器上命令的程序。它旨在提供两个不信任的主机在不安全网络上进行安全加密通信。X11 连接、任意 TCP 端口和 Unix 域套接字也可以通过安全通道转发。
ssh 连接并登录到指定的目的地,目的地可以指定为 [user@]hostname 或 ssh://[user@]hostname[:port] 形式的 URI。用户必须使用以下几种方法之一来向远程机器证明其身份(如下所示)。
如果指定了命令,则将在远程主机上执行该命令,而不是登录 shell。完整的命令行可以指定为命令,或者可以附加其他参数。如果提供了参数,则将在将其发送到服务器以执行之前,将参数附加到命令中,并用空格分隔。
选项如下:
-4 强制 ssh 仅使用 IPv4 地址。
-6 强制 ssh 仅使用 IPv6 地址。
-A 启用从身份验证代理(如 ssh-agent(1))转发连接。这也可以在每个主机的基础上在配置文件中指定。
应谨慎启用代理转发。具有绕过远程主机上文件权限(用于代理的 Unix 域套接字)能力的用户可以通过转发的连接访问本地代理。但是,攻击者无法从代理中获取密钥材料,但是他们可以对密钥执行操作,从而使他们能够使用加载到代理中的身份进行身份验证。更安全的替代方法可能是使用跳跃主机(参见 -J)。
-a 禁用身份验证代理连接的转发。
-B bind_interface 在尝试连接到目标主机之前,绑定到 bind_interface 的地址。这仅在具有多个地址的系统上才有用。
-b bind_address 使用本地机器上的 bind_address 作为连接的源地址。仅在具有多个地址的系统上才有用。
-C 请求压缩所有数据(包括 stdin、stdout、stderr 以及转发的 X11、TCP 和 Unix 域连接的数据)。压缩算法与 [gzip]({filename}../../gzip)(1) 中使用的算法相同。压缩对于调制解调器线路和其他慢速连接是有益的,但会在快速网络上降低速度。默认值可以在每个主机的基础上在配置文件中设置;请参阅 ssh_config(5) 中的“压缩”选项。
-c cipher_spec
选择用于加密会话的密码规范。cipher_spec 是一个逗号分隔的密码列表,按偏好顺序排列。有关更多信息,请参阅 ssh_config(5) 中的“密码”关键字。
-D [bind_address:]port
指定本地“动态”应用层端口转发。它通过分配一个套接字来侦听本地侧的端口,可以选择性地绑定到指定的 bind_address。每当对该端口进行连接时,连接都会通过安全通道转发,然后使用应用程序协议来确定从远程计算机连接到哪里。目前支持 SOCKS4 和 SOCKS5 协议,并且 ssh 将充当 SOCKS 服务器。只有 root 用户才能转发特权端口。动态端口转发也可以在配置文件中指定。
IPv6 地址可以通过将地址括在方括号中来指定。 只有超级用户才能转发特权端口。默认情况下,本地端口将根据 GatewayPorts 设置进行绑定。但是,可以使用显式的 bind_address 将连接绑定到特定地址。bind_address 为“localhost”表示侦听端口仅绑定到本地使用,而空地址或“*”表示端口应从所有接口提供。
-E log_file
将调试日志附加到 log_file,而不是标准错误。
-e escape_char
设置带有 pty 的会话的转义字符(默认:‘\~’)。转义字符仅在行首时才会被识别。转义字符后跟一个点(‘.’)会关闭连接;后跟 control-Z 会暂停连接;后跟它本身会发送转义字符一次。将字符设置为“none”会禁用所有转义,并使会话完全透明。
-F configfile
指定替代的每个用户的配置文件。如果在命令行中给出了配置文件,则将忽略系统范围的配置文件 (/etc/ssh/ssh_config)。每个用户的配置文件的默认值为 ~/.ssh/config。如果设置为“none”,则不会读取任何配置文件。
-f 请求 ssh 在执行命令之前进入后台。如果 ssh 将提示输入密码或密码,但用户希望将其置于后台,这将非常有用。这表示 -n。启动远程站点上的 X11 程序的推荐方法是使用类似 ssh -f host xterm 的命令。
如果将 ExitOnForwardFailure 配置选项设置为“yes”,则使用 -f 启动的客户端将等待所有远程端口转发都成功建立,然后才将自身置于后台。 请参阅 ForkAfterAuthentication 在 ssh_config(5) 中的描述以获取更多详细信息。
-G 导致 ssh 在评估 Host 和 Match 块后打印其配置并退出。
-g 允许远程主机连接到本地转发的端口。 如果在多路复用连接中使用,则必须在主进程中指定此选项。
-I pkcs11
指定 ssh 应使用的 PKCS#11 共享库,用于与提供用于用户身份验证的密钥的 PKCS#11 令牌进行通信。
-i identity_file
选择一个文件,从中读取用于公钥身份验证的身份(私钥)。 也可以指定一个公钥文件,以使用与本地不存在的私钥文件对应的私钥,该私钥已加载到 `ssh-agent(1)` 中。 默认值为 `~/.ssh/id_rsa`、`~/.ssh/id_ecdsa`、`~/.ssh/id_ecdsa_sk`、`~/.ssh/id_ed25519` 和 `~/.ssh/id_ed25519_sk`。 身份文件也可以在配置文件的基础上为每个主机指定。 可以有多个 `-i` 选项(以及配置文件中指定的多个身份)。 如果尚未通过 `CertificateFile` 指令显式指定任何证书,则 ssh 还会尝试从通过将 `-cert.pub` 附加到身份文件名获得的 filename 加载证书信息。
-J destination
通过首先建立到由 `destination` 描述的跳跃主机的 ssh 连接,然后从那里建立到最终目标的 TCP 转发来连接到目标主机。 可以使用逗号分隔多个跳跃,IPv6 地址可以通过将其括在方括号中来指定。 这是指定 `ProxyJump` 配置指令的快捷方式。 请注意,命令行中提供的配置指令通常适用于目标主机,而不适用于指定的任何跳跃主机。 使用 `~/.ssh/config` 来指定跳跃主机的配置。
-K 启用基于 GSSAPI 的身份验证以及将 GSSAPI 凭据转发到服务器。
-k 禁用将 GSSAPI 凭据转发到服务器。
-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
指定连接到本地(客户端)主机上给定 TCP 端口或 Unix 套接字的连接将被转发到远程侧的给定主机和端口或 Unix 套接字。 这通过分配一个套接字来实现,该套接字用于监听本地侧的 TCP 端口(可选地绑定到指定的 `bind_address`)或 Unix 套接字。 每当对本地端口或套接字进行连接时,连接都会通过安全通道转发,并且将在远程机器上建立到主机端口 `hostport` 或 Unix 套接字 `remote_socket` 的连接。
端口转发也可以在配置文件中指定。只有超级用户才能转发特权端口。可以通过将地址括在方括号中来指定 IPv6 地址。
默认情况下,本地端口的绑定方式与 GatewayPorts 设置一致。但是,可以使用显式的 bind_address 将连接绑定到特定地址。bind_address 为“localhost”表示监听端口仅供本地使用,而空地址或“*”表示端口应可从所有接口访问。
-l login_name
指定要在远程计算机上登录的用户。这也可以在配置文件的基础上为每个主机指定。
-M 将 ssh 客户端置于“主”模式,用于连接共享。多个 -M 选项会将 ssh 置于“主”模式,但需要在使用 ssh-askpass(1) 确认后才能执行每个更改复用状态的操作(例如,打开新会话)。有关详细信息,请参阅 ssh_config(5) 中 ControlMaster 的描述。
-m mac_spec
逗号分隔的 MAC(消息身份验证码)算法列表,按首选顺序指定。有关更多信息,请参阅 ssh_config(5) 中的 MACs 关键字。
-N 不执行远程命令。这对于仅转发端口很有用。请参阅 ssh_config(5) 中 SessionType 的描述,以了解详细信息。
-n 将 stdin 重定向到 /dev/null(实际上,阻止从 stdin 读取)。当 ssh 在后台运行时,必须使用此选项。一个常用的技巧是使用此选项在远程计算机上运行 X11 程序。例如,ssh -n shadows.cs.hut.fi emacs & 将在 shadows.cs.hut.fi 上启动 emacs,并且 X11 连接将通过加密通道自动转发。ssh 程序将被放入后台。(如果 ssh 需要提示密码或密码短语,则此方法不起作用;另请参见 -f 选项。)请参阅 ssh_config(5) 中 StdinNull 的描述,以了解详细信息。
-O ctl_cmd
控制活动的连接复用主进程。当指定 -O 选项时,将解释 ctl_cmd 参数并传递到主进程。有效的命令是:“check”(检查主进程是否正在运行)、“forward”(请求转发,无需执行命令)、“cancel”(取消转发)、“proxy”(以代理模式连接到正在运行的复用主进程)、“exit”(请求主进程退出)和“stop”(请求主进程停止接受进一步的复用请求)。
-o option
可用于以配置文件中使用的格式提供选项。这对于指定没有单独命令行标志的选项很有用。有关以下选项的完整详细信息及其可能的值,请参阅 ssh_config(5)。
AddKeysToAgent
AddressFamily
BatchMode
BindAddress
BindInterface
CASignatureAlgorithms
CanonicalDomains
CanonicalizeFallbackLocal
CanonicalizeHostname
CanonicalizeMaxDots
CanonicalizePermittedCNAMEs
CertificateFile
ChannelTimeout
CheckHostIP
Ciphers
ClearAllForwardings
Compression
ConnectTimeout
ConnectionAttempts
ControlMaster
ControlPath
ControlPersist
DynamicForward
EnableEscapeCommandline
EnableSSHKeysign
EscapeChar
ExitOnForwardFailure
FingerprintHash
ForkAfterAuthentication
ForwardAgent
ForwardX11
ForwardX11Timeout
ForwardX11Trusted
GSSAPIAuthentication
GSSAPIKeyExchange
GSSAPIClientIdentity
GSSAPIDelegateCredentials
GSSAPIKexAlgorithms
GSSAPIRenewalForcesRekey
GSSAPIServerIdentity
GSSAPITrustDns
GatewayPorts
GlobalKnownHostsFile
HashKnownHosts
Host
HostKeyAlgorithms
HostKeyAlias
HostbasedAcceptedAlgorithms
HostbasedAuthentication
Hostname
IPQoS
IdentitiesOnly
IdentityAgent
IdentityFile
IgnoreUnknown
Include
KbdInteractiveAuthentication
KbdInteractiveDevices
KexAlgorithms
KnownHostsCommand
LocalCommand
LocalForward
LogLevel
LogVerbose
MACs
NoHostAuthenticationForLocalhost
NumberOfPasswordPrompts
ObscureKeystrokeTiming
PKCS11Provider
PasswordAuthentication
PermitLocalCommand
PermitRemoteOpen
Port
PreferredAuthentications
ProxyCommand
ProxyJump
ProxyUseFdpass
PubkeyAcceptedAlgorithms
PubkeyAuthentication
RekeyLimit
RemoteCommand
RemoteForward
RequestTTY
RequiredRSASize
RevokedHostKeys
SecurityKeyProvider
SendEnv
ServerAliveCountMax
ServerAliveInterval
SessionType
SetEnv
StdinNull
StreamLocalBindMask
StreamLocalBindUnlink
StrictHostKeyChecking
SyslogFacility
TCPKeepAlive
Tag
Tunnel
TunnelDevice
UpdateHostKeys
User
UserKnownHostsFile
VerifyHostKeyDNS
VisualHostKey
XAuthLocation
-P tag 指定一个标签名称,该名称可用于在 ssh_config(5) 中选择配置。 请参阅 ssh_config(5) 中的 Tag 和 Match 关键字以获取更多信息。
-p port
Port 连接到远程主机上的端口。 可以在配置文件中按主机指定此选项。
-Q query_option
查询以下功能之一支持的算法:cipher(支持的对称密码)、cipher-auth(支持带身份验证加密的对称密码)、help(使用 -Q 标志的受支持的查询术语)、mac(支持的消息完整性代码)、kex(密钥交换算法)、kex-gss(GSSAPI 密钥交换算法)、key(密钥类型)、key-ca-sign(用于证书的有效 CA 签名算法)、key-cert(证书密钥类型)、key-plain(非证书密钥类型)、key-sig(所有密钥类型和签名算法)、protocol-version(支持的 SSH 协议版本)和 sig(支持的签名算法)。 或者,可以使用来自 ssh_config(5) 或 sshd_config(5) 且接受算法列表的任何关键字作为相应 query_option 的别名。
-q 静默模式。这会导致大多数警告和诊断消息被抑制。
-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port
指定将连接转发到远程(服务器)主机上的给定 TCP 端口或 Unix 套接字。
这通过在远程侧分配一个套接字来监听 TCP 端口或 Unix 套接字来实现。每当建立到此端口或 Unix 套接字的连接时,连接将通过安全通道转发,并在本地机器上建立到显式目标(由 host:port 指定)或 local_socket 的连接。
如果未指定显式目标,ssh 将作为 SOCKS 4/5 代理,并将连接转发到远程 SOCKS 客户端请求的目的地。
端口转发也可以在配置文件中指定。只有在远程机器上以 root 用户身份登录时,才能转发特权端口。可以通过将地址括在方括号中来指定 IPv6 地址。
默认情况下,服务器上的 TCP 监听套接字将仅绑定到环回接口。可以通过指定 bind_address 来覆盖此设置。空的 bind_address 或地址“*”表示远程套接字应监听所有接口。指定远程 bind_address 仅在服务器的 GatewayPorts 选项启用时才会成功(请参阅 sshd_config(5))。
如果端口参数为“0”,则将在服务器上动态分配监听端口,并在运行时向客户端报告。与 -O forward 选项一起使用时,分配的端口将打印到标准输出。
-S ctl_path
指定用于连接共享的控制套接字的位置,或字符串“none”以禁用连接共享。请参阅 ssh_config(5) 中 ControlPath 和 ControlMaster 的描述以获取详细信息。
-s 可用于请求在远程系统上调用子系统。子系统便于将 SSH 用作其他应用程序的安全传输方式(例如 [sftp]({filename}../../sftp)(1))。子系统作为远程命令指定。请参阅 ssh_config(5) 中 SessionType 的描述以获取详细信息。
-T 禁用伪终端分配。
-t 强制分配伪终端。这可用于在远程机器上执行任意基于屏幕的程序,这对于实现菜单服务非常有用。多个 -t 选项强制分配 tty,即使 ssh 没有本地 tty。
-V 显示版本号并退出。
-v 详细模式。导致 ssh 打印有关其进展的调试消息。这有助于调试连接、身份验证和配置问题。多个 -v 选项会增加详细程度。最大值为 3。
-W host:port
请求将客户端的标准输入和输出通过安全通道转发到指定主机和端口。这意味着启用了 -N、-T、ExitOnForwardFailure 和 ClearAllForwardings,但这些选项可以通过配置文件或使用 -o 命令行选项进行覆盖。
-w local_tun[:remote_tun]
请求使用指定的 tun(4) 设备在客户端(local_tun)和服务器(remote_tun)之间建立隧道设备转发。
设备可以通过数值 ID 或关键字“any”来指定,使用“any”时会使用下一个可用的隧道设备。如果未指定 remote_tun,则默认为“any”。请参阅 ssh_config(5) 中的 Tunnel 和 TunnelDevice 指令。
如果未设置 Tunnel 指令,则会将其设置为默认隧道模式,即“point-to-point”。如果需要不同的 Tunnel 转发模式,则应在 -w 选项之前进行指定。
-X 启用 X11 转发。这也可以在配置文件的基础上为每个主机进行指定。
X11 转发应谨慎启用。具有绕过远程主机上文件权限能力的用户(对于用户的 X 授权数据库),可以通过转发的连接访问本地 X11 显示器。攻击者随后可能能够执行诸如键盘监控之类的活动。
因此,默认情况下,X11 转发受到 X11 SECURITY 扩展的限制。请参阅 ssh -Y 选项和 ssh_config(5) 中的 ForwardX11Trusted 指令,以获取更多信息。
(Debian 特有:X11 转发默认情况下不受 X11 SECURITY 扩展的限制,因为当前有太多程序在这种模式下会崩溃。将 ForwardX11Trusted 选项设置为“no”以恢复上游行为。这在未来可能会根据客户端改进而发生变化。)
-x 禁用 X11 转发。
-Y 启用受信任的 X11 转发。受信任的 X11 转发不受 X11 SECURITY 扩展的控制。
(Debian 特有:在默认配置中,此选项等效于 -X,因为 ForwardX11Trusted 默认设置为“yes”,如上所述。将 ForwardX11Trusted 选项设置为“no”以恢复上游行为。这在未来可能会根据客户端改进而发生变化。)
-y 使用 syslog(3) 系统模块发送日志信息。默认情况下,此信息将发送到 stderr。
ssh 还可以从每个用户的配置文件和系统范围的配置文件中获取配置数据。文件格式和配置选项在 ssh_config(5) 中描述。
身份验证
OpenSSH SSH 客户端支持 SSH 协议 2。
可用的身份验证方法是:基于 GSSAPI 的身份验证、基于主机的身份验证、公钥身份验证、键盘交互式身份验证和密码身份验证。身份验证方法按照上述顺序进行尝试,但可以使用 PreferredAuthentications 来更改默认顺序。
基于主机的身份验证工作方式如下:如果用户登录的机器在远程机器上的 /etc/hosts.equiv 或 /etc/ssh/shosts.equiv 中列出,并且用户不是 root 用户,或者双方的用户名称相同;或者如果远程机器上的用户主目录中存在 ~/.rhosts 或 ~/.shosts 文件,并且这些文件包含一行,其中包含客户端机器的名称和该机器上的用户名,则该用户将被视为可以登录。此外,服务器必须能够验证客户端的主机密钥(请参见下面关于 /etc/ssh/ssh_known_hosts 和 ~/.ssh/known_hosts 的描述),才能允许登录。这种身份验证方法可以消除由于 IP 欺骗、DNS 欺骗和路由欺骗而导致的安全漏洞。
[注意:管理员请注意:/etc/hosts.equiv、~/.rhosts 以及 rlogin/rsh 协议通常是不安全的,如果需要更高的安全性,应禁用它们。]
公钥身份验证的工作方式如下:该方案基于公钥密码学,使用加密和解密使用单独密钥的密码系统,并且从加密密钥中推导出解密密钥是不可行的。其思想是每个用户为身份验证目的创建一个公钥/私钥对。服务器知道公钥,只有用户知道私钥。ssh 自动实现公钥身份验证协议,使用 ECDSA、Ed25519 或 RSA 算法之一。
^ /.ssh/authorized_keys 文件列出了允许用于登录的公钥。当用户登录时,ssh 程序会告诉服务器它想要用于身份验证的密钥对。客户端证明它有权访问私钥,并且服务器会检查相应的公钥是否被授权接受该帐户。
服务器可以在使用其他方法完成身份验证后,告知客户端导致公钥身份验证失败的错误。可以通过将 LogLevel 提高到 DEBUG 或更高(例如,使用 -v 标志)来查看这些错误。
用户可以通过运行 ssh-keygen(1) 来创建他们的密钥对。这会将私钥存储在 ~/.ssh/id_ecdsa(ECDSA)、~/.ssh/id_ecdsa_sk(authenticator-hosted ECDSA)、~/.ssh/id_ed25519(Ed25519)、~/.ssh/id_ed25519_sk(authenticator-hosted Ed25519)或 ~/.ssh/id_rsa(RSA)中,并将公钥存储在 ~/.ssh/id_ecdsa.pub(ECDSA)、~/.ssh/id_ecdsa_sk.pub(authenticator-hosted ECDSA)、~/.ssh/id_ed25519.pub(Ed25519)、~/.ssh/id_ed25519_sk.pub(authenticator-hosted Ed25519)或 ~/.ssh/id_rsa.pub(RSA)中,这些文件都位于用户的主目录中。然后,用户应将公钥复制到远程机器的主目录中的 ~/.ssh/authorized_keys 文件中。authorized_keys 文件与传统的 ~/.rhosts 文件相对应,每行包含一个密钥,但这些行可以非常长。之后,用户无需提供密码即可登录。
公钥身份验证的一种变体是以证书身份验证的形式提供:使用签名的证书而不是一组公钥/私钥。 这样做的优点是可以利用单个受信任的证书颁发机构,而无需使用多个公钥/私钥。 请参阅 ssh-keygen(1) 的 CERTIFICATES 部分,了解更多信息。
使用身份验证代理可能是使用公钥或证书身份验证的最便捷方式。 请参阅 ssh-agent(1) 和(可选)ssh_config(5) 中的 AddKeysToAgent 指令,了解更多信息。
键盘交互式身份验证的工作方式如下:服务器发送任意“挑战”文本并提示响应,可能多次。 键盘交互式身份验证的示例包括 BSD 身份验证(请参阅 login.conf(5))和 PAM(某些非 OpenBSD 系统)。
最后,如果其他身份验证方法失败,ssh 会提示用户输入密码。 密码将发送到远程主机进行检查;但是,由于所有通信都经过加密,因此无法通过监听网络的人看到密码。
ssh 自动维护并检查一个数据库,其中包含所有曾经使用过的主机的标识信息。 主机密钥存储在用户主目录的 ~/.ssh/known_hosts 中。 此外,还会自动检查文件 /etc/ssh/ssh_known_hosts,以查找已知主机。 任何新主机都会自动添加到用户文件中。 如果主机的标识信息发生变化,ssh 会发出警告并禁用密码身份验证,以防止服务器欺骗或中间人攻击,否则这些攻击可能会被用来绕过加密。 可以使用 StrictHostKeyChecking 选项来控制对主机密钥未知或已更改的机器的登录。
当服务器接受用户的身份后,服务器将执行给定的命令,在非交互式会话中执行,或者如果没有指定命令,则登录到机器并为用户提供一个正常的 shell,作为交互式会话。 与远程命令或 shell 的所有通信都将自动加密。
如果请求交互式会话,则默认情况下,ssh 仅会对客户端具有终端时才请求伪终端 (pty)。 可以使用 -T 和 -t 标志来覆盖此行为。
如果已分配伪终端,则用户可以使用下面注明的转义字符。
如果未分配伪终端,则会话是透明的,并且可以可靠地用于传输二进制数据。 在大多数系统上,将转义字符设置为“无”也会使会话即使在使用 tty 时也保持透明。
当远程机器上的命令或 shell 退出并且所有 X11 和 TCP 连接都已关闭时,会话将终止。
转义字符
当请求了伪终端时,ssh 支持通过使用转义字符来执行一些功能。
单个波浪线字符可以通过 ~~ 或在波浪线后跟非以下描述的字符来发送。转义字符必须始终位于换行符之后,才能被解释为特殊字符。可以使用配置文件中的 EscapeChar 配置指令或命令行中的 -e 选项来更改转义字符。
支持的转义字符(假设默认值为“\~”)如下:
~. 断开连接。
~^Z 将 ssh 置于后台。
~# 列出已转发的连接。
~& 在注销时将 ssh 置于后台,等待已转发的连接/X11 会话终止。
~? 显示转义字符列表。
~B 向远程系统发送 BREAK 信号(只有当对端支持时才有用)。
~C 打开命令行。当前,这允许使用 `-L`、`-R` 和 `-D` 选项添加端口转发(参见上文)。它还允许使用 `-KL[bind_address:]port`(用于本地)、`-KR[bind_address:]port`(用于远程)和 `-KD[bind_address:]port`(用于动态)来取消现有的端口转发。`!command` 允许用户执行本地命令,如果 `ssh_config(5)` 中启用了 `PermitLocalCommand` 选项。可以使用 `-h` 选项获取基本帮助。
~R 请求重新协商连接密钥(只有当对端支持时才有用)。
~V 在将错误写入 stderr 时降低冗长级别 (LogLevel)。
~v 在将错误写入 stderr 时增加冗长级别 (LogLevel)。
TCP 转发
可以通过命令行或配置文件指定通过安全通道转发任意 TCP 连接。TCP 转发的一个可能应用是用于加密的邮件服务器连接;另一个是用于防火墙。
在下面的示例中,我们来看如何加密 IRC 客户端的通信,即使 IRC 服务器本身不支持加密通信。它的工作原理如下:用户使用 ssh 连接到远程主机,并指定要用于转发连接的端口。之后,可以在本地启动程序,ssh 将加密并转发连接到远程服务器。
以下示例将 IRC 会话从客户端隧道传输到 IRC 服务器“server.example.com”,加入频道“#users”,昵称为“pinky”,使用标准的 IRC 端口 6667:
$ ssh -f -L 6667:localhost:6667 server.example.com sleep 10
$ irc -c '#users' pinky IRC/127.0.0.1
^ f 选项将 ssh 置于后台,并且指定远程命令“sleep 10”,以允许一定的时间(示例中为 10 秒)来启动将使用隧道连接的程序。如果在指定时间内未建立连接,ssh 将退出。
X11 转发
如果 ForwardX11 变量设置为“yes”(或者参见上面对 -X、-x 和 -Y 选项的描述),并且用户正在使用 X11(DISPLAY 环境变量已设置),则会将对 X11 显示器的连接自动转发到远程,以便从 shell(或命令)启动的任何 X11 程序都将通过加密通道,并且连接到实际的 X 服务器将从本地计算机进行。用户不应手动设置 DISPLAY。 X11 连接的转发可以在命令行或配置文件中进行配置。
ssh 设置的 DISPLAY 值将指向服务器机器,但显示号大于零。这是正常的,因为 ssh 会在服务器机器上创建一个“代理”X 服务器,用于通过加密通道转发连接。
ssh 还会自动在服务器机器上设置 Xauthority 数据。为此,它将生成一个随机授权 cookie,将其存储在服务器上的 Xauthority 中,并验证任何转发的连接是否携带此 cookie,并在打开连接时将其替换为真实的 cookie。真实的授权 cookie 绝不会发送到服务器机器(并且不会以明文形式发送任何 cookie)。
如果 ForwardAgent 变量设置为“yes”(或者参见上面对 -A 和 -a 选项的描述),并且用户正在使用身份验证代理,则会将对代理的连接自动转发到远程。
验证主机密钥
首次连接到服务器时,服务器的公钥指纹将呈现给用户(除非禁用了 StrictHostKeyChecking 选项)。可以使用 ssh-keygen(1) 确定指纹:
$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
如果指纹已知,则可以进行匹配并接受或拒绝密钥。如果仅提供服务器的旧版(MD5)指纹,则可以使用 ssh-keygen(1) -E 选项将指纹算法降级以进行匹配。
由于仅通过查看指纹字符串来比较主机密钥很困难,因此还支持以视觉方式比较主机密钥,即使用随机艺术。通过将 VisualHostKey 选项设置为“yes”,每次登录到服务器时都会显示一个小的 ASCII 图形,无论会话本身是否是交互式的。通过学习已知服务器生成的模式,用户可以很容易地发现主机密钥何时更改,因为会显示一个完全不同的模式。但是,由于这些模式不是明确的,因此看起来与记住的模式相似的模式仅表示主机密钥相同,但这并非绝对保证。
要获取所有已知主机的指纹及其随机艺术图案列表,可以使用以下命令行:
$ ssh-keygen -lv -f ~/.ssh/known_hosts
如果指纹未知,则可以使用另一种验证方法:通过 DNS 验证的 SSH 指纹。将附加的资源记录 (RR)(即 SSHFP)添加到区域文件中,连接客户端可以将其与所呈现的密钥的指纹进行匹配。
在本示例中,我们正在将客户端连接到服务器“host.example.com”。应首先将 SSHFP 资源记录添加到 host.example.com 的区域文件中:
$ ssh-keygen -r host.example.com.
这些输出行必须添加到区域文件中。要检查该区域是否响应指纹查询:
$ dig -t SSHFP host.example.com
最后,客户端连接:
$ ssh -o "VerifyHostKeyDNS ask" host.example.com
[...]
在 DNS 中找到匹配的主机密钥指纹。
您确定要继续连接吗(是/否)?
有关更多信息,请参阅 ssh_config(5) 中的 VerifyHostKeyDNS 选项。
基于 SSH 的虚拟专用网络
ssh 支持使用 tun(4) 网络伪设备进行虚拟专用网络 (VPN) 隧道,从而可以安全地连接两个网络。sshd_config(5) 配置文件中的 PermitTunnel 选项控制服务器是否支持此功能,以及支持的级别(第二层或第三层流量)。
以下示例将客户端网络 10.0.50.0/24 与远程网络 10.0.99.0/24 使用从 10.1.1.1 到 10.1.1.2 的点对点连接,前提是运行在远程网络网关上的 SSH 服务器(位于 192.168.1.15)允许这样做。
在客户端上:
# ssh -f -w 0:1 192.168.1.15 true
# ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252
# route add 10.0.99.0/24 10.1.1.2
在服务器上:
# ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252
# route add 10.0.50.0/24 10.1.1.1
可以通过 /root/.ssh/authorized_keys 文件(参见下文)和服务器端的 PermitRootLogin 选项更细粒度地调整客户端访问。以下条目将允许用户“jane”在 tun(4) 设备 1 上进行连接,如果 PermitRootLogin 设置为“forced-commands-only”,则允许用户“john”在 tun 设备 2 上进行连接:
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
由于基于 SSH 的设置涉及相当大的开销,因此可能更适合临时设置,例如用于无线 VPN。更永久的 VPN 最好由 ipsecctl(8) 和 isakmpd(8) 等工具提供。
环境
ssh 通常会设置以下环境变量:
DISPLAY DISPLAY 变量指示 X11 服务器的位置。ssh 会自动将其设置为“hostname:n”形式的值,其中“hostname”指示运行 shell 的主机,而“n”是一个大于或等于 0 的整数。
ssh 使用此特殊值通过安全通道转发 X11 连接。用户通常不应显式设置 DISPLAY,因为这会使 X11 连接不安全(并且需要用户手动复制任何必需的授权 cookie)。
HOME 设置为用户的家目录路径。
LOGNAME USER 的同义词;设置为与使用此变量的系统兼容。
MAIL 设置为用户的邮箱路径。
PATH 设置为编译 ssh 时指定的默认 PATH。
SSH_ASKPASS 如果 ssh 需要密码,它将从当前终端读取密码(如果它是从终端运行的)。如果 ssh 没有与终端关联,但设置了 DISPLAY 和 SSH_ASKPASS,它将执行由 SSH_ASKPASS 指定的程序,并打开一个 X11 窗口来读取密码。这在使用 .xsession 或相关脚本调用 ssh 时特别有用。(请注意,在某些机器上,可能需要将输入从 /dev/null 重定向以使其正常工作。)
SSH_ASKPASS_REQUIRE 允许对 askpass 程序的用法进行进一步控制。如果此变量设置为“never”,则 ssh 绝不会尝试使用它。如果设置为“prefer”,则 ssh 将优先使用 askpass 程序而不是 TTY 来请求密码。最后,如果变量设置为“force”,则无论是否设置了 DISPLAY,都将使用 askpass 程序来获取所有密码输入。
SSH_AUTH_SOCK 标识用于与代理通信的 Unix 域套接字的路径。
SSH_CONNECTION 标识连接的客户端和服务器端。该变量包含四个空格分隔的值:客户端 IP 地址、客户端端口号、服务器 IP 地址和服务器端口号。
SSH_ORIGINAL_COMMAND 如果执行了强制命令,则此变量包含原始命令行。可用于提取原始参数。
SSH_TTY 设置为与当前 shell 或命令关联的 tty 的名称(设备路径)。如果当前会话没有 tty,则不设置此变量。
SSH_TUNNEL 可选地由 [sshd]({filename}../../sshd)(8) 设置,以包含如果客户端请求了隧道转发,则分配的接口名称。
SSH_USER_AUTH 可选地由 [sshd]({filename}../../sshd)(8) 设置,此变量可以包含一个指向文件的路径,该文件列出了在会话建立时成功使用的身份验证方法,包括任何使用的公钥。
TZ 如果守护程序启动时设置了此变量,则此变量设置为指示当前时区(即,守护程序将该值传递给新的连接)。
USER 设置为登录用户的名称。
此外,ssh 读取 ~/.ssh/environment,并添加格式为“VARNAME=value”的行到环境中(如果该文件存在并且允许用户更改其环境)。有关更多信息,请参阅 sshd_config(5) 中的 PermitUserEnvironment 选项。
文件
~/.rhosts
该文件用于基于主机的身份验证(参见上方)。在某些机器上,如果用户的家目录位于 NFS 分区上,则此文件可能需要是世界可读的,因为 sshd(8) 以 root 身份读取它。此外,此文件必须由用户拥有,并且不得允许其他人具有写入权限。对于大多数机器,建议的权限是用户可读/写,且其他用户不可访问。
~/.shosts
此文件与 .rhosts 的使用方式完全相同,但允许在不启用 rlogin/rsh 登录的情况下进行基于主机的身份验证。
~/.ssh/
此目录是所有用户特定配置和身份验证信息的默认位置。没有普遍要求对此目录的整个内容保密,但建议的权限是用户可读/写/执行,且其他用户不可访问。
~/.ssh/authorized_keys
列出了可以用于以该用户身份登录的公钥(ECDSA、Ed25519、RSA)。 该文件的格式在 sshd(8) 手册页中描述。此文件不是高度敏感的文件,但建议的权限是用户可读/写,且其他用户不可访问。
~/.ssh/config
这是每个用户的配置文件。文件格式和配置选项在 ssh_config(5) 中描述。由于可能被滥用,因此此文件必须具有严格的权限:用户可读/写,且其他用户不可写。如果该组仅包含用户,则可以组可写。
~/.ssh/environment
包含其他环境变量的定义;请参见“ENVIRONMENT”,上方。
~/.ssh/id_ecdsa
~/.ssh/id_ecdsa_sk
~/.ssh/id_ed25519
~/.ssh/id_ed25519_sk
~/.ssh/id_rsa
包含用于身份验证的私钥。这些文件包含敏感数据,应由用户可读,但其他用户不可访问(可读/写/执行)。如果私钥文件可供其他用户访问,ssh 将简单地忽略它。在生成密钥时,可以指定密码短语,该密码短语将用于使用 AES-128 加密此文件的敏感部分。
~/.ssh/id_ecdsa.pub
~/.ssh/id_ecdsa_sk.pub
~/.ssh/id_ed25519.pub
~/.ssh/id_ed25519_sk.pub
~/.ssh/id_rsa.pub
包含用于身份验证的公钥。这些文件不是敏感文件,可以(但不一定需要)由任何人读取。
~/.ssh/known_hosts
包含用户已登录的所有主机的 host key 列表,这些主机不在系统范围内的已知主机 key 列表中。有关此文件的格式的更多信息,请参见 sshd(8)。
~/.ssh/rc
当用户登录时,ssh 将执行此文件中包含的命令,在用户 shell(或命令)启动之前。有关更多信息,请参见 sshd(8) 手册页。
/etc/hosts.equiv
此文件用于基于主机的身份验证(参见上方)。它应该只能由 root 用户写入。
/etc/ssh/shosts.equiv
此文件以与 hosts.equiv 相同的方式使用,但允许基于主机的身份验证,而无需允许使用 rlogin/rsh 登录。
/etc/ssh/ssh_config
系统范围的配置文件。文件格式和配置选项在 ssh_config(5) 中描述。
/etc/ssh/ssh_host_ecdsa_key
/etc/ssh/ssh_host_ed25519_key
/etc/ssh/ssh_host_rsa_key
这些文件包含主机密钥的私有部分,用于基于主机的身份验证。
/etc/ssh/ssh_known_hosts
系统范围内已知主机密钥的列表。此文件应由系统管理员准备,其中包含组织中所有机器的公共主机密钥。它应该是世界可读的。有关此文件的格式的更多详细信息,请参见 sshd(8)。
/etc/ssh/sshrc
当用户登录时,ssh 会执行此文件中包含的命令,然后启动用户的 shell(或命令)。有关更多信息,请参见 sshd(8) 手册页。
退出状态
ssh 以远程命令的退出状态退出,或者如果发生错误,则以 255 退出。
参见
scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-argv0(1), ssh-keygen(1), ssh-keyscan(1), tun(4), ssh_config(5), ssh-keysign(8), sshd(8)
标准
S. Lehtinen 和 C. Lonvick,《安全外壳 (SSH) 协议分配的编号》,RFC 4250,200 年 1 月。
T. Ylonen 和 C. Lonvick,《安全外壳 (SSH) 协议体系结构》,RFC 4251,2006 年 1 月。
T. Ylonen 和 C. Lonvick,《安全外壳 (SSH) 身份验证协议》,RFC 4252,2006 年 1 月。
T. Ylonen 和 C. Lonvick,《安全外壳 (SSH) 传输层协议》,RFC 4253,2006 年 1 月。
T. Ylonen 和 C. Lonvick,《安全外壳 (SSH) 连接协议》,RFC 4254,2006 年 1 月。
J. Schlyter 和 W. Griffin,《使用 DNS 以安全方式发布安全外壳 (SSH) 密钥指纹》,RFC 4255,2006 年 1 月。
F. Cusack 和 M. Forssen,《安全外壳 (SSH) 协议的通用消息交换身份验证》,RFC 4256,2006 年 1 月。
J. Galbraith 和 P. Remaker,《安全外壳 (SSH) 会话通道中断扩展》,RFC 4335,2006 年 1 月。
M. Bellare、T. Kohno 和 C. Namprempre,《安全外壳 (SSH) 传输层加密模式》,RFC 4344,2006 年 1 月。
B. Harris,《改进的安全外壳 (SSH) 传输层协议的 Arcfour 模式》,RFC 4345,2006 年 1 月。
M. Friedl、N. Provos 和 W. Simpson,《安全外壳 (SSH) 传输层协议的 Diffie-Hellman 组交换》,RFC 4419,2006 年 3 月。
J. Galbraith 和 R. Thayer,《安全外壳 (SSH) 公钥文件格式》,RFC 4716,2006 年 11 月。
D. Stebila 和 J. Green,《安全外壳传输层中椭圆曲线算法的集成》,RFC 5656,2009 年 12 月。
A. Perrig 和 D. Song,《哈希可视化:一种改进现实世界安全性的新技术》,1999 年,国际密码技术与电子商务研讨会(CrypTEC '99)。
作者
OpenSSH 是原始的免费 ssh 1.2.12 版本的衍生品,由 Tatu Ylonen 创建。Aaron Campbell、Bob Beck、Markus Friedl、Niels Provos、Theo de Raadt 和 Dug Song 修复了许多错误,重新添加了较新的功能,并创建了 OpenSSH。Markus Friedl 贡献了对 SSH 协议版本 1.5 和 2.0 的支持。