查看源代码 ssh (ssh v5.2.5)
ssh 应用程序的主要 API
这是 SSH
应用程序的接口模块。安全外壳 (SSH) 协议是一种用于在不安全的网络上进行安全远程登录和其他安全网络服务的协议。有关支持的 RFC、版本、算法和 Unicode 处理的详细信息,请参阅 ssh。
使用 SSH 应用程序,可以启动客户端和启动守护进程(服务器)。
客户端通过 connect/2
、connect/3
或 connect/4
启动。它们在 TCP/IP 之上打开一个加密连接。在该加密连接中,可以使用 ssh_connection:session_channel/2,4 打开一个或多个通道。
每个通道都是客户端进程和服务器端进程之间的隔离“管道”。这些进程对可以处理例如文件传输 (sftp) 或远程命令执行(shell、exec 和/或 cli)。如果实现了自定义 shell,则客户端用户可以远程执行特殊命令。请注意,用户不一定是人,而很可能是一个与 SSH 应用程序交互的系统。
客户端使用 ssh_connection:subsystem/4
请求服务器端子系统(通道)服务器。
服务器(守护进程)通过 daemon/1、daemon/2
或 daemon/3 启动。可能的通道处理程序(子系统)在启动守护进程时使用 subsystem 选项声明。
要在远程计算机上仅运行 shell,可以使用将所需三个步骤捆绑到一个函数中的函数:shell/1,2,3。同样,要仅打开与远程计算机的 sftp(文件传输)连接,最简单的方法是使用 ssh_sftp:start_channel/1,2,3。
要编写自己的客户端通道处理程序,请使用行为 ssh_client_channel
。对于服务器通道处理程序,请使用 ssh_server_channel
行为(替换 ssh_daemon_channel)。
客户端和守护进程都接受控制确切行为的选项。某些选项对两者都是通用的。这三组选项称为 客户端选项、守护进程选项 和 通用选项。
选项的描述使用带有解释文本的 Erlang 类型语言。
注意
另请参阅 SSH 应用程序参考和 示例 部分。
密钥和文件
SSH 应用程序要工作,必须存在许多对象。这些对象默认存储在文件中。默认名称、路径和文件格式与 OpenSSH 相同。可以使用 OpenSSH 中的 ssh-keygen
程序生成密钥。请参阅 用户指南。
可以通过选项轻松更改路径:user_dir
和 system_dir
。
通过使用行为 ssh_client_key_api
和/或 ssh_server_key_api
编写回调模块,可以与完全不同的存储进行交互。可以使用选项 key_cb
将回调模块安装到客户端和/或守护进程。
守护进程
密钥默认存储在文件中
必需:一个或多个主机密钥,包括私钥和公钥。默认是将它们存储在目录
/etc/ssh
的文件中ssh_host_dsa_key
和ssh_host_dsa_key.pub
ssh_host_rsa_key
和ssh_host_rsa_key.pub
ssh_host_ecdsa_key
和ssh_host_ecdsa_key.pub
可以使用选项
system_dir
更改主机密钥目录。可选:在
publickey
授权的情况下,一个或多个用户的公钥。默认是将它们连接存储在用户主目录中的文件.ssh/authorized_keys
中。可以使用选项
user_dir
更改用户密钥目录。
客户端
密钥和一些其他数据默认存储在用户主目录中的 .ssh
目录中的文件中。
可以使用选项 user_dir
更改目录。
可选:先前连接的主机的主机公钥列表。此列表由 SSH 应用程序处理,无需用户协助。默认是将它们存储在文件
known_hosts
中。host_accepting_client_options/0
与此密钥列表相关联。可选:在
publickey
授权的情况下,一个或多个用户的私钥。默认文件为id_dsa
和id_dsa.pub
id_rsa
和id_rsa.pub
id_ecdsa
和id_ecdsa.pub
摘要
类型:其他数据类型
表示连接内部通道的不透明数据类型。
来自 connection_info/1
和 connection_info/2
函数的返回值。
表示客户端和服务器(守护进程)之间连接的不透明数据类型。
来自 daemon_info/1
和 daemon_info/2
函数的返回值。
表示守护进程的不透明数据类型。
定义不在产品中使用的实验性选项的不透明类型。
该套接字应是 gen_tcp:connect 或 gen_tcp:accept 的结果。该套接字必须处于被动模式(即,使用选项 {active,false})
打开)。
函数
关闭 SSH 连接。
连接到 Host
上 Port
的 SSH 服务器。
返回有关连接的信息,用于例如调试或日志记录。
等效于 daemon/3
。
启动一个服务器,侦听给定端口上的 SSH 连接。如果 Port
为 0,则选择一个随机空闲端口。有关如何查找所选端口号,请参阅 daemon_info/1
。
返回有关守护进程的信息,用于例如调试或日志记录。
将正在运行的守护进程中的选项替换为 NewUserOptions
中的选项。仅影响此调用之后建立的连接,而不影响已建立的连接。
返回键值列表,其中键是不同类型的算法,值是算法本身。
获取 SSH 连接下的 TCP 套接字的 TCP 套接字选项值。
hostkey_fingerprint([DigestType], HostKey) -> [string()]hostkey_fingerprint(DigestType, HostKey) -> string()
在 SSH 连接下的 TCP 套接字上设置 TCP 套接字选项。
连接到 Host
和 Port
(默认为 22)上的 SSH 服务器,并在该远程主机上启动交互式 shell。
启动应用程序 crypto
、public_key
和 ssh
的实用函数。默认类型为 temporary
。有关更多信息,请参阅 Kernel 中的 application
手册页。
停止 ssh
应用程序。有关更多信息,请参阅 Kernel 中的 application
手册页。
停止侦听器以及由侦听器启动的所有连接。
停止侦听器,但保持侦听器启动的现有连接处于运行状态。
要求 ConnectionRef
的远程服务器侦听 ListenHost:ListenPort
。当有人连接该地址时,连接将从服务器通过加密通道转发到客户端。然后客户端(即调用此函数的节点)连接到 ConnectToHost:ConnectToPort
。
告诉本地客户端侦听 ListenHost:ListenPort
。当有人连接该地址时,连接将通过加密通道转发到 ConnectionRef
的对等服务器。然后该服务器连接到 ConnectToHost:ConnectToPort
。
类型:客户端选项
类型:守护进程选项
类型:通用选项
类型:其他数据类型
-opaque channel_id()
表示连接内部通道的不透明数据类型。
-type conn_info_algs() :: [{kex, kex_alg()} | {hkey, pubkey_alg()} | {encrypt, cipher_alg()} | {decrypt, cipher_alg()} | {send_mac, mac_alg()} | {recv_mac, mac_alg()} | {compress, compression_alg()} | {decompress, compression_alg()} | {send_ext_info, boolean()} | {recv_ext_info, boolean()}].
-type conn_info_channels() :: [proplists:proplist()].
来自 connection_info/1
和 connection_info/2
函数的返回值。
在 option
info 元组中,仅包含与默认值不同的选项。
-type connection_info_tuple() :: {client_version, version()} | {server_version, version()} | {user, string()} | {peer, {inet:hostname(), ip_port()}} | {sockname, ip_port()} | {options, client_options()} | {algorithms, conn_info_algs()} | {channels, conn_info_channels()}.
-type connection_ref() :: pid().
表示客户端和服务器(守护进程)之间连接的不透明数据类型。
由函数 connect/2,3,4
和 ssh_sftp:start_channel/2,3
返回。
-type daemon_info_tuple() :: {port, inet:port_number()} | {ip, inet:ip_address()} | {profile, atom()} | {options, daemon_options()}.
来自 daemon_info/1
和 daemon_info/2
函数的返回值。
在 option
info 元组中,仅包含与默认值不同的选项。
-opaque daemon_ref()
表示守护进程的不透明数据类型。
由函数 daemon/1,2,3
返回。
-type host() :: string() | inet:ip_address() | loopback.
-type ip_port() :: {inet:ip_address(), inet:port_number()}.
-type opaque_common_options() :: {transport, {atom(), atom(), atom()}} | {vsn, {non_neg_integer(), non_neg_integer()}} | {tstflg, [term()]} | ssh_file:user_dir_fun_common_option() | {max_random_length_padding, non_neg_integer()}.
定义不在产品中使用的实验性选项的不透明类型。
-type opaque_daemon_options() :: {infofun, fun()} | opaque_common_options().
-type open_socket() :: gen_tcp:socket().
该套接字应是 gen_tcp:connect 或 gen_tcp:accept 的结果。该套接字必须处于被动模式(即,使用选项 {active,false})
打开)。
-type protocol_version() :: {Major :: pos_integer(), Minor :: non_neg_integer()}.
-type software_version() :: string().
-type version() :: {protocol_version(), software_version()}.
类型
函数
-spec close(ConnectionRef) -> ok | {error, term()} when ConnectionRef :: connection_ref().
关闭 SSH 连接。
-spec connect(OpenTcpSocket, Options) -> {ok, connection_ref()} | {error, term()} when OpenTcpSocket :: open_socket(), Options :: client_options().
等效于 connect/4
。
-spec connect(open_socket(), client_options(), timeout()) -> {ok, connection_ref()} | {error, term()}; (host(), inet:port_number(), client_options()) -> {ok, connection_ref()} | {error, term()}.
等效于 connect/4
。
-spec connect(Host, Port, Options, NegotiationTimeout) -> {ok, connection_ref()} | {error, term()} when Host :: host(), Port :: inet:port_number(), Options :: client_options(), NegotiationTimeout :: timeout().
连接到 Host
上 Port
的 SSH 服务器。
作为替代方法,可以将已打开的 TCP 套接字传递给函数中的 TcpSocket
。SSH 初始化和协商将在该套接字上启动,另一端应为 SSH。
没有启动通道。这通过调用 ssh_connection:session_channel/2,4 完成。
NegotiationTimeout
以毫秒为单位。默认值为 infinity
或 connect_timeout
选项的值(如果存在)。对于连接超时,请使用选项 connect_timeout
。
-spec connection_info(ConnectionRef) -> InfoTupleList when ConnectionRef :: connection_ref(), InfoTupleList :: [InfoTuple], InfoTuple :: connection_info_tuple().
等效于 connection_info/2
。
-spec connection_info(ConnectionRef, ItemList | Item) -> InfoTupleList | InfoTuple when ConnectionRef :: connection_ref(), ItemList :: [Item], Item :: client_version | server_version | user | peer | sockname | options | algorithms | sockname, InfoTupleList :: [InfoTuple], InfoTuple :: connection_info_tuple().
返回有关连接的信息,用于例如调试或日志记录。
当 Key
是单个 Item
时,结果是一个 InfoTuple
。
-spec daemon(inet:port_number()) -> {ok, daemon_ref()} | {error, term()}.
等效于 daemon/3
。
-spec daemon(inet:port_number() | open_socket(), daemon_options()) -> {ok, daemon_ref()} | {error, term()}.
等效于 daemon/3
。
-spec daemon(any | inet:ip_address(), inet:port_number(), daemon_options()) -> {ok, daemon_ref()} | {error, term()}; (socket, open_socket(), daemon_options()) -> {ok, daemon_ref()} | {error, term()}.
启动一个服务器,侦听给定端口上的 SSH 连接。如果 Port
为 0,则选择一个随机空闲端口。有关如何查找所选端口号,请参阅 daemon_info/1
。
作为替代方案,可以将已打开的 TCP 套接字以 TcpSocket
的形式传递给该函数。当 TCP 套接字的另一端启动 SSH 时,将在此套接字上启动 SSH 初始化和协商。
有关选项的说明,请参阅 守护进程选项。
请注意,由于历史原因,HostAddress
参数和 gen_tcp connect_option() {ip,Address}
都设置了监听地址。这可能会导致设置不一致。
处理这两个地址传递选项的规则是
- 如果
HostAddress
是 IP 地址,则该 IP 地址为监听地址。如果存在“ip”选项,则会将其丢弃。 - 如果
HostAddress
是原子loopback
,则监听地址为loopback
,并且底层层将选择一个回环地址。如果存在“ip”选项,则会将其丢弃。 - 如果
HostAddress
是原子any
且不存在“ip”选项,则监听地址为any
,并且套接字将监听所有地址。 - 如果
HostAddress
是any
并且存在“ip”选项,则监听地址设置为“ip”选项的值。
-spec daemon_info(DaemonRef) -> {ok, InfoTupleList} | {error, bad_daemon_ref} when DaemonRef :: daemon_ref(), InfoTupleList :: [InfoTuple], InfoTuple :: daemon_info_tuple().
等效于 daemon_info/2
。
-spec daemon_info(DaemonRef, ItemList | Item) -> InfoTupleList | InfoTuple | {error, bad_daemon_ref} when DaemonRef :: daemon_ref(), ItemList :: [Item], Item :: ip | port | profile | options, InfoTupleList :: [InfoTuple], InfoTuple :: daemon_info_tuple().
返回有关守护进程的信息,用于例如调试或日志记录。
当 Key
是单个 Item
时,结果是一个 InfoTuple
。
请注意,由于兼容性原因,daemon_info/1
和 daemon_info/2
返回不同类型。
-spec daemon_replace_options(DaemonRef, NewUserOptions) -> {ok, daemon_ref()} | {error, term()} when DaemonRef :: daemon_ref(), NewUserOptions :: daemon_options().
将正在运行的守护进程中的选项替换为 NewUserOptions
中的选项。仅影响此调用之后建立的连接,而不影响已建立的连接。
注意
在此函数的最后阶段,监听进程将重新启动。因此,在此最后阶段尝试连接到守护进程可能会失败。
Erlang 配置的处理在《用户指南》中有描述;请参阅 SSH 中的配置 和 在 SSH 中配置算法 章节。
-spec default_algorithms() -> algs_list().
返回键值列表,其中键是不同类型的算法,值是算法本身。
有关示例,请参阅 《用户指南》。
-spec get_sock_opts(ConnectionRef, SocketGetOptions) -> ok | {error, inet:posix()} when ConnectionRef :: connection_ref(), SocketGetOptions :: [gen_tcp:option_name()].
获取 SSH 连接下的 TCP 套接字的 TCP 套接字选项值。
此函数调用 inet:getopts/2
,请阅读该文档。
-spec hostkey_fingerprint(public_key:public_key()) -> string().
-spec hostkey_fingerprint(TypeOrTypes, Key) -> StringOrString when TypeOrTypes :: public_key:digest_type() | [public_key:digest_type()], Key :: public_key:public_key(), StringOrString :: string() | [string()].
hostkey_fingerprint([DigestType], HostKey) -> [string()]hostkey_fingerprint(DigestType, HostKey) -> string()
从公钥计算 SSH 指纹,就像 OpenSSH 所做的那样。
hostkey_fingerprint/1
中的算法是 md5,以便与较旧的 ssh-keygen 命令兼容。第二个变体的字符串前面会加上大写的算法名称,就像较新的 ssh-keygen 命令一样。
示例
2> ssh:hostkey_fingerprint(Key).
"f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
3> ssh:hostkey_fingerprint(md5,Key).
"MD5:f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
4> ssh:hostkey_fingerprint(sha,Key).
"SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY"
5> ssh:hostkey_fingerprint(sha256,Key).
"SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"
6> ssh:hostkey_fingerprint([sha,sha256],Key).
["SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY",
"SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"]
-spec set_sock_opts(ConnectionRef, SocketOptions) -> ok | {error, inet:posix()} when ConnectionRef :: connection_ref(), SocketOptions :: [gen_tcp:option()].
在 SSH 连接下的 TCP 套接字上设置 TCP 套接字选项。
此函数调用 inet:setopts/2
,请阅读该文档,以及关于 gen_tcp:option/0
的文档。
除了以下选项外,允许使用所有 gen_tcp 套接字选项
active
deliver
mode
和packet
这些排除的选项由 SSH 应用程序保留。
警告
这是一个极其危险的函数。您需要自行承担使用风险。
某些选项取决于操作系统和操作系统版本。除非您了解选项值对 TCP 流的影响,否则请勿使用它。
某些值可能会破坏 SSH 协议的功能。
-spec shell(open_socket() | host() | connection_ref()) -> _.
等效于 shell/3
。
-spec shell(open_socket() | host(), client_options()) -> _.
等效于 shell/3
。
-spec shell(Host, Port, Options) -> _ when Host :: host(), Port :: inet:port_number(), Options :: client_options().
连接到 Host
和 Port
(默认为 22)上的 SSH 服务器,并在该远程主机上启动交互式 shell。
作为替代方案,可以将已打开的 TCP 套接字以 TcpSocket
的形式传递给该函数。将在此套接字上启动 SSH 初始化和协商,最后将在 TCP 套接字另一端的主机上启动 shell。
有关选项的说明,请参阅 客户端选项。
该函数等待用户输入,并且在远程 shell 结束(即退出 shell)之前不会返回。
-spec start() -> ok | {error, term()}.
等效于 start/1
。
-spec start(Type) -> ok | {error, term()} when Type :: permanent | transient | temporary.
启动应用程序 crypto
、public_key
和 ssh
的实用函数。默认类型为 temporary
。有关更多信息,请参阅 Kernel 中的 application
手册页。
-spec stop() -> ok | {error, term()}.
停止 ssh
应用程序。有关更多信息,请参阅 Kernel 中的 application
手册页。
-spec stop_daemon(DaemonRef :: daemon_ref()) -> ok.
等效于 stop_daemon/3
。
-spec stop_daemon(inet:ip_address(), inet:port_number()) -> ok.
等效于 stop_daemon/3
。
-spec stop_daemon(any | inet:ip_address(), inet:port_number(), atom()) -> ok.
停止侦听器以及由侦听器启动的所有连接。
-spec stop_listener(daemon_ref()) -> ok.
等效于 stop_listener/3
。
-spec stop_listener(inet:ip_address(), inet:port_number()) -> ok.
等效于 stop_listener/3
。
-spec stop_listener(any | inet:ip_address(), inet:port_number(), term()) -> ok.
停止侦听器,但保持侦听器启动的现有连接处于运行状态。
tcpip_tunnel_from_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort)
查看源代码 (自 OTP 23.0 起)-spec tcpip_tunnel_from_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort) -> {ok, TrueListenPort} | {error, term()} when ConnectionRef :: connection_ref(), ListenHost :: host(), ListenPort :: inet:port_number(), ConnectToHost :: host(), ConnectToPort :: inet:port_number(), TrueListenPort :: inet:port_number().
tcpip_tunnel_from_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort, Timeout)
查看源代码 (自 OTP 23.0 起)-spec tcpip_tunnel_from_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort, Timeout) -> {ok, TrueListenPort} | {error, term()} when ConnectionRef :: connection_ref(), ListenHost :: host(), ListenPort :: inet:port_number(), ConnectToHost :: host(), ConnectToPort :: inet:port_number(), Timeout :: timeout(), TrueListenPort :: inet:port_number().
要求 ConnectionRef
的远程服务器侦听 ListenHost:ListenPort
。当有人连接该地址时,连接将从服务器通过加密通道转发到客户端。然后客户端(即调用此函数的节点)连接到 ConnectToHost:ConnectToPort
。
返回的 TrueListenPort
是监听的端口。它与 ListenPort
相同,除非 ListenPort = 0
。在这种情况下,底层操作系统会选择一个空闲端口。
请注意,如果对等端是 Erlang/OTP SSH 服务器(守护进程),则该服务器必须已使用选项 tcpip_tunnel_out 启动才能允许连接。
tcpip_tunnel_to_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort)
查看源代码 (自 OTP 23.0 起)-spec tcpip_tunnel_to_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort) -> {ok, TrueListenPort} | {error, term()} when ConnectionRef :: connection_ref(), ListenHost :: host(), ListenPort :: inet:port_number(), ConnectToHost :: host(), ConnectToPort :: inet:port_number(), TrueListenPort :: inet:port_number().
tcpip_tunnel_to_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort, Timeout)
查看源代码 (自 OTP 23.0 起)-spec tcpip_tunnel_to_server(ConnectionRef, ListenHost, ListenPort, ConnectToHost, ConnectToPort, Timeout) -> {ok, TrueListenPort} | {error, term()} when ConnectionRef :: connection_ref(), ListenHost :: host(), ListenPort :: inet:port_number(), ConnectToHost :: host(), ConnectToPort :: inet:port_number(), Timeout :: timeout(), TrueListenPort :: inet:port_number().
告诉本地客户端侦听 ListenHost:ListenPort
。当有人连接该地址时,连接将通过加密通道转发到 ConnectionRef
的对等服务器。然后该服务器连接到 ConnectToHost:ConnectToPort
。
返回的 TrueListenPort
是监听的端口。它与 ListenPort
相同,除非 ListenPort = 0
。在这种情况下,底层操作系统会选择一个空闲端口。
请注意,如果对等端是 Erlang/OTP SSH 服务器(守护进程),则该服务器必须已使用选项 tcpip_tunnel_in 启动才能允许连接。