Skip to main content

Linux SSH 啟用 OTP 驗證登入

安裝Qrencode、OATH和pam
apt install qrencode oathtool libpam-oath

設定oathtool

產生一組隨機的十六進位字串,並把它存成環境變數 HEX_SECRET

export HEX_SECRET=$(head -15 /dev/urandom | sha256sum | cut -b 1-30)

產生六位數OTP密碼

oathtool --totp=SHA256 --verbose --digits=6 $HEX_SECRET

紀錄Base32 secret值,後續Qrencode會依照這個參數生成

root@ssh:~#  oathtool --totp=SHA256 --verbose --digits=6 $HEX_SECRET
Hex secret: 2180dcb885c46412345674e3aa4dba
Base32 secret: EGANZOEFYRddasdsa5STR2UTN2
Digits: 6
Window size: 0
TOTP mode: SHA256
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: 2025-10-07 14:56:47 UTC (1759849007)
Counter: 0x37F1B01 (58661633)

961769

建立oath檔案

touch /etc/users.oath
chmod 0600 /etc/users.oath

寫入oath檔案

echo HOTP/T30 $USER - $HEX_SECRET \ >> /etc/users.oath

移除環境變數

unset HEX_SECRET

SSH 設定

/etc/pam.d/sshd最上面加入

auth required pam_oath.so usersfile=/etc/users.oath

修改/etc/ssh/sshd_config

ChallengeResponseAuthentication yes 
AuthenticationMethods keyboard-interactive:pam 
KbdInteractiveAuthentication yes 
service ssh restart

產生Qrencode

建立otp.sh並輸入以下

secret輸入上面Base32 secret的值

#!/bin/bash
secret=EGANZOEFYRddasdsa5STR2UTN2
echo $secret
qrencode -o - $(echo otpauth://totp/test:test123?secret=${secret}&issuer=test&algorithm=SHA256&digits=6&period=30) -o qrcode.png -t png -s 5
test:test123  關聯標籤
issuer 發行人名稱
algorithm 演算法
digits OTP位數
period 時間更新

執行otp.sh後會產生一個qrcode,使用任何OTP APP掃描新增

測試登入

登入後顯示要求輸入otp密碼

root@server:~# ssh 192.168.100.100
(root@192.168.100.100) One-time password (OATH) for `root': 
(root@192.168.100.100) Password: