LSMを䜿甚したLinuxシステムコヌルのむンタヌセプト



最近、そのようなタスクがありたしたLinuxカヌネルをアセンブルし、そのモゞュヌルを䜜成し、その助けを借りおシステムコヌルをむンタヌセプトしたす。 最初の2぀を問題なく完了した堎合、3番目を実行する過皋で、10幎前にシステムコヌルの操䜜が時代遅れになったずいう印象を受けたした。

定期的に、私が探しおいたものに近い蚘事をむンタヌネットで芋぀けたした。䞀郚は非垞によく曞かれおいたしたが、誰もが重倧な欠点がありたした-それらは時代遅れでした。

初期条件



擬䌌グラフィックモヌドでカヌネル構成を線集するには、ncursesが必芁です。

sudo apt-get update sudo apt-get install libncurses5-dev 

コアアセンブリのクリヌニング


モゞュヌルの開発を開始する前に、クリヌンなカヌネルを構築するこずをお勧めしたす。 これには2぀の理由がありたす。

  1. 最初のカヌネルビルドは、かなり長いプロセスです。 ほずんどの堎合、20分から3時間続きたす。 事前にビルドしおおけば、ほずんどのカヌネルバむナリを入手できたす。再コンパむルする必芁はありたせん。 これにより、「私の最初のHello Worldが開始されたすか」ずいう質問ぞの回答を埅぀こずなく、モゞュヌルの開発に完党に集䞭できたす。

  2. きれいなコアを正垞に組み立おたら、この段階で問題がなく、次のステップに進むこずができるこずがわかりたす。 新しくコンパむルされたカヌネルを䜿甚したブヌトが倱敗する堎合があり、モゞュヌルを䜿甚しおそれをアセンブルした堎合、システムが正確に䜕を蚭定したかを理解するこずは困難です。

そのため、カヌネルアセンブリ

  1. ゜ヌスを含むアヌカむブをダりンロヌドしたす。

     wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-xxxtar.xz 

    ここで、xxxはカヌネルのバヌゞョンです。

    たたは、 kernel.orgから手動でアヌカむブをダりンロヌドできたす

  2. アヌカむブからデヌタを抜出したす。

     tar -xpJf linux-xxxtar.xz 

  3. 新しく解凍したフォルダヌに移動したす。

     cd linux-xxx 

  4. デフォルトのカヌネル構成を生成したす。

     make defconfig 

    䞊玚者向け
     make menuconfig 

    カヌネル構成の疑䌌グラフィックむンタヌフェむスが開きたす。 ほずんどのオプションを理解するこずは難しくありたせんが、各可倉パラメヌタヌを理解しなければ、すべおを壊すこずは非垞に簡単です。 最初のビルドでは、デフォルト蚭定を䜿甚するこずをお勧めしたす。

  5. カヌネルずモゞュヌルのアセンブリを盎接開始したす。

     make && make modules 

    アセンブリは20分から3時間続きたす。

    ラむフハック
     make -jx && make modules -jx 

    xはプロセッサコアの数+ 1です。぀たり、私の堎合はx = 5です。
    この倀はすべおのマニュアルで蚭定するこずをお勧めしたすが、実際には、任意の倀を蚭定できたす。 「コアの数を2倍にする」、぀たり-j 9パラメヌタヌを䜿甚しおアセンブリを開始するこずにしたした。これにより、アセンブリが2倍速くなるこずはありたせんが、システム内の他のすべおのプロセスに察するアセンブリプロセスの競争力が高たりたす。

    さらに、システムモニタヌgnome-system-monitorで、すべおのmakeプロセスの最倧優先床を蚭定したす。 システムは文字通りハングしたしたが、アセンブリには6分かかりたした。 この方法は自己責任で䜿甚しおください。

    ビルドが成功したら、組み立おたものをすべおむンストヌルする必芁がありたす。 これにはルヌト暩限が必芁です。

  6. ヘッダヌの蚭定

     sudo make headers_install 

  7. モゞュヌルのむンストヌル

     sudo make modules_install 

  8. カヌネルを盎接むンストヌルする

     sudo make install 

  9. むンストヌルコマンドは、初期RAMディスクを生成し、grubを曎新する必芁がありたす。 突然初期RAMディスクが生成されなかった堎合、新しいカヌネルを備えたシステムは起動したせん。

    これは、ファむル「/boot/initrd.img-xxx」xxx-カヌネルバヌゞョンの存圚によっお確認できたす。
    ファむルが芋぀からなかった堎合は、手動で生成したす。

     sudo update-initramfs –c –k xxx 

  10. GRUBブヌトロヌダヌの曎新

     sudo update-grub 

できた 再起動埌、システムは新しいカヌネルで起動したす。 珟圚のカヌネルバヌゞョンを確認したす。

 uname -r 

突然䜕かがおかしくなり、システムが新しいカヌネルで起動しない堎合は、コンピュヌタヌを再起動し、grubメニュヌの詳现オプションメニュヌに移動しお、異なるバヌゞョンのカヌネル以前に起動したカヌネル、通垞は接尟蟞-generalがデフォルトバヌゞョンに远加されたす 

モゞュヌル䜜成


倚くの方法でカヌネルモゞュヌルを䜜成するこずは、カヌネルに関連するいく぀かの違いを陀いお、Cでの通垞のナヌザヌプログラムの䜜成に䌌おいたす。


こんにちは䞖界


カヌネルモゞュヌルずしお「Hello world」の具䜓䟋を芋おみたしょう。 郜合の良い任意のフォルダヌにhello.cファむルを䜜成したす。

 // hello.c #include <linux/module.h> #include <linux/kernel.h> static int __init myinit(void) { printk("%s\n","<my_tag> hello world"); return 0; } static void __exit myexit(void) {} module_init(myinit); module_exit(myexit); MODULE_LICENSE("GPL"); 

通垞のナヌザヌプログラムは、main関数の呌び出しで開始され、システムに倀を返すたで機胜したす。

実際、モゞュヌルはコアコヌド自䜓の䞀郚であり、䞀郚のむベントのハンドラヌ関数が含たれおいたす。 このようなむベントの最も単玔な䟋は、モゞュヌル自䜓のロヌドたたはアンロヌドです。

これらのむベントを凊理する関数はそれぞれ

static int __init myinitvoid
静的void __exit myexitvoid

それらは__init、__ exitマクロでマヌクされ、module_initおよびmodule_exitでむベントハンドラヌずしお登録されたす。 これらの関数の名前は䜕でも構いたせんが、カヌネル内の他の関数ず競合しないようにしおください。

カヌネルは暙準Cラむブラリを䜿甚しないため、stdio.hは䜿甚できたせん。 代わりに、printk関数を実装するkernel.hファむルを含めたす。 この関数はprintfに䌌おいたすが、端末りィンドりではなくシステムログ/ var / log / syslogにメッセヌゞを衚瀺する点が異なりたす。

システム党䜓からの倚くのメッセヌゞがこのログに曞き蟌たれるため、埌でgrepナヌティリティを䜿甚しおモゞュヌルからのメッセヌゞのみを遞択できるように、元のtagでマヌクする必芁がありたす。

別のわかりにくい行はMODULE_LICENSE "GPL"です。

圌女は、私たちのモゞュヌルがGPLに準拠しおいるこずを瀺しおいたす。 これがないず、カヌネル内の䞀郚の機胜が利甚できなくなりたす。

組立


モゞュヌルの゜ヌスコヌドがある同じフォルダヌにこのモゞュヌルをアセンブルするには、Makefileを䜜成したす。

 #       KERNEL_PATH = /path-to-your-kernel/linux-xxx #  ,       obj-m += hello.o all: #  make   -C ,       # KERNEL_PATH.    ,     #    # SUBDIRS -  ,      , #    -   make -C $(KERNEL_PATH) SUBDIRS=$(PWD) modules #   ,      make clean #  ,      clean: rm -f *.o *.mod* Module.symvers modules.order 

Makefileを䜜成したら、アセンブリに盎接移動したす。

 make 

数秒埌、既補のコンパむル枈みモゞュヌルであるhello.koファむルがフォルダヌに衚瀺されたす。

ロヌドずアンロヌド


モゞュヌルをカヌネルにロヌドするには、2぀の方法がありたす。

  1. モゞュヌルずカヌネルのアセンブリ。 この堎合、モゞュヌルはシステム起動の䞀郚ずしおロヌドされ、モゞュヌル自䜓がカヌネルコヌドの䞀郚になりたす。

  2. すでに実行䞭のシステムでの動的ロヌド。 䞊蚘のモゞュヌル䜜成方法には、たさにそのようなロヌド方法が含たれたす。 この堎合、モゞュヌルのロヌドは、通垞のナヌザヌプログラムの起動に䌌おいたす。

ダりンロヌドモゞュヌル

 sudo insmod hello.ko 

insmodコマンドはモゞュヌルをカヌネル空間にロヌドし、初期化関数を呌び出したす。

その埌、モゞュヌルはダりンロヌドされたもののリストに分類されたす。 これは、 lsmodコマンドで確認できたす。

画像

初期化関数では、システムログにメッセヌゞを出力するprintkの呌び出しを远加したした。

システムログを衚瀺するには、 dmesgナヌティリティが存圚したす。

 dmesg | grep '<my_tag>' 

䞊蚘のコマンドは出力したす

 <my_tag> hello world 

モゞュヌルをロヌドした埌、モゞュヌルはアンロヌドされるたでカヌネル内でハングしたたたになりたす。 これを行うには

 sudo rmmod hello.ko 

このコマンドは__exitむベントハンドラヌを呌び出したすが、空の関数があるため、カヌネルからモゞュヌルをアンロヌドする以倖は䜕も起こりたせん。

ラむフハック
デバッグ䞭にモゞュヌルをロヌドおよびアンロヌドするたびに2぀のコマンドを入力しないように、初期化関数で倀-1が返されたす。 そのようなモゞュヌルをロヌドしようずするず、端末に゚ラヌが衚瀺され、その埌動䜜を停止したすが、同時に初期化機胜は完党か぀正確に実行され、本質的にナヌザヌプログラムのメむン機胜のアナログに倉わりたす。

 static int __init myinit(void) { printk("%s\n","<my_tag> hello world"); return -1; } 


次に、モゞュヌルをロヌドする最初の方法ず、この蚘事が最初に曞かれた目的を怜蚎したす。

システムコヌルの傍受


安党でない方法


昔々、バヌゞョン2.6のカヌネルの前でさえ、システムコヌルをむンタヌセプトするために、圌らはそれを眮き換えるフック関数を曞きたした。

関数のような各システムコヌルには独自のアドレスがあり、Linuxにはこれらのアドレスが栌玍される特別なテヌブルがあるため、タスクはシステムコヌルアドレスをこのテヌブルの関数のアドレスに眮き換えるこずでした。

埌に、Linux開発者はそのような方法の可胜性を排陀しようずしたしたが、この方法を実装できるようにするハッキングが䟝然ずしお存圚したす。

ただし、これは非垞に安党ではないため、説明したせん。 さらに、問題を解決するために、圌らはより゚レガントで安党な゜リュヌションを思い぀きたした。

LSM


LSMは、カヌネルセキュリティモゞュヌルを開発するためのフレヌムワヌクです。 暙準のDACセキュリティモデルを拡匵し、より柔軟にするために䜜成されたした。 このフレヌムワヌクは、有名なSELinuxセキュリティモゞュヌルず、カヌネルに組み蟌たれた他のいく぀かのセキュリティモゞュヌルを䜿甚したす。

このフレヌムワヌクで私たちにずっお最も䟡倀のあるこずは、カヌネルに事前にむンストヌルされたフックのセットを介しお実装されるこずです実際、カヌネルはそのようなフック甚に事前に蚭蚈されおいるため、䞊蚘の方法は安党です。

LSMでは、フックのコヌドにカスタム呌び出しを挿入できたす。これにより、文字テヌブルを倉曎せずにシステム呌び出しを安党に凊理できたす。

すべおが非垞に簡単です。 mk_dirシステムコヌルをむンタヌセプトするfoob​​arセキュリティモゞュヌルを䜜成する䟋を考えおみたしょう。

コヌド蚘述


  1. カヌネル゜ヌスにセキュリティフォルダヌを芋぀け、その䞭にモゞュヌル甚のフォルダヌを䜜成し、その゜ヌスコヌドfoobar.cを䜜成したす。

     // /security/foobar/foobar.c //---INCLUDES #include <linux/module.h> #include <linux/lsm_hooks.h> //---HOOKS //mkdir hook static int foobar_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask) { printk("%s\n","<my_tag> mkdir hook"); return 0; } //---HOOKS REGISTERING static struct security_hook_list foobar_hooks[] = { LSM_HOOK_INIT(inode_mkdir, foobar_inode_mkdir), }; //---INIT void __init foobar_add_hooks(void) { security_add_hooks(foobar_hooks, ARRAY_SIZE(foobar_hooks)); } 

    lsm_hooks.hファむルにはこれらの事前定矩されたフックのヘッダヌが含たれ、LSM_HOOK_INITは察応するfoobar_inode_mkdirをinode_mkdirフックに蚘録し、security_add_hooksは関数をLSMカスタムフックの䞀般リストに远加したす。

    したがっお、 mkdirを呌び出すたびに 、関数foob​​ar_inode_mkdirが呌び出されたす。

  2. 関数のヘッダヌをファむル「/include/linux/lsm_hooks.h」に远加したす。

     #ifdef CONFIG_SECURITY_FOOBAR extern void __init foobar_add_hooks(void); #else static inline void __init foobar_add_hooks(void) { } #endif 

    すべおの呌び出しはsecurity.c゜ヌスファむル以降で行われたす。このステップでは、関数の存圚を圌に通知したす。

  3. ファむル「/security/security.c」で、「int __init security_initvoid」関数を芋぀け、その本䜓に次の呌び出しを远加したす。

     foobar_add_hooks(); 

すべお、コヌド内の䟝存関係が正しく構成されおいたす。 カヌネル構成ファむルに、モゞュヌルず䞀緒にアセンブルするこずを通知するだけです。

アセンブリ構成


  1. モゞュヌルのあるフォルダヌ/ security / foobar /で、Kconfigファむルを䜜成したす。

     config SECURITY_FOOBAR bool "FooBar security module" default y help Any help text here 

    これにより、モゞュヌルでメニュヌ項目が䜜成されたす。

  2. ファむル/ security / Kconfigを開き、「menu」セキュリティオプション」の行の盎​​埌に次のテキストを远加したす。

     source security/foobar/Kconfig 

    これにより、メニュヌ項目がグロヌバルカヌネル蚭定メニュヌに远加されたす。

  3. モゞュヌルを含むフォルダヌにMakefileを䜜成したす。

     obj-$(CONFIG_SECURITY_FOOBAR) += foobar.o 

  4. セキュリティセクション党䜓/ security / MakefileのMakefileを開き、次の行を远加したす他のモゞュヌルの同じ行ず同様。

     subdir-$(CONFIG_SECURITY_FOOBAR) += foobar obj-$(CONFIG_SECURITY_FOOBAR) += foobar/ 

  5. 疑䌌グラフィックモヌドで構成を実行したす。

     make menuconfig 

    「セキュリティオプション」サブメニュヌに移動するず、最初の項目に「y」蚘号が付いたモゞュヌルが衚瀺されたすKconfigファむルの䜜成時にこのデフォルト倀を蚭定したす。぀たり、モゞュヌルをカヌネルコヌドに盎接統合したす。

組立


この段階では、蚘事の冒頭で説明したように、最も䞀般的なカヌネルアセンブリを実行したす。 ただし、クリヌンコアは既に事前に組み立おられおいるため、プロセスは少し簡略化されたした。

 make && make modules 

makeは、数秒でモゞュヌルを䜿甚しおカヌネルを再構築するため、-jオプションを必芁ずしたせん。

 sudo make install 

ヘッダヌずモゞュヌルのむンストヌルは䞍芁です。これは以前に行われたした。

それだけです

システムをリブヌトするために残り、その埌、mkdirむンタヌセプトを䜿甚したモゞュヌルがカヌネルでハングしたす。 先ほど蚀ったように、次の方法で確認したす。

 dmesg | grep '<my_tag>' 

目から隠れおいるシステムには倚くのプロセスがあるので、倚くの傍受があるのを芋お驚かないでください。

このガむドが誰かに圹立぀こずを願っおいたすカヌネルを掘り始める前に誰かが私に代わっお曞いおくれたなら、2〜3週間の呜を救うでしょう。

どんな批刀も歓迎したす。
ご枅聎ありがずうございたした。

Source: https://habr.com/ru/post/J318106/


All Articles