setuidジョブを正しく実行する方法は?

setuidジョブを正しく実行する方法は?

PHPのウェブサイトがあり、ウェブサイトのコードの実行に基づいてファイアウォールレベルでIPをブロックしたいとしましょう。サイトは root ではなくユーザーとして実行されます。

サイトコードのIPをスクリプト(ルートにのみ書き込むことができます)に渡す予定です。

#!/bin/bash
function validate_ip()
{ ... code here ...}
if validate_ip $1; then 
    /usr/sbin/iptables -I INPUT -s $1 -j DROP
    echo 'blocked'; 
else 
    echo 'bad IP $1'; 
fi

suidビットを使用してください。 XSSやその他の悪い問題(必要に応じて編集可能な考え)を避けるために追加のIP検証を追加したいので、Webサイトからiptablesを直接呼び出すことは望ましくありません。

スクリプトが機能しませんcan't initialize iptables table 'filter': Permission denied (you must be root)bash は suid ビットを削除します。

回避策があります。許可sudoのiptablesしかし、私はそれが安全だとは思わない。そのタスクを実行できるバイナリを開発/購入する時間/可能性はありません。誰かがスクリプトをバイナリにラップすることを提案しましたが、躊躇しました。より良い方法がありますか?

したがって、質問は、ルート以外のアプリケーションが安全な方法でファイアウォールでiptables IPをブロックできるようにする方法です。

答え1

bash スクリプト suid ルートを作成する代わりに、sudo で bash スクリプトを実行します。追加の利点により、rootとしてスクリプトを実行できる人と渡されるパラメータを簡単にロックできます。たとえば、次のように許可できます。

phpuser ALL=(root) NOPASSWD: /usr/local/sbin/your-script [0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9]

次に、PHPスクリプトが常に各IPアドレスオクテットの形式を3桁の数字で指定していることを確認してください。

PHPがsudoを呼び出すのが難しい場合(そうではありません!)、スクリプトを直接呼び出すことができます。たとえば、次のようになります。

#!/bin/sh

[ "$(id -u)" -eq 0 ] || exec sudo -- "$0" "$@"
# rest of script here

(iptablesが前のゼロを満たすかどうかはわかりません。そうしないと削除できます。)

PS:シェルスクリプトから変数を引用してください。

if validate_ip "$1"; then 
    /usr/sbin/iptables -I INPUT -s "$1" -j DROP
    # ⋮

関連情報