檢視原始碼 在 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 階段計算出的金鑰(以及其他資訊)來產生實際使用的金鑰。範例包括三重 DES'3des-cbc'
和許多 AES 變體中的一種'aes192-ctr'
。此清單實際上是兩個 - 每個方向一個,即從伺服器到客戶端和從客戶端到伺服器。因此,在一個連線中,兩個方向使用不同的演算法是可能的,但很少見。
mac
- 訊息驗證碼對等方之間發送的每條訊息的「校驗和」。範例包括 SHA
'hmac-sha1'
和 SHA2'hmac-sha2-512'
。此清單也分為兩個方向。
compression
- 是否壓縮訊息以及如何壓縮。範例包括none
,即不壓縮,以及zlib
。此清單也分為兩個方向。
SSH 應用程式的機制
SSH 應用程式預設使用的演算法集取決於以下項目支援的演算法:
crypto
應用程式,- OTP 連結的 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,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','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,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',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,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','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,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',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,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',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,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','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,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',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, ...}
]}
每個 ...
可以是 algs_list()
,作為 preferred_algorithms
選項的引數。
範例 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,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','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,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',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 中的配置章節。