docker環境で Samba4 Active Directory認証(以下AD認証)を使用してRedmineにログインする。
以前、docker上にRedmineとopenLDAP認証環境を構築を行ったが、少し発展させてAD認証にチャレンジしたので、その時のメモを残す。
(2017/09/17追加)Back up and Restoring a Samba AD DCを参考にバックアップ方法を追加
環境
- CentOS7.3 (VMWare Fusion上にゲストOSとして構築)
- Docker 1.12.6 (yumリポジトリのものを使用)
- docker-compose 1.9.0 (yum epelリポジトリのものを使用)
- Redmine redmine:3.4.2 (docker hubよりpull)
- DB postgres:9.6.3 (docker hubよりpull)
- Samba4 sonohara/samba4-ad:latest (docker hubよりpull)
- LDAPブラウザ JXplorer JXv3.3.1.2
いつものように、dockerのイメージはlatestではない最新のタグを使用する。Samba4にはタグが付与されていなかったので、latestを使用する。(Versionを確認すると 4.5.3 を使用している)
pullの数が多い(みんながダウンロードしている?)ので、pitkley/samba-ad-dc を試してみたが、winbinddのエラーが出て上手く繋がらなかったため、sonohara/samba4-adを使用する。
本来ならば、ADの管理ツールを使用するのだが、OSX上で利用できるAD管理ツールを探すのが面倒だったので、すぐに見つかったLDAPブラウザ(JXplorer)を利用する。
1. dockerイメージの取得
$ docker pull sonohara/samba4-ad:latest
$ docker pull redmine:3.4.2
$ docker pull postgres:9.6.3
2. docker設定
ネットワークは、今後gitlab、mattermostととの連携を考えているので、個別に専用のネットワークをdocker networkコマンドで作成する。
$ docker network create redmine_network
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1361f0cf0a0c bridge bridge local
.....
ea5779e11ae6 redmine_network bridge local
(2017/09/03 削除 コンテナ内のDNSは 127.0.0.11 となっている)
```
$ docker network inspect --format='{{.IPAM.Config}}' redmine_network
[{172.18.0.0/16 172.18.0.1/16 map[]}]
```
データ永続化のための領域(logとsambaの設定)を作成する。SELinuxを有効にしている場合は、dockerコンテナ内からアクセスできるようにコンテキストを設定する必要がある
```
$ mkdir log samba files db
$ chcon -t svirt_sandbox_file_t log samba files db
```
前回の[docker上にRedmineとopenLDAP認証環境を構築](http://qiita.com/ir-shin1/items/12d0dbea40d1f1f06747)のymlをベースに変更を加える。
```:docker-compose.yml
version: '2'
services:
addc:
image: sonohara/samba4-ad:latest
container_name: addc_sv
environment:
DOCKER_DEBUG: 0
DNS_FORWARD: 127.0.0.11
DNS_DOMAIN: projectx.local
AD_PASSWORD: PASS0rd123
AD_REALM: projectx.local
AD_DOMAIN: PROJECTX
ports:
- "53:53/tcp" # DNS(tcp)
- "53:53/udp" # DNS(udp)
- "139:139"
- "389:389"
- "445:445"
- "636:636"
volumes:
- ./samba:/var/lib/samba
- ./log:/var/log/samba
networks:
- redmine_network
redmine:
image: redmine:3.4.2
container_name: redmine_sv
environment:
REDMINE_DB_PASSWORD: rdpassword
ports:
- "80:3000"
links:
- "postgres:postgres"
- "addc:ldap"
volumes:
- ./files:/usr/src/redmine/files
networks:
- redmine_network
postgres:
image: postgres:9.6.3
container_name: postgres_sv
environment:
POSTGRES_PASSWORD: rdpassword
POSTGRES_USER: redmine
volumes:
- ./db:/var/lib/postgresql/data
networks:
- redmine_network
networks:
redmine_network:
external: true
```
## 3. 起動
```
$ docker-compose up -d
Creating postgres_sv
Creating addc_sv
Creating redmine_sv
```
## 4. ADの設定
### 4.1 ユーザの登録
```
$ docker exec -ti addc_sv samba-tool user list
Administrator
krbtgt
Guest
$ docker exec -ti addc_sv samba-tool user create yamada.tarou test1Pass \
--use-username-as-cn \
"--mail-address=yamada.tarou@test.com" --given-name=山田 --surname=太郎
User 'yamada.tarou' created successfully
$ docker exec -ti addc_sv samba-tool user create suzuki.hanako test1Pass \
--use-username-as-cn \
"--mail-address=suzuki.hanako@test.com" --given-name=鈴木 --surname=花子
User 'suzuki.hanako' created successfully
$ docker exec -ti addc_sv samba-tool user list
Administrator
yamada.tarou
suzuki.hanako
krbtgt
Guest
```
```
samba-tool user create yamada.tarou test1Pass \
--use-username-as-cn \
"--mail-address=yamada.tarou@test.com" \
--given-name=山田 --surname=太郎
```
上記のコマンドパラメータは、ADには以下のように登録されている。
(2017/09/02) --use-username-as-cn を追加することで、cnにユーザ名を設定
* sAMAccountName: yamada.tarou
* ~~~cn: 山田 太郎 ⇒ これで一意性をとっているので、重複しないようにする必要がある。~~~
* cn: yamada.tarou
* mail: yamada.tarou@test.com
* sn: 太郎
* givenName: 山田
## 4.2 LDAPブラウザ(JXplorer)での確認
JXplorerを起動し、登録した情報を確認する。JXplorerから確認はできるが、変更・修正方法については不明。submitを押してもエラーになる。
AD認証情報のメンテナンスは、WindowsのAD管理ツールに任せることにする。
<img width="1030" alt="JXplorer001.png" src="https://qiita-image-store.s3.amazonaws.com/0/137664/9412b2e1-c72f-f4b8-eb56-15c525cd6a5c.png">
以下のパラメータでログインする。
* ホスト:192.168.45.131 ※ VMware上のゲストのIPアドレス
* ポート:389
* プロトコル:LDAPv3
* ベースDN:DC=projectx,DC=local
* Level:User+Password
* UserDN:CN=Administrator,CN=Users,DC=projectx,DC=local
* Password:PASS0rd123 ※ docker-compose.ymlのAD_PASSWORDで定義した値
<img width="1040" alt="JXplorer002.png" src="https://qiita-image-store.s3.amazonaws.com/0/137664/0158b6fe-d06d-8198-9c6f-4ef4759ed650.png">
先に登録した情報を確認する。
<img width="1047" alt="JXplorer003.png" src="https://qiita-image-store.s3.amazonaws.com/0/137664/703c8e56-e911-9602-e545-09476a045683.png">
## 5. Redmineの設定
### 5.1 Redmineログイン
ホストPCからVMWareゲスト(http://192.168.45.131) にアクセスし、ユーザadmin、パスワードadminでログインする。パスワード変更画面になるので、adminのパスワードを変更する。
![1redmine01.png](https://qiita-image-store.s3.amazonaws.com/0/137664/ee4c4e1c-a3af-ecd5-9820-d5e79c01c276.png)
### 5.2 新しい認証方式の追加
「管理」⇒「LDAP認証」⇒「新しい認証方式」で設定方式の追加を行う。
* 名称:ADDC
* ホスト:ldap ※ docker-compose.ymlのlinksで定義したホスト名
* ポート:389
* アカウント:PROJECTX\Administrator ※ ドメイン名はdocker-compose.ymlのAD_DOMAINで定義した値
* パスワード:PASS0rd123 ※ docker-compose.ymlのAD_PASSWORDで定義した値
* ベースDN:CN=Users,DC=projectx,DC=local
![1redmine02.png](https://qiita-image-store.s3.amazonaws.com/0/137664/e6ae2df9-c69d-ab40-bfe1-b98ed85a597d.png)
あわせてユーザーを作成:チェック
* ログインIDの属性:sAMAccountName
* 名の属性:givenName
* 姓の属性:sn
* メールアドレスの属性:mail
作成ボタンを押し、新しい認証方式を登録する。登録後「テスト」ボタンを押し、ADと接続できることを確認する。
![1redmine03.png](https://qiita-image-store.s3.amazonaws.com/0/137664/3a6b7c99-15db-3a83-6250-39b815c34c35.png)
### 5.3 ログアウトし、LDAPで登録したユーザ(yamada.tarou)でログイン
「あわせてユーザーを作成」をチェックしているので、Redmineに登録していないユーザは自動的に登録される。
![1redmine04.png](https://qiita-image-store.s3.amazonaws.com/0/137664/998930dd-ab03-bf09-0ca5-0970bc67c97e.png)
### 5.4 既存ユーザのパスワード認証先の変更
管理者でRedmineにログイン後、管理->ユーザ->ログインIDを選択で画面を開き、認証-認証方式を「内部」から「ADDC」に変更すれば、LDAP認証に変わる。
![1redmine05.png](https://qiita-image-store.s3.amazonaws.com/0/137664/4a53b366-a620-a3f6-92ab-cf7edbf49a2e.png)
これで、Active Directoryのパスワードを含む情報の変更がopenLDAPより簡単に出来れば、当初の目的はかなえられる。
後は、今考えている gitlabなどのサービスとSSOで連携が出来ればベストなのだが。
## 6. テーマ・プラグインを追加
素のRedmineを使用するのではもったいないので、テーマ・プラグインをインストールするスクリプトを作成。本当は、Dockerfile を作成してイメージを作成するべきなのだろうがお手軽にスクリプトにした。
```bash:create-redmine.sh
#!/usr/bin/env bash
REDMINE=redmine_sv
set -x
## 必要なパッケージを追加
docker exec ${REDMINE} apt-get -y update
docker exec ${REDMINE} apt install -y unzip ghostscript fonts-ipaexfont
docker exec ${REDMINE} mkdir -pm 755 /home/redmine
docker exec ${REDMINE} chown redmine.redmine /home/redmine
docker exec ${REDMINE} bash -c 'ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime'
docker exec ${REDMINE} bash -c 'gem install bundler'
docker exec ${REDMINE} bash -c 'chown redmine.redmine /usr/src/redmine/Gemfile.lock*'
## テーマインストール
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/ ; git clone git://github.com/farend/redmine_theme_farend_fancy.git public/themes/farend_fancy'
## プラグインインストール
# チケットテンプレートプラグイン
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q -b 0.1.6 https://github.com/akiko-pusu/redmine_issue_templates.git'
# Redmine サイドバー オン・オフプラグイン
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q https://github.com/bdemirkir/sidebar_hide.git'
# Redmine View Custom
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q https://github.com/onozaty/redmine-view-customize.git view_customize'
# クリップボードイメージアップロードプラグイン
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q https://github.com/peclik/clipboard_image_paste.git'
# Messengerプラグイン
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q https://github.com/alphanodes/redmine_messenger.git redmine_messenger'
# GibHub hook Plugin
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; git clone -q https://github.com/koppen/redmine_github_hook.git'
docker cp EasyGanttFree.zip ${REDMINE}:/usr/src/redmine/plugins/.
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; unzip EasyGanttFree.zip'
docker cp redmine_agile-1_4_4-light.zip ${REDMINE}:/usr/src/redmine/plugins/.
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; unzip redmine_agile-1_4_4-light.zip'
docker cp redmine_checklists-3_1_6-light.zip ${REDMINE}:/usr/src/redmine/plugins/.
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; unzip redmine_checklists-3_1_6-light.zip'
docker cp redmine_work_time-0.3.4.zip ${REDMINE}:/usr/src/redmine/plugins/.
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; unzip redmine_work_time-0.3.4.zip'
docker exec ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; bundle install'
docker exec -u redmine ${REDMINE} bash -c 'cd /usr/src/redmine/plugins ; RAILS_ENV=production bundle exec rake redmine:plugins:migrate'
docker restart ${REDMINE}
```
以下の手順でプラグインをインストールする。
```
$ ./create-redmine.sh 2>&1 | tee run.log
```
## 7. Samba4情報のバックアップ・リストア (2017/09/17変更)
[Back up and Restoring a Samba AD DC](https://wiki.samba.org/index.php/Back_up_and_Restoring_a_Samba_AD_DC)で使用している [samba_backup](https://git.samba.org/?p=samba.git;a=blob;f=source4/scripting/bin/samba_backup) コマンドは tdbbackup コマンドを呼び出しているが、使用しているコンテナのイメージには入っていない。
tdbbackup コマンドは、処理の流れをみるとsambaがオープンしているだろうデータベースファイル XXX.tbl を整合性を保持したまま XXX.tbl.bak を作成するコマンドのようだ。
バックアップ時にサービスを止めても良い方針を考えているので、サービスを止めて、バックアップ、サービス再開で行くことにする。バックアップ時にサービスを止めてはいけない環境ならば、先にセカンダリADを考えるべきだろう。
samba_backup を見ると、privateとetcとsysvolをバックアップしているので、バックアップ対象とする。
また、バックアップ・リストアについては、オーナー・パーミッションなどが合わせるのが大変なため、バックアップ・リストア用のコンテナを作成して実行する。
### 7.1 バックアップ
使用しているsamba4のイメージが ENTRYPOINT で起動コマンドをしているため、単純にdocker runでコマンドを指定しても先に ENTRYPOINT が実行される。そこで、ENTRYPOINT をbash に変更してバックアップを行うようにしている。
```bash:samba-ad_backup.sh
#!/usr/bin/env bash
BACKUP=$PWD/backup
set -x
mkdir -p ${BACKUP}
chcon -t svirt_sandbox_file_t ${BACKUP}
# LDAPサービスを停止
docker stop ldap_sv
# バックアップ実行
docker run --rm \
--entrypoint="/bin/bash" \
--volume ${BACKUP}:/backup \
--volumes-from ldap_sv:ro \
sonohara/samba4-ad:latest \
-c "cd /var/lib/samba ; tar zcf /backup/samba$(date +%Y%m%d%H%M%S).tar.gz \$(cd /var/lib/samba ; find private sysvol -type f -o -type l )"
# LDAPサービスを起動
docker start ldap_sv
```
### 7.2 リストア
```bash:samba-ad_restore.sh
#!/usr/bin/env bash
BACKUP=$PWD/backup
backupfile="$1"
date=$(date +%Y%m%d%H%M%S)
# バックアップファイルチェック
if [ \! -f ${BACKUP}/${backupfile} ] ; then
backupfile=$(basename "$1")
if [ \! -f ${BACKUP}/${backupfile} ] ; then
echo "not found backup file $1"
exit 1
fi
fi
set -x
if mkdir samba/samba.${date} ; then
# LDAPサービスを停止
docker stop ldap_sv
# リストア実行
docker run --rm \
--entrypoint="/bin/bash" \
--volume ${BACKUP}:/backup:ro \
--volumes-from ldap_sv \
sonohara/samba4-ad:latest \
-c "cd /var/lib/samba ; mv * samba.${date}/. ; tar xf /backup/${backupfile}"
# LDAPサービスを起動
docker start ldap_sv
mv samba/samba.${date} .
else
echo "mkdir error"
exit 1
fi
```
# 参考
[開発環境の認証を改善して Redmineを社内標準にした話](https://www.slideshare.net/ryousoda/redmine-69559249)
[sAMAccountNameをキーとして、OpenLDAPとActiveDirectoryを検索する](http://qiita.com/ryouma_nagare/items/bcda4c372347ed83fe7c)
[RedmineでのLDAP認証(ActiveDirectory)設定方法](https://yoshinorin.net/2016/04/03/Redmine-LDAP/)
[Docker コンテナ・ネットワークの理解](http://docs.docker.jp/engine/userguide/networking/dockernetworks.html)