web-dev-qa-db-ja.com

Linuxで「kill」コマンドを無効にする方法

すべてのkillコマンド(rootユーザーを含む)を無効にしたい。権限を変更しようとしましたが、実行できます。それを行う方法はありますか?

5
xxlali

killrootを「無効にする」ことは、たとえ可能であったとしても、システムスクリプトの誤動作などの望ましくない副作用が発生する可能性が高く、最悪の(可能性が高い)シナリオでは、コンピュータが適切に起動しない(またはシャットダウンが正しく行われる)。

ユーザーにとっても、問題が発生します。たとえば、非特権ユーザーとして実行するスクリプトがあり、kill -0 $pidを使用して特定のプロセスが実行されているかどうかを確認します。これらのスクリプトは機能しなくなります。

自分では、aliaskillコマンドをecho "kill"のような他のコマンドに渡すことができます。

$ alias kill='echo "kill"'

それは少なくともkillがコマンドラインで有用なことをするのを防ぎます:

$ kill -s HUP $$
kill -s HUP 11985
54
Kusalananda

このカーネルモジュールを使用して、AMD64killシステムコールを無効にします。
自己責任。壊滅的な副作用が予想されます。

#include <linux/module.h>

MODULE_LICENSE("GPL");

int __init init(void) __attribute__((noreturn))
{
     unsigned long long cr0 = read_cr0();
     write_cr0(cr0 & ~(1 << 16));  /* Clear Write Protection (WP) bit */
     *(unsigned char *)sys_kill = 0xc3;  /* opcode for "ret" */
     write_cr0(cr0);

     /* This makes sure that delete_module below won't complain */
     __this_module.refcnt = 1;
     __this_module.state = MODULE_STATE_LIVE;

     asm volatile
     (
          "mov %0, %%rsp\n\t" /* It seems GCC refuses to mess with the stack pointer */
          "jmp sys_delete_module\n\t"  /* call delete_module(name, flags) */
          :: "r"(current->stack + THREAD_SIZE - sizeof(struct pt_regs) - 8), "D"(__this_module.name), "S"(0) :
     );
}

void __exit exit(void)
{
    return;
}

他のモジュールと同じようにコンパイルします。次に、insmodを使用します。

65
user69874

システムスクリプトで使用されるため、すべきではありませんシステム全体で無効にします(たとえば、initscriptsパッケージの/etc/init.d/functionsで)。

ログインシェルの場合(およびそのサブシェルの場合)は、 alias 'をtrue/false(またはkill_disabledのようなもの)にすると無効にできますno-opではなくエラーを取得したい)。

この方法は絶対確実ではないことに注意してください。直接実行されるコマンドにのみ影響します(スクリプト内のコマンドには影響しません)。また、ユーザーはunaliasを使用してエイリアスを削除できます。


これを行うには、次のコマンドを実行します

alias kill=kill_disabled

または、適切な bash起動ファイル に追加して、ログインごとに実行します。

ここで、killをインタラクティブに実行すると、以下が生成されます。

$ kill 9999
-bash: kill_disabled: command not found

私が言ったように、上記の方法は簡単に破壊されます。誰にでもできる方法が必要な場合、唯一の解決策は、ログインシェルセッション全体を chroot 環境で実行することです。それでも、直接syscallではなく、stockコマンド、のみが無効になりますが、行われます。後者は無効にすることはできません。通常の操作(たとえば、 CtrlCSIGINTを送信し、パイプにはSIGPIPEが必要であり、バックグラウンドプロセスは5つ以上の異なる信号で制御されます)。 chroot環境のセットアップは高度なタスクであり、ユーザーがファイルシステム全体にアクセスする必要がある場合、通常は不便です。

7
ivan_pozdeev

ユーザーが特定のプログラムを強制終了しようとする場合を除いて、ユーザーがkillを通常どおりに使用できるようにするには、ユーザープロファイルの.bashrckill関数を定義できます。この関数内で、ユーザーがプログラムを強制終了しようとしているかどうかを確認します。そうでない場合は、関数自体からkillユーティリティを呼び出すことができます。

例として、sleepユーティリティを強制終了しないが、提供されている他のパラメータの通常の強制終了ユーティリティとして機能する小さなkill関数を作成しました。

function kill() {
    process=$(ps -p "${@: -1}" | awk 'END{print $(NF)}');
    if [[ $process == "sleep"]]
    then
        echo "Killing $process is not allowed"
    else
        /bin/kill $@
    fi
}