博客 / 詳情

返回

Archery + LDAP 一體化部署

Archery 是一個開源的 SQL 審核與運維管理平台,它主要面向 DBA 和開發人員,用於安全、可控地管理數據庫變更、查詢和慢 SQL 分析。
主要功能:
支持多種數據庫:MySQL、PostgreSQL、SQLServer、ClickHouse 等
提供 SQL 審核、執行工單、慢 SQL 分析、查詢權限控制
支持接入 LDAP、釘釘、企業微信、飛書 等認證方式
通過 Web 界面統一管理,提高數據庫操作安全性與合規性

一、安裝 Docker 與 Docker Compose
> 適用於 CentOS 7+

# 安裝依賴
yum install -y yum-utils
# 添加 Docker 官方阿里雲鏡像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安裝 Docker 與 Compose 插件
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 啓動並設置開機自啓
systemctl enable docker --now
# 檢查版本
docker -v
docker-compose version || docker compose version
# 若 docker-compose 插件不可用,可使用傳統二進制安裝:
curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

 二、部署 Archery

1. 下載 Archery 源碼包

wget https://github.com/hhyo/Archery/archive/refs/tags/v1.13.0.tar.gz
tar xf v1.13.0.tar.gz
cd Archery-1.13.0/src/docker-compose

2. 啓動容器服務

docker-compose -f docker-compose.yml up -d

# 默認會啓動 `archery`、`mysql`、`redis`、`nginx` 等容器。

# 若端口衝突,請在 `.env` 中修改 `NGINX_PORT=9123`。

 三、初始化數據庫結構

1. 進入容器:

docker exec -it archery /bin/bash

2. 進入虛擬環境:

source /opt/venv4archery/bin/activate
cd /opt/archery

3. 執行表結構初始化:

python3 manage.py makemigrations sql
python3 manage.py migrate

4. 加載基礎數據:

python3 manage.py dbshell < sql/fixtures/auth_group.sql
python3 manage.py dbshell < src/init_sql/mysql_slow_query_review.sql

5. 創建管理員用户:

python3 manage.py createsuperuser

6 退出容器:

exit

四、日誌與訪問

1. 查看運行日誌:

docker logs archery -f --tail=100

2. 訪問系統:

http://<服務器IP>:9123

五、部署LDAP(企業統一認證)
推薦 go-ldap-admin,它是一款基於 Go 語言開發的 輕量級 Web LDAP 管理平台。
它可視化地管理 LDAP 用户、組織、組、權限等信息,支持常見的 OpenLDAP 或 AD 環境。
主要特點:
簡潔易用的 Web 管理界面
用户、組織、組、權限圖形化管理
支持賬號創建、修改、禁用、密碼重置等操作
應用場景:
搭建統一身份認證系統(SSO)
為 Archery、Jenkins、GitLab、SonarQube 等系統提供 LDAP 認證支持

1. 安裝:

# docker-compose.yml 文件
services:
  go-ldap-admin:
    image: docker.cnb.cool/opsre/go-ldap-admin
    container_name: go-ldap-admin
    hostname: go-ldap-admin
    restart: always
    environment:
      WAIT_HOSTS: openldap:389
    configs:
      - source: go_ldap_admin_config
        target: /app/config.yml
    ports:
      - 8888:8888
    volumes:
      - ./data/go-ldap-admin:/app/data
    depends_on:
      - openldap
    links:
      - openldap:go-ldap-admin-openldap
    networks:
      - go-ldap-admin

  openldap:
    image: docker.cnb.cool/znb/images/openldap:1.4.1
    container_name: go-ldap-admin-openldap
    hostname: go-ldap-admin-openldap
    restart: always
    environment:
      TZ: Asia/Shanghai
      LDAP_ORGANISATION: "sh.com"
      LDAP_DOMAIN: "sh.com"
      LDAP_ADMIN_PASSWORD: "xxxxxx"
    command: [ '--copy-service' ]
    volumes:
      - ./data/openldap/database:/var/lib/ldap
      - ./data/openldap/config:/etc/ldap/slapd.d
    ports:
      - 389:389
    networks:
      - go-ldap-admin

  phpldapadmin:
    image: docker.cnb.cool/znb/images/phpldapadmin:0.9.0
    container_name: go-ldap-admin-phpldapadmin
    hostname: go-ldap-admin-phpldapadmin
    restart: always
    environment:
      TZ: Asia/Shanghai
      PHPLDAPADMIN_HTTPS: "false"
      PHPLDAPADMIN_LDAP_HOSTS: go-ldap-admin-openldap
    ports:
      - 8091:80
    volumes:
      - ./data/phpadmin:/var/www/phpldapadmin
    depends_on:
      - openldap
    links:
      - openldap:go-ldap-admin-openldap
    networks:
      - go-ldap-admin

configs:
  go_ldap_admin_config:
    content: |
      # delelopment
      system:
        # 設定模式(debug/release/test,正式版改為release)
        mode: release
        # url前綴
        url-path-prefix: api
        # 程序監聽端口
        port: 8888
        # 是否初始化數據(沒有初始數據時使用, 已發佈正式版改為false)
        init-data: true
      logs:
        # 日誌等級(-1:Debug, 0:Info, 1:Warn, 2:Error, 3:DPanic, 4:Panic, 5:Fatal, -1<=level<=5, 參照zap.level源碼)
        level: 0
        # 日誌路徑
        path: data/logs
        # 文件最大大小, M
        max-size: 50
        # 備份數
        max-backups: 100
        # 存放時間, 天
        max-age: 30
        # 是否壓縮
        compress: false
      database:
        # 數據庫類型 mysql sqlite3
        driver: mysql
        # 數據庫連接sqlite3數據文件的路徑
        source: data/go-ldap-admin.db
      mysql:
        # 用户名
        username: root
        # 密碼
        password: xxxxxx
        # 數據庫名
        database: go_ldap_admin
        # 主機地址
        host: 10.0.0.100
        # 端口
        port: 3306
        # 連接字符串參數
        query: parseTime=True&loc=Local&timeout=10000ms
        # 是否打印日誌
        log-mode: true
        # 數據庫表前綴(無需再末尾添加下劃線, 程序內部自動處理)
        table-prefix: tb
        # 編碼方式
        charset: utf8mb4
        # 字符集(utf8mb4_general_ci速度比utf8mb4_unicode_ci快些)
        collation: utf8mb4_general_ci
      # jwt配置
      jwt:
        # jwt標識
        realm: test jwt
        # 服務端密鑰
        key: hjYtXJmMe4kyPqf1
        # token過期時間, 小時
        timeout: 12000
        # 刷新token最大過期時間, 小時
        max-refresh: 12000
      # 令牌桶限流配置
      rate-limit:
        # 填充一個令牌需要的時間間隔,毫秒
        fill-interval: 50
        # 桶容量
        capacity: 200
      # email configuration
      email:
        port: '465'
        user: 'xxxxxx@qq.con'
        from: 'ldap-admin後台'
        host: 'smtpdm.aliyun.com'
        is-ssl: true
        pass: 'xxxxxx'
      # # ldap 配置
      ldap:
        # ldap服務器地址
        url: ldap://10.0.0.100:389
        # ladp最大連接數設置
        max-conn: 10
        # ldap服務器基礎DN
        base-dn: "dc=sh,dc=com"
        # ldap管理員DN
        admin-dn: "cn=admin,dc=sh,dc=com"
        # ldap管理員密碼
        admin-pass: "xxxxxx"
        # ldap用户OU
        user-dn: "ou=people,dc=sh,dc=com"
        # ldap用户初始默認密碼
        user-init-password: "xxxxxx"
        # 是否允許更改分組DN
        group-name-modify: false
        # 是否允許更改用户DN
        user-name-modify: false
        # 用户密碼加密方式 默認為 ssha 還可指定為 clear(表示不加密)
        user-password-encryption-type: "ssha"
        # 默認郵箱後綴
        default-email-suffix: "sh.com"
      # 📢 即便用不到如下三段配置信息,也不要刪除,否則會有一些奇怪的錯誤出現
      dingtalk:
        # 配置獲取詳細文檔參考: http://ldapdoc.shs.com/pages/94f43a/
        flag: "dingtalk" # 作為釘釘在平台的標識
        app-key: "xxxxxxxxxxxxxxx" # 應用的key
        app-secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 應用的secret
        agent-id: "12121212" # 目前agent-id未使用到,可忽略
        enable-sync: false  # 是否開啓定時同步釘釘的任務
        dept-sync-time: "0 30 2 * * *" # 部門同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點
        user-sync-time: "0 30 3 * * *" # 用户同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點,注意請把用户同步的任務滯後於部門同步時間,比如部門為2點,則用户為3點
        dept-list:    # 配置要同步的部門列表,配置留空則同步所有部門,在開頭加^表示不同步此部門
          #- "48456726"   # 需要同步的部門ID
          #- "^61213417"  # 不需要同步的部門ID
        is-update-syncd: false # 當釘釘用户的郵箱,手機號,部門等信息更新之後,是否同步更新,默認為false,如果你不瞭解這個字段的含義,則不建議開啓
        user-leave-range: 0 #按配置天數查離職時間範圍內的用户,為0時不限制
      wecom:
        # 配置獲取詳細文檔參考:http://ldapdoc.shs.com/pages/cf1698/
        flag: "wecom" # 作為微信在平台的標識
        corp-id: "xxxx" # 企業微信企業ID
        agent-id: 1000003 # 企業微信中創建的應用ID
        corp-secret: "xxxxx" # 企業微信中創建的應用secret
        enable-sync: false # 是否開啓定時同步企業微信的任務
        dept-sync-time: "0 30 2 * * *" # 部門同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點
        user-sync-time: "0 30 3 * * *" # 用户同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點,注意請把用户同步的任務滯後於部門同步時間,比如部門為2點,則用户為3點
        is-update-syncd: false # 當企微用户的郵箱,手機號,部門等信息更新之後,是否同步更新,默認為false,如果你不瞭解這個字段的含義,則不建議開啓
      feishu:
        # 配置獲取詳細文檔參考:http://ldapdoc.shs.com/pages/83c90b/
        flag: "feishu" # 作為飛書在平台的標識
        app-id: "xxxxxxx" # 飛書的app-id
        app-secret: "xxxxxxxxxxx" # 飛書的app-secret
        enable-sync: false  # 是否開啓定時同步飛書的任務
        dept-sync-time: "0 20 0 * * *" # 部門同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點
        user-sync-time: "0 40 0 * * *" # 用户同步任務的時間點 * * * * * * 秒 分 時 日 月 周, 請把時間設置在凌晨 1 ~ 5 點,注意請把用户同步的任務滯後於部門同步時間,比如部門為2點,則用户為3點
        dept-list:    # 配置要同步的部門列表,配置留空則同步所有部門,在開頭加^表示不同步此部門
          #- "48456726"   # 需要同步的部門ID
          #- "^61213417"  # 不需要同步的部門ID
        is-update-syncd: false # 當飛書用户的郵箱,手機號,部門等信息更新之後,是否同步更新,默認為false,如果你不瞭解這個字段的含義,則不建議開啓
networks:
  go-ldap-admin:
    driver: bridge

# 啓動 docker
-compose up -d

 2. 訪問系統:

http://<服務器IP>:8888

六、接入 LDAP

 1.  archery/settings.py 增加配置:

import ldap
from django_auth_ldap.config import LDAPSearch

ENABLE_LDAP = True
LDAP_SERVER = "ldap://10.0.0.100:389"
LDAP_BIND_DN = "cn=admin,dc=sh,dc=com"
LDAP_BIND_PASSWORD = "xxxxxx"
LDAP_SEARCH_BASE = "ou=people,dc=sh,dc=com"

AUTH_LDAP_USER_SEARCH = LDAPSearch(
    "ou=people,dc=shs,dc=com",
    ldap.SCOPE_SUBTREE,
    "(uid=%(user)s)"
)

LDAP_ATTR_MAP = {
    "username": "uid",
    "display": "cn",
    "email": "mail",
}
LDAP_AUTO_CREATE_USER = True

2.  重啓archery

docker restart archery

七、接入Nginx

1. 部署nginx,並配置證書。修改nginx配置。

server{
    listen 443 ssl; #監聽的端口
    server_name archery.xxx.com;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_certificate /etc/nginx/cert/cert.crt;         # 配置證書文件地址
    ssl_certificate_key /etc/nginx/cert/cert.key;     # 配置密鑰文件地址

    client_max_body_size 100m;     #配置請求的body大小
location
/ { proxy_pass http://內網IP:9123; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

2.  archery/settings.py 增加配置:

CSRF_TRUSTED_ORIGINS = ['https://archery.xxx.com']

3.  重啓archery

docker restart archery

八、常見問題與排查

| `Access denied for user 'root'@'localhost'` | `.env` 中數據庫密碼不匹配 | 確認 `DATABASE_URL` 與 MySQL 容器一致 |
| `AUTH_LDAP_USER_SEARCH must be an LDAPSearch instance` | 未引入 `from django_auth_ldap.config import LDAPSearch` | 加入該 import |
| `SERVER_DOWN: Can't contact LDAP server` | 容器網絡無法訪問 LDAP | 確保 Archery 和 LDAP 在同一網絡 (`docker network ls`) |
| 登錄 LDAP 用户失敗 | LDAP DN / Base 配置錯誤 | 使用 `ldapsearch` 測試,確認能查詢用户 |
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.