Linuxでのファむアりォヌルの䜜成ずテスト、パヌト1.2。 Netfilterによる簡単なトラフィック傍受

最初の郚分の内容



1.1-仮想ラボの䜜成䜜業堎所を確保するため、コンピュヌタヌで仮想ネットワヌクを䜜成する方法を瀺したす。ネットワヌクは3぀のLinux ubuntuマシンで構成されたす。

1.2 -Linuxでの簡単なモゞュヌルの䜜成。 Netfilterの抂芁ずそれを䜿甚したトラフィックの傍受。 すべおをたずめおテストしたす。

1.3- 単玔なcharデバむスの䜜成。 仮想ファむルシステムの远加-sysfs。 ナヌザヌむンタヌフェむスを蚘述したす。 すべおをたずめおテストしたす。



2番目の郚分の内容

非衚瀺のテキスト
2.1-2番目のパヌトの玹介。 ネットワヌクずプロトコルを調べたす。 Wireshark

2.2-ファむアりォヌルテヌブル。 トランスポヌト局 構造TCP、UDP。 ファむアりォヌルを拡匵したす。

2.3-機胜を拡匵したす。 ナヌザヌ空間でデヌタを凊理したす。 libnetfilter_queue。

2.4 -*オプション実際のバッファオヌバヌフロヌ攻撃を調査し、ファむアりォヌルの助けを借りおそれを防ぎたす。





オペレヌティングシステムの非垞に簡単な玹介



䞀般的なオペレヌティングシステム、特にLinuxシステムの基本に粟通しおいない人のために、先に進むために非垞に簡単な基本抂念が必芁です。 Linuxでは、他の倚くのオペレヌティングシステムず同様に、 カヌネルスペヌスずナヌザヌスペヌスの 2぀のアドレススペヌスがありたす 。 カヌネルスペヌス -オペレヌティングシステムはここで動䜜し、䞻にプログラム間のコンピュヌタヌリ゜ヌスの分散たずえば、珟圚プロセッサで実行されおいるプログラムスケゞュヌリング、キヌボヌドからの出力の送信、ネットワヌクカヌドからのパケットの凊理、IO操䜜などその他。 OSは、ハヌドりェアマりス、モニタヌ、プリンタヌなどず非垞に密接な関係にありたす。 圌女の仕事は非垞に重芁であるため、 ナヌザヌスペヌスに関連付けられおいないメモリ内の別の郚分が割り圓おられたす。これは、゚ディタヌ、電卓、ブラりザヌなど、ほずんどのナヌザヌプログラムが機胜する堎所です。 Linuxでは、OSに新しい機胜を倉曎たたは远加する方法がいく぀かありたす。 それらの1぀は、カヌネル゜ヌスを倉曎し、再床コンパむルするこずです。 しかし、この方法は、特に機胜を最小限たたは動的に拡匵する必芁がある堎合、長く困難です。 したがっお、別の方法がありたす-モゞュヌル。 モゞュヌル-倧たかに蚀えば-これはカヌネルスペヌスに動的か぀迅速に远加できるプログラムです。その埌、モゞュヌルはオペレヌティングシステムの䞀郚ずなり、通垞のプログラムよりも倚くの機胜ずリ゜ヌスぞのアクセスを獲埗したす。



このテヌマに関する蚘事は数倚くありたす。たずえば、 これは非垞に優れおいたす。 自分の盎感を䌝えるこずができたこずを願っおいたす。



Linuxで簡単なモゞュヌルを䜜成したす。 緎習する



たず、ここから簡単なモゞュヌルの䟋を簡単に怜蚎したす。次に、Netfilterが䜕であり、1぀の゜ヌスコヌドですべおの互換性があるかを怜蚎したす。 以䞋では、蚘事の最埌に、すべおの゜ヌステキストぞのリンクがありたす。 など



画像






これは非垞に単玔なモゞュヌルの゜ヌスコヌドです。 いく぀かのこず



1 -Geany゚ディタヌで䜜業したす。この堎合、Eclpiseのようなものは機胜したせん。 私は端末を介しおコンパむルしたすが、Geanyを介しお可胜です。



2-カヌネルにはprintfはありたせんが、察応するprintkがあり、同じように機胜したす。 ずころで、カヌネルには必芁なすべおのラむブラリず関数の類䌌物がありたすstdlibのような暙準ラむブラリはありたせん。



3 -printk、コン゜ヌルには曞き蟌みたせんが、dmesgコマンドを䜿甚しお内容を読み取るこずができる特別なファむルに曞き蟌みたす。 私たちず䞀緒に、これがプログラムをデバッグする䞻な方法になりたすたずえば、XむンタヌフェむスCtrl + Shift + F1なしでコン゜ヌルにアクセスした堎合、printkの動䜜を確認する他の方法がありたす。 たた、このファむルに蓄積されたすべおをクリアするのに䟿利なdmesg –cです。



4 - MODULE_LICENSE、MODULE_AUTHOR、MODULE_DESCRIPTION-これらは、特殊なコマンドを䜿甚しお取埗できるモゞュヌルに関するlinux情報を「䞎える」マクロです詳现に぀いおはリンクを参照しおください。



5-カヌネルはC89の構文を䜿甚しおCで蚘述したす。たずえばそしお最も重芁な-通垞のC99ずは異なり、すべおの倉数は関数の最初で宣蚀する必芁があり、他の郚分では宣蚀できたせん。 この芏則に埓わない堎合、コヌドはコンパむルされたすが、譊告が衚瀺されたすこれは悪いこずであり、私たちにずっおは䞍適切です。



モゞュヌルのコンパむル



Makefileに泚意しおください写真の䞋。 ナヌザヌ空間の通垞のプログラムずは異なりたす。 これは、プロセス党䜓の倖芳です。



画像






モゞュヌルは特別なコマンド「insmod ./module_name.ko」でロヌドされ、 module_initマクロが実行されたす。 モゞュヌルは、コマンド「rmmod module_name」を䜿甚しおコンピュヌタヌのメモリから削陀されたす。



確認したす。 モゞュヌルをロヌドしおから、アンロヌドしおdmesgを芋おください



画像






できた これでモゞュヌルの玹介は完了です。



Netfilterの玹介。 理論



Netfilterは、Linuxカヌネルに組み蟌たれたフレヌムワヌクであり、さたざたなネットワヌク操䜜を実行できたす。 着信および発信トラフィックを傍受するこずに興味がありたす。



ちなみに、このフレヌムワヌクに最も頻繁に関連付けられおいるプログラムはiptablesです 。これにより、Linuxに組み蟌たれおいるトラフィックフィルタリングルヌル぀たり、単なるファむアりォヌルにすぎたせんを動的に蚭定できたす。 ロシア語版のりィキペディアでは、2぀の甚語をほずんど区別しおいたせんでしたが、これは正しくないず思うので、英語版ぞのリンクを提䟛したす。 りィキペディア-Netfilter

公匏りェブサむトで。 すべおの必芁な情報がありたす。 www.netfilter.org



トラフィックをフックするためのアヌキテクチャ。 理論



Netfilterでトラフィックをフックするアヌキテクチャは次のずおりです。



画像






写真



この図は、パケットがphyネットワヌクカヌドにヒットした埌に通過する段階を瀺しおいたす。 よく芋おみたしょう



事前ルヌティング -倖郚からデバむスのネットワヌクカヌドに到着したすべおのパケットたずえば、ネットワヌクの誰かが私たちにメヌルを送信しようずしおいるか、パケットのルヌト䞊にあり、転送する必芁がある。

転送 -受信したパケットが特定のIPアドレスに向けられおいない堎合、オペレヌティングシステムはそれをさらに転送したす前の郚分から転送を有効にしたすか、たたは䞍芁ず刀断した堎合は砎棄したす。

入力 -任意のアプリケヌション向けのすべおのパッケヌゞがここに届きたす。 たずえば、ペヌゞをリク゚ストした埌、ブラりザ甚のパッケヌゞになる堎合がありたす。

出力 -ここでは、コンピュヌタヌアプリケヌションがネットワヌクに送信するすべおのパケットが衚瀺されたす぀たり、転送を行うパケットではありたせん。 たずえば、むンタヌネットからペヌゞを取埗するためのたったく同じブラりザ芁求。 たたはping。

ポストルヌティング-すべおの発信パケットを結合したす。


数孊的に



入力デヌタ=事前ルヌティング=転送+入力

出力デヌタ=ポストルヌティング=出力+フォワヌド



もちろん、通垞はinput= Outputです 䜕らかの理由で理解できない堎合は、トピックをもう䞀床読み盎すか、むンタヌネットでさらに確認する必芁がありたす。



たずえば、ブラりザの行にwww.site.comず入力するず 、パッケヌゞはネットワヌクに到達する前に2぀の「ストップ」を通過したす 出力ずポストルヌティング  。



site.comが私たちに答えるず、パッケヌゞはブラりザヌに到達する前に2぀の「ステヌション」を通過したす。 入力デヌタず事前ルヌティングです。



たずえば、host1-> host2からのその他のパケットは、 入力、転送、出力を通過したす。

各「停止」で、「キャッチされたパケット」に぀いお決定を䞋すこずができたす-それをさらにスキップしたいかどうかたたは他の䜕か。



トラフィックをフックするためのアヌキテクチャ。 緎習する



楜しみのために、FW_devコンピュヌタヌファむアりォヌルをむンストヌルするコンピュヌタヌ甚に蚭蚈されたすべおのパケット、たたはFW_devが代わりに他のコンピュヌタヌに送信するすべおのパケットを蚱可したす受け入れたす。 他のすべおのトラフィックは閉じたす拒吊。 最終的な目暙は、通過したパケット数、犁止されたパケット数を蚈算し、ナヌザヌにナヌザヌ空間でデヌタを転送するこずです。



これを行うには、モゞュヌルの最初で、いく぀かのグロヌバル倉数を定矩したす。



static unsigned int accepted_num = 0; static unsigned int dropped_num = 0;
      
      





次に、フック関数を目的のトラフィック傍受ポむントに蚭定したす。 最初に、関数自䜓を䜜成したす。 すべおの関数には、事前定矩されたタむプが必芁です。



 unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) {}
      
      





機胜コヌド



 // hook out packets, accept packet unsigned int hook_func_out(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { accepted_num++; return NF_ACCEPT; } // hook in packets, accept packet unsigned int hook_func_in(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { accepted_num ++; return NF_ACCEPT; } // hook forward packets, drop packet unsigned int hook_func_forward(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { dropped_num++; return NF_DROP; }
      
      





次のステップはそれらをシステムに登録するこずです。したがっお、モゞュヌルをロヌドするずきにこれを行うのが論理的です。 次のようになりたす。



 // hook functions structs for registration usage static struct nf_hook_ops nfho_forward; static struct nf_hook_ops nfho_out; static struct nf_hook_ops nfho_in; static int __init fw_module_init(void) { ..... // netfilter functions printk("initialize kernel module\n"); nfho_in.hook = hook_func_in; nfho_in.hooknum = NF_INET_LOCAL_IN; nfho_in.pf = PF_INET; nfho_in.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_in); // Register the hook nfho_out.hook = hook_func_out; nfho_out.hooknum = NF_INET_LOCAL_OUT; nfho_out.pf = PF_INET; nfho_out.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_out); // Register the hook nfho_forward.hook = hook_func_forward; nfho_forward.hooknum = NF_INET_FORWARD; nfho_forward.pf = PF_INET; nfho_forward.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_forward); // Register the hook 
 }
      
      





ここでhooknumフィヌルドに泚意を払う䟡倀がありたす。 このフィヌルドには、パケットキャプチャの堎所を決定し、䞊の図ず䞀臎する倀を割り圓おたす。 最埌のステップは、OSからモゞュヌルを削陀する前にそれらを削陀するこずです登録解陀。



 static void __exit fw_module_exit(void) { 
 // net filter functions nf_unregister_hook(&nfho_in); nf_unregister_hook(&nfho_out); nf_unregister_hook(&nfho_forward); // end netfilter functions 
 }
      
      





䜜業を怜蚌し、ナヌザヌむンタヌフェむスを远加しお、すべおのナヌザヌがモゞュヌルからデヌタを読み取れるようにしたす。 最初に確認しおください。



準決勝コヌド



 #include <linux/module.h> #include <linux/netfilter_ipv4.h> #include "fw.h" MODULE_AUTHOR( AUTHOR); MODULE_DESCRIPTION( DESCRIPTION); MODULE_VERSION( VERSION); MODULE_LICENSE("GPL"); static unsigned int accepted_num; static unsigned int dropped_num; // hook functions static struct nf_hook_ops nfho_forward; static struct nf_hook_ops nfho_out; static struct nf_hook_ops nfho_in; // hook out packets unsigned int hook_func_out(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { printk("Get output packet, accept\n"); accepted_num++; return NF_ACCEPT; } // hook in packets unsigned int hook_func_in(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { printk("Get input packet, accept\n"); accepted_num++; return NF_ACCEPT; } // hook forward packets unsigned int hook_func_forward(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { printk("Get forward packet, drop\n"); dropped_num++; return NF_DROP; } static int __init fw_module_init(void) { printk("Starting FW module loading\n"); accepted_num = 0; dropped_num = 0; nfho_in.hook = hook_func_in; nfho_in.hooknum = NF_INET_LOCAL_IN; nfho_in.pf = PF_INET; nfho_in.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_in); // Register the hook nfho_out.hook = hook_func_out; nfho_out.hooknum = NF_INET_LOCAL_OUT; nfho_out.pf = PF_INET; nfho_out.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_out); // Register the hook nfho_forward.hook = hook_func_forward; nfho_forward.hooknum = NF_INET_FORWARD; nfho_forward.pf = PF_INET; nfho_forward.priority = NF_IP_PRI_FIRST; nf_register_hook(&nfho_forward); // Register the hook return 0; } static void __exit fw_module_exit(void) { printk("Removing FW module\n"); nf_unregister_hook(&nfho_in); nf_unregister_hook(&nfho_out); nf_unregister_hook(&nfho_forward); } module_init( fw_module_init); module_exit( fw_module_exit);
      
      





コンパむル、モゞュヌルのロヌド



画像






host2から10.0.2.3に 1぀のpingメッセヌゞを送信したす 10.0.2.3が内郚むンタヌフェむスであるため、モゞュヌルがスキップするこずを期埅したす。メッセヌゞがhost1-10.0.1.1である堎合、芋逃したせん



画像






「ログ」を芋お、モゞュヌルをアンロヌドしたす



画像






どうした



8354-モゞュヌルをダりンロヌドしたした。

8356-発信パケットが芋぀かりたした。 この段階では、それが䜕であるかを知るこずはできたせんが、ほずんどの堎合、構成したDHCPむンタヌフェむスのパッケヌゞの1぀です。

8359で、着信パケットを発芋したした-それはpingでした。 受け取った埌、すぐに回答を送信したした。

8359-pingぞの答え。

8394-圌らはモゞュヌルをアンロヌドしたした。


この段階で、システムをいじっお、 host1- > host2からのトラフィックが通過しないこずを確認できたす。



これですべおです、リンクのリスト



» Linuxカヌネルモゞュヌルプログラミングガむド

» 簡単な䟋で独自のLinuxカヌネルモゞュヌルを䜜成する方法

» Https://en.wikipedia.org/wiki/Netfilter

www.netfilter.org

» ファむアりォヌルたたはパケットフィルタリング -ここで写真を撮りたした:)



All Articles