在线文档教程

ssh

ssh

模块

ssh

模块摘要

ssh应用程序的主要API

描述

接口模块为ssh应用程序。

请参阅ssh(6)支持的版本,算法和unicode支持的详细信息。

选项

一些功能的确切行为可以通过使用与功能一起记录的选项来调整。通常每个功能调用中最多可以使用每个选项。如果给出两次或更多次,除非明确记录,否则效果不可预测。

选项有不同的种类:

范围

这改变了系统中的限制,例如同时登录尝试次数。

超时

如果在给定的事件或行动之前经过了很长的时间,例如等待答案的时间,那么这给出了一些定义的行为。

回调

这使得函数的调用者可以在某些事件上执行自己的代码,例如调用自己的日志记录功能或执行自己的登录功能

行为

这改变了系统行为。

数据类型

在此模块中多次使用的类型定义,或抽象表示数据类型的预期用途,或两者:

boolean() =

true | false

string() =

[byte()]

ssh_daemon_ref() =

opaque() - 返回 ssh:daemon/[1,2,3]

ssh_connection_ref() =

opaque() - 返回 ssh:connect/3

ip_address() =

inet::ip_address

subsystem_spec() =

{subsystem_name(), {channel_callback(), channel_init_args()}}

subsystem_name() =

string()

channel_callback() =

atom()- 使用ssh_channel行为实现子系统的Erlang模块的名称,请参阅ssh_channel(3)

key_cb() =

atom() | {atom(), list()}

atom()- 实现这些行为的erlang模块的名称ssh_client_key_apissh_client_key_api视情况而定。

list() - 可以传递给回调模块的选项列表。

channel_init_args() =

list()

algs_list() =

list( alg_entry() )

alg_entry() =

{kex, simple_algs()} | {public_key, simple_algs()} | {cipher, double_algs()} | {mac, double_algs()} | {compression, double_algs()}

simple_algs() =

list( atom() )

double_algs() =

[{client2serverlist,simple_algs()},{server2client,simple_algs()}] | simple_algs()

modify_algs_list() =

list( {append,algs_list()} | {prepend,algs_list()} | {rm,algs_list()} )

输出

close(ConnectionRef) -> ok

类型

关闭SSH连接。

connect(Host, Port, Options) ->connect(Host, Port, Options, Timeout) ->connect(TcpSocket, Options) ->connect(TcpSocket, Options, Timeout) -> {ok, ssh_connection_ref()} | {error, Reason}

类型

22是默认的,为SSH分配了众所周知的端口号。谈判超时以毫秒为单位。默认值是infinity。对于连接超时,请使用选项{connect_timeout, timeout()}。该插座应该是从gen_tcp:connectgen_tcp:accept可以选择{active,false}

连接到SSH服务器。没有频道开始。这是通过调用完成的ssh_connection:session_channel/[2, 4]

选项:

{inet, inet | inet6}

IP版本使用。

{user_dir, string()}

设置用户目录,即,包含目录ssh为用户配置文件,如known_hostsid_rsa, id_dsa,和authorized_key。默认为通常称为的目录~/.ssh

{dsa_pass_phrase, string()}

如果用户DSA密钥受密码保护,则可以使用此选项。

{rsa_pass_phrase, string()}

如果用户RSA密钥受密码保护,则可以使用此选项。

{silently_accept_hosts, boolean()}

{silently_accept_hosts, CallbackFun}

{silently_accept_hosts, {HashAlgoSpec, CallbackFun} }

HashAlgoSpec = crypto:digest_type() | [ crypto:digest_type() ]

CallbackFun = fun(PeerName, FingerPrint) -> boolean()

PeerName = string()

FingerPrint = string() | [ string() ]

此选项指导connect当连接的服务器提供客户端以前未见过的主机密钥时,如何处理该功能。默认是询问用户是否接受或拒绝新主机密钥的问题。另请参阅记录先前接受的主机密钥user_dir的文件路径选项known_hosts

该选项可以以三种不同的形式给出,如上所示:

  • 值是 boolean()。该值true将使客户端接受任何未知的主机密钥,而无需任何用户交互。该值false保持在stdio上询问用户的默认行为。

{user_interaction, boolean()}

如果false,如果需要任何用户交互(例如接受要添加到known_hosts文件的服务器或提供密码),则禁用客户端连接到服务器。默认为true。即使允许用户交互,也可以通过其他选项来抑制,例如silently_accept_hostspassword。但是,从安全角度来看,这些选项并不总是令人满意的。

{disconnectfun, fun(Reason:term()) -> _}

在服务器断开客户端连接时提供了一种函数的功能来实现自己的日志记录

{unexpectedfun, fun(Message:term(), Peer) -> report | skip }

提供一种有趣的功能,可在发生意外消息时实现自己的日志记录或其他操作。如果函数返回report,则发出通常的信息报告,但如果返回skip,则不生成报告。

Peer格式是{Host,Port}

{pref_public_key_algs, list()}

尝试使用的用户(客户端)公钥算法的列表。

默认值是public_key输入ssh:default_algorithms/0

如果没有可用的指定类型的公钥,则忽略相应的条目。请注意,可用集取决于潜在的cryptolib和当前用户的公钥。

{preferred_algorithms, algs_list()}

在算法协商中使用的算法列表。默认值algs_list()可以从default_algorithms/0中获得

如果algs_list()中缺少alg_entry(),则默认值将用于该条目。

这是一个这个选项的例子:

{preferred_algorithms, [{public_key,['ssh-rsa','ssh-dss']}, {cipher,[{client2server,['aes128-ctr']}, {server2client,['aes128-cbc','3des-cbc']}]}, {mac,['hmac-sha2-256','hmac-sha1']}, {compression,[none,zlib]} ] }

该示例在两个方向(client2server和server2client)中指定了不同的算法(用于密码),但为mac和双向压缩指定了相同的算法。kex(密钥交换)是隐式的,但public_key是明确设置的。

有关背景和更多示例,请参阅User's Guide

警告

更改这些值可能会使连接不太安全。除非你确切知道你在做什么,否则不要改变。如果你不了解这些值,那么你不应该改变它们。

{modify_algorithms, modify_algs_list()}

修改用于算法协商的算法列表。在应用选项preferred_algorithms(如果存在)后应用修改。

修改的算法是这样的:

输入是modify_algs_list()和从preferred_algorithms选项(如果存在)获得的一组算法A,或者从ssh:default_algorithms / 0中获得。

- Append or prepend supported but not enabled algorithm(s) to the list of algorithms. If the wanted algorithms already are in `A` they will first be removed and then appended or prepended,

- Remove (rm) one or more algorithms from `A`.

  • 用尾部modify_algs_list()和结果重复修改步骤A'

如果一个不支持的算法在中modify_algs_list(),它将被默默地忽略

如果有多个modify_algorithms选项,结果是未定义的。

这是一个这个选项的例子:

{modify_algorithms, [{prepend, [{kex, ['diffie-hellman-group1-sha1']}], {rm, [{compression, [none]}]} ] }

该示例指定:

  • 旧的密钥交换算法'diffie-hellman-group1-sha1'应该是主要的选择。这将是主要的选择,因为它已经预先列入清单

有关背景和更多示例,请参阅User's Guide

{dh_gex_limits,{Min=integer(),I=integer(),Max=integer()}}

设置指导连接的服务器选择组的三个diffie-hellman-group-exchange参数。有关thoose的功能,请参阅RFC 4419。默认值是{1024, 6144, 8192}

{connect_timeout, timeout()}

在传输层连接上设置超时。对于gen_tcp该时间以毫秒为单位,默认值是infinity

{auth_methods, string()}

逗号分隔的字符串,用于确定客户端应该支持哪种身份验证方法以及尝试使用哪种方式。默认为"publickey,keyboard-interactive,password"

{user, string()}

提供用户名。如果未提供此选项,请ssh从环境(LOGNAMEUSER在UNIX USERNAME上,Windows上)读取。

{password, string()}

提供密码验证的密码。如果没有给出这个选项,如果尝试了密码认证方法,则要求用户输入密码。

{recv_ext_info, boolean()}

告诉服务器客户端接受扩展协商。详情请参阅Draft-ietf-curdle-ssh-ext-info (work in progress)

目前实现的扩展是server-sig-algs服务器首选用户公钥算法的列表。

默认值是true

{key_cb, key_cb()}

实施行为的模块ssh_client_key_api。可以用来自定义公钥的处理。如果回调选项与模块名称一起提供,它们将通过在key_cb_private键下传递给它的选项使其可用于回调模块。

{quiet_mode, atom() = boolean()}

如果true客户没有在授权上打印任何内容。

{id_string, random | string()}

客户端最初呈现给连接的服务器的字符串。默认值是“Erlang / VSN”,其中VSN是ssh应用程序的版本号。

该值random将导致在每次连接尝试时创建一个随机字符串。这是为了让恶意对等方更难以找到ssh软件的品牌和版本。

{fd, file_descriptor()}

允许使用现有的文件描述符(通过将其传递给传输协议)。

{rekey_limit, integer()}

以字节为单位提供何时启动密钥更新。默认为每GB一次,每小时一次。

{idle_time, integer()}

当没有通道处于活动状态时,在连接上设置超时。默认为infinity

{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}

提供一个乐趣来实现自己的SSH消息SSH_MSG_DEBUG的日志记录。最后三个参数来自消息,参见RFC4253,第11.3节。这ConnectionRef是对消息到达的连接的引用。乐趣的返回值不被检查。

默认行为是忽略消息。要获取每封邮件的打印输出AlwaysDisplay = true,请使用例如{ssh_msg_debug_fun, fun(_,true,M,_)-> io:format("DEBUG: ~p~n", [M]) end}

connection_info(ConnectionRef, [Option]) ->[{Option, Value}]

类型

检索有关连接的信息。

daemon(Port) ->daemon(Port, Options) ->daemon(HostAddress, Port, Options) ->daemon(TcpSocket) ->daemon(TcpSocket, Options) -> {ok, ssh_daemon_ref()} | {error, atom()}

类型

The socket is supposed to be from `gen_tcp:connect` or `gen_tcp:accept` with option `{active,false}`

启动一个侦听给定端口上SSH连接的服务器。如果Port是0,则选择一个随机空闲端口。查看daemon_info/1如何找到选定的端口号。

请注意,由于历史原因,HostAddress参数和inet套接字选项都会ip设置监听地址。这是可能的不一致设置的来源。

处理这两个地址传递选项的规则是:

  • 如果HostAddress是IP地址,则该IP地址是监听地址。如果存在,“ip”选项将被丢弃。

选项:

{inet, inet | inet6}

当主机地址被指定为时使用的IP版本any

{subsystems, [subsystem_spec()]}

提供处理子系统的规范。通过调用来检索“sftp”子系统规格ssh_sftpd:subsystem_spec/1。如果子系统选项不存在,[ssh_sftpd:subsystem_spec([])]则使用该值。如果您不希望守护程序运行任何子系统,则可以将该选项设置为空列表。

{shell, {Module, Function, Args} | fun(string() = User) - > pid() | fun(string() = User, ip_address() = PeerAddr) -> pid()}

定义当客户端请求shell时使用的read-eval-print循环。默认是使用Erlang shell:{shell, start, []}

{ssh_cli, {channel_callback(), channel_init_args()} | no_cli}

提供您自己的CLI实现,即实现shell和命令执行的通道回调模块。可以使用选项自定义shell read-eval-print循环shell。这意味着比实施自己的CLI通道更少的工作。如果设置为no_cli,则CLI通道将被禁用,并且只允许子系统通道。

{user_dir, string()}

设置用户目录。也就是说,含目录ssh的用户配置文件,如known_hostsid_rsa, id_dsa,和authorized_key。默认为通常称为的目录~/.ssh

{system_dir, string()}

设置系统目录,其中包含标识主机密钥的主机密钥文件ssh。默认为/etc/ssh。出于安全原因,该目录通常只能由root用户访问。

{auth_methods, string()}

逗号分隔的字符串,用于确定服务器支持哪种身份验证方法以及尝试使用哪种顺序。默认为"publickey,keyboard-interactive,password"

请注意,客户可以自由使用任何订单并排除方法。

{auth_method_kb_interactive_data, PromptTexts}

where:

PromptTexts = kb_int_tuple() | fun(Peer::{IP::tuple(),Port::integer()}, User::string(), Service::string()) -> kb_int_tuple()

kb_int_tuple() = {Name::string(), Instruction::string(), Prompt::string(), Echo::boolean()}

设置守护程序发送给客户端的文本字符串,以便在使用keyboar-interactive身份验证时向用户呈现。如果使用fun / 3,则在实际身份验证发生时调用它,因此可能会返回动态数据,如时间,远程ip等。

该参数Echo指导客户端需要隐藏密码。

默认值是: {auth_method_kb_interactive_data, {"SSH server", "Enter password for \""++User++"\"", "password: ", false}>

{user_passwords, [{string() = User, string() = Password}]}

提供密码验证的密码。当有人试图连接到服务器并且公钥用户认证失败时使用密码。该选项提供了有效用户名和相应密码的列表。

{password, string()}

提供验证任何用户的全局密码。从安全角度来看,这个选项使得服务器非常脆弱。

{preferred_algorithms, algs_list()}

在算法协商中使用的算法列表。默认值algs_list()可以从中获得default_algorithms/0

如果algs_list()中缺少alg_entry(),则默认值将用于该条目。

这是一个这个选项的例子:

{preferred_algorithms, [{public_key,['ssh-rsa','ssh-dss']}, {cipher,[{client2server,['aes128-ctr']}, {server2client,['aes128-cbc','3des-cbc']}]}, {mac,['hmac-sha2-256','hmac-sha1']}, {compression,[none,zlib]} ] }

该示例在两个方向(client2server和server2client)中指定了不同的算法(用于密码),但为mac和双向压缩指定了相同的算法。kex(密钥交换)是隐式的,但public_key是明确设置的。

有关背景和更多示例,请参阅User's Guide

警告

更改这些值可能会使连接不太安全。除非你确切知道你在做什么,否则不要改变。如果你不了解这些值,那么你不应该改变它们。

{modify_algorithms, modify_algs_list()}

修改用于算法协商的算法列表。在应用选项后应用修改preferred_algorithms(如果存在)

可能的修改是:

  • 将支持但未启用的算法附加或预先添加到算法列表中。如果想要的算法已经在算法列表中,它们将首先被删除,然后附加或预先加入。

如果列表中存在不受支持的算法,它将被默认忽略

这是一个这个选项的例子:

{modify_algorithms, [{prepend, [{kex, ['diffie-hellman-group1-sha1']}], {rm, [{compression, [none]}]} ] }

该示例指定:

  • 旧的密钥交换算法'diffie-hellman-group1-sha1'应该是主要的选择。这将是主要的选择,因为它已经预先列入清单

有关背景和更多示例,请参阅User's Guide

{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} {ssh_moduli_file,filename()} }

定义diffie-hellman-group-exchange协商时服务器可以选择的组。有关详细信息,请参阅RFC 4419。这个选项的三个变体是:

{Size=integer(),G=integer(),P=integer()}这些组在这个列表中明确给出。可能有几个相同的元素Size。在这种情况下,服务器将在协商尺寸中随机选择一个。 {file,filename()}该文件必须有一个或多个三元组{Size=integer(),G=integer(),P=integer()}以点结尾。守护进程启动时读取该文件。 {ssh_moduli_file,filename()}该文件必须位于ssh-keygen moduli file format。守护进程启动时读取该文件。

默认列表是从public_key应用程序中获取的。

{dh_gex_limits,{Min=integer(),Max=integer()}}

限制客户在Diffie-hellman-group-exchange中可以要求的内容。限制将是{MaxUsed = min(MaxClient,Max), MinUsed = max(MinClient,Min)}其中MaxClientMinClient是通过连接客户机提出的值。

默认值是{0,infinity}

如果MaxUsed < MinUsed在密钥交换中,它将失败,并断开连接。

请参阅RFC 4419了解最大值和最小值的功能。

{pwdfun, fun(User::string(), Password::string(), PeerAddress::{ip_adress(),port_number()}, State::any()) -> boolean() | disconnect | {boolean(),any()} }

提供密码验证功能。这可以用于调用外部系统,或者密码应该存储为散列。有趣的回报:

  • true 如果用户和密码是有效的

这种函数也可以用来延迟身份验证尝试,例如通过调用timer:sleep/1。为了便于计数失败的尝试,State可以使用变量。此状态仅适用于每个连接。第一次调用pwdfun进行连接时,该State变量具有该值undefined。除了上述值之外,pwdfun还可以返回一个新的状态:

  • {true, NewState:any()} 如果用户和密码有效或

第三种用法是阻止来自行为不当的同行的登录尝试。在State上述可被用于此目的。除上述回应外,还引入了以下返回值:

  • disconnect 如果连接应在发送SSH_MSG_DISCONNECT消息后立即关闭。

{pwdfun, fun(User::string(), Password::string()) -> boolean()}

提供密码验证功能。 该函数以用户和密码作为字符串调用,如果密码有效则返回true,否则返回false。

该选项({pwdfun,fun/2})与previous({pwdfun,fun/4})的子集相同。它保持兼容性。

{negotiation_timeout, integer()}

认证协商的最长时间(以毫秒为单位)。默认为120000(2分钟)。如果客户端在此时间内未能登录,则连接关闭。

{max_sessions, pos_integer()}

随时为此守护程序接受的同时会话的最大数量。这包括正在授权的会话。因此,如果设置为N,并且N客户端已连接但未启动登录过程,N+1则会中止连接尝试。如果N连接已通过身份验证并且仍然登录,则不会接受更多登录,直到其中一个现有登录退出。

计数器是每个侦听端口。因此,如果启动了两个守护进程,则整个应用程序都会接受一个连接{max_sessions,N},另一个连接{max_sessions,M},总N+M连接ssh

请注意,如果parallel_login为false,则一次只能有一个客户端处于身份验证阶段。

默认情况下,该选项未设置。这意味着数量不受限制。

{max_channels, pos_integer()}

每个与此守护程序建立连接的活动远程子系统通道的最大数量

默认情况下,该选项未设置。这意味着数量不受限制。

{parallel_login, boolean()}

如果设置为false(默认值),则一次只处理一个登录。如果设置为true,则允许同时允许无限次数的登录尝试。

如果max_sessions选项设置为N,parallel_login设置为true,则任何时候同时登录尝试的最大次数限制为N-K,其中K是此守护程序中存在的已验证连接数。

警告

如果没有通过其他方式保护服务器,例如max_sessions选项或防火墙配置,请不要启用parallel_logins。 如果设置为true,则无法防止DOS攻击。

{minimal_remote_max_packet_size, non_negative_integer()}

守护程序在来自客户端的通道打开请求中将接受的最小数据包大小。默认值是0。

{id_string, random | string()}

守护进程最初将显示给连接对等体的字符串。默认值是“Erlang / VSN”,其中VSN是ssh应用程序的版本号。

该值random将导致在每次连接尝试时创建一个随机字符串。这是为了让恶意对等方更难以找到ssh软件的品牌和版本。

{send_ext_info, boolean()}

如果客户要求,向客户发送扩展名列表。详情请参阅Draft-ietf-curdle-ssh-ext-info (work in progress)

目前实施的扩展是发送server-sig-algs服务器首选用户的公钥算法的列表。

默认值是true

{key_cb, key_cb()}

实施行为的模块ssh_server_key_api。可以用来自定义公钥的处理。如果回调选项与模块名称一起提供,它们将通过在key_cb_private键下传递给它的选项使其可用于回调模块。

{profile, atom()}

与ip-address和port一起使用来唯一标识一个ssh守护进程。 这在虚拟化环境中非常有用,其中可以有多个服务器具有相同的IP地址和端口。 如果此属性未明确设置,则假定ip-address和port唯一标识SSH守护进程。

{fd, file_descriptor()}

允许使用现有的文件描述符(传递给传输协议)。

{failfun, fun(User::string(), PeerAddress::ip_address(), Reason::term()) -> _}

当用户未通过身份验证时提供了一种函数的功能来实现自己的日志记录。

{connectfun, fun(User::string(), PeerAddress::ip_address(), Method::string()) ->_}

当用户向服务器进行身份验证时,提供一种函数的功能来实现自己的日志记录

{disconnectfun, fun(Reason:term()) -> _}

当用户从服务器断开连接时提供了一种函数的功能来实现您自己的日志记录。

{unexpectedfun, fun(Message:term(), Peer) -> report | skip }

提供一种函数的功能,可在发生意外消息时实现自己的日志记录或其他操作。如果函数返回report,则发出通常的信息报告,但如果skip返回,则不生成报告。

Peer格式是{Host,Port}

{idle_time, integer()}

当没有通道处于活动状态时,在连接上设置超时。默认为infinity

{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}

提供一个函数来实现自己的SSH消息SSH_MSG_DEBUG的日志记录。最后三个参数来自消息,参见RFC4253,第11.3节。这ConnectionRef是对消息到达的连接的引用。函数的返回值不被检查。

默认行为是忽略消息。要获取每封邮件的打印输出AlwaysDisplay = true,请使用例如{ssh_msg_debug_fun, fun(_,true,M,_)-> io:format("DEBUG: ~p~n", [M]) end}

daemon_info(Daemon) -> {ok, [DaemonInfo]} | {error,Error}

类型

用关于守护进程的信息返回一个键值列表。目前,只有侦听端口被返回。这适用于守护程序在端口设置为0时启动的情况。

default_algorithms() -> algs_list()

返回一个键值列表,其中键是不同类型的算法,值是算法本身。一个例子:

20> ssh:default_algorithms(). [{kex,['diffie-hellman-group1-sha1']}, {public_key,['ssh-rsa','ssh-dss']}, {cipher,[{client2server,['aes128-ctr','aes128-cbc','3des-cbc']}, {server2client,['aes128-ctr','aes128-cbc','3des-cbc']}]}, {mac,[{client2server,['hmac-sha2-256','hmac-sha1']}, {server2client,['hmac-sha2-256','hmac-sha1']}]}, {compression,[{client2server,[none,zlib]}, {server2client,[none,zlib]}]}] 21>

shell(Host) ->shell(Host, Option) ->shell(Host, Port, Option) ->shell(TcpSocket) -> _

类型

The socket is supposed to be from `gen_tcp:connect` or `gen_tcp:accept` with option `{active,false}`

通过给定的SSH服务器启动交互式shell Host。该函数等待用户输入,直到远程shell结束(即退出shell)才会返回。

start() ->start(Type) -> ok | {error, Reason}

类型

启动该应用程序的功能cryptopublic_key以及ssh。默认类型是temporary。有关更多信息,请参阅application(3)内核中的手册页。

stop() -> ok | {error, Reason}

类型

停止ssh应用程序。有关更多信息,请参阅application(3)内核中的手册页。

stop_daemon(DaemonRef) ->stop_daemon(Address, Port) -> ok

类型

停止侦听器以及由侦听器启动的所有连接。

stop_listener(DaemonRef) ->stop_listener(Address, Port) -> ok

类型

停止侦听器,但保持侦听器开始运行的现有连接。