OpenBSD 20周年、5.8 リリース、sudoに代わる「doas」コマンドやpledgeセキュリティシステム導入 46
ストーリー by hylom
もう20年 部門より
もう20年 部門より
あるAnonymous Coward 曰く、
10月18日にOpenBSD 5.8がリリースされた(OpenBSD journal、OSDN Magazine)。
通常Open BSDは5月および11月の1日にリリースされるが、今回はソースツリー構築から20年目の18日がリリース日となった。
影響の大きな変更としては、sudoがport/packageのみの提供となり、代わりにdoasというシンプルなコマンドが用意された。また、fileコマンドが書き直され、その過程で簡便な権限制限の仕組みとしてpledge(旧名 tame)が導入された。現在pledgeは積極的にユーザランドでテストされているので5.9では広く活用されるはずだ。
pledge (スコア:5, 興味深い)
pledge は流行ると思いますか?
まず pledge がどういうものかを説明します。
プログラムって、最初は設定ファイルを読んだり一時ファイルを開いたりするけど、
その後メインループに入ったら権限を殆ど必要としないことが多いですよね。
だから、コマンドラインオプション等に応じて [openbsd.org]
メインループ直前で権限を落とすという仕組みなんです。
だから最初は tame (調教する [openbsd.org]) という名前の関数でした。
獰猛な野獣 (いったん任意のコマンド実行を許す脆弱性があると何でもできちゃう) を
手なずける (脆弱性があっても殆どのシステムコールが実行不可能) という感じですね。
現在では主語が変わって、pledge (宣誓する) という名前です。
「私は stdio の範囲のみ使用し、その他には近寄らないことを宣言します!」
等と誓わせるわけですね。
ファイル単位、ユーザ/グループ単位のアクセス制限とは、かなり違う粒度です。
プログラムの途中で権限を落としていくというのは、前例があるんでしょうか。
最初は「Android apps みたいな権限宣言かな?」と思いましたが、考えてみると
こちらは権限を落とす一方だし、コード埋め込みだし、実行中に落としていくので、全然違いますね。
さて、開発陣は、これがセキュリティを大幅に向上させるというよりは
「抜け道いっぱいだけど、まあシートベルトみたいなもんだね」
と言っています。 [openbsd.org]これって意味あるんですかね。
あとはインターフェースが珍しいです。
ふつうシステムコールって、ヘッダで定数を定義して OR 演算させたくなりませんか。
ここ [tedunangst.com]にあるように
というインターフェースにするのが普通の発想じゃないかと思うんですが、この pledge は
という呼び方をします。
「セキュリティ関連システムコールで文字列操作かよ!」ってツッコミたくなりません?
宣誓した範囲を超えようとするとエラーで終了するので、
思わぬところで DNS にアクセスしてクラッシュする等の問題が出ているようです。
OpenBSD (というか Theo) の哲学としては
「プログラムが何をするのかを把握できないならプログラマの意味ないじゃん、信頼性とかゼロじゃん」 [marc.info]
そして
「オフにできる仕組みはユーザがオフにしちゃうから無意味」 [openbsd.org]
らしいので、ユーザに何の利便性向上もなくシステムを不安定にして
理論上セキュリティを向上させるという、茨の道に進んでいるわけです。すごいですねー()
Re:pledge (スコア:1)
ちょっと違うところはあるんですが, FreeBSDのcapsicum [gihyo.jp]あたりが近いと思います. 最初に必要な操作を発行しておいて, その後制限モードに移行するという所が同じですね. 基本的にプログラマの予期しない動作は何かおかしい, というフェイルセーフの思想だと思います.
capsicumについてはLinuxにも移植 [mynavi.jp]されていて, OpenBSDにも移植の話がいくつか出ていたみたいですし.
Re:pledge (スコア:1)
> tame(TAME_STDIO | TAME_CMSG | TAME_GETPW | TAME_PROC | TAME_DNS, NULL);
>というインターフェースにするのが普通の発想じゃないかと思うんですが、この pledge は
> tame("stdio cmsg getpw proc dns", NULL);
後者の方が,今風のAPIだと思います
理由は3つ
1) 後者のほうが短い(≒可読性も高い)
古典的なC言語だと
tame(TAME_STDIO | TAME_CMSG | TAME_GETPW | TAME_PROC | TAME_DNS, NULL);
はよく見かける記述ですが,これ冗長だと思いませんか?
2) 今時のCPUは高速なので,文字列処理は大したオーバヘッドにならない
特に tame() は頻繁に実行する処理ではないので,文字列処理のオーバヘッドはあまり問題になりません
3) 文字列のほうが拡張性・保守性が高い
カーネルのAPI/ABIでは,将来的な変更・修正が少ないことも重視されます
ヘッダで定数のORを取る方針だと,たとえば64bit整数だと最大64個しかオプションが定義できません.
65個目のオプションが必要なった場合は API/ABI を追加,または変更しなければなりません.そのため細かい制御には不向きであると言えます
一方文字列で指定する方針だと,API/ABIを保ったまま柔軟な拡張ができます.
たとえば
tame("get*", NULL);
tame("getpw[uid==1000]", NULL);
などです.
この手の拡張は,定数でOR作戦だと実質無理です.
個人的には,3番目の理由だけで,私は定数をORで指定する方式は選択肢にさえなりません
Re:pledge (スコア:2)
ですねぇ。加えて言うと、文字列なら他の言語との親和性も高くなりますしね。ヘッダファイル等での余計な定義も不要になりますし。
ほえほえ
Re: (スコア:0)
それでも文字列はないな。考慮しなきゃならないケースが無駄に多くなりすぎる。
それはバグの温床だし、すなわちセキュリティホールの温床にもなりうる。
それに理由3は割と簡単にあとから拡張可能だしね。
Re: (スコア:0)
文字列の方が拡張性が高いのはわかるんですが、保守性も高いんでしょうか?
プリコンパイルやリンクでチェックやリンクできずにエラーになるならいいと思うんですけど、
実行時にしかエラーがわからなさそうなものってどうにも抵抗が…
(javaや.NETのリフレクションで文字列指定するのとかも抵抗があるんですよね。あっちはIDEのリファクタリング機能の対象外になるのも敬遠したくなる所以ですが)。
優秀なIDEがあればコードtypoなんかは警告だしてくれそうですが、それもあるかどうか不明ですし。
実際に作る時はマクロでもつかってそのあたりの不安を埋めてくんでしょうかね?
# 最近jsばかり書いてるせいか、どうせ文字列つかうなら文字列テーブルにすればいいのにとも。
Re: (スコア:0)
商用UNIXでは普通にありますよ。
Re: (スコア:0)
Linux のcap-ngとの比較,批評をどなたかしていただけませんでしょうか.
http://people.redhat.com/sgrubb/libcap-ng/ [redhat.com]
Re: (スコア:0)
> プログラムの途中で権限を落としていくというのは、前例があるんでしょうか。
「落とす」ではなくて、プログラム上の必要な箇所だけ「上げる」というのは、Winodws NTがそうなってますね。
基本ポリシーとして Unix (TrustedUnix系を除く) は、全権限を持つものを根にして、子供が権限を落としていくという方法ですけど Windows は、全く権限の無い状態から、必要な箇所だけ認証して権限を上げるという方向です。
旧Unix 的な方式では、子供の不具合で親にロールバックした場合に権限が上がってしまうというアーキテクチャとしての欠陥があるので Windows 型の方式になった TrustedUnix というのが出てきたわけです。
Re:pledge (スコア:1)
(完全に余談です)
従来どおりのアクセス制限の範疇になりますが、Windowsでも「落とす」方向の作りは珍しくありません。Windowsサービスで可能です。
具体的にはこういう風にします。サービスの実行ユーザーをLocalSystemアカウント(これは例えるならroot、強い権限を持っている)にします。このプロセスから、弱い権限のアカウントを実引数としてImpersonate系関数(seteuid/setegidで一時的に落とす感じ)やCreateProcessAsUser関数(forkしてsetuid/setgidしてexecする感じ)を呼び出します。
Impersonateはseteuid/setegid同様に戻り値で成功したことの確認が必須です。一方、CreateProcessAsUserは失敗したらプロセスの作成が行われないので、最悪エラーチェックなしでも幾分安全と言えると思います(もちろん、しなくていいとは言っていない)。
#seteuid/setegidやsetuid/setgidでの例えが正しいのか不安。
Re: (スコア:0)
IISがやっているのがまさにそれですね。
Re:pledge (スコア:1)
そういえば、もしかしたら特殊ながらWindowsで「プログラムの途中で権限を落としていく」のようなことはできるかもしれません。すなわち「前例がある」と言えるかもしれません。
「自プロセスをOpenProcessTokenして、AdjustTokenPrivilegesでSE_PRIVILEGE_REMOVEDする」が可能なら、できると言えます。ドキュメントにはそう書いていないけど、自プロセスに対してSE_PRIVILEGE_REMOVEDはできないという制限がもしあったら、できないということになります。
これで落とせるのは「特権」と呼ばれるものになります。「物理メモリのロック」とか「時刻変更」とか「シャットダウン」とか、ファイルや各種オブジェクトに対するアクセス権限とは別の種類のアクセス制限です。特権の一覧:特権 [microsoft.com](これはちょっと古いので、Vista世代で増えたものが載っていない)
Re: (スコア:0)
Chromiumのサンドボックスプロセスが普通にやってますよ。初期化時にだけ権限が必要な操作をやって以後権限を落としたり。
Re:pledge (スコア:1)
あれ、そうでしたか。あれは、低い権限のアクセストークンで新しいプロセスを作っているだけだと思っていました。
ここまでリリースソングに関するコメント無し (スコア:1)
20 years ago today [openbsd.org]
Fanza [openbsd.org]
So much better [openbsd.org]
A Year in the Life [openbsd.org]
曲の内容としては・・・仕事から帰った所なんで、風呂入ってから聴きます :)
Re: (スコア:0)
a と d が the beatles なのは分かった。
b と c はオリジナルかな?
b は結構すき。
リリースソングを話題にするなら、
アートワークや寄付の話もしないと。
でもその前に httpd の話とか、
(入ったのは 5.8 の後だけど) rebound の話とかもしないと。
doasというシンプルなコマンド (スコア:0)
sudoもシンプルだと思うんだけど... (´・ω・`)
Re:doasというシンプルなコマンド (スコア:1)
infinity
Re: (スコア:0)
だれかdoasのアドバンテージを3行で頼む。
Re:doasというシンプルなコマンド (スコア:5, おもしろおかしい)
右手人差し指を
赤ポッチにつけたまま
入力できます。
Re: (スコア:0)
sudo に対するアドバンテージを…
Re: (スコア:0)
Re: (スコア:0)
ちょっとOが遠いよね
Re:doasというシンプルなコマンド (スコア:2, 参考になる)
素人でもコード [openbsd.org]が数分で読める
スクロールしないでマニュアル [openbsd.org]が読める
安心して設定ファイル [openbsd.org]が書ける
Re:doasというシンプルなコマンド (スコア:1)
doas.confの設定により
ユーザ単位よりもきめ細かくコマンド単位で
許可・不許可が設定できる
という理解で良いのかな?
あまり詳しくなくて申し訳ありませんが、 (スコア:0)
あまり詳しくなくて申し訳ありませんが、
sudo.conf に出来ない事を doas.conf で実現する、
という事なのでしょうか?
# 本日ハ晴天ナリ
Re:あまり詳しくなくて申し訳ありませんが、 (スコア:4, 参考になる)
いいえ、逆みたいです。
「suid root なプログラムのくせに複雑すぎる」というセキュリティ上の懸念と
「ユースケースの 99% は単純に root でコマンド打ちたいだけだろ」という
現実的な分析に基づき、sudo にできることを極力できなくしたものです。
http://www.tedunangst.com/flak/post/doas [tedunangst.com]
sudo のメンテナは OpenBSD の人なのに、
ports にある高機能 sudo と、base にある安全重視 sudo の乖離が激しく、
Theo がイライラしていたようです。
特殊な使い方をしたい人は package で sudo を入れろということになりました。
Re: (スコア:0)
こういう俺程度にはどうでもいいところにイライラするほどこだわる。
この辺、さすがOpenBSDだなぁ。
末永く頑張って欲しい。俺は使わないけど。
Re: (スコア:0)
そうかぁ?、同じような名前で同じような機能を実現するものが二つもあるってのは、イライラさせられるけどなぁ。
PC-BSD (FreeBSD もそうなのか?) で、libiconv が /usr と /usr/local にあって、イライラさせられたばかりなんだけどね。
Re: (スコア:0)
論理的・技術的に正しいかどうかがBSDでは全てではないでしょうか?
まあ、俺は使わないけど。
Re: (スコア:0)
baseにある方はdoasに変わったので同じ名前ではなくなりましたね。
スマホ的セキュリティー (スコア:0)
スマホOSだと既存のカーネルを使いつつも、アプリ毎にuidを割り振り、プロセス間通信の種類ごとに許可不許可を含むチェックをすることがセキュリティーの基礎になるという作りが多いようです。
スマホのOSは面倒だったり権限の種類分けがおかしかったりするので、OpenBSDあたりがその方向をサポートしてくれたりしませんかねー。unix的モデルで開発されてきた物に非unix的なのを乗せるのは面倒かもしれませんが。
Re: (スコア:0)
Android は確かにヘンだけど
都度許可になる [nikkeibp.co.jp]と少しはマトモになるんじゃないかな。
# オフトピ御免
Re: (スコア:0)
つ[ユニバーサルアプリ]
めんどくせーな (スコア:0)
sudoしようとするとコマンドがねーとか言われて
duasって打ち直さなきゃいけないんだな。
めんどくせー。
ま、OpenBSDなんてさわることは多分ないからいいけど。
Re:めんどくせーな (スコア:2, おもしろおかしい)
duasって打ち直さなきゃいけないんだな。
コマンドがありません
Re: (スコア:0)
あー、うん。
慣れないコマンド名だとそういうことになるから、めんどくせーな、と。
Re: (スコア:0)
これからは sudo -u root doas -u root su - などとするんですね
# 某所でそんなスクリプトを見たのでAC
Re:めんどくせーな (スコア:1)
最初に一回 sudo bash と入力してたのが、doas bash に変わるだけですよ。
Re: (スコア:0)
もうrootでログインしたらいいんじゃね? ぜんぜんWindowsを笑えねーな。
Re: (スコア:0)
duas: コマンドが見つかりません.
Re: (スコア:0)
シェルスクリプト書くなりalias定義するなりすればいいじゃん…
須藤さんクビかー (スコア:0)
そうやって日本人をクビにする・・・
Re: (スコア:0)
後藤さんも迫害されてるし
Re: (スコア:0)
RubyやVBでバリバリ働く俺遠藤。
Re: (スコア:0)
国際結婚してDoasさんになっただけよ。