少し叙情的な紹介
どういうわけか、奇妙なもの、つまりユーザーが
Campingマイクロフレームワークに基づいてWebアプリケーションを単独でダウンロードして実行できる管理しやすいホスティングが必要な顧客がいました。 そして、nginx、thinサーバー、およびezjailをjail管理ツールとして使用して、FreeBSD 9.0を実行する仮想サーバーで提案しました(すべてが非常に簡単ですが、興味のある方は説明します)。 1週間後、顧客は実際にAppleソリューションのファンであり、Mac OS Xを実行しているメインサーバーで同じシステムが実行されていることを望んでいることを認めました。そして、私は以前に触れた喜びがなかったため、ソリューションを適応させることに喜んで同意しましたこのシステムと少なくとも少しそれを勉強したかった。 「しかし」たった1つしかありませんでした-MacOS X Serverには刑務所はありません(8)。 そこで、ユーザーがロードしたアプリケーションを可能な限り安全に実行するソリューションを探して(多くの理由でchrootを使用することはできなかったし、したくありませんでした)、システムに非常に柔軟で完全に統合されたツール
Sandboxを見つけました。
ホスティングの基盤を構築する
サンドボックス
サンドボックスは素晴らしいツールであることが判明しました。 AppArmorを連想させるもの、多少SeLinuxですが、実際に動作するために必要以上の機能を提供せず、アプリケーションをチェックし続ける完全にユニークな方法です。 サンドボックスポリシーを適用する方法は、サンドボックスでアプリケーションを起動し、このアプリケーション用に以前に記述されたプロファイル(セキュリティポリシーの説明を含むテキストファイル)へのパスをオプションとして渡すことです。 残念ながら、Sandboxは私が慣れているよりも
文書の質がやや劣り
ます (FreeBSDハンドブックの詳細が壊れています)が、ネットワーク上で特定のプロファイルを記述する多くの例があり、それがタスクをはるかに容易にしました。 軽量の
Thin rubyアプリケーションサーバーのプロファイル、その使用方法を記述する必要がありました。以下で説明します。 すべてのプロファイルは、マークアップ言語バージョンの宣言で始まり、できればデフォルトポリシー(この場合は明らかに禁止されています)で始まります。 すべてのディレクティブまたはそのセットは括弧で囲まれています。 ポリシー名(または「操作」-操作)はマスク(ワイルドカード-*)をサポートし、ルールの範囲を拡大します。 フィルター(パスネットワークファイルモードxattrマッハ信号の6つのみ)は、ルールに従って設定されます(詳細については、構文を参照して
ください )。 たとえば、文字列、正規表現(regex)、文字列でパスを指定できます。英語をトレースすることを許してください、「サブパス」。 すべてのコメントは「;」で始まります。
; ; Sandbox profile for application owned by virtual (non-system) user XXXXXX ; (version 1) ; (deny default) ; ; (, unix-). ; , ; unix- (allow network-bind) ; Thin (. ) ; , fork() (allow process-fork) ; DirectoryService ; , . (allow mach-lookup (global-name "com.apple.system.DirectoryService.libinfo_v1") (global-name "com.apple.system.DirectoryService.membership_v1") ) ; Thin-, ruby ; - - , ;-) (allow process-exec (regex "^/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr") (regex "^/usr/bin/thin$") ) ; , file-read ; , regex ^/opt/sandbox/apps/XXXXXX ; - , - (allow file-read-metadata (literal "/opt/sandbox/apps/XXXXXX/log") (literal "/opt/sandbox/apps/XXXXXX/tmp") ) ; gem', (allow file-read* (literal "/usr/bin/thin") (regex "^/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr") (regex "^/System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent") (regex "^/Library/Ruby/Gems/1.8/") (regex "^/usr/lib") (regex "^/opt/sandbox/apps/XXXXXX") ) ; , - . (allow file* (regex "^/opt/sandbox/apps/XXXXXX/tmp/thin.sock$") (regex "^/opt/sandbox/apps/XXXXXX/tmp/thin.pid$") (regex "^/opt/sandbox/apps/XXXXXX/log/thin.log$") )
薄い
Thinは、カスタムCampingアプリケーションを実行するために選択されました。 なぜMongrel、Passenger、uWSGIなどではなく、Thinですか? 彼は必要なすべての機能をサポートし、リソースをあまり要求しませんでした(ただし、深刻な研究はしませんでした)。 さらに、どういうわけかアプリケーションを単独で実行するような方法でPassengerを準備する方法を見つけることができませんでしたが、おそらく何らかの方法で可能だったでしょう(異なるユーザーに代わってnginxの多くのコピーを実行するオプションを取りません、このオプションは考慮されましたが、マークされていました)、コメントの誰かが実用的なソリューションを提案している場合、私は見て喜んでいます。 私のお気に入りの収穫機-最後のヒントからのuWSGI-は、FreeBSD(開発者に通知され、数日以内にすべてが修理されましたが、残念ながら、列車は去りました)およびMacOS Xのラックアプリケーションで正しく動作することを拒否しましたまったく何もしません。 Mongrelは試す時間はなく、Thinに立ち止まって、本当にうまくいきました。 そのため、ThinコンテナでのCampingラックベースアプリケーションの起動ラインは次のとおりです。
cd /opt/sandbox/apps/XXXXXX && \ sandbox-exec -f /opt/sandbox/profiles/XXXXXX.sb \ /usr/bin/thin --socket /opt/sandbox/apps/XXXXXX/tmp/thin.sock \ --rackup /opt/sandbox/apps/XXXXXX/approot/config.ru \ --environment production --timeout 4 --chdir /opt/sandbox/apps/XXXXXX/approot \ --log /opt/sandbox/apps/XXXXXX/log/thin.log \ --daemonize --pid /opt/sandbox/apps/XXXXXX/tmp/thin.pid \ --user thinbot --group thinbot --tag XXXXXX start
「タグ」オプションを使用すると、すべてのリソースを正確に食べたトップとpsを見ることができます(システムユーザーはすべての起動に単独で使用されます)。
Nginx
すべてが簡単です。 統計なし。 ホスティングの仮想「ユーザー」の名前は、それに割り当てられたサブドメインと同等です。
server { server_name ~(.+).domain.tld; set $user $1; location / { proxy_pass http://unix:/opt/sandbox/apps/$user/tmp/thin.sock:/; } }
スクリプトバインディング
私はshを使用してバインディングを設計しました。シンプルでポータブルなものが好きだからです。 批判は大歓迎です。スクリプトはかなり湿っています。 スクリプトはルート(root)として実行されることを前提としています。
仮想ユーザー管理
-users_management.sh:
ユーザーアプリケーション管理
-application_management.sh:
おわりに
Sandboxはかなり強力なサンドボックスであり、Mac OS Xをサーバープラットフォームとして普及させるのに役立つと思います。
PS:
Habrahabrサイトの管理に感謝します。これにより、ネガティブなカルマでも投稿を公開できました。 この記事に対する聴衆の態度があまり厳しくないことを本当に願っています-これがHabréでの私の最初の実際の投稿です-そして、私は書き続けることを望みます。 近い将来、私はそのようなトピックについて書くと思います。DjangoアプリケーションのパッチのインスタントWebプレゼンテーションのためのgitフックと帝国のuWSGIモードの使用。 uWSGIは、柔軟性のある1つのホスティング言語に限定されない、柔軟なWebアプリケーションコンテナを作成します。 Informix DBMSの全国展開の機能。 しかし、あなたが思いとどまれば、私はしません。
みんなありがとう。