QNAP Container Station LLDAP Server 構築

TS-h1283XU-RP」上のコンテナ(Container Station)で Joplin Server を構築します。

基本のセットアップ方法については、「QNAP QuTS hero 5 セットアップ」をご覧ください。

 

LLDAP Server って何?

QNAP QuTS hero 5 セットアップ」のページ中でも述べましたが、ユーザーを認証するためのLDAPサーバーを構築したいです。

本当はドメインコントローラーで使用しているユーザー情報をそのまま利用して各種Webサービスを公開したいところなのですが、ログインパスワードとWebサービス向けのパスワードを分けたいのです。

LAN内のPCにログインするときのパスワードは日常的に入力するので簡易的なもの、外部に公開する前提のWebサービス上で使用するパスワードは強力なものを設定したいということです。

スキーマ拡張してカスタム属性(アトリビュート)を追加すれば、パスワードの欄は増やせます。

しかし、ドメインコントローラーも各種Webアプリの類も、パスワードとして読みに行く属性はuserPasswordに決まっているものが多く、カスタム属性が使えないものがほとんどです。

そのため、新たにLDAPサーバーを構築して、ここではWebサービス上で使用するパスワードをメインで管理することにします。

 

LDAPサーバーにとらわれず様々な認証を視野に入れると、以下のようなソフトウェアが見つかります。

しかしながら、LDAPサーバー機能は備えていないため、別途LDAPサーバーのバックエンド等を用意しないと外部からLDAPで接続することができません。

 

LDAPサーバーメインで調査してみると、以下のようなソフトウェアが見つかります。

FreeIPAはLinux版のActive Directoryとも呼べるもので、LDAP以外の機能も豊富に実装されています。(内部で389 Directory Serverを使用)

今回必要なのはLDAPだけで、FreeIPAは規模が大きいので除外します。

OpenLDAPは昔からある有名なソフトウェアですが、設定が複雑です。

また、管理用のWebUIを備えていないため、GUIで操作したい場合には別途「LDAP Account Manager (LAM)」や「phpLDAPadmin」を導入する必要があります。

389 Directory ServerLLDAPは管理用のWebUIを備えているためこのどちらかを使用したいです。

今回は「Light LDAP implementation」(笑)な、LLDAPを試してみます。

(LDAPがLightweight Directory Access ProtocolなのにOpenLDAPが難解すぎてLightなLDAP実装が出てくるとは何事?)

 

LLDAP Server を Container Station に設定

詳細はこちらにある通りで、このDockerイメージを動かす場合には、ユーザー情報のデータベース、その他環境変数の設定が必要になります。

latest タグは本当に最新のコードを管理していて、安定リリースは stable タグとのことです。

 

事前準備

ユーザー情報の保存先としてディレクトリを作成します。

データベースサーバーに接続も出来るのですが、そこまでのユーザー数を扱うわけではないので、簡単にSQLiteを使用することにします。

そのため、SQLiteのデータベースファイルを保存する必要があり、以下のディレクトリを準備しておきます。

  • /share/Container/lldap/

デフォルトで生成された「/share/Container」以下、適当に「lldap」フォルダにしましたが何でもいいと思います。

コマンド例:

mkdir -p /share/Container/lldap/

 

Dockerコンテナの設定

「Container Station」を開き、「コンテナ」タブから「探索」ボタンを押してDockerHubからlldapを探します。

QNAP Docker LLDAP Server 001 QNAP Docker LLDAP Server 002

「コンテナまたはアプリケーションの作成」という画面が表示されるので、検索欄に「lldap」などと入力して「lldap/lldap」を探します。

「lldap/lldap」の右に表示される「デプロイ」ボタンを押します。

確認画面が表示されますが、lldap公式なので大丈夫でしょう。

 

QNAP Docker LLDAP Server 003

イメージバージョンの選択画面になるので、stable に変更をします。

コンテナ作成の画面になるので、以下のように設定していきます。

 

QNAP Docker LLDAP Server 004

  • 名前:任意(わかりやすいもの)
  • 設定・再起動ポリシー:「停止時以外」
  • ネットワーク設定・露出ポート:17170/tcp, 3890/tcp(新しいポートの公開ボタンで追加する)
  • ネットワーク設定・デフォルトの Web URL ポート:無効

「詳細設定」をクリックして、詳細設定に進む。

 

「環境」ページ

QNAP Docker LLDAP Server 005

「新しい変数の追加」ボタンで以下の内容を増やす。

  • 変数「TZ」値「Asia/Tokyo」(creation_date等はUTCで表示されるが、データベースで保持する時間はUTCなので正常)
  • 変数「LLDAP_JWT_SECRET」値「REPLACE_WITH_RANDOM」
  • 変数「LLDAP_KEY_SEED」値「REPLACE_WITH_RANDOM」
  • 変数「LLDAP_LDAP_BASE_DN」値「dc=ldap,dc=example,dc=com」(使用するドメイン名:ldap.example.com の場合)
  • 変数「LLDAP_LDAP_USER_PASS」値「(adminユーザーに対する8文字以上のパスワードを入力する)」

(1度データベースが生成されれば、LLDAP_LDAP_USER_PASSは必要なくなります)

 

「ストレージ」ページ

QNAP Docker LLDAP Server 006

ボリューム「/data」設定があるため、それを削除。

「ボリュームの追加」ボタン横の矢印から「マウントされたホストのパスをバインド」を選択して追加。

  • ホスト「/Container/lldap」に対してコンテナ「/data」

(なお、ボリュームの設定のままでも、ボリュームに /share/Container/lldap のパスで設定を入れると勝手にマウントになります)

この設定でコンテナ内のディレクトリをファイルシステムにマッピングさせます。

 

QNAP Docker LLDAP Server 007

以上で最低限起動する設定になっています。

ブラウザで http://[サーバーのIPアドレス]:17170 にアクセスすると管理画面を開くことができるでしょう。

 

「/share/Container/lldap」ディレクトリ以下に

  • lldap_config.toml (設定ファイル)
  • users.db (SQLiteデータベースファイル)

が生成され、その情報でLLDAPが動作します。

LLDAP_LDAP_USER_PASSで指定したパスワードでadminユーザーが作成されているため、それでログイン出来ると思います。

データベース中のadminユーザーにパスワードが設定されれば、環境変数で指定する必要はないので、後ほどLLDAP_LDAP_USER_PASSは削除しておきます。

> Setup permissions..
> Starting lldap..

Loading configuration from /data/lldap_config.toml
WARNING: A key_seed was given, we will ignore the key_file and generate one from the seed! Set key_file to an empty string in the config to silence this message.
Error: The JWT secret must be initialized to a random string, preferably at least 32 characters long. Either set the `jwt_secret` config value or the `LLDAP_JWT_SECRET` environment variable. You can generate the value by running
LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' </dev/urandom | head -c 32; echo ''
or you can use this random value: XpKPHi8OSKL~mhIST;[~o?EV=<mH}10h

最低限必要な環境変数・設定が無いとこのように永遠とコンテナが再起動を繰り返すので注意してください。

無事LLDAPが起動してくれば、 http://[QNAPのIPアドレス]:17170 で管理画面にアクセスできます。

adminユーザーが作成されているので、ログイン可能になっています。(パスワードは環境変数で指定したもの)

適当なLinuxマシン(QNAP自身)から、以下のコマンドで接続確認しても良いでしょう。

$ ldapsearch -x -H ldap://localhost:3890 -b "dc=ldap,dc=example,dc=com" "(objectClass=*)"

接続できない場合は「Can't contact LDAP server (-1)」と表示されます。

匿名バインドが許可されていないので「Anonymous bind not allowed」で正常です。

 

メール送信SMTP設定

パスワードリセット機能を有効化するために、SMTPの設定をします。

メールを送信するために、今回はGmailのサーバーを利用することにします。

コンテナの設定内容を変更するため、Container Stationで対象のコンテナの歯車アイコンから「再作成」を選択します。

詳細設定中の環境で以下の環境変数を追加します。

  • 変数「LLDAP_SMTP_OPTIONS__ENABLE_PASSWORD_RESET」値「true」
  • 変数「LLDAP_SMTP_OPTIONS__SERVER」値「smtp.gmail.com」
  • 変数「LLDAP_SMTP_OPTIONS__PORT」値「465」
  • 変数「LLDAP_SMTP_OPTIONS__SMTP_ENCRYPTION」値「TLS」
  • 変数「LLDAP_SMTP_OPTIONS__USER」値「no-reply@example.com」(Googleアカウントのメールアドレス)
  • 変数「LLDAP_SMTP_OPTIONS__PASSWORD」値「abcdefghijklmnop」(発行したアプリパスワード)
  • 変数「LLDAP_SMTP_OPTIONS__FROM」値「no-reply no-reply@example.com」(メールでの送信元の表示)
  • 変数「LLDAP_HTTP_URL」値「https://ldap.example.com/」(リセットメールからアクセスするためのドメイン名)

送りつけるだけなので、reply-toは指定しません。

Gmailだと、FROMはあくまで返信での表示となり、相手の表示メールアドレスはLLDAP_SMTP_OPTIONS__USERになるようです。

 

LDAPS対応(LDAP over SSL)

QNAP Container Station certbot-dns-route53 ワイルドカード証明書発行」の設定がしてある前提で進めます。

コンテナの設定内容を変更するため、Container Stationで対象のコンテナの歯車アイコンから「再作成」を選択します。

詳細設定で以下の内容を追加します。

  • ネットワーク設定・露出ポート:6360/tcp を追加
  • ストレージマッピングでホスト「/Container/certbot/etc/letsencrypt」コンテナ「/etc/letsencrypt」を「RO」で追加

環境変数に以下を追加。

  • 変数「LLDAP_LDAPS_OPTIONS__ENABLED」値「true」
  • 変数「LLDAP_LDAPS_OPTIONS__CERT_FILE」値「/etc/letsencrypt/live/example.com/fullchain.pem」
  • 変数「LLDAP_LDAPS_OPTIONS__KEY_FILE」値「/etc/letsencrypt/live/example.com/privkey.pem」

これで設定完了です。

$ ldapsearch -x -H ldaps://localhost:6360 -b "dc=ldap,dc=example,dc=com" "(objectClass=*)"

のようなコマンドを実行して、ldap_bindが出れば大丈夫です。(匿名バインドは無効にされてるので許可されていない表示になります)