OpenSSH 9.0 的 scp 與 sntrup761x25519 (Streamlined NTRU Prime)

OpenSSH 9.0 發行了,從 release-9.0 這邊可以看到重點,首先是 scp 的底層換掉,改用 SFTP 了,這點在先前「OpenSSH 的 scp 改用 SFTP 協定」這邊也有提到過:

This release switches scp(1) from using the legacy scp/rcp protocol to using the SFTP protocol by default.

另外一個是將 OpenSSH 8.9 引入的 post-quantum cipher 放入 default:

ssh(1), sshd(8): use the hybrid Streamlined NTRU Prime + x25519 key exchange method by default ("sntrup761x25519-sha512@openssh.com"). The NTRU algorithm is believed to resist attacks enabled by future quantum computers and is paired with the X25519 ECDH key exchange (the previous default) as a backstop against any weaknesses in NTRU Prime that may be discovered in the future. The combination ensures that the hybrid exchange offers at least as good security as the status quo.

We are making this change now (i.e. ahead of cryptographically-relevant quantum computers) to prevent "capture now, decrypt later" attacks where an adversary who can record and store SSH session ciphertext would be able to decrypt it once a sufficiently advanced quantum computer is available.

查了一下 Streamlined NTRU Prime 發現有 djb 參與,而且發現頭銜上面有掛中研院:

Daniel J. Bernstein, University of Illinois at Chicago, USA, and Ruhr University Bochum, Germany, and Academia Sinica, Taiwan

清單裡面有不少中研院的人:

Ming-Shing Chen, Academia Sinica, Taiwan

Bo-Yuan Peng, National Taiwan University and Academia Sinica, Taiwan

裡面還看到魯教授

Bo-Yin Yang, Academia Sinica, Taiwan

後面也有看到計畫相關的資訊:

Taiwanese authors were supported by Taiwan Ministry of Science and Technology Grants 108-2221-E-001-008 and 109-2221-E-001-009-MY3, Sinica Investigator Award AS-IA-109-M01, Executive Yuan Data Safety and Talent Cultivation Project (AS-KPQ-109-DSTCP).

SSH 的 StrictHostKeyChecking=accept-new

OpenSSH 在連到新的 host 時會跳出 key fingerprint 的資訊讓使用者確認,有時候為了自動化會用 StrictHostKeyChecking=no 避開,在 Lobsters Daily 上則看到了新的選項可以用,StrictHostKeyChecking=accept-new

就如同選項的名字所描述的,查了一下 OpenSSH Release Notes 可以看到這是在 OpenSSH 7.5 導入的參數,是在 March 20, 2017 引入的:

* ssh(1): expand the StrictHostKeyChecking option with two new settings. The first "accept-new" will automatically accept hitherto-unseen keys but will refuse connections for changed or invalid hostkeys. This is a safer subset of the current behaviour of StrictHostKeyChecking=no. The second setting "off", is a synonym for the current behaviour of StrictHostKeyChecking=no: accept new host keys, and continue connection for hosts with incorrect hostkeys. A future release will change the meaning of StrictHostKeyChecking=no to the behaviour of "accept-new". bz#2400

對於一些自動化的流程應該夠用了,不需要到用 no 完全關掉。

翻了「Ubuntu – Package Search Results -- openssh-client」可以看到 18.04 之後都是 7.5 之後的版本了,支援度應該是沒什麼太大問題...

OpenSSH 的 scp 改用 SFTP 協定

在「By default, scp(1) now uses SFTP protocol」這邊看到的,OpenSSH 的 scp 改用 SFTP 協定了,原因也有附在文章裡:

SFTP offers more predictable filename handling and does not require expansion of glob(3) patterns via the shell on the remote side.

要注意這是 BC-break change,有些之前會動的 case 在改用 SFTP 後會爛掉,但這算是前進了一大步,scp 因為 spec 的關係很難維護安全性。

在「Deprecating scp」這邊也有提到相關的問題,另外也給出了一些範例。

SSH 對傳入參數的 quoting

昨天在 Hacker News 首頁上看到「SSH quoting」這個,看得出來作者被 OpenSSH 玩弄到不要不要的樣子...

先簡單的整理一下:

$ ssh example.com 'cd /tmp; pwd'
/tmp
$ ssh example.com 'bash -l -c "cd /tmp; pwd"'
/tmp
$ ssh example.com bash -l -c "cd /tmp; pwd"  
/home/gslin

第三個指令發生的「預期外的行為」,但寫習慣的人會把指令全部包成一個字串,就很自然的避開這個問題了。當然 OpenSSH 的設計 (讓你不用加 quote 也會動) 的確也是容易中獎的點啦...

GitHub 支援 SSH 使用 Security Key 了

GitHub 宣佈支援使用 security key 的 SSH key 操作了:「Security keys are now supported for SSH Git operations」。

也就是需要 SSH key + security key 才有辦法認證,只有拿到 SSH key 或是 security key 都是沒有辦法認證過。

目前官方支援 ecdsa-sked25519-sk

Now you can use two additional key types: ecdsa-sk and ed25519-sk, where the “sk” suffix is short for “security key.”

不過在 Ubuntu 20.04 下用預設的系統只能支援 ecdsa-sk,因為 ed25519-sk 會遇到類似「ed25519 problem with libressl」這邊的問題,就算你用的是 OpenSSL

然後生完 key 後在 ~/.ssh/config 裡面指定對 github.com 使用這把 key:

Host github.com
    IdentityFile ~/.ssh/id_ecdsa_sk

接下來操作的時候就會需要碰一下 security key 了。

OpenSSH 8.4 預設停用 ssh-rsa

前幾天 OpenSSH 8.4 釋出了:「Announce: OpenSSH 8.4 released」。

比較重要的改變是 ssh-rsa 預設變成停用,因為是使用 SHA-1 演算法的關係:

It is now possible[1] to perform chosen-prefix attacks against the SHA-1 algorithm for less than USD$50K. For this reason, we will be disabling the "ssh-rsa" public key signature algorithm by default in a near-future release.

官方給了三個方案:

  • The RFC8332 RSA SHA-2 signature algorithms rsa-sha2-256/512. These algorithms have the advantage of using the same key type as "ssh-rsa" but use the safe SHA-2 hash algorithms. These have been supported since OpenSSH 7.2 and are already used by default if the client and server support them.
  • The ssh-ed25519 signature algorithm. It has been supported in OpenSSH since release 6.5.
  • The RFC5656 ECDSA algorithms: ecdsa-sha2-nistp256/384/521. These have been supported by OpenSSH since release 5.7.

掃了一下 ~/.ssh/known_hosts,看起來目前大多都是 ssh-ed25519 了,還有少數還是 ssh-rsa

翻了一下 Ubuntu 這邊的版本,16.04 是 7.2p2,看起來目前有支援的版本都可以用這三個。

官方有提到可以在 command 上強制關閉 ssh-rsa 測試的方法:

ssh -oHostKeyAlgorithms=-ssh-rsa user@host

現在看起來比較麻煩的是 Dropbear 的部份,我自己之前是有包 PPA 來用 (2019.78),但看起來還是不夠新支援 ssh-ed25519 (要今年六月的 2020.79 才支援),所以也許要找時間來把 PPA 更新到 2020.80...

另外一種方法是走 ecdsa-sha2-nistp{256,384,521} 這些演算法,不過從名字就可以知道裡面演算法的由來,卡個 NIST 在那邊看起來就不太舒服,但還是寫一下方法好了:

先用 dropbearkey 產生對應的 ecdsa host key:

sudo dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key -s 256

再來在 /etc/default/dropbear 裡面把 DROPBEAR_EXTRA_ARGS 加上對應的 ecdsa host key 資訊,這邊直接用 -r 是因為他可以重複指定,不會影響到其他的 host key 設定:

# any additional arguments for Dropbear
DROPBEAR_EXTRA_ARGS="-r /etc/dropbear/dropbear_ecdsa_host_key"

然後重跑 dropbear 就可以了。

另外有興趣的人可以用 ssh -Q key 看 openssh client 支援的演算法。

OpenSSH 的三個進階用法:CA 架構、透過 Jump Server 連線、2FA

在「How to SSH Properly」這篇裡面講了三個 OpenSSH 的進階用法:CA 架構、透過 Jump Server 連線,以及 2FA 的設定。

之前蠻常看到使用 -o StrictHostKeyChecking=off 關閉檢查,但 OpenSSH 有支援 CA 架構,可以先產生出 Root CA,然後對 Host 的 Public Key 簽名,在連線的時候就可以確保連線沒有被調包 (通常是 MITM),但得設計一套機制,自動化機器生出來後的步驟。

另外一個可能的方式是 SSHFP,搭配 DNSSEC 也可以確認連線沒有被調包,不過這又牽扯到 DNS 的部份...

第二個提到的是 Jump Server (Bastion host),之前的作法是用 -A 把 authentication agent 帶過去再連進去,這邊則是教你怎麼下指令直接連線,而不需要先連到 Jump Server (但實際上底層是透過 Jump Server)。

第三個是 2FA,對於還是使用密碼登入的系統可以多一層保護。文章裡面講的是 TOTP 的方式 (就是現在還蠻常見的 app + 六碼動態數字)。

先知道有這些東西,之後真的有用到的場景時再回來看...

AWS System Manager 支援 SSH 的 -L 功能 (Port Forwarding)

AWS System Manager 宣佈支援了 SSH Port Forwarding 的功能 (也就是 OpenSSH 指令裡的 -L):「New – Port Forwarding Using AWS System Manager Sessions Manager」。

以往是連到那台主機上後,再透過 -R 反過來再穿一層,但這必須在那台機器有 Internet 存取權限的情況下才有辦法做... 這次的方法是 AWS System Manager 直接提供了,所以只需要可以連到主機就可以做。

Mac 上讓 SSH 走 Socks5 的方式

在泰國住的飯店提供頗快的網路:

不過到 HiNet 看起來應該是有繞到美國之類的地區?

gslin@Gea-Suans-MacBook-Pro [~] [08:16/W4] mtr --report 168.95.1.1
Start: 2019-04-07T08:16:33+0700
HOST: Gea-Suans-MacBook-Pro.local Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.20.1                 0.0%    10    1.8   2.0   1.3   3.1   0.6
  2.|-- node-iyp.pool-101-108.dyn  0.0%    10    3.9   3.6   2.7   4.5   0.6
  3.|-- 172.17.36.105              0.0%    10    3.2   4.1   3.2   8.3   1.5
  4.|-- 203.113.44.205             0.0%    10    6.5   5.3   3.9   6.7   1.0
  5.|-- 203.113.44.177             0.0%    10    5.4   4.8   4.0   7.2   1.0
  6.|-- 203.113.37.194             0.0%    10    4.6   6.5   3.0  11.1   2.5
  7.|-- in-addr.net                0.0%    10    3.9   4.4   3.1   5.6   0.8
  8.|-- ???                       100.0    10    0.0   0.0   0.0   0.0   0.0
  9.|-- pcpd-4001.hinet.net        0.0%    10  355.4 356.9 355.1 365.4   3.0
 10.|-- pcpd-3212.hinet.net        0.0%    10  215.6 216.6 214.2 225.4   3.4
 11.|-- tpdt-3022.hinet.net        0.0%    10  219.4 215.9 214.0 221.5   2.5
 12.|-- tpdt-3012.hinet.net        0.0%    10  218.9 217.2 215.0 218.9   1.4
 13.|-- tpdb-3311.hinet.net        0.0%    10  212.5 212.9 211.9 214.1   0.6
 14.|-- 210-59-204-229.hinet-ip.h  0.0%    10  213.5 212.7 212.0 213.7   0.6
 15.|-- dns.hinet.net              0.0%    10  214.4 214.5 213.7 216.0   0.7

這樣有些影音服務只吃台灣 IP 就沒辦法用了,所以就得找方法來解決... 想法是透過我在 GCP 上開的機器繞回 HiNet,所以就得找 Mac 上 SSH 要怎麼設定 Socks5。

本來以為要用 tsocks 之類的工具 (i.e. 用 LD_PRELOAD 處理 connect()),但意外的在「SSH through a SOCKS Proxy? (client = OpenSSH OS X)」這邊看到可以用內建的 nc 處理,因為 nc 有支援 Socks5。

所以就變成兩包 ssh 指令:

ssh -D 1081 gcp.server
ssh -D 1080 -o "ProxyCommand nc -X 5 -x 127.0.0.1:1081 %h %p" hinet.server

然後 127.0.0.1:1080 就是打通的版本了,可以讓瀏覽器直接掛上去使用。

至於後來想起來不需要用 Socks5,可以用 ssh -L 而笑出來又是另外一件事情了 :o