MFA
freeradius
gauth
協助同事處理 MFA 驗證問題,之前也沒玩過,順便紀錄一下過程。這種架構應該是蠻適合用 Docker 建立的,有機會再說囉!
使用 hostnamectl
可不用重啟系統調整主機名稱,但記得要重新登入。
hostnamectl set-hostname authServer
hostnamectl
Ubuntu 預設使用 systemd-timesycd 作為 NTP 校時服務。
使用 timedatectl
確認系統時間相關資訊。
timedatectl [status]
以上資訊可以得知:
System clock synchronized: yes
該系統啟用系統網路校時服務。timedatectl set-ntp true
timedatectl set-ntp false
systemd-timesyncd.service active: yes
該系統目前使用 systemd-timesyncd
服務進行網路校時作業。/etc/systemd/timesyncd.conf
。[Time]
NTP=time1.google.com time2.google.com time3.google.com time4.google.com
FallbackNTP=ntp.ubuntu.com
systemctl restart systemd-timesyncd
重啟服務。同樣使用 timedatectl
列出可用時區及調整時區。
timedatectl list-timezones
指定 Asia/Taipei
作為系統時區。
timedatectl set-timezone Asia/Taipei
再次使用 timedatectl
確認系統時間相關設定。
timedatectl [status]
注意
RTC 時間 請使用 UTC 時間,而不要儲存本地時間(Local Time)。
一般 Linux 作業系統關於 DNS 解析都可以檢視 /etc/resolv.conf
並修改其中 nameserver
參數。
不過,目前似乎各發行版本都改由 systemd-resolved
服務處理。該組態檔可以檢視
/run/systemd/resolve/resolv.conf
: 基本上可以直接修改此組態檔,再重啟服務。
/run/systemd/resolve/stub-resolv.conf
當然也可以使用不同 Linux 發行平台所提供的工具。
組態檔: /etc/netplan/<network_config>.yaml
。編輯網路組態後,使用 netplan apply
套用設定。
使用 systemd-resolve --status | grep -A2 'DNS Servers'
查詢設定。
使用 nmcli connection modify <device> ipv4.dns "8.8.8.8 8.8.4.4"
使用 resolvectl status | grep 'DNS Servers'
查詢設定。
使用 dig
確認名稱解析。
$ sudo apt-get install build-essential libpam0g-dev freeradius git libqrencode3
$ sudo apt-get install -y libpam-google-authenticator
參考
以上系統更新及套件安裝動作,可以使用腳本檔一鍵執行完成,可以免去重複打字或輸入錯誤的問題或使用 Ansible 自動佈署達成。
#!/bin/bash
#
passport="${HOME}/.passport"
if [ -f ${passport} ]; then
pass=$(cat ${passport})
else
echo -e "<!> ${passport} NOT FOUND!<!>\n"
exit
fi
##
echo -e "\n[TASK] Update the System\n"
echo ${pass} | sudo -S apt update && sudo -S apt -y upgrade
echo -e "\n[TASK] Install FreeRadius & PAM packages\n"
echo -e " - build-essential
- libpam0g-dev
- freeradius
- freeradius-utils
- git
- libqrencode3"
echo
echo ${pass} | sudo -S apt install -y build-essential libpam0g-dev freeradius freeradius-utils git libqrencode3
echo -e "\n[TASK] Install Google Authenticator packages\n"
echo -e " - libpam-google-authenticator"
echo
echo ${pass} | sudo -S apt install -y libpam-google-authenticator
注意
freeradius -v
可檢視安裝版本。
/etc/freeradius/3.0/
。為了不刪除既有使用者,建立一個暫時禁用權限的群組 radius-disabled
。
sudo addgroup radius-disabled
/etc/freeradius/3.0/radiusd.conf
警告 在編輯任一個服務組態檔時,務必先備份原始檔案後變動。
將會變動以下列出組態檔內容:
編輯組態檔 /etc/freeradius/3.0/radiusd.conf
,進行以下變更。
註解以下內容
#user = freerad
#group = freeead
增加以下內容
user = root
group = root
/etc/freeradius/3.0/users
請在 # Deny access for a group of users. 這個區塊加入以下內容。
請務必按照以下內容的格式對齊,否則將會出現無法正確啟用 FreeRADIUS 應用服務。
DEFAULT Group == "radius-disabled", Auth-Type := Reject
Reply-Message = "Your account has been disabled."
DEFAULT Auth-Type := PAM
/etc/freeradius/3.0/sites-enabled/default
請在 Pluggable Authentication Modules. 這個區塊加入註解掉 pam
內容。
/etc/pam.d/radiusd
配置 PAM 以便透過組合本機用戶密碼和 Google Authenticator 產生 PIN 作為驗證方式。
以下註解
#@include common-auth
#@include common-account
#@include common-password
#@include common-session
增加以下設定
auth requisite pam_google_authenticator.so forward_pass
auth required pam_unix.so use_first_pass
完成以上設定,請將系統重開,並確認服務運作正常。
$ reboot
$ sudo systemctl status freeradius
用戶端就是設定可以向 FreeRADIUS 要求進行用戶身份驗證的主機。若以防火牆整合驗證需求來看,防火牆 就可視為一個用戶端,而設定的 IP 位址就是要與 FreeRADIUS 溝通並進行驗證行為的。
/etc/freeradius/3.0/clients.conf
以下是用戶端設定範例。
client Gateway {
ipaddr = 10.2.2.1
secret = SECRET
}
client 10.2.2.1 {
secret = SECRET
shortname = Gateway
}
我們也可以參考設定檔中 localhost
和 localhost_ipv6
的設定。
根據以下流程建立使用者並進行 Goolge Authenticator 生成。
可以使用以下簡單的腳本檔建立測試使用者帳號及密碼。
#!/bin/bash
passport="${HOME}/.passport"
pass=$(cat ${passport})
username="${1:-user01}"
password='VMware1!'
userid='1500'
if id -u ${username} &>/dev/null; then
echo -e "<!> User [${username}] is existed\n"
exit
fi
echo -e "\n[TASK] Create a user for Google Authenticator"
echo ${pass} | sudo -S useradd -s /bin/bash -d "/home/${username}" -u ${userid} -m ${username}
echo "${username}:${password}" | sudo chpasswd
echo -e "\n[RESULT] User Infomation:"
id ${username}
使用 sudo userdel -r {user_name}
命令可以刪除使用者相關資訊。
使用新建立的使用者帳號及密碼登入系統進行測試。
在該使用者家目錄下直接執行 google-authenticator
程式。
在終端機中產生的 QR-Code 尺寸過大,所以加入
-Q UTF8
可縮小一些,要不然就要手動調整終端機配置了!
由於我們使用的是 Time-based One-Time Password(TOTP),所以第一個選項請回答 y
。
Do you want authentication tokens to be time-based (y/n) y
接著系統便會產生相關資訊:
稍微研究一下顯示 QR Code URL。程式產生的 URL 如下:
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user02@authServer%3Fsecret%3DRAP7KZ4CPRCRDTU6WRIKSEB2W4%26issuer%3DauthServer
其中帶了一些 urlencode 碼 [參考],可以透過 urlencode -d
轉換成可識別字符。
所以 QR Code 顯示 URL 的結構可以解析成 (1) + (2)。其中 (1) 部份為固定, (2) 部份其中 {variable} 則為變數。
(1) https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&
(2) chl=otpauth://totp/{USERNAME}@{HOSTNAME}?secret={SECRET_KEY}&issuer={HOSTNAME}
所以此 QR Code 顯示的 URL,可以取得相關 {變數} 後自行產生建立。
有關 Key URI 詳細資訊可以參考 [連結]。
參考以下步驟繼續完成 Goolge Authenticator Token 建立程序。
完成上述設定程序,會將相關資訊儲存在該使用者家目錄中的 .google-authenticator
檔案。
其實可以研究一下 google-authenticator
程式執行的參數,讓這樣的設定程序可以自動化一點。
根據上述的問答流程,大致可以知道需要的配置如下:
$ google-authenticator --quiet --force \
--time-based \
--disallow-reuse \
--window-size=3 \
--rate-limit=3 --rate-time=30 \
--step-size=30 \ ## 可省略,會自帶
--emergency-codes=5 ## 可省略,會自帶
可簡寫為以下命令:
$ google-authenticator -qftd -w 3 -r 3 -R 30 -S 30 -e 5
透過上述命令可以查看執行結果,省去產生 QR Code 及問答流程,可直接產生組態檔。
至於 QR Code URL 透過以下簡單的腳本程式就可以取得!
getCodeUrl.sh
#!/bin/bash
#
username="${1}"
user_home=$(grep "${username}" /etc/passwd | cut -d: -f6)
mfa_config="${user_home}/.google_authenticator"
echo -e "\n[TASK] Check the configuration of Google Authenticator"
if [ ! -f "${mfa_config}" ]; then
echo -e " > Not found!! Please run \"google-authenticator\" first"
exit
fi
secretkey=$(head -n1 ${mfa_config})
hostname=$(hostname)
baseUrl='https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&'
keyUri="chl=otpauth://totp/${username}@${hostname}?secret=${secretkey}&issuer=${hostname}"
qrCodeUrl="${baseUrl}${keyUri}"
echo -e "\n[TASK] QR Code URL for \"${username}@${hostname}\""
echo -e "\n${qrCodeUrl}\n"
將上述產生的 QR Code URL 貼於瀏覽器確認狀態。
若要取得該使用者的驗證備用碼也很容易!
$ cat .google_authenticator | sed -n '/^[0-9].*[0-9]$/p'
透過簡單的 mailx | mutt 程式,可以模擬將驗證碼資訊寄發給使用者的應用情境。信件內文的訊息就是透過以上動作整合完成的。
這樣一來,串連以上相關的步驟,應該就可以自動化產生驗證碼並寄發使用者相關資訊了!
若要透過 Linux 主機的郵件服務寄送至外部郵件伺服器,則須注意是否有被 Anti-SPAM 功能阻擋囉。
公司採用的是 Office365,可以透過 反垃圾郵件 IP 取消清單網站 [連結] 將 IP 位址列入驗證要求清單。完成設定,可能需要等待一段時間再進行測試吧。
重新寄送驗證碼資訊到公司郵箱,模擬使用者收到驗證碼設定的郵件,看起來沒有問題!
注意: 請務必確認以下連結是否存在,否則二次驗證在 FreeRADIUS 中無法成功啟用。
完成所有配置程序,將 FreeRADIUS 服務重啟。
$ sudo systemctl restart freeradius
若有需要進行手機 App 測試,請取得 QR Code URL 後,以手機 App 操作掃描完成相關設定即可。
為了簡化驗證測試,就先使用 localhost
本機進行驗證程序。使用 radtest
命令,採用使用者 user02
,驗證密碼為 {使用者密碼}{Google Authenticator 驗證碼}
。使用以下命令進行測試。
$ sudo radtest {username} {password} localhost 18120 testing123
執行結果
驗證碼也採用備用碼以簡化測試過程。
另外檢視使用者的組態檔 .google_authenticator
,也可發現使用的備用碼也從該組態檔中刪去。
可查看 /var/log/auth.log
檔檢視驗證紀錄。
待解問題