標籤:FreeIPA

如何從 NSSDB (certutil) 中取出 pem 格式的 key

本篇提到的 certutil 系指 UNIX 系統下的 Certificate Database 管理工具,與 Windows Server 的 certutil 無關,若想了解 Windows Server 下的 certutil,請造訪: https://docs.microsoft.com/zh-tw/windows-server/administration/windows-commands/certutil

因為最近在玩 FreeIPA 的關係,會需要幫 https 服務簽署憑證,在理解如何使用 FreeIPA 簽署的同時,順便發現到了一個管理憑證與其金鑰的工具 —— certutil[1]

certutil 可以管理 NSS Database 裡面的憑證與金鑰,FreeIPA 中的 PKI 服務 Dogtag 亦使用此一工具來管理憑證,就連 Firefox 自有的憑證庫也是使用這個方式儲存。不過,雖然這個 toolset 很棒,但我的 https 服務只吃 pem 格式的憑證,但從 NSSDB 取出的金鑰則會是 p12[2] 格式,這裡需要再做一些人工的轉換,所以這裡筆記一下該如何使用這些工具順便簡單介紹一下從 FreeIPA 上簽發憑證的流程吧。

建立 NSSDB 並放入 CA

在跟 FreeIPA 請求憑證簽署之前,我們要先有自己的金鑰庫,所以我們要先透過 certutil 來建立金鑰庫並先匯入我們的 CA 憑證,先假設我們要把 NSSDB 存放在 ~/certs

$ mkdir -p ~/certs
$ certutil -N -d ~/certs # 建立新的 NSSDB
$ certutil -A -d ~/certs -n 'IPA CA' -t CT,, -a < ca.crt # 匯入 CA 憑證

certutil 的指令說明可以去參考使用手冊,這裡只會解釋有用到的部分:

  • -d 指定 NSSDB 位置
  • -N 建立新的 NSSDB
  • -A 匯入已存在的憑證
    • -n 給予該憑證一個暱稱(此例為 IPA CA
    • -t 設定該憑證的信任模式,這裡我們採取信任該 CA 簽署的任何 Server/Client SSL
    • -a 採 ASCII 編碼輸入/出

建立金鑰及憑證簽署請求

有了自己的金鑰庫之後,就是要產生金鑰及憑證簽署請求(Certificate Request)了,透過 certutil 我們可以一步同時產生兩者:

$ certutil -R -d ~/certs -a -g 4096 -s CN=web.example.com,O=EXAMPLE.COM > web.csr
  • -R 產生一個憑證簽署請求檔(.csr
    • -g 金鑰長度,預設為 1024(此例為 4096
    • -s 主體名稱(Subject),此處需填寫此憑證的 Common Name(通常是 FQDN),以及 FreeIPA 要求需填寫 Organization

若需要加入 SAN[3],可以再加上 --extSAN 參數,例如 --extSAN dns:web.example.com,dns:web.example.org

從 FreeIPA 簽發憑證

從 FreeIPA 簽發的部分可以從 Web UI 或 CLI 建立,這邊兩者都會介紹,請讀者自己選擇自己喜歡的方式:

via CLI

$ kinit admin # 先登入有權限簽發憑證的 IPA 帳號
Password for [email protected]:
$ ipa cert-request --principal=HTTP/web.example.com web.csr
Issuing CA: ipa
Certificate: ...
Subject: CN=web.example.com,O=EXAMPLE.COM
Issuer: CN=Certificate Authority,O=EXAMPLE.COM
Not Before: Wed Mar 18 00:00:00 2020 UTC
Not After: Thu Mar 17 00:00:00 2022 UTC
Serial number: 11 # <= 記下序號
Serial number (hex): 0xB
$ ipa cert-show 11 --out=web.crt # 填入序號(11)
Issuing CA: ipa
Certificate: ...
Subject: CN=web.example.com,O=EXAMPLE.COM
Issuer: CN=Certificate Authority,O=EXAMPLE.COM
Not Before: Wed Mar 18 00:00:00 2020 UTC
Not After: Sat Mar 19 00:00:00 2022 UTC
Serial number: 11
Serial number (hex): 0xB
Revoked: False
  • ipa cert-request 簽署憑證
    • --principal IPA 中的 Kerberos 主體
  • ipa cert-show 取得對應序號之憑證

取得憑證後,我們接下來就是要準備取得 pem 格式的金鑰了。

via Web UI

首先找到我們要簽署的服務(HTTP/web.example.com),然後按下 Service Certificate 中的 Add,並填入剛剛產生的 csr 內容:


接下來對剛剛產生的 Certificate 按下 Actions -> Get,就可以取得剛剛產生的憑證,我們先複製下來並儲存到 web.crt,然後就可以準備取得 pem 格式的金鑰了。


取得 pem 格式金鑰

終於要進入本篇主題了 —— 取得 NSSDB 中的金鑰,這裡我們還會需要 NSS Security Tools 裡的另一個工具 pk12util[4],他負責將 NSSDB 中的憑證及金鑰以 p12 的格式匯入/匯出,我們稍後要利用他匯出 p12 格式的金鑰並轉成 pem 格式。

匯入簽發憑證

在取得金鑰之前,我們必須先匯入剛剛取得的憑證,讓 NSSDB 知道我們有一個憑證對應到剛剛產生的金鑰,之後我們才可以將金鑰取出:

$ certutil -A -d ~/certs -n web -t u,u,u -i web.crt
  • -A 匯入已存在的憑證
    • -n 給予該憑證一個暱稱(此例為 web
    • -t 設定該憑證的信任模式,這裡我們信任該憑證作為驗證及簽章用
    • -i 憑證檔名

取出 p12 金鑰

成功匯入憑證之後我們就可以使用 pk12util 將金鑰匯出了:

$ pk12util -d ~/certs -n web -o web.p12

pk12util 的參數大致上都跟 certutil 差不多,執行完畢後會得到一個 p12 格式的金鑰 web.p12

轉換成 pem 金鑰

轉換的步驟也很簡單,透過萬能的 OpenSSL 就可以轉換了:

$ openssl pkcs12 -in web.p12 -out web.key -nocerts -nodes

經過轉換後的 pem 格式金鑰會被存放在 web.key 中,如果打開來看的話會發現除了金鑰本體,還會附上一些額外資訊如下,如果是要拿去給服務吃的話可以直接刪掉留下金鑰本體即可:

Tag Attributes
    friendlyName: web
    localKeyID: ...
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

後記

之前有發過一篇關於使用 OpenSSL 來簽發中介 CA 的方法,這次改嘗試使用不同的工具來操作憑證,畢竟達到相同目的的工具百百種,多用一些抓到自己最順手的方式及工具可以大大的提升工作效率,如果有興趣使用 NSSDB 管理憑證及金鑰的朋友們可以多試試看,真的滿方便的,金鑰再也不會亂丟了 XDDDD


  1. 一個在 UNIX 系統下管理 Certificate Database 的工具,屬於 NSS Security Tools 的一部分,在 Debian/Ubuntu 下套件名為 libnss3-tools;RHEL/Fedora/CentOS 下則為 nss-tools。使用說明可以參考 MDNman 1 certutil↩︎

  2. PKCS #12,存放金鑰及憑證的一種格式,常見副檔名有 .p12.pfx,詳見維基百科上的《PKCS 12》條目 ↩︎

  3. Subject Alternative Name,為 X.509 extension 的一部分,支援單一憑證擴充描述替代用的主體名稱,可用來讓憑證支援多個 domain。 ↩︎

  4. 使用說明可以參考 MDNman 1 pk12util↩︎

如何將 Rancher 串上 FreeIPA 驗證

因工作需求,最近在研究如何使用 Rancher[1] 來管理 Kubernetes[2] 叢集,於是打算在 Homelab 上也建一組,想說前幾個禮拜還在研究 FreeIPA[3] 乾脆把他們湊一堆好了 XD

準備 Service Account

在開始將 FreeIPA 驗證接進 Rancher 之前,Rancher 要求先在 IPA 裡面建立一個 Service Account 來提供 Rancher 查詢 Domain 下的使用者與群組,但這個建立 Service Account 的步驟無法從 FreeIPA Web 界面執行,必須手動將這個 Account 加入 LDAP 中[4],首先到 IPA master 上執行下列步驟:(假設 IPA domain 為 example.com

$ cat - <<-EOF > add-srvacct-rancher.ldif
dn: uid=rancher,cn=sysaccounts,cn=etc,dc=example,dc=com
changetype: add
objectclass: account
objectclass: simplesecurityobject
uid: rancher
userPassword: 2Brq/Ux4rs:2Dnt3#%Rx
nsIdleTimeout: 0
EOF
$ ldapmodify -x -D 'cn=Directory Manager' -W < add-srvacct-rancher.ldif
Enter LDAP Password: # Enter Dircetory Manager password
adding new entry "uid=rancher,cn=sysaccounts,cn=etc,dc=example,dc=com"
$

其中 dc=example,dc=com 記得換成自己的 IPA domain,以及自己產生 userPassword(筆者是使用密碼產生器產生)後記下,待會會在 Rancher 設定用到。

設定 Rancher

首先登入有 administrator 權限的帳號,並依照以下步驟設定 FreeIPA Authenticate:

  1. 在 Global 域中選擇 Security -> Authentication
  2. 選擇 FreeIPA
  3. 填入 FreeIPA 伺服器資訊
  4. 在 Service Account 相關資訊中填入剛剛建立的 Service Account
    • Service Account Distinguished Name(記得換成 IPA domain)
      • uid=rancher,cn=sysaccounts,cn=etc,dc=example,dc=com
    • Service Account Password
      • 剛剛建立的 userPassword
  5. 填入使用者資料庫相關資訊
    • User Search Base(記得換成 IPA domain)
      • cn=users,cn=accounts,dc=example,dc=com
    • Group Search Base(記得換成 IPA domain)
      • cn=groups,cn=accounts,dc=example,dc=com
  6. Customize Schema 的部分我會選擇調整使用者的帳號資訊對應
    • Username Attribute(使用者顯示名稱)
      • displayName
    • Login Attribute(使用者帳號)
      • uid
    • Search Attribute(搜尋欄位,在搜尋使用者時會去尋找的欄位,預設是姓名跟帳號)
      • uid
  7. 在 Test and enable authentication 中填入要與目前帳號綁定的 FreeIPA 帳號資訊
    • 根據 Rancher 的說明[5],在這裡填入的 FreeIPA 帳號(external principal)會自動對應到目前用來設定的管理員帳號(local principal),並會在設定成功之後自動改用 external principal 登入 Rancher
  8. 在設定完成後點擊 Authenticate with FreeIPA 即可完成設定

設定完成後發現會被 Rancher 自動以剛剛 test authentication 的帳號登入,並且同時又是剛剛設定時使用的管理員帳號,從 Preference 頁面可以看到這個現象,但不要緊張,只是因為 Rancher 把這兩個帳號綁定了,共用 local ID。

後記

這次的篇幅稍短,介紹的內容也是偏簡單,僅對於 FreeIPA 如何建立 Service Account 的部分有特別需要撰寫 ldif 來手動加入 LDAP。 不知道大家對於這種篇幅及類型的文章接受度如何,就先當作是嘗試看看,同時也是在回應筆者朋友兼大神 小飛機 提出的看法[6]「資訊太多,透過文字消化資訊和整理思緒」並為自己而寫,因此打算開始嘗試這種廢文體短篇筆記型的內容,同時用比較輕鬆的態度來發文看看 XD


  1. 管理 Kubernetes 叢集的工具,提供多叢集、ACL、自動部署、Web 界面等特點,該公司還有出很多 K8s 相關的其他工具,詳見官方網站 ↩︎

  2. Kubernetes 是用於自動部署、擴展和管理「容器化(containerized)應用程式」的開源系統,詳見其官方網站 ↩︎

  3. FreeIPA 是免費的開源身份管理系統,IPA 分別代表 Identity、Policy、Audit,同時也是 Red Hat Identity Manager 的上游開源專案,詳見其官方網站 ↩︎

  4. FreeIPA 的 HowTo/LDAP 頁面亦有提及如何新增 Service Account/System Account ↩︎

  5. https://rancher.com/docs/rancher/v2.x/en/admin-settings/authentication/#external-authentication-configuration-and-principal-users ↩︎

  6. 請見小飛機大大的文章《成為一名技術留跡者↩︎