LoginSignup
38
40

More than 5 years have passed since last update.

CI/CD関連ツールのユーザー情報をLDAPで一元管理してみる

Last updated at Posted at 2017-12-17

前回はSpring Security使ってLDAP認証できるよ〜というネタでしたが・・・今回は、CI/CDに関わるツール達(直接関係ない子もw)にログインするためのユーザー情報(認証情報)をLDAPで管理する方法をメモっておく。なお、各環境の構築にはDocker(Docker Compose)を使用した。

WARNING:

本エントリーでは各ツールへアクセスする際にhttpを利用する前提にしていますが、パスワードなどの秘匿情報や個人情報を扱う可能性があるのでhttpsでアクセスするのが望ましい。(完全にクローズな環境で悪いことする人がいない前提ならhttpでもよいかもしれませんが・・・)

対象ツール

今回は・・・実案件で使う可能性が高い以下のツールでLDAP認証を試した。

ツール名 ツール概要 利用バージョン
GitLab Gitリポジトリのホスティングツール(GitHubのクローン)。「Issue管理」「マージリクエスト(GitHubで言う所のプルリクエスト)」「Wiki」などのGUI機能が提供されている。 10.1.5-ce.0
Redmine プロジェクト管理ツール。「タスク管理(チケット管理)」「進捗管理」「情報共有」などの機能が提供されており、Gitなどのバージョン管理システム(+Gitのホスティングツール)と連携することもできる。 3.4.3
Jenkins CI管理ツール。プログラムの修正を検知して「テストの実施」「成果物(=リリース物、レポートなど)の生成」「成果物のリリース」を自動で行うための機能が提供されている。 2.95
SonarQube プログラムの品質管理ツール。プログラムの静的解析結果やテスト結果(カバレッジ)などのレポートを出力することができる。 6.7
Nexus ライブラリ(成果物)管理ツール。ソースコードから生成した成果物(Jar or War)を管理するための機能が提供されており、Maven Centralなどのパブリックリポジトリへのプロキシーとして使うことができる。 3.6.2
Mattermost チャットツール(Slackのクローン)。CIのビルド結果を専用のチャットルームに通知することで、CI結果を関係者に素早く知らせることができる。 4.5

NOTE:

最近のGitLabはMattermostを同梱しているが、あえて同梱版を使用しない方法にした。もちろん同梱版でも同じことを実現することはできる。

サンプル

本エントリーで作成・編集したファイルは、以下のGitHubリポジトリで公開済み。(Spring Bootアプリ用のMavenプロジェクト構成になっていますが、そこは気にせずスルーしてください!!)

管理イメージ

OpenLDAPでユーザ情報(認証情報)を管理し、各ツールの認証はLDAP経由を介して行う。Mattermost OSS版はLDAP認証をサポートしていないが、OAuth 2.0の認可コードグラントフローを利用したSSO機能を利用することで、MattermostのOSS版でもGitLabを介して(=間接的に)LDAP認証を行うことができる。

image.png

LDAPサーバ

OpenLdap 2.4.44を使用してLDAPサーバを作成し、以下のLDIFファイルをインポートして4つのグループと2人分のユーザー情報を作成する。

ユーザ名 パスワード 氏名 所属するグループ
kazuki password Kazuki Shimizu admin, user, sonar-administrators, nx-admin
user password Taro Yamada user
openldap/schema.ldif
version: 1

dn: ou=groups,dc=example,dc=com
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: cn=admin,ou=groups,dc=example,dc=com
cn: admin
objectclass: groupOfUniqueNames
objectclass: top
uniquemember: uid=kazuki,ou=people,dc=example,dc=com

dn: cn=sonar-administrators,ou=groups,dc=example,dc=com
cn: sonar-administrators
objectclass: groupOfUniqueNames
objectclass: top
uniquemember: uid=kazuki,ou=people,dc=example,dc=com

dn: cn=nx-admin,ou=groups,dc=example,dc=com
cn: nx-admin
objectclass: groupOfUniqueNames
objectclass: top
uniquemember: uid=kazuki,ou=people,dc=example,dc=com

dn: cn=user,ou=groups,dc=example,dc=com
cn: user
objectclass: groupOfUniqueNames
objectclass: top
uniquemember: uid=user,ou=people,dc=example,dc=com
uniquemember: uid=kazuki,ou=people,dc=example,dc=com

dn: ou=people,dc=example,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people

dn: uid=kazuki,ou=people,dc=example,dc=com
cn: Kazuki Shimizu
mail: kazuki@example.com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
sn: Shimizu
givenName: Kazuki
uid: kazuki
userpassword: {CRYPT}7pnoyta7lRz7M


dn: uid=user,ou=people,dc=example,dc=com
cn: Taro Yamada
mail: user@example.com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
sn: Yamada
givenName: Taro
uid: user
userpassword: {CRYPT}SjPCVdR9pFLD6

以下のようなDockerfileを作成し、本エントリー用のイメージをビルドしてコンテナを作成するようにした。

openldap/Dockerfile
FROM osixia/openldap:1.1.11
# 設定ファイルを上書き
COPY schema.ldif /container/service/slapd/assets/config/bootstrap/ldif/custom/schema.ldif

NOTE:

/container/service/slapd/assets/config/bootstrap/ldif/custom/にldifファイルを格納しておくと、コンテナ作成時にLdifファイルをインポートすることができる。

LDAPの管理ツール(phpLDAPadmin)でLDAPの中を覗くと、以下のようなディレクトリ構成になっていることが確認できる。

image.png

adminグループの状態は以下のような感じ。

image.png

uid=kazukiの状態は以下のような感じ。

image.png

GitLab

GitLabでLDAP認証を行う場合は、/etc/gitlab/gitlab.rbを以下のように編集する。

  • gitlab_rails['ldap_enabled']trueにする
  • gitlab_rails['ldap_servers']にmainのLDAPサーバーを(YAML形式で)指定する
gitlab/gitlab.rb
### LDAP Settings
###! Docs: https://docs.gitlab.com/omnibus/settings/ldap.html
###! **Be careful not to break the indentation in the ldap_servers block. It is
###!   in yaml format and the spaces must be retained. Using tabs will not work.**

gitlab_rails['ldap_enabled'] = true

###! **remember to close this block with 'EOS' below**
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
  main: # 'main' is the GitLab 'provider ID' of this LDAP server
    label: 'LDAP'
    host: 'ldap'
    port: 389
    uid: 'uid'
    bind_dn: 'cn=admin,dc=example,dc=com'
    password: 'password'
    encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
    verify_certificates: true
    ca_file: ''
    ssl_version: ''
    active_directory: false
    allow_username_or_email_login: false
    block_auto_created_users: false
    base: 'ou=people,dc=example,dc=com'
    user_filter: ''
    attributes:
      username: ['uid', 'userid', 'sAMAccountName']
      email:    ['mail', 'email', 'userPrincipalName']
      name:       'cn'
      first_name: 'givenName'
      last_name:  'sn'
#     ## EE only
#     group_base: ''
#     admin_group: ''
#     sync_ssh_keys: false
#
#   secondary: # 'secondary' is the GitLab 'provider ID' of second LDAP server
#     label: 'LDAP'
#     host: '_your_ldap_server'
#     port: 389
#     uid: 'sAMAccountName'
#     bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
#     password: '_the_password_of_the_bind_user'
#     encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
#     verify_certificates: true
#     ca_file: ''
#     ssl_version: ''
#     active_directory: true
#     allow_username_or_email_login: false
#     block_auto_created_users: false
#     base: ''
#     user_filter: ''
#     attributes:
#       username: ['uid', 'userid', 'sAMAccountName']
#       email:    ['mail', 'email', 'userPrincipalName']
#       name:       'cn'
#       first_name: 'givenName'
#       last_name:  'sn'
#     ## EE only
#     group_base: ''
#     admin_group: ''
#     sync_ssh_keys: false
EOS

NOTE:

コメントにも記載がありますが、YAML形式で指定するのでインデントは気をつける必要がある。

以下のようなDockerfileを作成し、本エントリー用のイメージをビルドしてコンテナを作成するようにした。

gitlab/Dockerfile
FROM gitlab/gitlab-ce:10.1.5-ce.0
# 設定ファイルを上書き
COPY gitlab.rb /etc/gitlab/gitlab.rb

設定を反映した状態でGitLabを起動した後にサインイン画面を開くと、「LDAP」用のログインフォームが表示される。

image.png

Redmine

RedmineでLDAP認証を行う場合は、

  • 管理者ユーザでログイン
  • トップメニューバーの「Administration」をクリック
  • レフトメニューバーの「LDAP authentication」をクリック
  • メイン表示領域右上の「New authentication mode」リンクをクリック

すると、以下のような入力画面が表示されるので、入力フォームにLDAP認証に必要な情報を入力して「Save」ボタンを押下する。
(画面キャプチャは登録後の編集画面)

image.png

項目 設定値
Name Main LDAP Server
Host ldap
Port 389
Account cn=admin,dc=example,dc=com
Password password
Base DN ou=people,dc=example,dc=com
LDAP filter
Timeout
On-the-fly user creation ON
Login attribute uid
Firstname attribute givenName
Lastname attribute sn
Email attribute mail

Jenkins

JenkinsでLDAP認証を行う場合は、

  • Jenkins初期セットアップ時にLDAP Pluginをインストール(後からインストールすることも可能)
  • 管理者ユーザでログイン
  • レフトメニューバーの「Manage Jenkins」をクリック
  • メニューから「Configure Global Security」を選択
  • Access Control > Security Realmを「LDAP」に選択
  • 「Advanced Server Configuration...」ボタンをクリック

すると、以下のような入力画面が表示されるので、入力フォームにLDAP認証に必要な情報を入力して「Save」ボタンを押下する。

NOTE:

「Test LDAP settings」ボタンをクリックすると、設定内容が正しいか確認することができる。画面キャプチャでは、uid=kazukiを使って接続テストした後の状態になっている。

image.png

項目 設定値
Server ldap
root DN dc=example,dc=com
User search base ou=people
User search filter uid={0}
Group search base ou=groups
Group search filter
Group membership Search for LDAP groups containing user
Group membership filter (uniquemember={0})
Manager DN cn=admin,dc=example,dc=com
Manager Password password
Display Name LDAP attribute cn
Email Address LDAP attribute mail

SonarQube

SonarQubeでLDAP認証を行う場合は、

  • Sonar LDAP Pluginのインストール (wgetしてpluing用のディレクトリへ格納)
  • /opt/sonarqube/conf/sonar.propertiesにLDAP認証情報の設定

を行う。

sonarqube/sonar.properties
# LDAP configuration
# General Configuration
sonar.security.realm=LDAP
ldap.url=ldap://ldap:389
ldap.bindDn=cn=admin,dc=example,dc=com
ldap.bindPassword=password

# User Configuration
ldap.user.baseDn=ou=people,dc=example,dc=com
ldap.user.request=(&(objectClass=inetOrgPerson)(uid={login}))
ldap.user.realNameAttribute=cn
ldap.user.emailAttribute=mail

# Group Configuration
ldap.group.baseDn=ou=groups,dc=example,dc=com
ldap.group.request=(&(objectClass=groupOfUniqueNames)(uniquemember={dn}))

以下のようなDockerfileを作成し、本エントリー用のイメージをビルドしてコンテナを作成するようにした。

sonarqube/Dockerfile
FROM sonarqube:6.7
# Pluginのインストール
RUN set -x \
    && wget -O /opt/sonarqube/extensions/plugins/sonar-ldap-plugin-2.2.0.608.jar "https://sonarsource.bintray.com/Distribution/sonar-ldap-plugin/sonar-ldap-plugin-2.2.0.608.jar"
# 設定ファイルを上書き
COPY sonar.properties /opt/sonarqube/conf/sonar.properties

NEXUS

NEXUSでLDAP認証を行う場合は、

  • 管理者ユーザでログイン
  • トップメニューバーの設定アイコン(ツールチップ「Server administration and configuration 」)をクリック
  • レフトメニューバーの「Security > LDAP」をクリック
  • 「+ Create Connection」ボタンを押下

すると、以下の項目を設定するための入力画面が表示されるので、入力フォームにLDAP認証に必要な情報を入力する。
(画面キャプチャは登録後の編集画面)

image.png

項目 設定値
Name Maon LDAP Server
LDAP server address ldap://ldap:389
Search base dc=example,dc=com
Authentication method Simple Authentication
Username or DN cn=admin,dc=example,dc=com
Password password

image.png

項目 設定値
Base DN ou=people
User subtree ON
Object class inetOrgPerson
User filter
User ID attribute uid
Real name attribute cn
Email attribute mail
Password attribute
Map LDAP groups as roles ON
Group type Static Groups
Group base DN ou=groups
Group subtree ON
Group object class groupOfUniqueNames
Group ID attribute cn
Group member attribute uniquemember
Group member format uid=${username},ou=people,dc=example,dc=com

「Verify user mapping」ボタンを押下すると、入力したLDAP認証情報が正しいか確認することができる。LDAP認証情報が正しいことが確認できたら「Save」ボタンを押下する。

image.png

Mattermost

MattermostのOSSバージョンでは、残念ながらLDAP認証をサポートしていないが・・・
OAuth 2.0の認可コードグラントフローを利用したSSO機能がサポートされているので、MattermostのOSS版でもGitLabを介して(=間接的に)LDAP認証を行うことができる。

ということで・・・
まずは、GitLabにMattermostをクライアントとして登録する。

具体的には、

  • 管理者ユーザでログイン
  • メニューからの「Configure GitLab」の「Configure」ボタンを押下
  • レフトメニューバーから「Applications」を選択
  • 「New application」ボタンをクリック

すると、以下の項目を設定するための入力画面が表示されるので、入力フォームに必要な情報を入力してMattermostをクライアントとして登録する。

項目 設定値
Name Mattermost
Redirect URI http://localhost:18065/login/gitlab/complete
http://localhost:18065/signup/gitlab/complete

image.png

Mattermost側でGitLabとのSSO機能を有効にするためには、/mm/mattermost/config/config_docker.jsonを以下のように編集する必要がある。

mattermost/config_docker.json
{
    "ServiceSettings": {
        "SiteURL": "http://localhost:18065"
    },
    "GitLabSettings": {
        "Enable": true,
        "Secret": "9c15d9a31f71eb671205d1735c168a042f081817c575fa5899b98089dc08a01c",
        "Id": "ae434f150981fa03da073fbe747fe3efcede25289bcc2b4d7765bb58c4686e5e",
        "Scope": "",
        "AuthEndpoint": "http://localhost/oauth/authorize",
        "TokenEndpoint": "http://gitlab/oauth/token",
        "UserApiEndpoint": "http://gitlab/api/v4/user"
    }
}

NOTE:

上記の設定例では説明に必要なところ(デフォルト値を変更する必要があるところ)だけ抜き出したものなので、そのままコピーしてファイルを上書きすると期待通りの動きにならない可能性がある事を補足しておきます。

項目 設定値 補足
ServiceSettings > SiteURL http://localhost:18065 Mattermost自身のサイトを開くためのURLを指定する。GitLab(認可エンドポイント)からMattermostへ戻るための(リダイレクトするための)URLを生成する際にこの設定値を参照している。
GitLabSettings > Enable true GitLabとのSSO機能を有効化する。
GitLabSettings > Secret {クライアントシークレット} アプリケーション登録時に生成されたクライアントシークレットを指定する。
GitLabSettings > Id {クライアントID} アプリケーション登録時に生成されたクライアントIDを指定する。
GitLabSettings > Scope   SSO時にアクセスを許可してもらうスコープを指定する。(本例では未指定だが適切な値を指定するようにする)
GitLabSettings > AuthEndpoint http://localhost/oauth/authorize GitLabの認可エンドポイント(認可コードを取得するための)URL
GitLabSettings > TokenEndpoint http://gitlab/oauth/token GitLabのトークンエンドポイント(アクセストークンを取得するための)URL
GitLabSettings > UserApiEndpoint http://localhost/oauth/authorize GitLabのユーザー情報エンドポイント(ユーザー情報を取得するための)URL

WARNING

上記の設定例では、認可サーバ(GitLab)提供のエンドポイントにアクセスするためのURLがhttpになっているが、OAuthの仕様的にはhttps(=通信の暗号化)にする必要である事を補足しておく。

以下のようなDockerfileを作成し、本エントリー用のイメージをビルドしてコンテナを作成するようにした。

mattermost/Dockerfile
FROM mattermost/mattermost-preview:4.5
# 設定ファイルを上書き
COPY config_docker.json /mm/mattermost/config/config_docker.json

設定を反映した状態でMattermostを起動した後にサインイン画面を開くと、「GitLabとのSSO」用のリンクが表示される。

image.png

SSO用のリンクを押すと、(GitLabに未ログイン状態であれば)GitLabのログイン画面が表示されるので、LDAPで管理しているユーザーでログインすると・・・・

image.png

GitLabで管理しているユーザー情報(=実態はLDAPで管理しているユーザー情報)へアクセスするための認可を求める画面が表示される。ここで「Authorize」ボタンを押下すれば、MattermostがGitLabのAPIを介してユーザー情報を取得して認証処理を行ないログイン状態になる。

image.png

認証に成功しログイン状態になると、(初回アクセスであれば)以下のような画面が表示される。

image.png

ツール達の起動(docker-compose.xml)

ツール達の起動は、以下のようなdocker-compose.xmlを作成してdocker-composeの機能を使用した。

docker-compose.yml
version: '2'

services:
  # LDAP
  openldap:
    build: ./openldap
    container_name: cicd-openldap
    environment:
      LDAP_ORGANISATION: "example"
      LDAP_DOMAIN: "example.com"
      LDAP_ADMIN_PASSWORD: "password"
    ports:
      - "10389:389"
  # LDAP Management Tool
  phpldapadmin:
    image: osixia/phpldapadmin:0.7.1
    container_name: cicd-phpldapadmin
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "ldap"
      PHPLDAPADMIN_HTTPS: "false"
    ports:
      - "10080:80"
    links:
      - "openldap:ldap"
  # VCS(SCM)
  gitlab:
    build: ./gitlab
    container_name: cicd-gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://localhost'
    ports:
      - '80:80'
      - '433:433'
    links:
      - "openldap:ldap"
  # Issue Tracker
  redmine:
    image: redmine:3.4.3
    container_name: cicd-redmine
    ports:
      - '13000:3000'
    links:
      - "openldap:ldap"
  # Chat
  mattermost:
    build: ./mattermost
    container_name: cicd-mattermost
    ports:
      - '18065:8065'
    links:
      - "gitlab:scm"
  # CI Management
  jenkins:
    image: jenkins/jenkins:2.95
    container_name: cicd-jenkins
    ports:
      - '18080:8080'
      - '50000:50000'
    links:
      - "openldap:ldap"
  # Repository Management
  nexus:
    image: sonatype/nexus3:3.6.2
    container_name: cicd-nexus
    ports:
      - '18081:8081'
    links:
      - "openldap:ldap"
  # Quality Management(& Report)
  sonarqube:
    build: ./sonarqube
    container_name: cicd-sonarqube
    ports:
      - '19000:9000'
    links:
      - "openldap:ldap"

NOTE:

(原因は解明していませんが・・・)再起動を繰り返すと、たまにMattermostのコンテナが起動しないことがあった。今回はLDAP環境構築が目的なので・・・コンテナを作りなおしてエラーを回避した。

参考サイト

38
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
40