本篇介紹如何在 macOS 中使用 SSH 搭配 Yubico 的 FIDO U2F Security Key 實體金鑰認證,登入遠端的 Linux 伺服器。
libfido2
在使用 Yubico 的金鑰之前,要先安裝 Yubico 的 libfido2 函式庫,這裡我以 macOS 為例,以 brew
來安裝:
# 安裝 libfido2
brew install libfido2
由於 OpenSSH 在 8.2 版之後才支援 FIDO U2F,所以要先把 macOS 系統上的 OpenSSH 更新到最新版:
# 安裝 openssh
brew install openssh
更新完 OpenSSH 後,開啟新的終端機,確認 ssh
的版本:
# 確認 ssh 版本 ssh -V
OpenSSH_9.0p1, OpenSSL 1.1.1o 3 May 2022
若要確認 Yubico 金鑰是否有被 macOS 抓到,可以將金鑰插入 macOS 之後,使用 ioreg
指令查看 USB 的設備:
# 查看 USB 設備 ioreg -p IOUSB
+-o Root <class IORegistryEntry, id 0x100000100, retain 23> +-o AppleUSBXHCI Root Hub Simulation@00000000 <class AppleUSBRootHubDevice, id 0x1000004fa, registered, matched, active, busy 0 (3 ms), retain 12> | +-o USB3.0 Hub @00200000 <class AppleUSBDevice, id 0x100004a0b, registered, matched, active, busy 0 (0 ms), retain 14> | +-o USB 10/100/1000 LAN@00230000 <class AppleUSBDevice, id 0x100004a8a, registered, matched, active, busy 0 (0 ms), retain 14> | +-o USB3.0 Hub @00220000 <class AppleUSBDevice, id 0x100004a94, registered, matched, active, busy 0 (0 ms), retain 13> | +-o Flash Card Reader/Writer@00224000 <class AppleUSBDevice, id 0x100004aff, registered, matched, active, busy 0 (0 ms), retain 12> +-o AppleUSBVHCIBCE Root Hub Simulation@80000000 <class AppleUSBRootHubDevice, id 0x100000501, registered, matched, active, busy 0 (4 ms), retain 15> | +-o Headset@80400000 <class AppleUSBDevice, id 0x100000507, registered, matched, active, busy 0 (4 ms), retain 11> | +-o Touch Bar Display@80600000 <class AppleUSBDevice, id 0x10000050b, registered, matched, active, busy 0 (4 ms), retain 13> | +-o Touch Bar Backlight@80700000 <class AppleUSBDevice, id 0x100000510, registered, matched, active, busy 0 (4 ms), retain 11> | +-o Ambient Light Sensor@80300000 <class AppleUSBDevice, id 0x100000515, registered, matched, active, busy 0 (4 ms), retain 11> | +-o Apple T2 Controller@80100000 <class AppleUSBDevice, id 0x10000051d, registered, matched, active, busy 0 (4 ms), retain 13> | +-o FaceTime HD Camera (Built-in)@80200000 <class AppleUSBDevice, id 0x100000522, registered, matched, active, busy 0 (5 ms), retain 13> | +-o Apple Internal Keyboard / Trackpad@80500000 <class AppleUSBDevice, id 0x100004bd6, registered, matched, active, busy 0 (1 ms), retain 20> +-o AppleUSBXHCI Root Hub Simulation@14000000 <class AppleUSBRootHubDevice, id 0x10000056e, registered, matched, active, busy 0 (4 ms), retain 9> +-o USB2.0 Hub @14400000 <class AppleUSBDevice, id 0x100004a24, registered, matched, active, busy 0 (0 ms), retain 14> +-o USB 2.0 BILLBOARD @14440000 <class AppleUSBDevice, id 0x100004ac6, registered, matched, active, busy 0 (1 ms), retain 12> +-o USB2.0 Hub @14420000 <class AppleUSBDevice, id 0x100004ad7, registered, matched, active, busy 0 (0 ms), retain 14> +-o HD Pro Webcam C920@14422000 <class AppleUSBDevice, id 0x100004b17, registered, matched, active, busy 0 (2 ms), retain 18> +-o Security Key by Yubico@14421000 <class AppleUSBDevice, id 0x1000090bb, registered, matched, active, busy 0 (1 ms), retain 12>
若要取得更詳細的 Yubico 實體金鑰資訊,可以使用 YubiKey Manager CLI,這個工具在 macOS 中可透過 brew
安裝:
# 安裝 YubiKey Manager
brew install ykman
安裝好 YubiKey Manager CLI 之後,使用 ykman
查詢 Yubico 實體金鑰資訊:
# 列出所有 Yubico 實體金鑰資訊
ykman list
FIDO U2F Security Key (4.2.7) [FIDO]
顯示 Yubico 實體金鑰詳細訊息:
# 顯示 Yubico 實體金鑰詳細訊息
ykman info
Device type: FIDO U2F Security Key Firmware version: 4.2.7 Enabled USB interfaces: FIDO Applications FIDO2 Not available OTP Not available FIDO U2F Enabled OATH Not available YubiHSM Auth Not available OpenPGP Not available PIV Not available
將 Yubico 實體金鑰插入 macOS 電腦中,接著使用 ssh-keygen
指令建立公私鑰檔案:
# 建立 ecdsa-sk 格式公私鑰檔案 ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk
Generating public/private ecdsa-sk key pair. You may need to touch your authenticator to authorize key generation. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/seal/.ssh/id_ecdsa_sk Your public key has been saved in /Users/seal/.ssh/id_ecdsa_sk.pub The key fingerprint is: SHA256:SICBg/TVFPPrSEfB/V2/GuneI+AxPjiu1OaOAbCdnFU seal@MacBookPro The key's randomart image is: +-[ECDSA-SK 256]--+ |oo.o..o+oE. | |+ o .. .+... .| | . o .. o . . o| | =.+.. . . ..| | . *..So . .| | o = + o . | | + ++ = o | | . =o + +.. | | o++. o....| +----[SHA256]-----+
執行上面這一行指令之後,要用手指按一下 Yubico 實體金鑰,並設定保護金鑰的密碼(也可以不設定,直接按下 Enter 跳過),最後就會產生一個私鑰檔案 ~/.ssh/id_ecdsa_sk
與一個公鑰檔案 ~/.ssh/id_ecdsa_sk.pub
。
接著將公鑰複製到遠端 Linux 伺服器,假設我們想要將 Yubico 實體金鑰用於 192.168.0.1
這台 Linux 主機的 myuser
使用者登入,可以用 ssh-copy-id
將公鑰複製到該台 Linux 主機的 myuser
帳號下:
# 將公鑰複製到遠端 Linux 伺服器 ssh-copy-id -i ~/.ssh/id_ecdsa_sk myuser@192.168.0.1
在執行這一行指令時,會需要輸入 myuser
的密碼,這行指令實際做的事情就是將公鑰內容寫入 myuser
帳號的 ~/.ssh/authorized_keys
檔案中。
由於這一支 Yubico 的 FIDO U2F Security Key 韌體版本比較舊,不支援 ed25519-sk 的金鑰格式,如果是比較新版的 Yubico 實體金鑰,可以考慮使用比較新的 ed25519-sk 金鑰格式:
# 建立 ed25519-sk 格式公私鑰檔案 ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk
設定完成後,我們就可以嘗試使用 Yubico 實體金鑰來登入遠端的 Linux 主機:
# 以 Yubico 實體金鑰登入遠端 Linux 主機
ssh myuser@192.168.0.1
執行登入指令後,我們要用手指按一下 Yubico 實體金鑰,這樣就可以使用 Yubico 實體金鑰登入遠端 Linux 主機了。
Confirm user presence for key ECDSA-SK SHA256:UfKCcfDhXt7sHCGjpSZ5wBirQ/3C546b7L9jPMFecrg User presence confirmed Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-110-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Mon May 16 15:09:24 CST 2022 System load: 0.04 Processes: 171 Usage of /: 78.0% of 93.73GB Users logged in: 0 Memory usage: 5% IPv4 address for ens3: 192.168.0.1 Swap usage: 0% * Super-optimized for small spaces - read how we shrank the memory footprint of MicroK8s to make it the smallest full K8s around. https://ubuntu.com/blog/microk8s-memory-optimisation 0 updates can be applied immediately. Last login: Mon May 16 15:08:55 2022 from 192.168.0.2
如果在執行 ssh
登入指令時,沒有插入 Yubico 實體金鑰,就無法使用該實體金鑰登入,錯誤訊息會類似這樣:
Confirm user presence for key ECDSA-SK SHA256:UfKCcfDhXt7sHCGjpSZ5wBirQ/3C546b7L9jPMFecrg sign_and_send_pubkey: signing failed for ECDSA-SK "/Users/seal/.ssh/id_ecdsa_sk": device not found
如果測試過實體金鑰可以正常登入之後,可以考慮將密碼認證功能關閉,並只接受實體金鑰登入,排除其他軟體類型的金鑰,讓系統更安全:
# 不接受密碼認證 PasswordAuthentication no # 只接受 ed25519-sk 與 ecdsa-sk 類型的金鑰 PubkeyAcceptedKeyTypes sk-ecdsa-sha2-nistp256@openssh.com,sk-ssh-ed25519@openssh.com
不過這樣的設定需要非常小心,因為一但實體金鑰不見了,就會完全無法透過 SSH 登入系統。各種金鑰類型的比較,可參考 SSH implementation comparison。
設定完成後,重新啟動 ssh
服務:
# 重新啟動 ssh 服務
sudo systemctl restart ssh
ssh-agent
macOS 系統預設啟動的 ssh-agent
是 /System/Library/LaunchAgents/com.openssh.ssh-agent.plist
中指定的 /usr/bin/ssh-agent
,但是這個版本太舊了,無法支援 FIDO U2F,所以若要使用 ssh-agent
的功能,就必須手動啟動 /usr/local/bin/ssh-agent
,以下是操作範例。
# 啟動 ssh-agent eval `ssh-agent` # 加入金鑰 ssh-add ~/.ssh/id_ed25519_sk # 進行 SSH 連線(啟用 agent forwarding) ssh -A myuser@192.168.0.1 # 停止 ssh-agent ssh-agent -k