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 するしかないかも。

2017年10月7日土曜日

389 Directory Server リストア失敗 → 成功

くだらないミスだったんだけど、同じことでハマる人がいるかもしれないので役に立てばのメモ。

まぁ、タイトルは 389 Directory にしたけど本当は RHDS なんだけどね。おそらく同じだろうからまぁいいかな(違ってたらコメントで教えて下さい)。

bak2db.pl を使って、db2back.pl で取得したバックアップディレクトリからリストアを試みたが、/var/log/dirsrv/slapd-<instance>/errors には以下のエラーが。

ERR - ldbm_back_archive2ldbm - No back up "/home/ryo/rhds1-2017_10_7_3_20_46" exists.
ERR - task_restore_thread - Restore failed (error -1)

ぐぐっても情報が無いので、ソースから上記箇所を grep。すると servers/slapd/back-ldbm/archive.c に以下の箇所あり。

   48     return_value = dbversion_read(li, directory, &dbversion, &dataversion);
   49     if (return_value) {
   50         if (ENOENT == return_value) {
   51             slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_archive2ldbm", "No back up \"%s\" exists.\n",
   52                           directory);
   53             return -1;
   54         }

どうも DB のバージョンを確認するファイルが無いと(ENOENT)。バックアップディレクトリ内のファイル名から考えると
DBVERSION ってのがあるんだけど... うーーん permission も問題なし... あ、SELinux ?バックアプファイルの context を見てみる。

# ls -Z
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 DBVERSION
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse_index.ldif
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse_instance.ldif
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse.ldif
   :

あぁぁ... てことで

# chcon -R system_u:object_r:dirsrv_var_lib_t:s0 rhds1-2017_10_7_3_20_46/

これで解決しますた。

2017年10月4日水曜日

389-consle (redhat-idm-console)が ssh の X Forward で動かん→動いた

redhat-idm-console (389-console)をリモート越しに起動して手元の X で表示しようと、
試みたところ以下のエラーで起動できない。

Exception in thread "main" java.awt.HeadlessException
        at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
        at java.awt.Window.(Window.java:536)
        at java.awt.Frame.(Frame.java:420)
        at java.awt.Frame.(Frame.java:385)
        at javax.swing.JFrame.(JFrame.java:189)
        at com.netscape.management.client.console.Console.(Unknown Source)
        at com.netscape.management.client.console.Console.main(Unknown Source)
Headless というのがようわからんが、/etc/java/とredhat-389-console.conf で以下の
ようにとにかくこれを外してみた。


$ diff -u /etc/java/redhat-389-console.conf.dist /etc/java/redhat-389-console.conf
--- /etc/java/redhat-389-console.conf.dist      2016-10-10 01:45:11.000000000 +0000
+++ /etc/java/redhat-389-console.conf   2017-10-04 01:44:55.026633680 +0000
@@ -1,3 +1,3 @@
 mylang=${mylang:-en}
 ADDITIONAL_JARS=${ADDITIONAL_JARS:-redhat-idm-console_$mylang.jar}
-ADDITIONAL_OPTIONS=${ADDITIONAL_OPTIONS:-"-Dprogram.name=redhat-idm-console -Djava.util.prefs.systemRoot=$HOME/.redhat-idm-console -Djava.util.prefs.userRoot=$HOME/.redhat-idm-console"}
+ADDITIONAL_OPTIONS=${ADDITIONAL_OPTIONS:-"-Dprogram.name=redhat-idm-console -Djava.util.prefs.systemRoot=$HOME/.redhat-idm-console -Djava.util.prefs.userRoot=$HOME/.redhat-idm-console -Djava.awt.headless=false"}

すると、libawt_xawt.so が無いぞと怒られ調べたらこれは Headless でない
java-1.8.0-openjdk パッケージに含まれる模様

# yum install java-1.8.0-openjdk 

しかしなんで単なる設定をいじるのにこんなに重い GUI を起動せにゃあかんのか。しかも
激重な Java。Java は Windows 以上に嫌いだわ。どの OS とも相性が悪い。当初のコンセ
プトとは大違い。クソ言語。問題なのはプログラマが多いこと。だから糞システムが量産
される。Java の世界だけで OS 作って勝手にやってりゃいいのに。こっちくんな。

2017年9月7日木曜日

/etc/sudoers をいじらずに PATH を効かせる

RHEL系の /etc/sudoers には secure_path がデフォルトで定義されている。

デフォルトの /etc/sudoers をいじりたくないのだけど、secure_path を無効にして PATH を引き継ぎたい。
そんなことを思って /etc/sudoers.d/mysetting を以下のようにしてみようとした。が visudo  に怒られた。


Defaults    secure_path =
Defaults    env_keep +=  "PATH"
%mygroup ALL = (myuser) /path/to/target*
secure_path = "" も駄目。もうちょっと考えれば何かしら解法が見つかりそうなのだが、ちょっと時間がない。ただどうしても /etc/sudoers はいじりたくない。

とりあえず今は特定のパス(/path/to/target)だけ通せば良いから、/etc/sudoers.d/mysetting を以下のようにした。全部の PATH は無理だが、今回の要件は何とかクリア。

Defaults    secure_path = /path/to/target:/sbin:/bin:/usr/sbin:/usr/bin
Defaults    env_keep +=  "PATH"
%mygroup ALL = (myuser) /path/to/target*

RHEL デフォルト /etc/sudoers の secure_path は /sbin:/bin:/usr/sbin:/usr/bin なので、それに特定のパスの「/path/to/target」を追加しただけ。


ちなみに以下も試して全 PATH 通そうとしたが駄目だった。


Defaults    secure_path -= /sbin
Defaults    secure_path -= /bin
Defaults    secure_path -=/usr/sbin/
一旦定義したパラメータを無効にする命令は無いものか...