2

元の質問

とりわけ、システムの/etc/hostsファイルとnginx構成を編集できるLispライブラリを作成しようとしています。私が直面している問題は、私の Lisp イメージが非特権ユーザーとして動作するため、私のライブラリがこれらのことを実行できないことです。理想的には、root 権限が必要になったときに、ライブラリにパスワードを提供して、物事を成し遂げるためにアクセス権を一時的に引き上げることができるようにします。残念ながら、Common Lisp で に相当するものを見つけることができませんでしたsudo。ありますか?私はこれに間違った方法でアプローチしていますか? これを解決するにはどうすればよいですか?

コードでは、私ができるようにしたいのは基本的にこれです:

(with-sudo (:username "root" :password (securely-read-line))
  (with-open-file (f "/etc/hosts" :direction :output :if-exists :append)
    (format f "127.0.0.1 mywebsite.local~%")))

明確化

OS X で SBCL を使用しています。基本的に Web サイト用の QuickProject の特殊化であるライブラリを作成しようとしています。現在、ローカル コンピューターで新しい Web プロジェクトをセットアップするたびに、システム全体に散らばっている構成ファイルを編集する必要があります。私はそれを可能な限り自動化したいと考えており、通常開いて SBCL の単一のインスタンスに接続している SLIME セッション内からこれを実行できるようにしたいと考えています。

その他の考慮事項を次に示します。

  1. setuidSBCL のメイン インスタンスをrootにしたくない
  2. それが小さな C プログラムであろうと、数行のコードをロードして終了する SBCL の裸のインスタンスであろうと、新しいプロセスを生成することは気にしません。
  3. Lisp と C の比率をできるだけ高く保ちたいと思います。
  4. 一部のテキスト エディター (TextMate など) は、閲覧に高い権限が必要なファイルにアクセスすると、ユーザー名とパスワードを求めるプロンプトを表示し、それに応じてアクセスを許可します。Lisp ライブラリに同じことをさせるにはどうすればよいのだろうか?
  5. sudo最初は、 (実際のプログラム自体) を SBCL 内から動作させることができませんでした:

    (inferior-shell:run/ss '("sudo" "ls" ".")) ;; how can I pass sudo a password?

    sudoのオプションを使用すると、それが可能になるよう-Sです (JustAnotherCurious に感謝します)。私はこの道を行くかもしれないと思います。それは間違いなく私が今傾いているものです。

とにかく、みんなありがとう!私は皆さんから多くのことを学んでいます。

4

5 に答える 5

5

プロセスで root アクセス権限が必要な場合は、Lisp プロセスを最初に root として開始する必要があります。一般に、振り返ってみると、ルート以外のプロセスを実行することはできません。

幸いなことに、Unix には、実行時にプロセスが root 権限と非 root 権限を切り替えることができるメカニズムがあります。そのメカニズムは実効ユーザー ID と呼ばれます。seteuidroot として実行されるプロセスは、システム コールを使用して非 root の有効な uid に切り替えることができます。

確かに、Lisp プロセスをルートとして開始すると、そのプロセスはマシンを完全に制御できます。扱うデータとマシンによっては、それによってどのようなセキュリティ ホールが開く可能性があるかを考慮する必要があります。幸いなことに、Lisp でバッファ オーバーフローを生成するのは難しいため、その観点からは、より安全な側にいます :)

システム コール インターフェイスへのアクセスは Common Lisp では標準化されていませんが、ほとんどの実装にはシステムへのネイティブ インターフェイスがあり、プログラムを Linux/Unix ベースの Lisp 間で移植できるようにする場合は、CFFIを使用することもできます。

以下は、root として実行されている SBCL のトランスクリプトであり、seteuidの使用を示しています。

CL-USER> (defun write-file-in-filesystem-root ()
           (handler-case
               (with-open-file (f "/only-root-may-write-to-root"
                                  :direction :output
                                  :if-exists :supersede)
                 (write "hello" :stream f))
             (error (e) (format t "error: ~A~%" e))))
WRITE-FILE-IN-FILESYSTEM-ROOT
CL-USER> (sb-posix:seteuid 0)
0
CL-USER> (write-file-in-filesystem-root)
"hello"
CL-USER> (sb-posix:seteuid 1000)
0
CL-USER> (write-file-in-filesystem-root)
error: error opening #P"/only-root-may-write-to-root": Permission denied
NIL
CL-USER> (sb-posix:seteuid 0)
0
CL-USER> (write-file-in-filesystem-root)
"hello"
CL-USER> (delete-file "/only-root-may-write-to-root")
T

保護されたファイルへのアクセスのみが必要な場合、OSX 固有のままでよい場合、および標準の認証リクエスターを使用してユーザーを認証する場合は、OSX 固有のauthopenコマンドを使用できます。

于 2013-03-29T10:58:15.067 に答える
3

まず、Linux のパーミッション システムに違反することはできませんし、違反するべきではありません。パーミッションと認証システムを悪用する方法があれば、それは巨大なセキュリティ ホールになります。事実上、誰もがルート アクセス権を持つことになります。そのような不安が欲しいなら、MSDOS に戻ってください!

次に、システムを構成して、ほとんどすべてに root アクセスを許可することができます。sudoまたはコマンドがパスワードを要求しないように構成することもできsuperます (一部のマシンでは実際に意図的にそうしていますが、それがセキュリティ ホールである、または悪用される可能性があることはわかっています)。これは、その  sudoコマンドを実行しているエンティティ (人間またはプログラム) を信頼することを意味します。

また、一部のプログラム (例: /bin/login、....) はsetuid/usr/bin/sudoにすることができ( credentials(7)およびexecve(2)のマニュアル ページも参照)、Common Lisp の実装でsetuid(2)またはsetreuid( 2) syscalls (または、自分でC syscall を呼び出すラッパーを作成することもできます)。/usr/bin/super

127.0.0.1 mywebsite.localただし、エントリを/etc/hosts;に追加したいだけのようです。なぜそのようなエントリを前提条件にできないのですか (したがって、Common Lisp ソフトウェアをインストールするための人間の手順では、人間のシステム管理者にそのようなエントリを追加する必要があります)。次に、名前を Common Lisp プログラムに渡す方法を用意するだけで済みmywebsite.localます。これは簡単なはずです。

Common Lisp で書かれたsetuidバイナリ プログラムを使用しないように警告します。なぜなら、特別な注意を払わない限り、ほとんどの Common Lisp バイナリには (間接的にeval) Common Lisp コンパイラ全体が含まれているからです。また、Common Lisp (例: SBCL) のような動的で強力なコンパイラへのルート アクセス権を与えることは、セキュリティ ホールです。

mywebsite.localプログラムでCommon Lisp ライブラリからを追加することに固執する場合/etc/hostsは、小さなCヘルパー プログラムを作成できます。その実行可能ファイル/usr/local/libexec/helperbinaryは、たとえば root- setuidです (つまりchown root /usr/local/libexec/helperbinaryインストールchmod u+s /usr/local/libexec/helperbinary時に、これらとを実行するには明らかに root になる必要があります)。はまさにこれを行い、Common Lisp バイナリからのみ (適切なトリックを介して) 開始することができます。その小さなヘルパー プログラムをCでコーディングするときは十分に注意してください。たとえば、Advanced Linux Programmingを読んだり、 Cコードを数回校正したりします( setuidプログラムにセキュリティ ホールを簡単に作成できます)。chownchmod

于 2013-03-29T09:44:45.650 に答える
2

問題は、アクセス権を「強化」していないことです。スーパーユーザー権限で開始し、不要になったら削除します (参照しているプログラムは、これを達成するためにsetuid rootsudoとマークされています)。

したがって、達成したいことは、LISP インタープリターをルートとして開始し、別のインタープリター プロセスを fork させ、そのプロセスにスーパーユーザー権限をすぐにドロップさせることです。そこから、非特権プロセスは通常どおりコードを実行し、IPCを使用して特権プロセスに書き込み/etc/hostsます。

残念ながら、これを実装するのは簡単ではありません。

于 2013-03-29T09:13:31.800 に答える
2

ルートアクセスを伴うアクションがいくつかの小さくて簡単なアクションに制限されていて、プラットフォーム固有のコードを書くことが許可されている場合、それはうまくいくと思います.sudoを使用してコードからbash(または他のシェル)コマンドを実行しようとすることができます. -S.

須藤男より

The -S (stdin) option causes sudo to read the password from 
the standard input instead of the terminal device. 
The password must be followed by a newline character.

でも、そんなことは絶対にしないほうがいいと思います。

于 2013-03-29T09:52:06.477 に答える