Linuxのサンドボックスで信頼できないCプログラムを実行する方法があるかどうか疑問に思っていました。プログラムがファイルを開いたり、ネットワーク接続したり、フォークしたり、実行したりするのを妨げる何か?
サーバーにアップロードされ、ユニットテストが実行される小さなプログラム、宿題です。したがって、プログラムは短命です。
Linuxのサンドボックスで信頼できないCプログラムを実行する方法があるかどうか疑問に思っていました。プログラムがファイルを開いたり、ネットワーク接続したり、フォークしたり、実行したりするのを妨げる何か?
サーバーにアップロードされ、ユニットテストが実行される小さなプログラム、宿題です。したがって、プログラムは短命です。
回答:
Systraceを使用して、信頼できないプログラムを対話型モードと自動モードの両方でサンドボックス化しました。ptrace()
Linuxベースのシステムで特別な権限なしで使用できるようにする- ベースのバックエンドと、カーネルにパッチを当てる必要があるはるかに高速で強力なバックエンドがあります。
を使用してUnixライクなシステムでサンドボックスを作成することもできますが、chroot(1)
これはそれほど簡単でも安全でもありません。LinuxコンテナーとFreeBSDの刑務所は、chrootのより良い代替手段です。Linuxのもう1つの代替手段は、SELinuxやAppArmorなどのセキュリティフレームワークを使用することです。これは、私が本番システムに提案するものです。
やりたいことを具体的に教えていただければ、もっとお手伝いできます。
編集:
Systraceはあなたのケースで機能しますが、ディストリビューションによっては、AppArmorやSELinuxなどのLinuxセキュリティモデルに基づくものがより標準的であり、したがって、推奨される代替手段であると思います。
編集2:
一方でchroot(1)
(?すべて)Unixライクなシステムほとんどで利用可能ですが、それはかなりの数の問題があります。
壊れる可能性があります。システムで信頼できないCプログラムを実際にコンパイルまたは実行する場合は、この問題に対して特に脆弱です。そして、あなたの生徒が私のようなものであるなら、誰かが刑務所から抜け出そうとします。
タスクに必要なすべてのもので完全に独立したファイルシステム階層を作成する必要があります。chrootにコンパイラーを置く必要はありませんが、コンパイルされたプログラムを実行するために必要なものはすべて含める必要があります。これを助けるユーティリティはありますが、それはまだ簡単ではありません。
chrootを保守する必要があります。独立しているため、chrootファイルはディストリビューションとともに更新されません。chrootを定期的に再作成するか、必要な更新ツールをその中に含める必要があります。これには、本格的なLinuxディストリビューションである必要があります。また、システムデータとユーザーデータ(パスワード、入力ファイルなど)をホストシステムと同期させておく必要があります。
chroot()
ファイルシステムのみを保護します。悪意のあるプログラムがネットワークソケットを開いたり、悪質なプログラムが利用可能なすべてのリソースを吸い上げたりするのを防ぐことはできません。
リソース使用量の問題は、すべての選択肢で共通です。ファイルシステムクォータは、プログラムがディスクをいっぱいにするのを防ぎます。適切なulimit
(setrlimit()
Cでの)設定は、メモリの過剰使用やフォーク爆弾から保護するだけでなく、CPUの負荷を抑えることができます。nice(1)
これらのプログラムの優先度を下げることができるので、コンピュータは問題なくより重要と思われるタスクに使用できます。
最近、Linuxのサンドボックステクニックの概要を書きました。あなたの最も簡単なアプローチは、フォークなどを気にしないのであれば、Linuxコンテナー(lxc)を使用することだと思いますが、この環境ではそれほど重要ではありません。プロセスに読み取り専用のルートファイルシステム、分離されたループバックネットワーク接続を与えることができ、それでも簡単に強制終了してメモリ制限などを設定できます。
Seccompはコードがメモリを割り当てることさえできないので、少し難しいでしょう。
Selinuxはもう1つのオプションですが、コンテナーよりも作業が多いと思います。
Qemuを使用して、割り当てをすばやくテストできます。以下のこの手順は、私の5年前のラップトップで5秒未満かかります。
学生が、「-1」の行が到着するまで、それぞれが独自の行にある符号なし整数を受け取るプログラムを開発する必要があると仮定します。次に、プログラムはすべてのintを平均し、「平均:%f」を出力します。完全に分離されたプログラムをテストする方法は次のとおりです。
まず、root.bin
Jslinuxから取得します。これをユーザーランドとして使用します(tcc Cコンパイラーがあります)。
wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
生徒の提出物をに入れたいroot.bin
ので、ループデバイスをセットアップします。
sudo losetup /dev/loop0 root.bin
(これにもfuseext2を使用できますが、あまり安定していません。安定したら、rootは必要ありません)
空のディレクトリを作成します。
mkdir mountpoint
マウントroot.bin
:
sudo mount /dev/loop0 mountpoint
マウントされたファイルシステムを入力してください:
cd mountpoint
。
修正権:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:
#!/bin/sh
cd /root
echo READY 2>&1 > /dev/ttyS0
tcc assignment.c 2>&1 > /dev/ttyS0
./a.out 2>&1 > /dev/ttyS0
chmod +x etc/init.d/rcS
提出物をVMにコピーします。
cp ~/student_assignment.c root/assignment.c
VMのルートFSを終了します。
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
別のターミナルを開いて、ゲスト出力のリスニングを開始します。
dd if=/tmp/guest_output bs=1
別のターミナルで:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(ここではUbuntuカーネルを使用しましたが、多くのカーネルが機能します)
ゲストの出力に「READY」と表示されたら、qemuプロンプトからVMにキーを送信できます。たとえば、この割り当てをテストするには、次のようにします
(qemu) sendkey 1
(qemu) sendkey 4
(qemu) sendkey ret
(qemu) sendkey 1
(qemu) sendkey 0
(qemu) sendkey ret
(qemu) sendkey minus
(qemu) sendkey 1
(qemu) sendkey ret
これAverage = 12.000000
で、ゲスト出力パイプに表示されます。そうでない場合、学生は失敗しました。
quit
テストに合格したプログラムは、https://stackoverflow.com/a/14424295/309483です。のtcclib.h
代わりに使用してくださいstdio.h
。
ユーザーモードLinuxをお試しください。CPUを集中的に使用するジョブの場合、パフォーマンスオーバーヘッドは約1%ですが、I / Oを集中的に使用するジョブの場合は6倍遅くなる可能性があります。
Firejailは、そのための最も包括的なツールの1つです。seccomp、ファイルシステムコンテナー、機能などをサポートしています。
仮想マシン内で実行すると、必要なセキュリティと制限がすべて提供されます。
QEMUはこれに適しています。すべての作業(アプリケーションのダウンロード、ディスクイメージの更新、QEMUの起動、内部でのアプリケーションの実行、後で取得するための出力の保存)は、自動テスト実行用にスクリプト化できます。
ptrace(strace)チェックアウトに基づいてサンボクシングを行う場合:
" sydbox " sandboxおよび " pinktrace "プログラミングライブラリ(C99ですが、PythonとRubyへのバインディングは私の知る限りです)。
トピックに関連する収集されたリンク:
http://www.diigo.com/user/wierzowiecki/sydbox
(申し訳ありませんが、直接のリンクではありませんが、まだ十分な評判ポイントがありません)
これも有望なようです。syscallインターセプトを使用したLinux用のファイルシステムサンドボックス。
彼らが私を助けてくれたすべての答えに感謝します。しかし、私は元の質問をした人のための解決策としてそれらのどれも提案しません。言及されたすべてのツールは、教師、家庭教師、教授として生徒のコードをテストするために多くの作業を必要とします。この場合の最良の方法は、私の意見のvirtualboxです。OK、それは完全なx68システムをエミュレートし、このようにサンドボックス化の意味とは何の関係もありませんが、私のプログラミングの先生を想像すれば、彼にとっては最高でしょう。したがって、Debianベースのシステムで「apt-get install virtualbox」を実行すると、他のすべてのユーザーはhttp://virtualbox.org/にアクセスし、VMを作成し、ISOを追加して、[インストール]をクリックし、しばらく待ってから幸運です。user-mode-linuxをセットアップしたり、重いstraceを実行したりする方がはるかに簡単です...
そして、あなたがあなたの生徒をハッキングするのを恐れているなら、私はあなたが権威の問題を抱えていると思います、そしてそれに対する解決策は、彼らが与える仕事で男性器の一口だけを証明できるなら、あなたが彼らから生きている日光を訴えることになると彼らを脅かすでしょう君は...
また、クラスがあり、その1%が彼がそのようなことをするのと同じくらい良い場合、そのような単純なタスクでそれらを退屈させないでください。統合学習は誰にとっても最適なので、古いデッドロック構造を中継しないでください...
そして当然のことながら、ウェブの閲覧やソフトウェアのテストなどに使用しているのと同じコンピュータを、証明や試験の作成などの重要なものに使用しないでください。
重要なことにはオフラインコンピュータを使用し、その他すべてにはオンラインコンピュータを使用します。
しかし、偏執的な教師ではない他のすべての人にとって(誰も気分を害したくない、プログラマーの教師になる前にセキュリティと私たちの社会についての基本を学ぶべきだという意見です...)
...私はどこにいましたか...他の皆のために:
ハッピーハッキング!!