OSX ServerのOpenDirectoryにldapsを喋らせるためには

TL;DR

  1. Server.appでOpenDirectoryに有効な証明書を設定
    • ダメなら一回キーチェーンから証明書を削除して再登録
  2. SIPをオフにする
  3. /System/Library/LaunchDaemons/org.openldap.slapd.plistのProgramArgumentsの最後の要素にldaps:///を追加
  4. SIPをオンにする

背景

OSX Serverからいろんな機能を削るよというAppleの宣言により、一応使ってたサービスをどうするかという検討をしました。 我が家では、前に書いたようにOSX Serverを使って色々やっていました。主に使っていたのは以下のサービスです。

  • iOSデバイス向けMDM
  • カレンダーサーバ
  • メールサーバ*1

でした。MDMは今後も残る機能だからよく、カレンダーサーバはiCloudに移行すればよかったのでそうしたのですが、問題はメールサーバ。Postfixインストール済みのサーバはある*2から流用すれば良いけれど、ユーザ認証をどうするか。

ここで、OSX ServerのLDAPが出てくるわけです。 OpenDirectoryは手っ取り早くいうと「OpenLDAPに幾つかの薄い皮を被せたもの」なので、普通にLDAPv3サーバとして利用でき、ということはPostfixやdovecotとの連携も容易です。

問題は、インターネットから自宅サーバまでのセキュリティをどう保つか。 もちろんIPアドレス制限は当然のように行いますが、当然E2EのSSL通信としたい。となればLDAPSを喋らせたくなるわけです。

デフォルト状態

というわけで喋らせようと思うところ、そう簡単ではないわけです。 Server.appからSSLをオンにしてLDAPSで繋ごうとしてもうまくいきません。

# OK
% ldapsearch -D [bind DN] -H ldap://[OSX_SERVER] -b [base DN] [query]

# NG
% ldapsearch -D [bind DN] -H ldaps://[OSX_SERVER] -b [base DN] [query]

ldapsをサーバに喋らせるには(探索編)

こういう時、"OSX Server ldaps"とかでGoogle検索しても、なかなか良い情報が出てきません。マイナープラットフォームゆえの哀しさです。 なので一旦諦めて"OpenLDAP ldaps"などで検索するとlinuxでの方法が出てきます。例えばここなど。 このページには/etc/sysconfig/slapdを変更する、と書いてありますが、このディレクトリはOSX Serverには当然存在しないので読み替えます。マイナープラットフォームのユーザは常にこの手の「読み替え」が必要です。 man slapd などで調べてみるとこれはslapdの起動引数であることがわかります。なので、次は起動引数です。デーモンの起動引数といえばOSXでは(/System)?/Library/LaunchDaemonsなのでこの辺りでfindします。

% find /System/Library/LaunchDaemons -name \*ldap\* 

で引っかかるのが/System/Library/LaunchDaemons/org.openldap.slapd.plistです。 とりあえず覗いてみると該当箇所はこうです。

        <key>ProgramArguments</key>
        <array>
                <string>/usr/libexec/slapd</string>
                <string>-d</string>
                <string>0</string>
                <string>-h</string>
                <string>ldap:/// ldapi://%2Fvar%2Frun%2Fldapi</string>
        </array>

ここで「ああ/System配下なのか面倒だな」と思ったあなたはよく訓練されたOSXユーザです。そうですSIP(a.k.a rootless)です*3

ldapsをサーバに喋らせるには(解決編)

というわけで、/System/Library/LaunchDaemons/org.openldap.slapd.plistを変更すれば良いのですが、そのための手順は以下となります。

  1. リカバリモードで起動してSIPをオフにする
  2. /System/Library/LaunchDaemons/org.openldap.slapd.plistを変更
  3. SIPを再度オンにする*4

SIPをオフにする

まず再起動して、起動するまで⌘-Rを押し続けるとリカバリモードになります。ここで「ユーティリティ」から「ターミナル」を選びます。 ターミナルで以下コマンドを入力します。

# csrutil disable

ファイルを編集

org.openldap.slapd.plistの前掲の部分をこう変えます。

        <key>ProgramArguments</key>
        <array>
                <string>/usr/libexec/slapd</string>
                <string>-d</string>
                <string>0</string>
                <string>-h</string>
                <string>ldaps:/// ldap:/// ldapi://%2Fvar%2Frun%2Fldapi</string> <!-- ldaps://を追加している-->
        </array>

SIPをオフにする

リカバリモードで再起動したのち、再度オンにします。

# csrutil enable

ここまででOK、のはずが…

ここまででOKのはずが、なぜかldapsで繋げません。 色々いじったのですが解決せず。

結局、証明書を再度インストールすることでできました。 これだけで3時間くらいハマりました。

最後にルータのIPアドレス制限設定を忘れずに!!

これももちろん必要です。セキュリティのために取れる手段はどれも利用しましょう。

*1:主にSSL証明書受信目的での利用。外にMXサーバをおいてそこからフォワードしていた

*2:これまでフォワードに使ってたもの

*3:ワンピースの主題歌とは関係ないと思います

*4:厳密にいうとオプションですがセキュリティを確保する意味で実施することを強く推奨します

Rustでgemを書く際のハマりどころ in 2017

この記事は、Ruby Advent Calendar 2017の12/22の記事です。前日はTomoProgさんでした。

Rustという言語があります。 この言語の特徴は、一つは実行時のコストの低さ、もう一つは「所有権」システムにあると思います*1。所有権システムについては、2016年のRubyKaigiで発表されたGuildにインスピレーションを与えたことでもRuby界隈では知られているかと思います*2

が、今日の記事はRustについて記述することが目的ではないので、言語の特徴については細かくは触れないことにします。

RustによるRuby拡張の話題は、実はRubyKaigiでは2015年2017年の2度に亘ってセッションになっています。これは「型安全な」「実行が速い」言語で拡張を記述できるということに技術的関心が集まる、ということを表していると言えます。Rubyの特徴といえば「型がない」「実行が遅い」ですから、そうなるのも当然と言えるところはあると言えるでしょう。

というわけで実際にやってみたところ、そこそこハマりどころがあったので共有します。

*1:Rustをある程度学んだ人は皆この概念をRustの特徴として挙げると言われるくらい際立った特徴

*2:cf. http://rubykaigi.org/2016/presentations/ko1.html

続きを読む

Rustからposixとかlibcで使うような定数は割と簡単に参照できる

例えば、以下のコードはOSXではきちんと動く。

extern crate libc;

fn main() {
    println!("hoge = {}", libc::ENOMEM);
    println!("hoge = {}", libc::ENOENT);
    println!("hoge = {}", libc::EINTR);
    println!("hoge = {}", libc::ERANGE);
}

もちろんこれが独自ライブラリだと思うようにいかないので、適宜C実装してフォローしてあげる必要がありそうだけど。

なお、libcは当然のことながらプラットフォーム依存が強いので、ドキュメントはプラットフォームごとにある。
クロスプラットフォーム開発の時は、そこら辺も念頭に置いた方が良さそう。