2017年11月27日月曜日

389 Directory と AD の連携 (LDAP->AD 編)


前々回の389 Directory と AD の連携 (AD-> LDAP 編)の設定で双方向レプリケーションは自然に出来ているはず。が、どうも私の環境だとうまく行かない。389 Directory 側のエントリを modify しても AD に伝播してくれないのだ。

エラーログには以下のメッセージが。

NSMMReplicationPlugin - replica_update_state - Failed to update state of csn generator for replica dc=example,dc=com: LDAP error - 32

該当箇所のソースを見たがすぐにわかるようなものじゃないことが判明。仕方なくデバッグログ(nsslapd-errorlog-level: 8320)を出してみる。すると以下が。

Received result code 50 (00002098: SecErr: DSID-03150E49, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0 ) for modify operation

見覚えのあるエラー。AD 側に作ったレプリケーション用ユーザの権限が甘かったらしい。このユーザを Domain Admins グループに追加したところ OK。ここに書いてあった「Write/Create all child objects/Delete all child objects/Add GUID」は全部確認したんだけどなぁ...

まぁともあれ双方向レプリケーションは出来た。ちなみに LDAP-> AD 向きのパスワード同期については、ldappasswd (LDAPv3 Password Modify -RFC 3062) では駄目で、ldapmodify で userPassword に対して生パスワードを設定する必要がある。



2017年11月25日土曜日

Container Linux Config

Container Linux の設定が coreos-cloudinit でなく "Container Linux Config" で行うようになったけど、自分の頭の中の切り替えも結構必要なようだ。

普段 Vultr で CoreOS を使ってるが、running な CoreOS の設定(コンテナじゃなくて CoreOS 自体の設定)を変更しなくちゃならんときは、/usr/share/oem/cloud-config.yml をいじれば何とかなる。しかし、GCE の CoreOS や最新の PXE のイメージで標準になってる "Container Linux Config" の Ignition は本当に起動時にだけ実行され(see: https://coreos.com/ignition/docs/latest/what-is-ignition.html#when-is-ignition-executed)るとのこと。じゃぁ running で設定を変更したいときはどうするんじゃと...

https://www.bountysource.com/issues/43393940-edit-user-in-cloud-config-yml-remains-the-old-one-why あたりを見る限りは、Ignition には ignition.json を変更するというユースケースはないとのこと。

おそらく CoreOS 自体(コンテナじゃなくて)を永続化させるってのが、既にコンセプトと違うんだろう。etcd ver.3 (etcd-member)からは rkt の別コンテナで動かすようになってるし、とにかくステートを持つものはコンテナとして起動させろってことなんだろう。

全然関係ないけど、Vultr でインスタンスを作る時に「CoreOS」という名前のままなのは、レガシィな cloudinit 使ってるからなのか? あ、さらに関係ないけど、Vultr で Container Linux を iPXE で起動しようとして失敗するのは、たいていリソースが足りないからのようだ。Container Linux の本家のドキュメントには initrd を広げるのに最低 2GB の RAM が必要ということだ。ケチって 1GB RAM にすると失敗する。ケチりたいときは iPXE でなく既に用意されている CoreOS で cloud-config.yml をちまちまいじるしかないかも。

2017年11月21日火曜日

389 Directory と AD の連携 (AD->LDAP PassSync編)

先日の389 Directory と AD の連携 (AD-> LDAP 編)の続き。

前回は AD からアカウントの同期は出来るようになった。今回は AD 側でユーザが変更した(管理者が変更するのでもOK)パスワードを、389 Directory に送って同期するようにしてみる。

似たような仕組みは以前自分でも会社のプロジェクトで作ったことがあって、そのときは Windows 上の LSA(Local Security Authority) ってのがコールバックする PasswordChangeNotify() 関数を実装したけどおそらく同じ仕組みだろう。後で 389 のソース確認してみる->自分。

  1. まずは、389 Directory を LDAPS 化する。生でも行けるのかも知れんが、99 % のお客さんは暗号化して欲しいって言ってくるだろう。ただそんな場合でもオレオレ証明書(Self-Signed)で十分。なのでまずは 389 Directory に入れる証明書と秘密鍵を作って certutil に噛ませるために PKCS#12 にする。ここで -name で指定する friendlyname は Server-Cert という名前にしないと後で苦労するっぽい(この情報は Web のどこかに書いてあったんだけど見失ってしまった...)
  2. openssl req -x509 -newkey rsa:2048 -keyout 389.key -out 389.crt
    openssl pkcs12 -export -out 389.p12 -inkey 389.key -in 389.crt -name Server-Cert
    
  3. 上記でできた 389.p12 ファイルを pk12util で /etc/dirsrv/slapd-<インスタンス名>/ 下の NSS データベースに登録。
  4. pk12util -i 389.p12 -d /etc/dirsrv/slapd-ryo/
    
    PKCS#12 のパスワードやデータベースのパスワードを聞かれるので適切に応答する。そして登録できたか確認
    # certutil -L -d /etc/dirsrv/slapd-ryo
    Certificate Nickname                                         Trust Attributes
                                                                 SSL,S/MIME,JAR/XPI
    Windows Server AD CA cert                                    P,,  
    Server-Cert                                                  u,u,u
    
    Server-Cert って証明書があるのがわかる。ちなみにその上の Windows Server AD CA cert ってのは前回作った Windows Server 側の証明書。秘密鍵も確認。
    # certutil -K -d /etc/dirsrv/slapd-ryo
    certutil: Checking token "NSS Certificate DB" in slot "NSS User Private Key and Certificate Services"
    Enter Password or Pin for "NSS Certificate DB":
    < 0> rsa      1xxxxxxxxxxxxxxxaff5b7826ec1dxxxxxxxxxx   Server-Cert
    
    ちなみに何らか失敗して p12 ファイルの登録をやり直したい場合に証明書と秘密鍵を消すが、これを certutil の -D で証明書だけ消すと秘密鍵が消せなくなるので注意。この場合は再度同じ p12 を登録してから certutil の -F オプションを使うとよい。数年前のコミュニティの ML でバグだって言っている人がいたが、直してないところをみるとディベロッパはバグじゃないと思ってるんだろう。

  5. あとは 389 Directory の設定に証明書の情報を入れるため以下 ldif を ldapmodify (-D "cn=Directory Manager")で登録。詳細は公式ドキュメント参照。
  6. dn: cn=encryption,cn=config
    changetype: modify
    replace: nsSSL3
    nsSSL3: off
    -
    replace: nsSSLClientAuth
    nsSSLClientAuth: allowed
    -
    add: nsSSL3Ciphers
    nsSSL3Ciphers: +all
    
    dn: cn=config
    changetype: modify
    add: nsslapd-security
    nsslapd-security: on
    -
    replace: nsslapd-ssl-check-hostname
    nsslapd-ssl-check-hostname: off
    
    続けて同様に ldapmodify で、以下 ldif を登録。これは後述の /etc/dirsrv/dirsrv/slapd-<インスタンス名>/下の pin.txt ってファイル(これも ldif ぽい)に関する設定のようだ。以下の nsSSLToken というのは、pin.txt の中の属性名を指し示している模様。
    dn: cn=RSA,cn=encryption,cn=config
    changetype: add
    objectclass: top
    objectclass: nsEncryptionModule
    cn: RSA
    nsSSLPersonalitySSL: Server-Cert
    nsSSLToken: internal (software)
    nsSSLActivation: on
    
  7. NSS データベースのパスワードファイル /etc/dirsrv/slapd-<インスタンス名>/pin.txt を以下のように作成。左辺の「internal (software)」は上記の nsSSLToken の値であることに注意。
  8. internal (software):secret
    
    パーミッションを dirsrv:dirsrv の 0400 にする。
    # chown dirsrv:dirsrv /etc/dirsrv/slapd-ryo/pin.txt
    # chmod 400 /etc/dirsrv/slapd-ryo/pin.txt
    
  9. あとは dirsrv (ns-slapd)を再起動するだけ。
  10. systemctl restart dirsrv@ryo
    
    ss すれば 636 で listen してるはず。

  11. 上記までで LDAPS 化は完了して、あとは AD 側の設定。公式ドキュメント(Installing PassSync)のところに Windows 用バイナリのリンクがあるので、ダウンロードしてインストールする。インストーラの最初の画面で以下の項目を入力する必要がある。
    • Host Name: 389 Directory サーバの FQDN
    • Post Number: LDAPS ポート(636)
    • User Name: 前回 389 Directory 上に作ったレプリケーション用ユーザ (cn=sync user,cn=config)
    • Password: 上記レプリケーション用ユーザのパスワード
    • Cert Token: よくわからない。必須でないので空っぽ。
    • Search Base: 同期するユーザの 389 Directory 側の Base DN

  12. Windows Server に PassSync をインストールし終わったら、PassSync に 389 Directory の LDAPS のサーバ証明書を certutil.exe でインポートする。公式ドキュメント(Configuring PassSync)参照のこと。ここで注意したいのが、前回同様 certutil.exe の -t オプションを "P,," とすること。
  13. cd "C:\Program Files\389 Directory Password Synchronization"
    certutil.exe -d . -A -n "DS CA cert" -t "P,," -a -i \path\to\389.crt
    
    ここで Windows お得意のマシンごと再起動。

  14. 389 Directory に戻ってひとつだけ前回にやっていなかったことがあって、それをやらなくてはならない。前回はレプリケーション用ユーザの "cn=sync user" を 389 Directory 上に作ったが、このユーザに userPassword 属性の書込を許可する aci を与えていなかった。以下 ldif を ldapmodify (-D "cn=Directory manager") で登録する必要がある
  15. dn: ou=people,dc=example,dc=com
    changetype: modify
    add: aci
    aci: (targetattr="userPassword")(version 3.0;acl "password sync";allow (write,compare) userdn="ldap:///cn=sync user,cn=config";)
    

  16. 上記までで設定は完了。 AD 側で、あるユーザのパスワードを変更すると 389 Directory 側の対応するユーザの userPassword 属性が変更されるはず。うまく行かない場合は、Windows Server 側の C:\Program Files\389 Directory Password Synchronization/passsync.log を確認すると良い。



2017年11月17日金曜日

PNF No Root

子供にスマホを買い与えるな馬鹿親!って議論は置いておいて、とりあえず Google の Find My Device (端末を探す)でうちの子がどこにいるかを知りたいわけですよ。
まだそういう監視下に置かせるべき年頃なので。

で、最近 g06+ なるスマホを買って子供に渡す前に、DMM Mobile のデータ SIM (SMS付き)を入れていろいろ実験してみたところ、どうも Find My Device で Can't find device が頻発する事象に悩まされることに。

自分の Nexus 6P + Softbank SIM は全然いつでも Find OK なのに何で? といろいろと調べたところ、以下がヒット。

スリープ後、時間が経つとプッシュ通知が来なくなる件
どうも、格安 SIM に多い現象ということ。上記 URL によれば MVNO 側の NAT テーブルのタイムアウトが、Google の PUSH サーバの Keep-Alive の間隔より短いらしい(ん?NATってことは MVNO が IPv6 対応なら問題ないのかな)。

まぁ Find My Device も PUSH 通知とセッションの維持の仕方は似たようなもんだろうから、早速上記 URL にあった PNF No Root を入れてその間隔を18 分に設定。おぉ、見違えるほど反応がよくなった。副作用として、バッテリーの減り方も遅くなったぞ。うん。

まぁ DMM Mobile の SIM はあくまでも実験で使ってるんであって、最終的には mineo の 音声 SIM を入れるんだけど。

悩んでいる人はお試しください。

389 Directory と AD の連携 (AD-> LDAP 編)

また 389 Directory ネタ。 AD と連携できるってことで、「やってみた」レベルのことをやってみたのメモ。GUI 無し, とりあえず AD -> LDAP 方向のみ。オレオレ証明書で AD からの LDAPS。

  1. まず、389 Directory をインストール。OS は CentOS 7。Java の admin GUI は使わないので setup-ds.pl を使う。問答の途中でインストールタイプを聞かれるが、私はこれはカスタマイズしやすい 3 で作る。なお、インスタンス名は ryo , サフィックスは example.com とした。
    
    # yum install 389-ds-base
    # setup-ds.pl
    
  2. AD は Windows Server 2012 R2。このインストールや設定はここでは説明しません。適当にご自由に。なお、ここでは説明上 example.local という AD ドメインを設定した。
  3. オレオレ証明書を作って AD に入れて LDAPS させる。手前味噌だが以下を参照で。

    AD でオレオレ証明書で ldaps するのに AD CS で作った証明書じゃないとダメというデマ
    http://blogger.fastriver.net/2014/02/ad-ldaps-ad-cs.html
  4. 上記オレオレ証明書(ここでは my.crt とした)を 389 Directory にセット。
  5. 
    # cd /etc/dirsrv/slapd-ryo/
    # certutil -d . -A -n "Windows Server AD CA cert" -t P,, -a -i /path/to/my.crt
    

    ここで注意したいのが、-t オプションの値を「P,,」(Valid Peer)としてるところ。オレオレの時は C (Trusted CA) じゃなくてサーバ証明書そのものを信頼される証明書として指定すべきぽい。
  6. AD 側にレプリケーション用のユーザを作成する。これは以下の URL に従った。権限として「Write/Create all child objects/Delete all child objects/Add GUID」が必要とのこと。なお、ここではこのユーザの DN は「cn=replication,cn=Users,dc=example,dc=local」とした。

    http://directory.fedoraproject.org/docs/389ds/howto/howto-windowssync.html#creating-ad-user-with-replication-rights
  7. あとは 389 側にいろいろ ldif で設定を入れる。ldapmodify で -D 'cn=Directory Manamger' で接続すること前提。
    • suffix のエントリの作成。
    • dn: dc=example,dc=com
      changetype: add
      objectClass: top
      objectClass: domain
      dc: example.com
      aci: (targetattr!="userPassword || aci")(version 3.0; acl "Enable anonymous ac
       cess"; allow (read, search, compare) userdn="ldap:///anyone";)
      aci: (targetattr="carLicense || description || displayName || facsimileTelepho
       neNumber || homePhone || homePostalAddress || initials || jpegPhoto || labele
       dURI || mail || mobile || pager || photo || postOfficeBox || postalAddress ||
       postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddr
       ess || roomNumber || secretary || seeAlso || st || street || telephoneNumber 
       || telexNumber || title || userCertificate || userPassword || userSMIMECertif
       icate || x500UniqueIdentifier")(version 3.0; acl "Enable self write for commo
       n attributes"; allow (write) userdn="ldap:///self";)
      aci: (targetattr ="*")(version 3.0;acl "Directory Administrators Group";allow 
       (all) (groupdn = "ldap:///cn=Directory Administrators, dc=example,dc=com");)
      
    • people コンテナの作成
    • dn: ou=people,dc=example,dc=com
      changeType: add
      objectclass: top
      objectclass: organizationalUnit
      ou: people
      
    • changelog の有効化
    • dn: cn=changelog5,cn=config
      changetype: add
      objectclass: top
      objectclass: extensibleObject
      cn: changelog5
      nsslapd-changelogdir: /var/lib/dirsrv/slapd-ryo/changelogdb
      nsslapd-changelogmaxage: 7d
      
    • 389 Directory 側のレプリケーション用ユーザの作成(後の PassSync のため)
    • dn: cn=sync user,cn=config
      changetype: add
      objectClass: inetorgperson
      objectClass: person
      objectClass: top
      cn: sync user
      sn: SU
      userPassword: secret
      passwordExpirationTime: 20380119031407Z
      
    • レプリケーション設定
    • dn: cn=syncreplica,cn=dc\=example\,dc\=com,cn=mapping tree,cn=config
      changetype: add
      objectclass: top
      objectclass: nsds5replica
      objectclass: extensibleObject
      cn: syncreplica
      nsds5replicaroot: dc=example,dc=com
      nsds5replicaid: 7
      nsds5replicatype: 3
      nsds5flags: 1
      nsds5ReplicaPurgeDelay: 604800
      nsds5ReplicaBindDN: cn=sync user,cn=config
      
      ここで注意が必要で、上記 ldif dn: の cn=mapping tree より上の RDN においてはスペースは許されない。スペースを入れると以下のエラーに悩まされることになる
      ERR - NSMMReplicationPlugin - agmtlist_add_callback - Can't start agreement
      
    • Sync Agreement の作成
    • dn: cn=adagreement3,cn=syncreplica,cn=dc\=example\,dc\=com,cn=mapping tree,cn=config
      changetype: add
      objectclass: top
      objectclass: nsDSWindowsReplicationAgreement
      cn: adagreement3
      nsds7WindowsReplicaSubtree: cn=Users,DC=example,DC=local
      nsds7DirectoryReplicaSubtree: ou=people,dc=example,dc=com
      nsds7NewWinUserSyncEnabled: on
      nsds7NewWinGroupSyncEnabled: on
      nsds7WindowsDomain: SIOS
      nsDS5ReplicaRoot: dc=example,dc=com
      nsDS5ReplicaHost: ad-389.example.local
      nsDS5ReplicaPort: 636
      nsDS5ReplicaBindDN: cn=replication,cn=Users,dc=example,dc=local
      nsDS5ReplicaCredentials: MySecret-123
      nsDS5ReplicaTransportInfo: SSL
      nsds5replicabindmethod: SIMPLE
      winSyncInterval: 30
      winSyncMoveAction: delete
      nsds5BeginReplicaRefresh: start
      
これでいけるんじゃないかと。

2017年10月18日水曜日

db2bak.pl の結果を知りたい

389 Directory Server の db2bak.pl の中身を見る限り、どうやらこれは
 "cn=backup, cn=tasks, cn=config" にエントリを追加するだけで、後は task プラグイン
にお任せのようだ。

エントリの追加後タスクの実行を待っていたりしないので非同期で、その結果は db2bak.pl
だけでは得ることができない。同期モードを作るべきな気がするが。
# 自分で作れってw

ちなみに db2bak.pl の終了コードは perl の DSUtil:ldapmod() の返り値と同じなので、
エントリ追加が出来たかどうかしか取れない。

じゃぁ終了判断やその結果をどうやって知るかってことになるが、errors ログファイル
を見るのが一番確実ではあるが行parseするのが面倒。

db2bak.pl を実行すると以下のように標準出力にエントリの DN が表示される。

# db2bak.pl -Z testinst -D "cn=Directory Manager" -w password
Back up directory: /var/lib/dirsrv/slapd-testinst/bak/rhds1-2017_10_18_2_15_12
Successfully added task entry "cn=backup_2017_10_18_2_15_12, cn=backup, cn=tasks, cn=config"

そのエントリを参照すると以下のよう。


dn: cn=backup_2017_10_18_2_20_7,cn=backup,cn=tasks,cn=config
objectClass: top
objectClass: extensibleObject
cn: backup_2017_10_18_2_20_7
nsarchivedir: /var/lib/dirsrv/slapd-testinst/bak/hoge
nsdatabasetype: ldbm database
nstaskcurrentitem: 0
nstasktotalitems: 1
nstasklog:: xxxxxx
  :
nstaskstatus: Backup finished.
nstaskexitcode: 0

nstasklog 属性に base64 で詳細ログが記録されてる。終了したか否かの判断は
nstaskstatus と nstaskexitcode ですれば良いっぽい。ただ、このエントリは終了後
その結果にかかわらず 2 分で消える。2 分という設定がどこにあるかわからないが、
以下で 2 分と言っている人がいた。cn=config にはそれらしき設定は無かった。

http://www.databaseusers.com/article/7985099/backup+monitor

Once a task has finished (good or bad), the entry will stay visible for 2 minutes. By viewing the nstaskstatus and nstaskexitcode attributes you can find out how far it has gone and if the task has finished successfully or with an error.
Here is an example using a persistent search filtering on nstaskexitcode so you only get a response back once the job has completed:

これをぐるぐる回して同期なスクリプトを作るか。終了後 2 分で消えるということは、
db2bak.pl 実行後にぐるぐる回す間隔を 2 分以内にすればとりあえずはなんとか消える
前に結果が取れるってことかな。

めんどくさっ
今から python で作り変えてみる。

2017年10月10日火曜日

389 Directory MemberOf Plugin は refint 不要ぽい

389 Directory の MemberOf プラグインは、あるメンバーの実エントリの DN を modrdn して書き換えると、
何もしなくても(refint overlay 使わなくても)ちゃんと groupOfNames 側の member を書き換えてくれる。

その逆の、ある groupOfNames のグループの実エントリで、グループの DN を modrdn で書き換えても
ちゃんとユーザエントリ側の memberOf を書き換えてくれた。

しかしながら groupOfNames の owner 属性は対象外っぽい。こちらは refint するしかないかも。