GitLabとLDAP統合:認証一元化のための設定方法を解説
はじめに
現代の多くの組織では、従業員が使用する様々なITシステムへのアクセス管理が大きな課題となっています。システムごとにIDとパスワードを管理することは、ユーザーにとっては煩雑であり、管理者にとってはセキュリティリスクと運用コストの増大につながります。この課題を解決するための鍵となるのが、認証の一元化です。認証を一元化することで、ユーザーは単一のIDとパスワードで複数のシステムにアクセスできるようになり、管理者はID管理業務を効率化し、セキュリティポリシーを組織全体にわたって一貫して適用できます。
ソフトウェア開発ライフサイクルにおいて中心的な役割を担うGitLabも例外ではありません。多くの組織でGitLabは開発者だけでなく、プロジェクトマネージャー、運用担当者、場合によっては非技術職のメンバーも利用する共通基盤となっています。GitLabの認証を組織の既存のID管理システムと統合することは、ユーザー管理の効率化とセキュリティ強化に不可欠です。
この記事では、GitLabの認証を企業で広く利用されているディレクトリサービスであるLDAP(Lightweight Directory Access Protocol)と統合するための詳細な設定方法について解説します。LDAPは、ユーザーアカウント、グループ、その他のリソースに関する情報を構造化して保持するためのプロトコルであり、Active DirectoryやOpenLDAPなどの実装が代表的です。GitLabとLDAPを統合することで、LDAPサーバー上のユーザー情報に基づいてGitLabへのログインを許可し、ユーザーアカウントやグループ情報を自動的に同期することが可能になります。
この記事では、単なる設定ファイルの記述方法だけでなく、なぜLDAP統合を行うのか、統合によってどのようなメリットが得られるのかといった背景から、具体的な設定手順、Active DirectoryとOpenLDAPにおける設定の違い、グループ同期の方法、高度な設定、トラブルシューティング、そしてセキュリティに関する考慮事項まで、約5000語にわたって詳細に解説します。このガイドを通じて、GitLabとLDAPの統合を成功させ、組織における認証の一元化とGitLabの運用効率向上を実現するための一助となれば幸いです。
LDAPとは何か? なぜGitLabと統合するのか?
LDAPの基本
LDAP(Lightweight Directory Access Protocol)は、TCP/IP上で動作するディレクトリサービスにアクセスするためのプロトコルです。ディレクトリサービスとは、ユーザー、グループ、コンピューター、ネットワークリソースなどのオブジェクトに関する情報を階層的な構造(ツリー構造)で格納し、高速な検索と参照を可能にするサービスです。
LDAPディレクトリ内の各エントリは、DN(Distinguished Name)と呼ばれる一意の名前で識別されます。DNは、エントリの場所をディレクトリツリー内で完全に指定します。例えば、「cn=John Doe,ou=Users,dc=example,dc=com」のような形式です。エントリは属性(Attributes)の集合で構成されており、各属性はキー(例えばcn
, uid
, mail
)と値(例えばJohn Doe
, johndoe
, [email protected]
)のペアを持ちます。
代表的なLDAPディレクトリサービスの実装としては、MicrosoftのActive Directory (AD)や、オープンソースのOpenLDAPなどがあります。多くの企業では、ユーザーアカウント、コンピューター、グループポリシー管理のためにActive Directoryが広く利用されています。
GitLabとLDAPを統合する理由・メリット
GitLabとLDAPを統合することには、以下のような多くのメリットがあります。
- 認証の一元化: 組織のLDAPサーバーに登録されているIDとパスワードを使用してGitLabにログインできるようになります。これにより、ユーザーは複数のシステムで異なるパスワードを管理する必要がなくなり、パスワード忘れや流出のリスクが低減されます。
- 管理効率の向上: GitLabのユーザーアカウントをLDAPサーバーで一元管理できます。新しい従業員が入社した際にLDAPにアカウントを作成すれば、自動的にGitLabアカウントが作成されるように設定できます(JITプロビジョニング)。同様に、退職者が出た場合も、LDAPアカウントを無効化または削除するだけで、GitLabへのアクセスも自動的に無効化されます。これにより、GitLabのユーザー管理にかかる手間が大幅に削減されます。
- セキュリティ強化: 組織全体のパスワードポリシー(強度、有効期限など)をLDAPサーバーで一元的に適用できます。これにより、GitLabにおいても組織のセキュリティ基準を満たしたパスワードが使用されることが保証されます。また、LDAP統合を通じて、特定のユーザーのみにGitLabへのアクセスを許可するといった制御も可能です。
- グループ管理の自動化: LDAPのグループ情報をGitLabのグループに同期させることができます。これにより、LDAPグループのメンバーシップに基づいてGitLabのプロジェクトやグループへのアクセス権限を自動的に付与・剥奪することが可能になります。例えば、「Developers」LDAPグループのメンバーをGitLabの「開発」グループに自動的に追加し、Contributorロールを付与するといった設定が可能です。
- コンプライアンスと監査: ユーザーのアクセスログや変更履歴がLDAPサーバーの情報(DNなど)と紐づけられるため、誰がいつGitLabにアクセスしたのか、どのような操作を行ったのかといった監査証跡の信頼性が向上します。また、特定のコンプライアンス要件を満たすために、一元的なID管理システムが求められる場合があります。
これらのメリットから、特にユーザー数の多い組織や、すでにLDAPをID管理基盤として利用している組織にとって、GitLabとLDAPの統合は非常に有効な選択肢となります。
統合の基本的な考え方
GitLabとLDAPの統合には、主に二つの側面があります。
- 認証 (Authentication): ユーザーがGitLabにログインする際に、入力されたユーザー名とパスワードがLDAPサーバーに対して検証されます。パスワードがLDAPサーバーで認証されれば、GitLabへのログインが許可されます。GitLabはLDAPサーバー自体にパスワードを保存しません。
- 同期 (Synchronization) / プロビジョニング (Provisioning): LDAPサーバーに格納されているユーザー情報(ユーザー名、氏名、メールアドレス、グループメンバーシップなど)をGitLabに同期させます。
- JIT (Just-In-Time) プロビジョニング: LDAP認証に成功した際に、そのユーザーのGitLabアカウントがまだ存在しなければ、LDAPの情報に基づいて自動的に新規作成する機能です。
- バックグラウンド同期: 定期的に(例えば毎時間)、LDAPサーバー上のユーザーやグループの変更(属性の変更、グループメンバーの追加・削除など)をGitLabに反映させる機能です。これにより、LDAP側で情報が更新された場合に、ユーザーが次回ログインするのを待たずにGitLab側の情報も最新の状態に保つことができます。
GitLabのLDAP統合設定は、これらの認証と同期の挙動を細かく制御するために、様々なオプションを提供しています。
前提条件
GitLabとLDAPの統合設定を行う前に、以下の前提条件を満たしていることを確認してください。
- 稼働中のGitLabインスタンス: Omnibusパッケージ、Dockerコンテナ、またはソースコードからインストールされたGitLab Enterprise Edition (EE) または GitLab Community Edition (CE) インスタンスが稼働していること。LDAP統合機能はCE/EEの両方で利用可能ですが、一部の高度な機能(例: 複数のLDAPサーバー設定、LDAPグループ同期によるロールマッピングなど)はEEでのみ提供される場合があります。お使いのGitLabのバージョンとエディションの機能対応表を確認してください。
- 稼働中のLDAPサーバー: Active Directory、OpenLDAPなどのLDAPv3互換のディレクトリサービスが稼働していること。GitLabインスタンスからLDAPサーバーにネットワーク接続が可能である必要があります(ファイアウォールの設定などを確認)。
- LDAPサーバーへの接続情報: 以下の情報が必要です。
- LDAPサーバーのホスト名またはIPアドレス
- LDAPサーバーのポート番号(通常、標準LDAPは389、LDAP over SSL/TLSは636、StartTLSは389)
- 接続方法(
plain
、ssl
、starttls
) - LDAPサーバーを検索するための権限を持つユーザーアカウント(バインドDN)とそのパスワード。このアカウントには、GitLabが同期・認証対象とするユーザーおよびグループのエントリを読み取る権限が必要です。読み取り専用権限を持つユーザーを作成することが推奨されます。
- ユーザーエントリが格納されているベースDN(Base DN)。GitLabがユーザーを検索する際の起点となるディレクトリツリーのパスです。
- ユーザーを識別するための属性(例:
uid
,sAMAccountName
など)。 - ユーザーの氏名、メールアドレスなどを取得するための属性(例:
cn
,givenName
,sn
,mail
など)。 - (オプション)グループ同期を行う場合、グループエントリが格納されているベースDN、グループを識別するための属性(例:
cn
,sAMAccountName
など)、グループメンバーシップを示す属性(例:member
,memberUid
,uniqueMember
など)。
- GitLabインスタンスへの管理者権限: GitLabの設定ファイルを編集し、設定を再読み込みまたは再起動するためのroot権限またはそれに相当する権限が必要です。
- GitLabの設定ファイルへのアクセス: GitLab Omnibusパッケージの場合は
/etc/gitlab/gitlab.rb
、ソースコードインストールやDockerコンテナの場合は/home/git/gitlab/config/gitlab.yml
(または適切なパス) へのアクセスと編集権限が必要です。この記事では、多くの場合で採用されているGitLab Omnibusパッケージにおける/etc/gitlab/gitlab.rb
を中心に解説します。
GitLabの設定ファイル編集
GitLabのLDAP設定は、設定ファイルに記述します。Omnibusパッケージの場合は /etc/gitlab/gitlab.rb
、ソースコードインストールやDockerコンテナの場合は通常 /home/git/gitlab/config/gitlab.yml
です。ここでは、Omnibusパッケージを例に説明します。
/etc/gitlab/gitlab.rb
ファイルを編集します。LDAP設定は gitlab_rails['ldap_servers']
という設定ブロック内で行います。複数のLDAPサーバーを設定する場合は、このブロック内に複数のサーバー定義を記述します。
まず、設定ブロックを有効化します。ファイルの該当箇所を探し、コメントアウト(行頭の#
)を解除します。
“`ruby
gitlab_rails[‘ldap_servers’] = {
‘main’ => {
‘label’ => ‘LDAP’,
‘host’ => ‘your_ldap_server‘,
‘port’ => 389,
‘uid’ => ‘sAMAccountName’,
‘bind_dn’ => ‘cn=Administrator,cn=Users,dc=example,dc=com’,
‘password’ => ‘the_password‘,
‘encryption’ => ‘plain’,
‘verify_certificates’ => true,
‘timeout’ => 10,
‘active_directory’ => true,
‘allow_username_sync’ => true,
‘sync_ssh_keys’ => false,
‘sync_attribute’ => ‘objectclass’, # objectclass is default
‘sync_time’ => 3600, # hours
‘block_auto_created_users’ => false,
‘block_changes_on_missing_bind_dn’ => false,
‘smartcard_auth’ => false,
‘group_base’ => ‘ou=Groups,dc=example,dc=com’,
‘admin_group’ => ‘gitlab_admin’, # requires admin_group_base
‘group_sync_filter’ => ‘(objectclass=group)’,
‘admin_group_filter’ => ‘(objectclass=group)’,
‘member_of_attribute’ => ‘memberOf’, # requires active_directory: true
‘member_of_group_dn’ => ‘cn=mygroup,ou=Groups,dc=example,dc=com’,
‘lowercase_usernames’ => false, # requires gitlab 12.8+
‘lowercase_groups’ => false, # requires gitlab 14.4+
‘dns_gitlab_server_lookup’ => true, # requires gitlab 14.6+
‘pageSize’ => 1000 # requires gitlab 15.1+
# ‘replacements’ => {
# ‘dn’ => {
# /\r\n?|\n/ => ”
# }
# }
}
}
“`
このコメントアウトを解除し、{}
ブロック内の設定を適切に記述します。'main'
は任意のサーバー識別子です。複数のサーバーを設定する場合は、'main'
の他に'secondary'
などを追加し、それぞれ設定を記述します。
ruby
gitlab_rails['ldap_servers'] = {
'main' => {
# 設定項目をここに記述
}
}
以下に、主要な設定項目とそれぞれの意味、設定例を詳述します。
基本接続設定
'label'
(string): GitLabのログイン画面に表示されるLDAPサーバーのラベル。例:'Active Directory'
,'Corp LDAP'
。必須ではありませんが、設定することを推奨します。'host'
(string): LDAPサーバーのホスト名またはIPアドレス。例:'ad.example.com'
,'192.168.1.100'
。'port'
(integer): LDAPサーバーのポート番号。標準LDAPは389
、LDAP over SSL/TLS (LDAPS) は636
が一般的です。'uid'
(string): ユーザーがログイン時に入力するユーザー名に対応するLDAP属性名。Active DirectoryではsAMAccountName
またはuserPrincipalName (UPN)
、OpenLDAPではuid
などがよく使われます。例:'sAMAccountName'
,'uid'
,'userPrincipalName'
。'bind_dn'
(string): LDAPサーバーに接続し、ユーザーやグループを検索するためのバインドDN。このアカウントには検索対象のオブジェクトに対する読み取り権限が必要です。anonymous bindが許可されている場合は不要ですが、セキュリティ上推奨されません。例:'cn=GitLab Readonly,ou=ServiceAccounts,dc=example,dc=com'
(Active Directory)、'cn=readonly,dc=example,dc=com'
(OpenLDAP)。'password'
(string):bind_dn
のパスワード。設定ファイルに平文で記述されるため、設定ファイルのファイル権限を厳重に管理する必要があります。'encryption'
(string): LDAP接続の暗号化方法。以下のいずれかを指定します。'plain'
: 暗号化なし。非推奨です。'ssl'
: LDAPS (LDAP over SSL/TLS)。通常ポート636を使用します。'starttls'
: 標準ポート389で接続を開始し、その後TLSにアップグレードします。
セキュリティの観点から、'ssl'
または'starttls'
を使用し、'verify_certificates'
をtrue
に設定することを強く推奨します。
'verify_certificates'
(boolean): TLS/SSL接続時にLDAPサーバーの証明書を検証するかどうか。デフォルトはtrue
です。証明書が信頼されたCAによって発行されたものでない場合(例えば自己署名証明書)、検証に失敗します。この場合、false
に設定することも可能ですが、中間者攻撃のリスクを高めるため、推奨されません。信頼された証明書を使用するか、GitLabサーバーにCA証明書をインストールしてください。'timeout'
(integer): LDAP操作のタイムアウト時間(秒)。デフォルトは10秒です。LDAPサーバーの応答が遅い場合などに調整が必要かもしれません。'active_directory'
(boolean): 接続先LDAPサーバーがActive Directoryである場合にtrue
に設定します。Active Directory特有の設定(例:memberOf
属性の使用、LDAPフィルター構文の違いなど)が有効になります。OpenLDAPなどの場合はfalse
または設定不要です(デフォルトはfalse
)。
ユーザー検索設定
'base'
(string): GitLabがユーザーエントリを検索する際のベースDN。このDN以下のツリーからユーザーを検索します。組織構造に合わせて適切に設定してください。例:'ou=Users,dc=example,dc=com'
,'dc=example,dc=com'
(組織全体を検索する場合)。'user_filter'
(string): ユーザー検索をさらに絞り込むためのLDAPフィルター。特定のオブジェクトクラスを持つエントリのみを対象としたり、特定のアカウント状態(有効なアカウントなど)を持つユーザーのみを対象としたい場合に指定します。Active Directoryの場合、無効なアカウントを除外するために'(&(|(objectclass=user)(objectclass=person))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'
のようなフィルターがよく使われます。OpenLDAPの場合は、'(objectclass=person)'
など。このフィルターはbase
以下のエントリに適用されます。'attributes'
(array of strings): GitLabがユーザー同期のために読み取るLDAP属性のリスト。通常、最低限以下の属性が必要です。GitLabのユーザー情報(氏名、メールアドレス)にマッピングするために必要な属性を追加します。'uid'
: ユーザーログイン名(uid
設定と一致させる)'name'
: ユーザーの氏名に対応する属性(例:cn
,displayName
など)'email'
: ユーザーのメールアドレスに対応する属性(例:mail
,userPrincipalName
など)'extern_uid'
: GitLabがLDAPユーザーを一意に識別するために使用する属性。これはLDAPサーバー全体で一意かつ不変である必要があります。Active DirectoryではobjectGUID
やuserPrincipalName
、OpenLDAPではentryUUID
などが適しています。非常に重要な設定項目であり、一度設定すると変更が難しい場合があります。変更すると、既存のLDAPユーザーが重複して作成されたり、関連付けが失われたりする可能性があります。例:['uid', 'cn', 'mail', 'objectGUID']
(AD),['uid', 'cn', 'mail', 'entryUUID']
(OpenLDAP)。- (オプション)
'ssh_public_key'
: ユーザーの公開SSH鍵が格納されている属性。GitLabのユーザー設定で手動でSSH鍵を追加する代わりに、LDAPから同期できます。 - (オプション)
'password_expired'
: パスワード有効期限の状態を示す属性(LDAPスキーマによる)。 - (オプション)
'disabled'
: アカウントが無効化されているかを示す属性(LDAPスキーマによる)。
属性マッピング設定
GitLabは、LDAPから取得した属性値をGitLabユーザーの属性にマッピングします。これは、'attributes'
で指定した属性に基づいて自動的に行われることが多いですが、明示的にマッピングを指定することも可能です。主要なマッピングは以下の通りです。
- ユーザー名 (Username):
'uid'
属性で指定した値が、デフォルトでGitLabのユーザー名として使用されます。'lowercase_usernames'
をtrue
に設定すると、取得したユーザー名が小文字に変換されます(GitLab 12.8以降)。 - 氏名 (Name):
'attributes'
リストに'name'
に対応する属性(例:cn
,displayName
)が含まれていれば、その値がGitLabユーザーの氏名として設定されます。 - メールアドレス (Email):
'attributes'
リストに'email'
に対応する属性(例:mail
,userPrincipalName
)が含まれていれば、その値がGitLabユーザーのメールアドレスとして設定されます。 - 外部ID (External UID):
'extern_uid'
属性で指定した値が、GitLabユーザーの外部IDとして保存されます。このIDを使って、GitLabはLDAPサーバーの特定のエントリとGitLabユーザーを紐づけます。前述の通り、一意かつ不変な属性を使用することが極めて重要です。
同期設定
LDAP統合では、認証だけでなくユーザー情報の同期も重要な機能です。
'sync_time'
(integer): バックグラウンド同期の実行間隔(秒)。デフォルトは3600秒(1時間)です。この設定を大きくするとLDAPサーバーへの負荷は減りますが、GitLabの情報更新が遅延します。頻繁な同期が必要な場合は小さく設定します(ただしLDAPサーバーへの負荷に注意)。0に設定するとバックグラウンド同期は無効になります。'allow_username_sync'
(boolean): LDAP側でユーザー名(uid
属性の値)が変更された場合に、GitLabのユーザー名も自動的に更新を許可するかどうか。デフォルトはtrue
です。GitLabのユーザー名はプロジェクトのパスなどに影響するため、変更に注意が必要です。'block_auto_created_users'
(boolean): LDAP認証によって初めてGitLabにログインした際に自動的に作成される(JITプロビジョニングされる)ユーザーアカウントを、デフォルトでブロック状態にするかどうか。true
に設定した場合、管理者が手動でアカウントを有効化する必要があります。デフォルトはfalse
(自動でアクティブになる)です。'block_changes_on_missing_bind_dn'
(boolean): バインドDNで指定したユーザーが存在しない、またはパスワードが正しくないためにLDAPサーバーへの接続に失敗した場合に、LDAPユーザー同期によるGitLabユーザーアカウントの変更(ブロック、ブロック解除、グループメンバーシップの変更など)をブロックするかどうか。デフォルトはfalse
です。true
に設定すると、LDAP接続の問題が発生した場合に、意図せずユーザーアカウントが変更されてしまうリスクを減らせます。'sync_ssh_keys'
(boolean): LDAPの特定の属性('attributes'
リストに追加する必要がある)に格納されているユーザーの公開SSH鍵をGitLabに同期するかどうか。デフォルトはfalse
です。これを有効にするには、LDAPサーバーのスキーマにSSH公開鍵を格納できる属性が定義されている必要があります。'sync_attribute'
(string): バックグラウンド同期で変更を検出するための属性。デフォルトはobjectclass
ですが、これは変更を検出するのに適していない場合があります。Active Directoryの場合はwhenChanged
やmodifyTimestamp
などのタイムスタンプ属性、OpenLDAPの場合はmodifyTimestamp
など、エントリが変更された際に更新される属性を指定すると、効率的な同期が可能になります。この属性の値に基づいて、前回同期以降に変更があったエントリのみを同期対象とします。'lowercase_usernames'
(boolean): GitLab 12.8で導入された機能。LDAPから取得したユーザー名を小文字に変換してGitLabユーザー名として使用するかどうか。LDAPサーバーによってはユーザー名の大文字・小文字を区別しない場合があり、GitLabのユーザー名の一貫性を保つために役立ちます。'lowercase_groups'
(boolean): GitLab 14.4で導入された機能。LDAPから取得したグループ名を小文字に変換してGitLabグループ名として使用するかどうか。LDAPグループ名の大文字・小文字の揺れを吸収するために役立ちます。'dns_gitlab_server_lookup'
(boolean): GitLab 14.6で導入された機能。LDAPサーバーのホスト名をDNSで名前解決する際に、デフォルトのDNSサーバーではなく、GitLabサーバー自身のDNS設定を使用するかどうか。GitLabサーバーが特定のDNS設定(例: Active Directoryドメインコントローラーを指すDNS)に依存する場合に役立ちます。
グループ同期設定 (GitLab EEのみ)
LDAPグループとGitLabグループを同期させることで、LDAPのグループメンバーシップに基づいてGitLabプロジェクトやグループへのアクセス権限を自動的に管理できます。これはGitLab Enterprise Editionの機能です。
'group_base'
(string): GitLabがグループエントリを検索する際のベースDN。ユーザーベースDNとは別に設定できます。例:'ou=Groups,dc=example,dc=com'
,'dc=example,dc=com'
。'group_filter'
(string): グループ検索をさらに絞り込むためのLDAPフィルター。特定のオブジェクトクラスを持つエントリのみを対象とします。例:'(objectclass=group)'
,'(objectclass=groupOfNames)'
。'group_cn'
(string): グループの名前としてGitLabに同期するLDAP属性。通常はcn
またはsAMAccountName
を使用します。'group_member'
(string): グループメンバーを示すLDAP属性。この属性の値は、グループに所属するユーザーエントリのDNまたはユーザー識別属性(uid
で指定した属性)であることが多いです。Active Directoryの場合はmember
、OpenLDAPの場合はmember
またはuniqueMember
などが一般的です。この属性の値の形式はLDAPサーバーの実装に依存するため、確認が必要です。'admin_group'
(string): LDAP上の特定のグループのメンバーを、GitLabのグローバル管理者として自動的に設定するためのオプション。指定されたLDAPグループ名(group_cn
属性の値)に一致するグループのメンバーがGitLab管理者になります。この設定を使用する場合、admin_group_base
も設定する必要があるか、あるいはgroup_base
が適切に設定されている必要があります。'admin_group_filter'
(string):'admin_group'
で指定したグループを検索するためのLDAPフィルター。'member_of_attribute'
(string): Active Directoryの場合、ユーザーエントリ自身が所属するグループを示す属性(memberOf
属性)を使用してグループメンバーシップを取得できます。active_directory: true
の場合に有効です。この属性を使用する場合、group_member
属性を設定する必要はありません。'member_of_group_dn'
(string):'member_of_attribute'
を使用する場合に、同期対象とする特定のLDAPグループのDNを指定できます。このオプションは通常、特定のLDAPグループのメンバーのみをGitLabに同期したい場合などに使用します。
GitLabグループへのマッピング:
上記のグループ同期設定は、あくまでLDAP上のグループ情報を取得するためのものです。取得したLDAPグループをGitLabの既存グループにマッピングし、メンバーにロールを自動付与するには、GitLabの管理画面(Admin Area -> Groups)で行います。
- GitLab管理画面で対象のグループを選択または新規作成します。
- 「LDAP Sync」または「LDAP 同期」セクションを探します。
- 同期させたいLDAPサーバーとLDAPグループを選択します。LDAPグループは、
group_cn
属性の値で表示されます。 - そのLDAPグループのメンバーに付与したいGitLabでのデフォルトロール(Guest, Reporter, Developer, Maintainer, Owner)を選択します。
- 設定を保存すると、バックグラウンドのLDAP同期ジョブによって、指定したLDAPグループのメンバーがこのGitLabグループに自動的に追加され、指定されたロールが付与されます。LDAPグループからメンバーが削除されれば、GitLabグループからも自動的に削除されます。
その他の詳細設定
'pageSize'
(integer): GitLab 15.1以降で利用可能。LDAP検索の結果を一度に取得するエントリ数。大きなディレクトリに対して同期を行う際に、LDAPサーバーのページング設定に合わせて調整することで、パフォーマンスを向上させることができます。デフォルトは1000です。LDAPサーバーがページングをサポートしている必要があり、サポートしていない場合は無視されます。'replacements'
(hash): LDAP属性値に対して正規表現による置換処理を行うための設定。例えば、LDAPから取得したDNに含まれる不要な改行コードを除去したい場合などに使用できます。
設定例: Active Directory (AD) と OpenLDAP
Active Directory の設定例
Active DirectoryはLDAPv3に準拠していますが、特有のスキーマや機能があります。active_directory: true
に設定することで、ADに適した動作になります。
ruby
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'Active Directory',
'host' => 'ad.example.com', # Active Directoryサーバーのホスト名
'port' => 636, # LDAPSポート
'uid' => 'sAMAccountName', # ログインに使用する属性 (通常 sAMAccountName)
# 'uid' => 'userPrincipalName', # または UPN を使用する場合
'bind_dn' => 'cn=GitLabRead,ou=ServiceAccounts,dc=example,dc=com', # 読み取り専用アカウントのDN
'password' => 'YourPassword', # 読み取り専用アカウントのパスワード
'encryption' => 'ssl', # LDAPSを使用
'verify_certificates' => true, # 証明書を検証
'timeout' => 10,
'active_directory' => true, # Active Directory固有の設定を有効化
'allow_username_sync' => true,
'block_auto_created_users' => false,
'base' => 'ou=Users,dc=example,dc=com', # ユーザー検索のベースDN
# 有効なユーザーのみを対象とするフィルター
'user_filter' => '(&(|(objectclass=user)(objectclass=person))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
'attributes' => {
'username' => 'sAMAccountName', # GitLabユーザー名にマッピング
'name' => 'displayName', # GitLab氏名にマッピング
'email' => 'userPrincipalName', # GitLabメールアドレスにマッピング (ADではUPNがメールアドレスとして使われることが多い)
# 'email' => 'mail', # あるいは mail 属性
'extern_uid' => 'objectGUID', # GitLabの外部ID (一意かつ不変)
# 'ssh_public_key' => 'altSecurityIdentities' # SSH鍵を格納している属性名 (もしあれば)
},
# グループ同期設定 (EEのみ)
'group_base' => 'ou=Groups,dc=example,dc=com', # グループ検索のベースDN
'group_filter' => '(objectclass=group)', # グループを絞り込むフィルター
'group_cn' => 'cn', # グループ名の属性
'group_member' => 'member', # グループメンバーを示す属性 (ユーザーのDNが格納されている)
# または memberOf 属性を使用する場合 (ユーザーエントリにグループ情報がある)
# 'member_of_attribute' => 'memberOf',
# 'member_of_group_dn' => 'cn=GitLabUsers,ou=Groups,dc=example,dc=com', # 特定グループのメンバーのみ同期する場合
# 'admin_group' => 'GitLabAdmins', # GitLab管理者とするLDAPグループ名
# 'admin_group_filter' => '(objectclass=group)', # admin_group を絞り込むフィルター
'lowercase_usernames' => true # ユーザー名を小文字に変換
}
}
注意点:
- Active Directoryの属性名はLDAP標準とは異なる場合があります(例:
sAMAccountName
,displayName
,objectGUID
,userAccountControl
,memberOf
)。 userAccountControl
属性のフィルターは、アカウントが無効化されている(値に2が含まれる)ユーザーを除外するための一般的な方法です。extern_uid
には、ADオブジェクト全体で一意かつ変更されないobjectGUID
(バイナリ値なのでGitLabが適切に処理)またはuserPrincipalName
を使用することが推奨されます。- メールアドレスには
mail
またはuserPrincipalName
を使用します。
OpenLDAP の設定例
OpenLDAPはよりLDAP標準に準拠していますが、スキーマや構成は環境によって大きく異なります。
ruby
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'OpenLDAP',
'host' => 'ldap.example.com', # OpenLDAPサーバーのホスト名
'port' => 389, # 標準LDAPポート
'uid' => 'uid', # ログインに使用する属性 (通常 uid)
'bind_dn' => 'cn=readonly,dc=example,dc=com', # 読み取り専用アカウントのDN
'password' => 'YourPassword', # 読み取り専用アカウントのパスワード
'encryption' => 'starttls', # StartTLSを使用
'verify_certificates' => true, # 証明書を検証
'timeout' => 10,
'active_directory' => false, # OpenLDAPの場合は false
'allow_username_sync' => true,
'block_auto_created_users' => false,
'base' => 'ou=people,dc=example,dc=com', # ユーザー検索のベースDN
'user_filter' => '(objectclass=inetOrgPerson)', # inetOrgPerson オブジェクトクラスのユーザーを対象とするフィルター
'attributes' => {
'username' => 'uid', # GitLabユーザー名にマッピング
'name' => 'cn', # GitLab氏名にマッピング (Common Name)
'email' => 'mail', # GitLabメールアドレスにマッピング
'extern_uid' => 'entryUUID', # GitLabの外部ID (一意かつ不変 - OpenLDAP 2.4以降)
# 'ssh_public_key' => 'sshPublicKey' # SSH鍵を格納している属性名 (スキーマによる)
},
# グループ同期設定 (EEのみ)
'group_base' => 'ou=groups,dc=example,dc=com', # グループ検索のベースDN
'group_filter' => '(objectclass=groupOfNames)', # グループを絞り込むフィルター (groupOfNames / groupOfUniqueNames などスキーマによる)
'group_cn' => 'cn', # グループ名の属性
# グループメンバーを示す属性 (ユーザーのDNまたは uid が格納されているか確認)
'group_member' => 'member', # groupOfNames の場合
# 'group_member' => 'uniqueMember', # groupOfUniqueNames の場合
# 'admin_group' => 'gitlab_admins', # GitLab管理者とするLDAPグループ名
# 'admin_group_filter' => '(objectclass=groupOfNames)', # admin_group を絞り込むフィルター
'lowercase_usernames' => false # ユーザー名を小文字に変換 (必要に応じて true)
}
}
注意点:
- OpenLDAPはスキーマ定義が柔軟なため、使用している属性名やオブジェクトクラス、グループメンバーシップの格納方法(
member
かuniqueMember
か、格納されているのがDNかUIDか)などが環境によって異なります。お使いのOpenLDAPサーバーのスキーマと構成を確認してください。 extern_uid
には、OpenLDAP 2.4以降で標準的にサポートされている不変なentryUUID
を使用することが推奨されます。それ以前のバージョンやカスタムスキーマの場合は、別の不変な属性を探す必要があります。
設定の反映とテスト
設定ファイルを編集したら、GitLabに設定を反映させる必要があります。Omnibusパッケージの場合、以下のコマンドを実行します。
bash
sudo gitlab-ctl reconfigure
このコマンドは、gitlab.rb
の設定に基づいてGitLabおよび関連サービスの構成を再構築します。LDAP設定に構文エラーがある場合などは、ここでエラーが表示されます。
設定が正常に反映されたら、以下の手順でテストを行います。
- GitLabへのログインテスト:
- GitLabのログイン画面にアクセスします。
- LDAPサーバーのラベルが表示されているか確認します(
'label'
設定で指定した場合)。 - LDAPサーバーに存在するユーザーのIDとパスワードを入力してログインできるか試します。
- 初めてログインするLDAPユーザーの場合、JITプロビジョニングによってアカウントが自動作成されるか確認します。
'block_auto_created_users'
がtrue
の場合は、ログイン後に管理者による承認が必要になることを確認してください。
-
GitLab管理画面での確認:
- 管理者アカウントでGitLabにログインします。
- Admin Area に移動します。
- 左メニューから Settings -> General を選択し、「LDAP Sync」セクションを探します。
- ここでLDAP同期の状態を確認できます。「Sync Now」ボタンをクリックして手動で同期を実行できます。
- User Management -> Users に移動し、LDAPユーザーがリストされているか、ステータス(Active/Blocked)、最終ログイン時間などが正しく表示されているか確認します。ユーザーの詳細画面で、外部ID(External UID)が正しく設定されていることも確認してください。
- (EEの場合)Groups に移動し、LDAP同期を設定したグループで、LDAPグループのメンバーが正しく同期されているか確認します。
-
ログの確認:
- 設定やログイン、同期に問題がある場合、GitLabのログファイルを確認します。
- Omnibusパッケージの場合、以下のコマンドで関連ログをリアルタイムで確認できます。
bash
sudo gitlab-ctl tail gitlab-rails
sudo gitlab-ctl tail sidekiq gitlab-rails
ログはGitLab本体のウェブアクセスやアプリケーション処理に関するログ、sidekiq
ログはバックグラウンドジョブ(LDAP同期など)に関するログが出力されます。LDAP関連のエラーメッセージや警告が出力されていないか確認してください。
トラブルシューティングのヒント
- LDAPサーバーへの接続確認: GitLabサーバーからLDAPサーバーへのネットワーク接続が可能か(
telnet <LDAPサーバー> <ポート>
など)、ファイアウォール設定などを確認します。 - バインドDNとパスワード: 設定ファイルに記述したバインドDNとパスワードが正しいか、そのアカウントに検索権限があるか確認します。LDAPブラウザツール(Apache Directory Studio, LdapAdminなど)を使用して、同じバインドDNで接続し、ユーザーやグループを検索できるかテストすると良いでしょう。
- ベースDNとフィルター: ベースDNや
user_filter
、group_base
、group_filter
が正しいか、意図したユーザーやグループがこれらの設定で絞り込まれるか確認します。LDAPブラウザツールで同じベースDNとフィルターを指定して検索を実行してみるのが有効です。 - 属性名:
uid
,name
,email
,extern_uid
などの属性名が、お使いのLDAPサーバーのスキーマと正確に一致しているか確認します。大文字・小文字も区別される場合があります。LDAPブラウザツールでユーザーエントリの詳細を確認し、属性名と値を確認してください。 - TLS/SSL証明書:
'encryption'
が'ssl'
または'starttls'
で'verify_certificates'
がtrue
の場合、LDAPサーバーの証明書がGitLabサーバーから信頼されている必要があります。自己署名証明書の場合は、GitLabサーバーの証明書ストアにLDAPサーバーの証明書またはCA証明書をインポートする必要があるかもしれません。openssl s_client -connect <LDAPサーバー>:<ポート> -starttls ldap
のようなコマンドで証明書チェーンを確認できます。 - GitLabバージョンの違い: GitLabのバージョンによって設定項目や挙動が変更されることがあります。お使いのGitLabバージョンの公式ドキュメントを参照し、設定項目が正しいか確認してください。
高度な設定と考慮事項
複数のLDAPサーバー設定 (GitLab EEのみ)
GitLab Enterprise Editionでは、複数のLDAPサーバーを設定できます。これは、複数のドメインやLDAPフォレストが存在する環境で役立ちます。
/etc/gitlab/gitlab.rb
のgitlab_rails['ldap_servers']
ブロック内に、複数のサーバー定義をキーと値のペアで記述します。
ruby
gitlab_rails['ldap_servers'] = {
'main_ad' => {
'label' => 'Main AD',
'host' => 'ad1.example.com',
# ... その他の設定 ...
},
'second_ldap' => {
'label' => 'Secondary LDAP',
'host' => 'ldap.othercorp.com',
# ... その他の設定 ...
}
}
各サーバー定義は独自のラベル、接続情報、ベースDN、フィルターなどを持ちます。ユーザーはログイン画面でどのLDAPサーバーを使用してログインするかを選択できます。GitLabは複数のLDAPサーバーからのユーザーを管理できますが、同じユーザーが複数のLDAPサーバーに存在し、それぞれにGitLabアカウントが作成される可能性があることに注意が必要です。extern_uid
を適切に設定することで、この問題を回避できる場合があります。
同期の挙動の詳細
LDAP同期は、GitLabユーザーアカウントの状態やグループメンバーシップに影響を与えます。
- アカウントの作成: LDAP認証に成功した際にGitLabアカウントが存在しない場合、JITプロビジョニングによって自動的に作成されます(
'block_auto_created_users'
がfalse
の場合)。また、バックグラウンド同期によって、LDAPサーバー上に存在するユーザーがGitLabに同期されるよう設定することも可能です(通常はJITプロビジョニングと組み合わせて使用)。 - アカウントの更新: バックグラウンド同期によって、LDAPサーバー上でユーザーの属性(氏名、メールアドレスなど)が変更された場合に、GitLab側の情報も更新されます。ユーザー名(
uid
)の同期は'allow_username_sync'
で制御します。 - アカウントのブロック/ブロック解除: LDAPサーバーでユーザーアカウントが無効化された場合、バックグラウンド同期によってそのGitLabアカウントが自動的にブロックされます。これは退職者のアカウント管理において非常に重要な機能です。LDAPアカウントが再度有効化されれば、GitLabアカウントもブロックが解除されます。
- アカウントの削除: GitLabはLDAPサーバーから削除されたユーザーアカウントを自動的に削除しません。セキュリティ上のリスク(誤ってLDAPエントリを削除してしまった場合など)を考慮し、GitLab側ではアカウントをブロックする動作となります。削除が必要な場合は、手動でGitLabの管理者またはAPI経由で実行する必要があります。
- グループメンバーシップの同期 (EEのみ): LDAPグループのメンバーリストとGitLabグループのメンバーリストを同期させます。LDAPグループからメンバーが追加/削除されると、GitLabグループでも自動的にメンバーが追加/削除され、設定されたロールが付与/剥奪されます。これにより、プロジェクトやグループへのアクセス権限管理をLDAPに集約できます。
属性マッピングのカスタマイズ
前述の'attributes'
設定では、GitLabのユーザー名、氏名、メールアドレス、外部IDにマッピングするLDAP属性を指定しました。これらのマッピングは、LDAPサーバーのスキーマに合わせて適切に設定する必要があります。
例えば、氏名が姓と名で別の属性に分かれている場合(例: givenName
, sn
)、これらを組み合わせてGitLabの氏名として表示させるには、LDAPサーバー側で仮想属性を作成するか、あるいはGitLabのコードレベルでのカスタマイズが必要になる場合があります(ただし、後者は推奨されません)。多くの場合、cn
またはdisplayName
属性を使用するのが最も簡単です。
SSH公開鍵('sync_ssh_keys'
)を同期する場合、LDAPサーバーのユーザーエントリにSSH公開鍵を格納するための属性(例: sshPublicKey
– NISスキーマの一部)が必要です。スキーマが存在しない場合は、LDAPサーバーのスキーマを拡張する必要があります。
パフォーマンスに関する考慮事項
大規模なLDAPディレクトリ(数万、数十万ユーザー)と統合する場合、LDAP同期のパフォーマンスが問題となる可能性があります。
- LDAPサーバーの負荷: GitLabの同期ジョブは、設定によってはLDAPサーバーに対して大量の検索クエリや属性取得リクエストを発行します。LDAPサーバーのリソース(CPU、メモリ、ディスクI/O)が十分であるか確認してください。
- ネットワーク遅延: GitLabサーバーとLDAPサーバー間のネットワーク遅延が大きい場合、同期やログイン認証に時間がかかる可能性があります。
- LDAP検索の効率:
base
DNやuser_filter
、group_base
、group_filter
の設定は、検索範囲と結果数を制限することで、LDAPサーバーの負荷と応答時間を軽減するのに役立ちます。できるだけ具体的なベースDNを指定し、効率的なフィルターを使用してください。 sync_attribute
:'sync_attribute'
を適切に設定することで、前回の同期から変更されたエントリのみを対象とするため、同期の効率が大幅に向上します。pageSize
: LDAPサーバーがページングをサポートしている場合、'pageSize'
を調整することで大きな検索結果を効率的に取得できます。timeout
: タイムアウト値を適切に設定することで、LDAPサーバーの応答遅延によるGitLabのハングを防ぎます。
デバッグ方法
GitLabのLDAP統合に関する問題をデバッグするには、以下の方法があります。
- GitLabログ: 前述の
gitlab-ctl tail
コマンドで、gitlab-rails
とsidekiq
のログをリアルタイムに監視します。LDAP接続、バインド、検索、同期に関するエラーメッセージ(例:LDAP search error
,LDAP authentication failed
,Bind failed
など)が出力されていないか詳細に確認します。必要に応じて、GitLabのログレベルをデバッグレベルに引き上げると、より詳細な情報が得られる場合があります(ただし、本番環境でのデバッグレベルの使用はパフォーマンスに影響を与える可能性があるため注意が必要です)。 - LDAPブラウザツール: LDAPサーバーに直接接続し、設定したバインドDNで認証できるか、ベースDN以下に目的のユーザーやグループが存在するか、設定したフィルターで正しく絞り込めるか、必要な属性が取得できるかなどを手動で確認します。これにより、問題がGitLab側にあるのか、LDAPサーバー側にあるのかを切り分けることができます。
gitlab-rails console
: 高度なデバッグとして、sudo gitlab-rails console
コマンドでGitLabのRailsコンソールに入り、Rubyコードを使ってLDAP設定のテストやLDAPサーバーへのクエリ実行を試すことも可能です。GitLabの公式ドキュメントに関連するデバッグ方法が記載されている場合があります。
セキュリティに関する考慮事項
LDAP統合は認証の一元化によりセキュリティを向上させますが、いくつかのセキュリティ上の考慮事項があります。
- バインドユーザーの権限:
bind_dn
で指定するユーザーアカウントは、GitLabが認証・同期に必要なエントリ(ユーザー、グループ、属性)を読み取るための最小限の権限のみを持つべきです。誤って書き込み権限を与えてしまうと、GitLab側の設定ミスや脆弱性によってLDAPディレクトリが不正に変更されるリスクが生じます。読み取り専用権限を持つサービスアカウントを作成し、そのアカウント情報を使用することを強く推奨します。 - TLS/SSLの必須化: LDAPサーバーとの通信は、必ずTLS/SSL (
ssl
またはstarttls
) で暗号化してください。認証情報(バインドパスワード)やユーザー情報がネットワーク上を平文で流れるのを防ぎます。 - 証明書の検証:
'verify_certificates'
は必ずtrue
に設定し、LDAPサーバーの証明書を検証するようにしてください。これにより、中間者攻撃によって偽のLDAPサーバーに接続されるリスクを防ぎます。自己署名証明書を使用する場合は、信頼されたCA証明書としてGitLabサーバーにインストールするなどの対策が必要です。 - 設定ファイルの保護:
/etc/gitlab/gitlab.rb
などの設定ファイルには、バインドユーザーのパスワードが平文で含まれます。これらのファイルへのアクセス権限をオペレーティングシステムレベルで厳重に管理し、限られたユーザーのみが読み書きできるように設定してください(通常、rootユーザーのみがアクセス可能)。 - 外部ID (
extern_uid
) の重要性:extern_uid
はGitLabユーザーとLDAPエントリを紐づけるために使用される鍵です。一意で不変な属性を慎重に選択し、設定後に変更しないようにしてください。誤った設定は、セキュリティの問題(なりすましなど)やデータ不整合を引き起こす可能性があります。 - 不要な属性の同期停止:
'attributes'
リストには、GitLabの運用に最低限必要な属性のみを指定することを検討してください。機密性の高い属性をLDAPから同期しないようにすることで、GitLab側での情報漏洩リスクを低減できます。
まとめ
GitLabとLDAPの統合は、組織における認証の一元化、ユーザー管理の効率化、およびセキュリティ強化を実現するための非常に効果的な手段です。LDAPサーバーを信頼できるID基盤として利用することで、GitLabの運用コストを削減し、コンプライアンス要件への対応も容易になります。
この記事では、LDAPの基本、統合のメリット、GitLabにおけるLDAP統合の基本的な考え方、そしてOmnibusパッケージを中心とした詳細な設定方法、Active DirectoryとOpenLDAPそれぞれの設定例、設定の反映とテスト、高度な設定や考慮事項、トラブルシューティング、セキュリティに関する重要なポイントまで、幅広く解説しました。
LDAP統合の設定は、LDAPサーバーの構成(スキーマ、ベースDN、フィルター、属性名、認証方法など)を正確に把握していることが成功の鍵となります。設定に際しては、必ずお使いのLDAPサーバーのドキュメントやツール(LDAPブラウザなど)を用いて情報を確認し、GitLabのバージョンに合わせた公式ドキュメントも併せて参照しながら慎重に進めてください。
認証の一元化は、ITシステム全体のセキュリティと利便性を向上させるための重要なステップです。この記事で得られた知識を活用し、GitLabとLDAPの統合を成功させて、よりセキュアで効率的な開発環境を構築してください。