查看源代码 在 SSH 中配置算法
简介
要完全理解如何配置算法,必须对 SSH 协议以及 OTP SSH 应用程序如何处理相应的项有一个基本的了解。
第一小节将简要介绍 SSH 协议的背景,而后面的章节将描述实现并提供一些示例。
有关不同级别的配置如何“干扰”此项,请参阅算法配置章节中的SSH 中的配置。
ssh 协议的算法处理基础
SSH 在会话的不同阶段使用不同的算法集。要使用哪些算法由客户端和服务器在会话开始时协商。有关详细信息,请参见RFC 4253,《安全外壳(SSH)传输层协议》。
协商很简单:双方都会将它们支持的算法列表发送给对方。选择客户端列表中也出现在服务器列表中的第一个算法。因此,客户端的列表顺序决定了算法的优先级。
在连接设置中交换了五个列表。其中三个列表还分为两个方向,即发送到服务器和从服务器发送。
列表如下(名称与 SSH 应用程序的选项中相同)
kex
- 密钥交换选择一个算法来计算秘密加密密钥。示例包括:如今已弱的旧算法
'diffie-hellman-group-exchange-sha1'
以及非常强大和现代的'ecdh-sha2-nistp512'
。public_key
- 服务器主机密钥服务器的私钥-公钥对中使用的非对称加密算法。示例包括著名的 RSA
'ssh-rsa'
和椭圆曲线'ecdsa-sha2-nistp521'
。cipher
- 用于有效负载加密的对称密码算法。此算法将使用在 kex 阶段计算的密钥(以及其他信息)来生成实际使用的密钥。示例包括 triple-DES'3des-cbc'
和多种 AES 变体之一'aes192-ctr'
。此列表实际上是两个 - 每个方向一个,服务器到客户端和客户端到服务器。因此,在同一连接的两个方向上使用不同的算法是可能的,但很少见。
mac
- 消息认证码对等方之间发送的每条消息的“校验和”。示例包括 SHA
'hmac-sha1'
和 SHA2'hmac-sha2-512'
。此列表也分为两个方向
compression
- 是否以及如何压缩消息。示例包括none
,即不压缩,以及zlib
。此列表也分为两个方向
SSH 应用程序的机制
SSH 应用程序默认使用的算法集取决于以下算法支持的算法:
crypto
应用程序,- OTP 链接到的 cryptolib,通常是操作系统使用的 cryptolib,可能是 OpenSSL,
- 以及最终 SSH 应用程序实现的算法。
因此,不可能在文档中列出特定安装中可用的算法。
有一个重要的命令可以列出实际的算法及其顺序:ssh:default_algorithms/0
。
0> ssh:default_algorithms().
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['[email protected]',
'aes256-ctr','aes192-ctr','[email protected]',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['[email protected]','aes256-ctr',
'aes192-ctr','[email protected]','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'[email protected]',zlib]},
{server2client,[none,'[email protected]',zlib]}]}]
要更改算法列表,可以在 ssh:connect/2,3,4 和 ssh:daemon/2,3 中使用两个选项。当然,这些选项也可以用于启动连接的所有其他函数。
这两个选项是 preferred_algorithms 和 modify_algorithms。第一个选项替换默认集合,而后者修改默认集合。
替换默认集:preferred_algorithms
有关详细信息,请参阅参考手册
以下是一系列示例,范围从简单到更复杂。
为了预见选项的效果,有一个实验函数 ssh:chk_algos_opts(Opts)
。它以与 ssh:daemon
、ssh:connect
及其友元相同的方式处理 preferred_algorithms
和 modify_algorithms
选项。
示例 1
将 kex 算法列表替换为单个算法 'diffie-hellman-group14-sha256'
1> ssh:chk_algos_opts(
[{preferred_algorithms,
[{kex, ['diffie-hellman-group14-sha256']}
]
}
]).
[{kex,['diffie-hellman-group14-sha256']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['[email protected]',
'aes256-ctr','aes192-ctr','[email protected]',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['[email protected]','aes256-ctr',
'aes192-ctr','[email protected]','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'[email protected]',zlib]},
{server2client,[none,'[email protected]',zlib]}]}]
请注意,未提及的列表(public_key
、cipher
、mac
和 compression
)保持不变。
示例 2
在分为两个方向的列表(例如 cipher
)中,可以同时更改两个方向
2> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']}
]
}
]).
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'[email protected]',zlib]},
{server2client,[none,'[email protected]',zlib]}]}]
请注意,cipher
中的两个列表都已更改为提供的值('aes128-ctr'
)。
示例 3
在分为两个方向的列表(例如 cipher
)中,可以仅更改其中一个方向
3> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,[{client2server,['aes128-ctr']}]}
]
}
]).
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['[email protected]','aes256-ctr',
'aes192-ctr','[email protected]','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'[email protected]',zlib]},
{server2client,[none,'[email protected]',zlib]}]}]
示例 4
当然,可以更改多个列表
4> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']},
{mac,['hmac-sha2-256']},
{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{compression,[{server2client,[none]},
{client2server,[zlib]}]}
]
}
]).
[{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256']},
{server2client,['hmac-sha2-256']}]},
{compression,[{client2server,[zlib]},
{server2client,[none]}]}]
请注意,列表中元组的顺序无关紧要。
修改默认集:modify_algorithms
当需要使用受支持但已禁用的算法时,添加算法可能会很有用。一个例子是 'diffie-hellman-group1-sha1'
,它现在非常不安全,因此已被禁用。但是,它仍然受支持,并且可能会被使用。
对于添加或删除单个算法,preferred_algorithms
选项可能比较复杂。首先,必须使用 ssh:default_algorithms()
列出它们,然后在列表中进行更改。
为了方便添加或删除算法,提供了 modify_algorithms
选项。有关详细信息,请参阅参考手册。
该选项接受一个列表,其中包含追加、前置或删除算法的指令
{modify_algorithms, [{append, ...},
{prepend, ...},
{rm, ...}
]}
每个 ...
都可以是 preferred_algorithms
选项的参数的 algs_list()
。
示例 5
例如,让我们将 Diffie-Hellman Group1 添加到 kex 列表的开头。根据支持的算法,它是受支持的。
5> ssh:chk_algos_opts(
[{modify_algorithms,
[{prepend,
[{kex,['diffie-hellman-group1-sha1']}]
}
]
}
]).
[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
'ecdh-sha2-nistp521','ecdh-sha2-nistp256',
'diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['[email protected]',
'aes256-ctr','aes192-ctr','[email protected]',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['[email protected]','aes256-ctr',
'aes192-ctr','[email protected]','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'[email protected]',zlib]},
{server2client,[none,'[email protected]',zlib]}]}]
结果表明 Diffie-Hellman Group1 已添加到 kex 列表的开头
示例 6
在此示例中,我们将 'diffie-hellman-group1-sha1' 放在第一位,并将 'ecdh-sha2-nistp521'
移动到 kex 列表的末尾,即 append
它。
6> ssh:chk_algos_opts(
[{modify_algorithms,
[{prepend,
[{kex, ['diffie-hellman-group1-sha1']}
]},
{append,
[{kex, ['ecdh-sha2-nistp521']}
]}
]
}
]).
[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1','ecdh-sha2-nistp521']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
.....
]
请注意,追加的算法会从其原始位置删除,然后追加到同一列表中。
示例 7
在此示例中,我们同时使用两个选项(preferred_algorithms
和 modify_algorithms
),并且尝试预置一个不受支持的算法。任何不受支持的算法都将被悄悄删除。
7> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']},
{mac,['hmac-sha2-256']},
{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{compression,[{server2client,[none]},
{client2server,[zlib]}]}
]
},
{modify_algorithms,
[{prepend,
[{kex, ['some unsupported algorithm']}
]},
{append,
[{kex, ['diffie-hellman-group1-sha1']}
]}
]
}
]).
[{kex,['ecdh-sha2-nistp384','diffie-hellman-group1-sha1']},
{public_key,['ssh-rsa']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256']},
{server2client,['hmac-sha2-256']}]},
{compression,[{client2server,[zlib]},
{server2client,[none]}]}]
当然,任何人都可能想同时使用这两个选项,这很值得怀疑,但是如果出现不可预见的需要,这是可能的。
示例 8
在此示例中,我们需要使用 diffie-hellman-group1-sha1 密钥交换算法,尽管它不安全且默认情况下处于禁用状态。
我们使用 modify_algorithms 选项,因为我们想保留所有其他算法定义。
我们将选项添加到
{modify_algorithms, [{append, [{kex,['diffie-hellman-group1-sha1']}]}]}
函数调用中的 Options 列表,ssh.app
文件中,或 erl
命令的 .config
文件中。请参阅 SSH 用户指南中的SSH 中的配置章节。
示例 9
在此示例中,我们需要使用 DSA 密钥进行签名和验证。它可能是用户的密钥、主机的密钥,也可能是两者。
为此,我们启用了出于安全原因默认情况下禁用的 'ssh-dss' 算法。我们使用 modify_algorithms 选项,因为我们想保留所有其他算法定义。
我们将选项添加到
{modify_algorithms, [{append, [{public_key,['ssh-dss']}]}]}
函数调用中的 Options 列表,ssh.app
文件中,或 erl
命令的 .config
文件中。请参阅 SSH 用户指南中的SSH 中的配置章节。