前言
在前兩篇文章中,已經介紹了 SonarQube 的部署 以及 通過 sonar-cxx 插件實現 C/C++ 代碼掃描。
本篇將重點講 如何讓 SonarQube 對接 Windows AD(LDAP),實現域賬號登錄和基于 AD 組的權限管理。
一、背景與需求分析
需求分析
在原有環境中,代碼流轉流程是這樣的:
- 開發在 Gerrit 提交代碼
- Jenkins 節點定時或按需觸發自定義腳本掃描問題,并執行編譯
新需求:
- 在編譯之前,先掃描一次代碼(或編譯+掃描同步進行)
- 項目相關人員 能直接登錄 SonarQube 查看代碼問題并修復
- 非項目相關人員 無法訪問該項目(權限管控)
權限模型簡述
SonarQube 的權限是項目級的,可以通過:
- 將項目設為 私有
- 給特定 用戶組 或 成員 分配訪問所需權限
經測試,權限如下:
角色/權限項 | 組管理(添加/刪除成員) | 項目權限配置 | 項目刪除 | 備注 |
---|---|---|---|---|
系統管理員(Administrator) | ? 可以對任意組添加或刪除成員 | ? 可以配置任意項目的成員或組權限 | ? 可以刪除任意項目 | 擁有全局最高權限 |
項目管理員(Project Administrator) | ? 無法管理組成員 | ? 僅能管理該項目的權限(成員/組) | ? 僅能刪除該項目 | 該權限需系統管理將項目為私有后才可配置 |
普通組成員 | ? 無法管理組成員 | ? 無法配置項目權限 | ? 無法刪除項目 | 系統組沒有單獨的“組管理員”角色 |
所以這里無法單獨給項目設組管理員去維護組成員,但可以配置 項目管理員,由其對相關組或用戶進行權限管理 。
碰巧目前我司項目是由 部門/組
進行劃分,并且 Windows AD 上早已為這些成員配置了 AD 組
,所以只需要在項目上設 私有
并且給相應的組配置好權限,讓 LADP 將要組人員信息同步過來,那就可以減少一部分的人為操作管理。
二、Windows AD 集成
舊版本 SonarQube 需要額外安裝 LDAP 插件,而 9.9 LTS 版本(我是用的版本)已經內置了 LDAP 支持。
官方參考文檔:
- SonarQube 9.9 LDAP 配置文檔
這篇文檔,詳細介紹了 LDAP 怎么連接、使用、配置參數等,如:
ldap.url
這個參數是指 ldap 的連接地址 - SonarQube 環境變量配置文檔
但使用的是k8s
,即容器,該文檔介紹了 SonarQube 容器可使用哪些 env 參數。
配置思路
由于我是在 Kubernetes 環境運行 SonarQube,所以我選擇:
- 數據庫配置與 LDAP 配置都放到 Secret 中,避免明文寫在 Deployment YAML
- Deployment 通過
envFrom
讀取 Secret
原 Deployment(明文寫環境變量)
...
containers:
- name: sonarqubeimage: sonarqube:lts-communityenv:- name: TZvalue: 'Asia/Shanghai'- name: SONAR_JDBC_URLvalue: jdbc:postgresql://postgresql:5432/sonar- name: SONAR_JDBC_USERNAMEvalue: sonar- name: SONAR_JDBC_PASSWORDvalue: sonar- name: SONAR_WEB_JVM_OPTSvalue: "-Xmx2G -Xms1G -XX:+HeapDumpOnOutOfMemoryError"
...
新 Deployment(調用 Secret)
...
containers:
- name: sonarqubeimage: sonarqube:lts-communityenv:- name: TZvalue: 'Asia/Shanghai'- name: SONAR_WEB_JVM_OPTSvalue: "-Xmx2G -Xms1G -XX:+HeapDumpOnOutOfMemoryError"envFrom:- secretRef:name: sonar-secret
...
Secret 配置(secret.yaml
)
apiVersion: v1
kind: Secret
metadata:name: sonar-secretnamespace: sonar
type: Opaque
stringData:SONAR_JDBC_URL: "jdbc:postgresql://postgresql:5432/sonar"SONAR_JDBC_USERNAME: "sonar"SONAR_JDBC_PASSWORD: "sonar"SONAR_SECURITY_REALM: "LDAP" # 啟用 LDAP 認證SONAR_AUTHENTICATOR_DOWNCASE: "true" # 登錄名轉小寫,防止大小寫問題LDAP_URL: "ldap://192.168.1.1:389" # AD/LDAP 服務器地址(可改成 ldaps:// )LDAP_BINDDN: "CN=sonar,OU=User,OU=AA,DC=aa,DC=com"LDAP_BINDPASSWORD: "sonar" # 綁定賬號密碼LDAP_AUTHENTICATION: "simple" # 認證方式,一般 simple 就夠LDAP_REALM: "aa.com" # 可選,用于某些 Digest 認證LDAP_CONTEXTFACTORYCLASS: "com.sun.jndi.ldap.LdapCtxFactory" # LDAP Java 工廠類LDAP_STARTTLS: "false" # 是否啟用 StartTLS(不是 SSL)LDAP_FOLLOWREFERRALS: "false" # 是否跟隨 LDAP 引用LDAP_USER_BASEDN: "OU=AA,DC=aa,DC=com" # 用戶搜索起始 DNLDAP_USER_REQUEST: "(&(objectClass=user)(sAMAccountName={login}))" # 用戶搜索過濾條件LDAP_USER_REALNAMEATTRIBUTE: "cn" # 用戶真實姓名屬性LDAP_USER_EMAILATTRIBUTE: "mail" # 用戶郵箱屬性LDAP_GROUP_BASEDN: "OU=Groups,DC=aa,DC=com" # 組搜索起始 DNLDAP_GROUP_REQUEST: "(&(objectClass=group)(member={dn}))" # 組搜索過濾條件LDAP_GROUP_IDATTRIBUTE: "sAMAccountName" # 組 ID 屬性
參數解釋
變量名 | 作用 |
---|---|
SONAR_SECURITY_REALM | 啟用 LDAP 認證 |
SONAR_AUTHENTICATOR_DOWNCASE | 將用戶名轉換為小寫,避免 AD 大小寫問題 |
LDAP_URL | LDAP/AD 服務器地址,支持 ldap:// 和 ldaps:// |
LDAP_BINDDN | 用于綁定 LDAP 的賬號 DN(需有讀取用戶/組的權限) |
LDAP_BINDPASSWORD | 綁定賬號的密碼 |
LDAP_USER_BASEDN | 用戶搜索起點 DN |
LDAP_USER_REQUEST | 用戶搜索過濾規則 |
LDAP_GROUP_BASEDN | 組搜索起點 DN |
LDAP_GROUP_REQUEST | 組搜索過濾規則 |
LDAP_GROUP_IDATTRIBUTE | 組 ID 屬性,一般為 sAMAccountName |
小貼士:
LDAP_BINDDN
格式:
CN=sonar,OU=User,OU=AA,DC=aa,DC=com
表示 aa.com
域下 AA → User 組織單位中的 sonar 用戶。
部署與驗證
kubectl delete -f sonarqube.yaml
kubectl apply -f secret.yaml && kubectl apply -f sonarqube.yaml
常見啟動失敗原因:
- 數據庫連接信息錯誤
- LDAP 賬號/密碼錯誤
- DN 路徑拼寫錯誤
- 網絡防火墻攔截 LDAP 端口
若訪問有問題,
kubectl logs
看下啟動日志,一般就以上問題。
然后使用 AD 域賬號瀏覽器登錄 SonarQube ,成功登錄即加域成功。
三、AD 組同步的坑
經測試 + 官方聲明,發現 SonarQube 是 不會直接把 AD 組以及組內成員同步系統上 。
可以在 SonarQube 上面新建同名 AD 組,重啟系統進行同步,當然會存在一些 限制
:
-
組不會自動同步成員
- 只有當成員首次登錄 SonarQube 后,系統才會將該成員加入對應組。
- 并且 SonarQube 新建同名組,還得重啟服務器生效 。
-
組刪除成員不實時
- AD 組刪除成員,SonarQube 上面同名組并不會實時刪除。
- 需要重啟 SonarQube,并且該成員重新登錄后,才會被移出組。
-
多層組結構問題
- 如果 AD 中 A 組包含 B 組,B 組里有成員 C,SonarQube 不會識別成員 C 屬于 A 組
實際同步流程:
- 新建 SonarQube 組(與 AD 組同名)
- 重啟 SonarQube
- AD 組成員登錄一次
- 該成員才會被加入組
總結
正式上線前,給 AD 組配置同名組,并給這個同名組配好相關權限。并由 項目管理員 去配置項目權限。
后續 AD 賬號登錄 SonarQube 就自動加入對應組,即上線就有相應權限。
后續優化:
目前在新建 AD 同名組以及刪除 AD 域控上組成員,都必須要重啟 SonarQube 服務且 AD 用戶重新登錄才生效,后續看能不能通過調用 SonarQube 的 API 實現實時權限變更(通過調用 Gerrit/Jenkins 的 API 進行信息匹對)。
當然,也要看正式上線后大家反饋的問題,若有強烈的實時同步需求,就按上面方式進行優化。
下一篇將更新 SonarQube 如何打通 Jenkins。