今年買ってよかったもの2021

今年買ってよかったものは幾つかあるのですが、とりわけQoLを改善したものを1つだけ挙げておきます。

お湯が必要な量、すぐに沸く、ということがこれほど生活の質を上げてくれるとは思いませんでした。 インスタントスープやお茶等々をすぐに飲めたり生ラーメンを作る時にコンロを占有しないなど、大変便利に使っています。正直、電気ケトルの有用性を甘く見ていたと言わざるを得ません。 これを買って以来、顕著に紅茶を飲む量が増えました(ほぼ毎日飲んでいます)。

電気ケトルという商品は選択肢が結構あり、実際どれを買うか迷うところだと思いますが、3人家族の我が家に見合った容量、性能、ブランドを検討した結果これにしました。 今のところ満足しています。

そういえばAurora MySQLのLOAD XML FROM S3ステートメント

Aurora MySQLのLOAD XML FROM S3ステートメントのXMLの仕様にちょっと癖があるので、メモがてら雑に書いていく。どの辺に需要があるかは知らない。

  • 行を示す要素はルート直下になくても良いので、validなXMLにしたかったら適当なルート要素を付けてやると良い
    • デフォルトではrow要素を行とみなす*1
    • よくあるサンプル(1行での投入事例)ではベタにルートに1個だけ<row>と書いてある事例が多いのでどうすればいいか結構迷うと思う*2
    • やってみた感じ、階層は問わないようなので*3、適当な要素をルートにつけてやっても期待通りの動作をする。
  <?xml version="1.0" encoding="UTF-8"?>
  <table name="users">
    <row>
      <field name="id">1</field>
      <field name="name">Ichiro R. Tanaka</field>
    </row>
  </table>
  • CDATAセクションと&#式の実体参照は使えない
    • なのでエスケープ処理は真面目に書いてあげないといけない
    • &lt, &gt;, &amp;が使えるのは確認した

何かあればまた追加する(かも)

*1:オプションで指定できる

*2:少なくとも当方は迷った

*3:xpathの//型式とかDOMのgetElementByNameで実装されてるのだろう

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でメール送信

仕事でRustを使う口実ができたことができそうなので、とりあえずメール送信するサンプルを書いた。 雑に手元のメールサーバで送信したらできた*1

*1:なお外部メールは手元のメールサーバの設定がいい加減なのでOP25Bで死ぬ

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