跳转至主要内容

许多地方都强制要求停止使用 Telnet 连接系统,转而使用 SSH。其理由是安全性更高。当您使用 Telnet 登录时,您的密码以及任何其他数据都会以明文形式传输。 任何拥有网络分析仪的人都能读取您发送的内容。而 SSH 则会对所有数据进行加密,使其无法被读取。人们通常认为 Telnet 和 SSH 守护进程提供的用户体验是可互换的,但这种看法是错误的。

首先,SSH 和 Telnet 客户端种类繁多。它们的用户界面各不相同,且可能使用不同的终端类型。即使使用相同的终端类型,它们的行为也可能有所不同,因为它们是在模拟终端,而这种模拟并非完美无缺。 但是,即使不考虑客户端软件的差异,连接到 Telnet 守护进程(无论是 telnetd 还是 telnet_msd)的会话与连接到 SSH 守护进程的会话之间,也存在若干微妙和不那么微妙的差异。此外还有一些漏洞,我将在下文中进行说明。 请注意,我使用的是 OpenVOS 2.1.0k 版 Internet Security Pack (ISP) 中的 SSH 守护进程。这是本文撰写时可用的最新版本。

用户名:

在您登录之前,Telnet 和 SSH 在处理用户名的方式上就存在差异。Telnet 守护进程允许您使用用户名的任何唯一变体进行登录,且用户名不区分大小写。 以用户名 Noah_Davids 为例,使用 Telnet 时,我可以登录为 Noah_D、noah_d、NoAh_D 或 NoAh_DaViDs,但 SSH 仅支持 Noah_Davids。我的别名 nd 也是如此。在 Telnet 中,我可以使用 nd、ND 或 nD,但在 SSH 中只有 nd 有效。

组名:

Telnet 连接时显示的登录提示允许我指定一个 组名

telnet 164.152.77.217\
正在尝试连接...\
已连接到 164.152.77.217\
转义字符为 '^]'。

OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17
请登录  15:24:14
登录 nd.SysAdmin
密码? [在此处输入密码]

Noah_Davids.SysAdmin 已于 12-12-12 15:24:55 mst 登录到 %phx_vos#m17。
图 1 – 使用组名进行 Telnet 登录

但 SSH 协议只允许使用用户名。如果我添加组名,系统会将其视为用户名的一部分,导致登录失败。

>system>openssl>bin>ssh [email protected];
;
nd.系统管理员@164.152.77.217 的密码:[在此处输入密码]

权限被拒绝,请重试。
[email protected] 的密码:
图 2 – 使用组名进行 SSH 登录

登录后,您可以通过子登录来更改所属组(但请参阅下文关于ssl-403的部分,了解当前的限制)

密码差异:

Telnet 和 SSH 连接在密码处理方面的最大区别在于,SSH 无需使用密码进行身份验证。您可以配置公钥/私钥对,从而跳过整个密码输入步骤。请参阅《配置Stratus SSH 以使用公钥身份验证》一文,了解具体配置方法。

如果您使用密码登录,则需要注意以下几点差异。首先,密码过期机制有所不同。在 Telnet 中,登录提示符会在密码即将过期时发出警告,并允许您更改密码。

telnet 164.152.77.217\
正在尝试...\
已连接到 164.152.77.217\
转义字符为 '^]'。

OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17
请登录  14:04:40
登录 nd
密码? [在此输入当前密码]

您的密码将在 5 天后过期。
新密码(首次输入)?
图 3 – Telnet 连接密码过期警告/提示

SSH 会向您发出警告,但您无法直接修改密码。您必须使用 `change_password` 命令来使当前密码失效,这样您下次登录时就必须更改密码。

ssh [email protected]
[email protected] 的密码:[在此处输入当前密码]

您的密码将在 5 天后过期。
Noah_Davids.CAC 于 2009年1月13日 13:06:35 (MDT) 在 %phx_vos#m17 登录。

欢迎。

就绪  13:06:35
更改密码
您的密码已失效。下次登录时必须更改密码。
就绪  13:06:49
图 4 – SSH 连接密码过期警告
以及 change_password 命令

一旦您的密码过期(或您已通过 `change_password` 命令将其失效),系统将提示您更改密码。与 Telnet 不同,此操作并非可选,您必须在此时更改密码。更改密码后,系统会自动将您注销,您必须重新登录。

ssh [email protected]
[email protected] 的密码:

警告:您的密码已过期。
您必须立即更改密码并重新登录!
当前密码?[在此输入当前密码]

新密码(首次输入)?[在此输入新密码]

新密码(再次输入)?[在此输入新密码]

与 164.152.77.217 的连接已关闭。
图 5 – 在 SSH 连接期间更改密码

另一个区别在于,SSH 连接不支持挑战-响应密码,而 Telnet 连接则支持。

子系统:

当您首次通过 Telnet 连接到某个模块时,登录命令允许您选择一个 子系统

OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17
请登录  11:23:40
登录 -表单 -用法
 --------------------------------- 登录 -------------------------------
 用户名:
 -特权:      按注册信息使用
 -密码:
 -更改密码:否
 -优先级:
 -主目录:
 -模块:
 -子系统:
图 6 – Telnet 连接允许您指定子系统名称

SSH 协议没有指定子系统名称的机制。如果注册数据库条目中设置了 must_use_subsystem 标志,则会自动使用注册条目中指定的第一个子系统。如果该位未设置,则不使用任何子系统。 (请注意,在 ISP 2.1.0j 版本发布之前,即使未设置 must_use_subsystem 标志,系统也会使用第一个子系统。)虽然在实际登录之前,login 命令的参数中包含指定子系统的方法(参见图 6),但一旦登录成功,该选项将不再可用(参见图 7)。

登录 -表单 -用法
 --------------------------------- 登录 -------------------------------
 组名:  CAC
 -特权: 是
 -优先级:
 -密码:
 -模块:
图 7 – sub-login 命令行参数

登录后,要进入某个子系统,唯一的方法是通过Telnet重新连接到该系统并再次登录。

telnet 127.0.0.1
正在尝试...
已连接到 127.0.0.1。
转义字符为 '^]'。

OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17
请登录  11:37:34
登录 nd -子系统 test_ss
密码?        

Noah_Davids.CAC 已于 12-12-13 11:37:49 mst 登录到 %phx_vos#m17。
这是测试子系统

就绪  11:37:49
图 8 – 通过 Telnet 连接到回环地址并重新登录以进入子系统

 

访问控制:

Telnet 和 SSH 连接均支持 TCP Wrappers,以便您根据 IP 地址限制访问;但在 Telnet 守护进程中,默认情况下 TCP Wrappers 处于禁用状态,您必须使用 -tcpwrapper_check 控制参数明确启用它。而 SSH 守护进程默认启用了 TCP Wrappers,且无法将其禁用。 您可以在 TCP Wrappers 的 hosts.allow 配置文件中允许所有 SSH 连接,从而实现对其的实质性禁用。

telnetd -form -usage
 ------------------------------- telnetd ------------------------------
 -service_file:     >system>stcp>telnetservice
 -tcpwrapper_check: no
 -numeric:          是
图 9 – 在 telnetd 守护进程中启用 TCP Wrappers

 

telnet_msd -form -usage
 ------------------------------ telnet_msd ----------------------------
 -network_port:     24
 -max_sessions:     28
 -error_severity:   2
 -separate_log:     yes
 -log_dir:          >system>stcp>logs
 -vterm_starname:   telnet*
 -vterm_login:      是
 -vterm_slave_id:
 -extension:        133
 -force_edit:       是
 -EC_decimal_value: 8
 -EL_decimal_value: 21
 -tcpwrapper_check: no
 -numeric:          no
图 10 – 在 telnet_msd 守护进程中启用 TCP Wrappers

sshd 守护进程还支持 sshd_config 文件中的选项,允许您指定允许通过 SSH 访问的用户或组(AllowUsers 和 AllowGroups 指令),或禁止通过 SSH 访问的用户或组(DenyUsers 和 DenyGroups 指令)。这些指令允许您指定用户名、源域名或两者的组合。 例如,可以允许来自 corp.stratus.com 的 noah_davids 访问,但拒绝来自 az.stratus.com 的访问。

允许用户 *@*.stratus.com
拒绝用户 *@*az.stratus.com
图 11 – sshd_config 文件中 AllowUsers 和 DenyUsers 指令的示例
>system>openssl>bin>ssh [email protected]
[email protected] 的密码:

权限被拒绝,请重试。
[email protected] 的密码:
图 12 – 由于 DenyUsers 指令,来自 phxtest-m15.az.stratus.com 的登录请求被拒绝

 

命令环境:

登录后,Telnet 连接会显示标准的 VOS 命令环境。SSH 允许管理员指定标准命令环境或 bash 壳环境。这取决于端口号。

d sshservices

%phx_vos#m17_mas>opt>openssl>etc>sshservices  12-12-13 12:31:31 mst

ssh       "window_term"  ""         "login"         1 1  s$pt_log.m16
ssh2200   "window_term"  "-shell"   "bash"          1 1  s$pt_log.m16
图 13 – sshservices 文件,端口 22 是标准的 VOS 命令行,
端口 2200 是 bash 壳层
>system>openssl>bin>ssh [email protected] -p 2200
[email protected] 的密码:

欢迎。

sh-2.05$
图 14 – 使用 2200 端口建立 SSH 连接并进入 bash 终端

 

环境变量:

默认情况下,Telnet 连接仅设置 6 个环境变量,而 SSH 连接则设置 12 个

env\
HOME=/SysAdmin/Noah_Davids\
LOGNAME=root\
PATH=.:/system/command_library:/system/applications_library:/system/maint_library\
+y:/system/nio/command_library:/system/tools_library:/opt/apache/bin:/opt/libxml
+2/bin:/opt/php/bin:/opt/openssl/bin:/opt/mysql/bin:/system/stcp/command_library\
+:/system.17.1/gnu_library/bin
VOS_INCLUDE_PATH=.:/opt/apache/include:/opt/openssl/include:/opt/mysql/include/m
+ysql:/system/stcp/include_library/compat:/system/include_library
VOS_OBJECT_PATH=.:/opt/apache/lib:/opt/openssl/lib:/opt/mysql/lib/mysql:/system/
+stcp/object_library/complib:/system/posix_object_library/pthread:/system/posix_
+object_library:/system/c_object_library:/system/object_library
TERM=vt100
图 15 – Telnet 连接中设置的环境变量

 

env\
HOME=/SysAdmin/Noah_Davids\
PATH=.:/system/command_library:/system/applications_library:/system/maint_library\
+y:/system/nio/command_library:/system/tools_library:/opt/apache/bin:/opt/libxml
+2/bin:/opt/php/bin:/opt/openssl/bin:/opt/mysql/bin:/system/stcp/command_library\
+:/system.17.1/gnu_library/bin
VOS_INCLUDE_PATH=.:/opt/apache/include:/opt/openssl/include:/opt/mysql/include/m
+ysql:/system/stcp/include_library/compat:/system/include_library
VOS_OBJECT_PATH=.:/opt/apache/lib:/opt/openssl/lib:/opt/mysql/lib/mysql:/system/
+stcp/object_library/complib:/system/posix_object_library/pthread:/system/posix_
+object_library:/system/c_object_library:/system/object_library\
TERM=vt100\
TZ=mst+07:00:00\
USER=Noah_Davids\
LOGNAME=Noah_Davids\
MAIL=/var/spool/mail/Noah_Davids\
SHELL=/bin/sh
SSH_CONNECTION=164.152.77.34 49573 164.152.77.217 22
SSH_TTY=#s$pt_log.m16_3
图 16 – SSH 连接中设置的环境变量

 

设备类型:

最后,这其实并不是 Telnet 和 SSH 之间的区别,而是 telnetd 和 sshd 守护进程与 telnet_msd 守护进程之间的区别。telnetd 和 sshd 都使用 window_term 设备,而 telnet_msd 则使用 vterm 设备。 vterm 和 window_term 设备在处理命令行中的某些功能键(如 CANCEL)以及原始屏幕输出方面存在一些差异。 某些创建自有表单且尚未更新以使用新 s$control OP_CODES 的应用程序,在使用 window_term 设备时无法正确显示这些表单。处理此类应用程序的次优方案是使用SSH 隧道连接到系统,并将隧道配置为连接到 telnet_msd 守护进程。当然,处理该应用程序的最佳方式是将其更新为使用新的 OP_CODES。

 

除了上述 Telnet 和 SSH 固有的差异外,还有几个漏洞将在未来的版本中修复。

ssl-403 可用组:

使用 Telnet 连接时,注册条目中指定的所有组均可用于子登录;但使用 SSH 时,仅前 5 个组可用。

鉴于我已加入以下组:CAC、SysAdmin、Group_3、Group_4、Group_5、Group_6,因此我可以通过 Telnet 连接使用任意一个组进行子登录。

telnet 164.152.77.217
正在尝试...
已连接到 164.152.77.217.
转义字符为 '^]'。

OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17
请登录  15:38:02
登录 nd
密码? [在此输入当前密码]

Noah_Davids.CAC 于 12-12-12 15:38:08 mst 在 %phx_vos#m17 登录。

登录 Group_5

Noah_Davids.Group_5 于 12-12-12 15:39:39 mst 在 %phx_vos#m17 登录。
就绪  15:39:39
注销

登录 Group_6

Noah_Davids.Group_6 于 12-12-12 15:40:13 (MST) 在 %phx_vos#m17 登录。
就绪  15:40:13
图 17 – 通过 Telnet 连接的子登录

但是,使用 SSH 时,当我尝试使用 Group_6 时会出现错误。

>system>openssl>bin>ssh [email protected]
[email protected] 的密码:

Noah_Davids.CAC 已于 12-12-12 15:41:02 mst 在 %phx_vos#m17 登录。
就绪  15:41:02

登录 Group_5

Noah_Davids.Group_5 于 12-12-12 15:41:24 mst 在 %phx_vos#m17 登录。
就绪  15:41:24
注销

登录 Group_6
登录:参数格式无效。Group_6 不能作为组名。
就绪  15:41:59
图 18 – 通过 SSH 连接的子登录

 

ssl-418 – sub_process_level:

通过 Telnet 登录的子进程级别为 0,而通过 SSH 登录的子进程级别为 3。

telnet 164.152.77.217\
正在尝试...\
已连接到 164.152.77.217\
转义字符为 '^]'\
\
OpenVOS 版本 17.1.0ax,模块 %phx_vos#m17\
请登录  14:15:34
登录 nd
密码? [在此输入当前密码]

Noah_Davids.CAC 已于 12-12-13 14:15:39 mst 登录到 %phx_vos#m17。
就绪  14:15:39
display_line (process_info sub_process_level)
0     
就绪  14:15:49
图 19 – Telnet 连接中设置的子进程级别

 

>system>openssl>bin>ssh [email protected]
[email protected] 的密码:[在此处输入当前密码]

Noah_Davids.CAC 于 2013年12月12日 14:12:23 (MST) 在 %phx_vos#m17 登录。
就绪  14:12:23
display_line (process_info sub_process_level)
3     
就绪  14:12:37
图 20 – SSH 连接中设置的子进程级别

2013年1月14日更新: 这实际上是一个功能,而非错误。sshd 进程会在以下三个阶段进行 fork:首先在 start_process 完成时 fork 以启动监听进程;其次在 sshd 接受连接时 fork;最后在创建用户登录进程时 fork。Telnet 采用不同的机制来启动用户进程,因此不会产生任何 fork 出的子进程。

时区问题:

最后,我想说明一下,此前在夏令时与标准时之间切换,或者更广泛地说,在不同时区之间切换时,曾出现过一些问题。通过 SSH 登录的会话无法反映新的默认设置。这些问题都应已在本最新版本(2.1.0k)中得到修复。