シェルスクリプトでルート権限を削除するにはどうすればよいですか?


13

OpenVPNの「--up」オプションは、通常、ルーティングなどに使用されます。したがって、OpenVPNがルート権限を削除して誰としても実行されない前に処理されます。ただし、非特権ユーザーとして実行する必要があるシェルスクリプトを呼び出しています。

それ、どうやったら出来るの?私が研究しているドロッププロセス特権、特に多項式のとtylerlの答えを、私は実装する方法を理解していません。私はCentos 6.5で作業していますが、「chmod u + s」と「setuid()」の両方として、suidがブロックされています。

OpenVPNプラグイン( "openvpn-down-root.so")があります。これにより、 "-down"オプションによって呼び出されたスクリプトをrootとして実行できます。「openvpn-up-user.so」などの同等のものがありますが、見つかりませんでした。

編集0

Nikola Koturの答えに従って、Ian Meyerのrunit-rpmをインストールしました。chpstコマンドは端末で機能しますが、アップスクリプトでは「command not found」で失敗します。動作するのは、「sudo chpst」に加えて、適切な表示と言語の設定です。端末がユニコード文字を正しく出力しないのなぜですか?をご覧くださいそのため、upスクリプトには次の4行が必要です。

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &

編集1

0xC0000022Lのコメントごとに、「sudo -u user」は「sudo chpst -u user -U user」と同様に機能することがわかりました。

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &

私は男のスーダーを研究し、sudoを単独で使用する場合は更新します。


@ user66229が残したコメント:「sourceforge.net/p/openvpn/mailmanにアクセスして、最適なリストを購読することをお勧めします。」
slm

@ user66229ありがとうございます。しかし、これはOpenVPN固有の質問だとは思わない。なぜだと思いますか?
mirimir

回答:


7

このようなタスクにはrunitchpstツールを使用します。たとえば、upスクリプトから特権のないスクリプトを呼び出します。

chpst -u nobody /path/to/script

クール:)ありがとう。あるgithub.com/imeyer/runit-rpm CentOSに6.5にRUNIT取得するための最良の方法は?Red Hatリポジトリを使用しても、パッケージが見つかりません。
mirimir

@mirimir、はい、CentOS用のrunitパッケージをビルドする必要があるときに、このレポを使用します。
ニコラコトゥール

10

runitとsudoミスのみをカバーしています。runitのようなツールセットのファミリーが実際にあり、まさにこれを行うためのツールの幅広い選択肢があります。

  • ダニエル・J・バーンスタインのデーモンツールには、次のものがありますsetuidgid

    setuidgidユーザー/home/user/unprivileged.sh
  • Adam Sampsonのfreedtにはsetuidgid次のものがあります。

    setuidgidユーザー/home/user/unprivileged.sh
  • Bruce Guenterのdaemontools-encoreにはsetuidgid

    setuidgidユーザー/home/user/unprivileged.sh
  • Gerrit Papeのrunitにはchpst次のものがあります。

    chpst -u user /home/user/unprivileged.sh
  • ウェインマーシャルのperpにはrunuid

    runuidユーザー/home/user/unprivileged.sh
  • Laurent Bercotのs6にはs6-setuidgid次のものがあります。

    s6-setuidgidユーザー/home/user/unprivileged.sh
  • 私の鼻は持っていますsetuidgid

    setuidgidユーザー/home/user/unprivileged.sh

特権を追加するさまざまなタスクを混在させることはなく、対話モードに陥ることはありません。

あなたのタックオンの問題は、あなたが持っsbinているのを忘れているだけでなくbin、あなたのにありますPATH

参考文献


3

特権をドロップし、他のスクリプトを実行するスクリプト(ただし、ここでは自分自身を実行するようにしました):

#!/bin/sh

id=`id -u`
safeuser="nobody"

if [ $id = "0" ]
then
         # we're root. dangerous!
        sudo -u $safeuser $0
else
    echo "I'm not root"
    id
fi

例:

root@n3:/tmp/x# id
uid=0(root) gid=0(root) группы=0(root)
root@n3:/tmp/x# ./drop.sh
I'm not root
uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)

「sudo -u user」を使用すると一部のコマンドで機能しますが、私の目的には十分なユーザー環境が提供されません。また、「su -l user」は端末では正常に機能しますが、スクリプトでは何もしません。これはセキュリティ機能だと思います。だから、runitのインストールが残っているようです。
mirimir

1
@mirimir:なぜですか?どの環境変数を実行するプログラムに伝えることができるかなど/etc/sudoers非常に具体的にすることができますsudoman sudoers。正直なところ、誰でも使用するsudoためにのみsudo su -、この素晴らしいプログラムの背後に何があるかについての手掛かりを持っていないし、どのくらいあなたは、個々のプログラム、ユーザー、ホストなどのために物事をロックダウンすることができますスイッチのユーザーコンテキストまたはに...
0xC0000022L

@ 0xC0000022Lありがとう。sudoをもう一度見てみました。はい、「sudo -u user」に加えてディスプレイと言語も機能します。
mirimir 14年

1
危険といえば、あなたは信用できない$0。呼び出し元は、スクリプトの文字$0列を文字通り何にでも設定できます。さらに引用符を使用します。
チャールズダフィー

2
スクリプトのであれば... $0である/directory/name with spaces/script(そして、彼らはあっても、ユーザーは、自分の所有する場所に任意のシンボリックリンクを作成することができ、覚えていない使用exec -a somename yourscript呼び出すようにyourscriptして$0somename、あなたが取得したい、)sudo -u nobody /directory/name with spacesと、withそしてspacesあなたのコマンドに別々の引数として渡さ。
チャールズダフィー

1

どうですか:

sudo -Eu <user> <command>

前のコメントで環境について不平を言っていたので、出力間の違いを比較することもできます。

sudo -u <user> printenv
sudo -Eu <user> printenv

1

Linuxでは、PAMセッションが不要な場合runuserまたは使用できますsetpriv(両方からutil-linux):

runuser -u USER [--] COMMAND [ARGUMENTS...]

setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...]  # Like su/runuser/sudo
setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...]  # Like daemontools setuid(8)

sumanページから:

suは主に非特権ユーザー向けに設計されています。特権ユーザー(rootによって実行されるスクリプトなど)の推奨ソリューションは、認証を必要とせず、個別のPAM構成を提供する非set-user-IDコマンドrunuser(1)を使用することです PAMセッションがまったく必要ない場合は、コマンドsetpriv(1)を使用することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.