# 使用 FreeRADIUS 搭配 Google 認證服務進行雙重驗證 ###### tags: `MFA` `freeradius` `gauth` 協助同事處理 MFA 驗證問題,之前也沒玩過,順便紀錄一下過程。這種架構應該是蠻適合用 **Docker** 建立的,有機會再說囉! [toc] # 執行環境 - Ubuntu 18.04.6 LTS - FreeRADIUS 3.0 - [google-authenticator](https://github.com/google/google-authenticator) # 執行步驟 :::warning - 執行步驟應可以使用腳本檔執行達成目標,這樣一來只要**做一次一勞永逸**。 - 使用容器完成應該會更好。 ::: ## 修改主機名稱 使用 **`hostnamectl`** 可不用重啟系統調整主機名稱,但記得要**重新登入**。 - **`hostnamectl set-hostname authServer`**  - **`hostnamectl`**  ## 確認 NTP 狀態 Ubuntu 預設使用 **systemd-timesycd** 作為 NTP 校時服務。 使用 **`timedatectl`** 確認系統時間相關資訊。 - **`timedatectl [status]`**  以上資訊可以得知: - **`System clock synchronized: yes`** 該系統啟用系統網路校時服務。 :::info - **開啟 NTP 功能**: `timedatectl set-ntp true` - **關閉 NTP 功能**: `timedatectl set-ntp false` ::: - **`systemd-timesyncd.service active: yes`** 該系統目前使用 **`systemd-timesyncd`** 服務進行網路校時作業。 :::info - 組態檔 **`/etc/systemd/timesyncd.conf`**。 - 可在組態檔中指定校時 NTP 伺服器,若有多組以**空白**區隔。 ```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]`**  :::danger **注意** **RTC 時間** 請使用 **UTC 時間**,而不要儲存**本地時間(Local Time)**。 ::: ## 確認 DNS 解析 一般 Linux 作業系統關於 DNS 解析都可以檢視 **`/etc/resolv.conf`** 並修改其中 **`nameserver`** 參數。 不過,目前似乎各發行版本都改由 **`systemd-resolved`** 服務處理。該組態檔可以檢視 - **`/run/systemd/resolve/resolv.conf`**: 基本上可以**直接修改此組態檔,再重啟服務**。 - **`/run/systemd/resolve/stub-resolv.conf`**   當然也可以使用不同 Linux 發行平台所提供的工具。 - Ubuntu: **netplan** - 組態檔: **`/etc/netplan/<network_config>.yaml`**。編輯網路組態後,使用 **`netplan apply`** 套用設定。  - 使用 **`systemd-resolve --status | grep -A2 'DNS Servers'`** 查詢設定。  :::info [**Netplan configuration examples**](https://netplan.io/examples) ::: - Fedora: **nmcli** - 使用 **`nmcli connection modify <device> ipv4.dns "8.8.8.8 8.8.4.4"`**  - 使用 **`resolvectl status | grep 'DNS Servers'`** 查詢設定。  :::info [**Configuring IP networking with nmcli**](https://docs.fedoraproject.org/en-US/quick-docs/configuring-ip-networking-with-nmcli/) ::: 使用 **`dig`** 確認名稱解析。  ## 更新系統套件  ## 安裝 FreeRADIUS 和 PAM 相關套件 ```bash $ sudo apt-get install build-essential libpam0g-dev freeradius git libqrencode3 ``` ## 安裝 Google Authenticator 套件 ```bash $ sudo apt-get install -y libpam-google-authenticator ``` :::info **參考** 以上系統更新及套件安裝動作,可以使用腳本檔一鍵執行完成,可以免去重複打字或輸入錯誤的問題或使用 Ansible 自動佈署達成。 - **update_install.sh** ```bash! #!/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 使用 Google Authenticator 進行 MFA :::warning **注意** - freeRADIUS 有可能會因為**版本不同**造成**服務組態檔位置不同**,請根據實際安裝版本檢視並修正對應組態檔。 - 使用 **`freeradius -v`** 可檢視安裝版本。  - 下列以 **版本 3.0.16** 進行操作。 - 主要 freeRADIUS 組態檔所在目錄為 **`/etc/freeradius/3.0/`**。 ::: ### 建立暫時禁用權限群組 為了不刪除既有使用者,建立一個暫時禁用權限的群組 **`radius-disabled`**。 ```bash sudo addgroup radius-disabled ``` ### 編輯 `/etc/freeradius/3.0/radiusd.conf` :::danger **警告** 在編輯任一個服務組態檔時,務必先備份原始檔案後變動。 ::: :::info 將會變動以下列出組態檔內容: - /etc/freeradius/3.0/radiusd.conf - /etc/freeradius/3.0/users - /etc/freeradius/3.0/sites-enabled/default - /etc/freeradius/3.0/clients.conf - /etc/pam.d/radiusd ::: 編輯組態檔 **`/etc/freeradius/3.0/radiusd.conf`**,進行以下變更。 :::success **註解以下內容** ``` #user = freerad #group = freeead ``` **增加以下內容** ``` user = root group = root ``` :::   ### 編輯 `/etc/freeradius/3.0/users` 請在 **# Deny access for a group of users.** 這個區塊加入以下內容。 :::danger 請**務必**按照以下內容的**格式對齊**,否則將會出現**無法正確啟用 FreeRADIUS 應用服務**。 ::: :::success ``` 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** 作為驗證方式。 :::success **以下註解** ``` #@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 ``` :::  ### 重新開機 完成以上設定,請將**系統重開**,並確認服務運作正常。 ```bash $ reboot $ sudo systemctl status freeradius ```  ## 設定 FreeRADIUS 用戶端 用戶端就是設定可以向 FreeRADIUS 要求進行用戶身份驗證的主機。若以防火牆整合驗證需求來看,防火牆 就可視為一個用戶端,而設定的 IP 位址就是要與 FreeRADIUS 溝通並進行驗證行為的。 ### 編輯 `/etc/freeradius/3.0/clients.conf` 以下是用戶端設定範例。 :::success ``` client Gateway { ipaddr = 10.2.2.1 secret = SECRET } client 10.2.2.1 { secret = SECRET shortname = Gateway } ``` ::: 我們也可以參考設定檔中 **`localhost`** 和 **`localhost_ipv6`** 的設定。  :::info - **secret** 是 FreeRADIUS 與用戶端進行驗證的**密碼**。 - 若只是簡易測試,使用 **Localhost** 即可。 ::: ## 設定 FreeRADIUS 使用者資料庫 根據以下流程建立使用者並進行 Goolge Authenticator 生成。 ### 建立使用者 可以使用以下簡單的腳本檔建立測試使用者帳號及密碼。 ```bash! #!/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} ```  :::warning 使用 **`sudo userdel -r {user_name}`** 命令可以刪除使用者相關資訊。 ::: ### 使用新建立使用者登入 使用新建立的使用者帳號及密碼登入系統進行測試。  ### 創建 Google Authenticator 驗證碼 在該使用者家目錄下直接執行 **`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 寄給使用者,以完成 Google 兩步驟驗證功能設定。 - **QR Code** - **密鑰(Secret Key)** - **驗證碼(verification code)** - **備用碼(emergency scratch code)**  :::info 稍微研究一下顯示 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 碼 [[**參考**]](https://www.w3schools.com/tags/ref_urlencode.ASP),可以透過 **`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** 詳細資訊可以參考 [[**連結**]](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)。 ::: 參考以下步驟繼續完成 Goolge Authenticator Token 建立程序。  完成上述設定程序,會將相關資訊儲存在該使用者家目錄中的 **`.google-authenticator`** 檔案。  ### Google-Authenticator 探索 其實可以研究一下 **`google-authenticator`** 程式執行的參數,讓這樣的設定程序可以自動化一點。 根據上述的問答流程,大致可以知道需要的配置如下: - 使用 TOTP 驗證 - 自行產出密鑰 - 生成備用碼 5 組並更新原有設定檔(.google_authenticator) - 單一驗證碼不允許重複使用 - 驗證碼 30 秒刷新(預設) - 時間同步窗口 (3, 預設) - 限制每 30 秒內不超過 3 次驗證流量 - 不顯示 QR Code ```bash $ google-authenticator --quiet --force \ --time-based \ --disallow-reuse \ --window-size=3 \ --rate-limit=3 --rate-time=30 \ --step-size=30 \ ## 可省略,會自帶 --emergency-codes=5 ## 可省略,會自帶 ``` 可簡寫為以下命令: ```bash $ google-authenticator -qftd -w 3 -r 3 -R 30 -S 30 -e 5 ``` 透過上述命令可以查看**執行結果**,省去產生 QR Code 及問答流程,可直接產生組態檔。  至於 QR Code URL 透過以下簡單的腳本程式就可以取得! - **`getCodeUrl.sh`** ```bash! #!/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 貼於瀏覽器確認狀態。  若要取得該使用者的驗證備用碼也很容易! ```bash! $ cat .google_authenticator | sed -n '/^[0-9].*[0-9]$/p' ```  透過簡單的 **mailx | mutt** 程式,可以模擬將驗證碼資訊寄發給使用者的應用情境。信件內文的訊息就是透過以上動作整合完成的。  這樣一來,串連以上相關的步驟,應該就可以**自動化產生驗證碼並寄發使用者相關資訊**了! :::info 若要透過 Linux 主機的郵件服務寄送至外部郵件伺服器,則須注意是否有被 Anti-SPAM 功能阻擋囉。 公司採用的是 Office365,可以透過 **反垃圾郵件 IP 取消清單網站** [[連結]](https://sender.office.com/) 將 IP 位址列入驗證要求清單。完成設定,可能需要等待**一段時間**再進行測試吧。  重新寄送驗證碼資訊到公司郵箱,模擬使用者收到驗證碼設定的郵件,看起來沒有問題!  ::: ### 重啟 FreeRADIUS 服務 <font color=red>**注意: 請務必確認以下連結是否存在,否則二次驗證在 FreeRADIUS 中無法成功啟用。**</font>  完成所有配置程序,將 FreeRADIUS 服務重啟。 ```bash $ sudo systemctl restart freeradius ``` :::warning 若有需要進行手機 App 測試,請取得 QR Code URL 後,以手機 App 操作掃描完成相關設定即可。 ::: ## 功能驗證 為了簡化驗證測試,就先使用 **`localhost`** 本機進行驗證程序。使用 **`radtest`** 命令,採用使用者 **`user02`**,驗證密碼為 **`{使用者密碼}{Google Authenticator 驗證碼}`**。使用以下命令進行測試。 ```bash! $ sudo radtest {username} {password} localhost 18120 testing123 ``` **執行結果**  :::info 驗證碼也採用**備用碼**以簡化測試過程。 另外檢視使用者的組態檔 **`.google_authenticator`**,也可發現使用的備用碼也從該組態檔中刪去。  可查看 **`/var/log/auth.log`** 檔檢視驗證紀錄。  ::: :::success - 以上大致就是使用 FreeRADIUS 搭配 Google Authenticator 作 MFA 的紀錄。 - 至於後續與其他服務或網路設備整合,大致上只要將驗證主機指向 FreeRADIUS 服務應該就可以達成。 ::: :::warning **待解問題** - 雖然可以按照步驟完成 freeRADIUS 與 Google 認證產生 QRCode。但是整個**執行流程**似乎沒有**前端**可以提供給終端用戶。但可以**透過腳本程式達成一點點自動化的目標**。 - 若客戶**已有 AD 的使用者資料庫**,似乎 freeRADIUS 還要另外**與 AD 整合使用者資料庫**,否則將使造成管理者管理帳戶的負擔。 - 不清楚 AD 是否可以直接與 Google 認證結合?還是可以改用 **Microsoft Azure**? ::: --- # 參考 - [SSLVPN Two-factor Authentication with Google Authenticator](https://kb.hillstonenet.com/en/wp-content/uploads/2019/09/SSLVPN-Two-factor-Authentication-with-Google-Authenticator.pdf) - [FreeRADIUS Google Dual Factor Authenticator](https://developer.aliyun.com/article/449710) - [Setup FreeRADIUS on Kali Linux for 802.1X Authentication](https://www.youtube.com/watch?v=AwkIUw8mS_c) - [Quickly Install FreeRadius on CentOS 7 and Do a Basic Configuration](https://youtu.be/CXG51efc5oc)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.