2013年1月13日日曜日

.MaxOSX/environment.plistからPATH変数が読まれないことへの対処 [一部修正]

去年(2012年)の前半頃(まだ、Snow Leopardを使っていた頃)のことですが、NerdToolやcrontabから起動しているスクリプトの一部が動かなくなっていることに気づきました。


暫定的な対応


動いているスクリプトと動かないスクリプトを見比べると、スクリプトをフルパスで起動したり、PATH環境変数を再設定しているものは動いていました。PATH変数が何らかの原因で設定されていないようです。とりあえずスクリプト内の動かなかったコマンドが起動できるようにPATH変数を修正して動くようにしていました。
例えばこんな感じです。

修正前
#!/bin/sh
site_check.sh

~/bin ディレクトリにsite_check.shスクリプトを置いていますので、HOME変数を追加します。HOME変数は設定されていました。また、このスクリプト内から/opt/local/binあるコマンドを起動できるようPATHに追加します。

修正後
#!/bin/sh
PATH=/opt/local/bin:$PATH
$HOME/bin/site_check.sh

原因と対応

PATH環境変数が設定されなくなった原因は、Mac OS Xのセキュリティアップデートでの仕様変更のように思われる(どこかで読んだ記憶がある)のですが、ソースを見つけられませんでした。Security Update 2012-002による変更で、ログインした際に、~/.MacOSX/environment.plist内のDYLD_*変数を読み込まないようにしたという記述はあるのですが、PATH変数については記載されていませんでした。[Appleのリンク]

対処については、

  1. アプリケーション内でのInfo.plistでのLSEnvironmentキーを設定する方法
  2. /etc/launchd.confを作成する方法
  3. 個別のアプリケーション毎にlaunchd.plist (ファイル名は別にするようです)を記述する方法

などがあるようです。

1)は、最も安全だそうですですが、アプリケーションのバージョンアップ等で変更を忘れてしまいそうです。また、アプリケーションによっては使えません。2)は、今までログイン時(個別ユーザ用)に設定していたものを、他ユーザにも影響がでるような形で設定するのは、若干抵抗があります。設定自体は、シェルスクリプトの記法に近く楽そうでよいのですね。
3)は、設定がアプリケーション単位で個別にできるのがよい点です。記述は若干面倒そうです。(使い方はLaunchDaemons (launchctl, launchd.plist) の使い方にわかりやすくとめられていました)

いろいろ考えた末、以下の方針にしました。方針というほど大げさなものでもないのですが。
  1. /etc/launchd.confを使用するが、設定は最小限にする。特に、セキュリティのため、自分のIDの書き込み権がある場所は指定しない。
  2. 個別のアプリケーション内の環境設定等で対応できるものは、そこで対応する。NerdToolのシェルスクリプト等、手間がかからないものも各スクリプトで設定する。
  3. 1.〜2.で対応できない場合、そのアプリケーション用のlaunchd.plistを作成し、ユーザ領域の~/Library/LaunchAgents で管理する
  4. アプリケーション内のInfo.plistを修正は、バージョンアップ時に修正を忘れたり管理が大変なため行わない。

/etc/launchd.confを設定する前に、現在のlaunchdのPATH設定を調べたところ、以下のようになっていました。
$ sudo launchctl getenv PATH
/usr/bin:/bin:/usr/sbin:/sbin

/etc/launchd.confは存在していないのでこれらは、デフォルトで設定されているのでしょう。また、/etc/pathsは以下のようになっています。

/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

自分のPATH設定に入っている$HOME/bin, /opt/local/bin, /opt/X11/bin, /usr/local/clamXav/binが含まれていませんが、これらはログイン後シェルで使うものが多いので/usr/local/binだけを設定することにしました。それ以外は、.bash_profile等で変更します。

/etc/launchd.confには、

setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

と設定しました。また、/etc/pathsもそれに合わせて/usr/local/binを先頭に持ってきました。

また、crontabやNerdToolなどのシェルは、必要に応じてPATHを追加する方針ですが、現状既にそのように修正しているので基本的にはそのままです。PATHの追加が必要になるのは、ほとんどの場合、$HOME/bin か /opt/local/bin (MacPorts用のパス) です。

感想

environment.plistがサポートされなくなった背景には、Flashbackマルウェアの発生などMac OS Xでもセキュリティを厳しくする必要があるということが挙げられます。Mountain Lionでのsandbox化や承認されたアプリケーションしか基本的にはインストール・起動できないというのもその流れですね。もっと自由にしたいとか、いろいろ意見もあるようですが、今後ますますユーザレベルでも気を付けなければならないのではと思います。

[追記 2013/1/16 ] http://jvn.jp/cert/JVNTA13-010A/ によると、JAVAにまたセキュリティホールが見つかっていますね。注意したいものです。

0 件のコメント:

コメントを投稿