snort_ryu.png

最近在 Ryu contribute 一些 patch 終於加進去官方的 Project 了!
特地寫這篇稍微介紹一下 Snort Integration,也順便分享一下在 Ryu 官方本身是不希望貢獻者使用 Pull Request 的情況下,到底要怎麼對 Ryu project 做出你的貢獻呢?

首先大概簡單帶過一下 Snort 到底在做什麼事情,然後再談怎麼拿他去跟 Ryu 做整合。我的部落格上一篇就是記錄了 Snort 怎麼安裝,有興趣的可以參考。

About Snort


Snort 是一套開放源碼的入侵偵測系統(Intrusion Detection System)又稱作 IDS 。它能夠即時地監測網路上的封包,並透過 Snort Rule 比對攻擊模式,當發現疑似有網路攻擊的行為發生時,會發出警告的訊息(Alert message)通知網路管理者,攻擊者的 5-Tuple 與攻擊的手法,等等…

這其中的精神在 Snort Rule 它裡面描述著各種網路攻擊的形態,例如:DDoS, SQL injection 等等…
Snort 會在拆解封包的過程逐一比對 Snort Rule 一旦命中 Rule 就會發出警告。你可以花錢跟 Snort 官方購買他們的 Rule 或者是使用社群版免費的 Rule,或甚至你熟稔網路攻擊的形態你就可以自行撰寫 Rule 來定義你的規則。

Integrate with Ryu


在介紹怎麼整合之前有個小插曲,其實這個整合早在2013年的3月就有看到他們在做,可是不知道為什麼後來變成沒有人在維護,甚至那份資料還消失了!所幸我在 NTT 來台灣開的一場 SDN 研討會上,問了他們的 project lead 這個問題,會後他說會寄給我那篇 Snort Integrate 資料。

收到了這份資料之後,才發現他們沒再繼續做更新,為什麼需要更新呢?原因是 Ryu 曾經在某一版本的時候從使用 Gevent 換到 Eventlet (據他們表示,是因為 OpenStack 都是用 Eventlet 的框架去開發,為了跟 OpenStack 有比較高的整合度,所以才做出這個大改版)

這個大改版讓這些舊的程式都沒法再使用,所以我就跳下去看 Eventlet 來改他舊的程式,好讓他可以支援目前的 Eventlet。這時候新的Snort Integration就誕生啦!

回到正題,剛剛有提到 Snort 在發現遭受攻擊的時候,會提出警告訊息(Alert message)你可以選擇將這些訊息記錄在 log 檔、 console 上顯示或是把訊息輸出到 Unix Domain Socket 上(它是一個 client)。那我就參照之前就的那份 source code 去做,在 Ryu 上開一個 Unix Domain Socket的Server 這樣就能聽到 Snort 的警告訊息,最後在把它寫成一個 Event 讓它可以在 Application 上透過寫 event handler 的方式去把 alert message 的資訊顯示出來。

那我們來看一下,在同一檯機器上的時候 Snort 跟 Ryu 的架構圖:

workflow01.png

最終是完成了,但是人總是貪心的,或許我們能在上面再多做一些 feature?

就有人說啦,把 Snort 跟 Ryu 跑在同一檯機器上, Snort 需要拆解網路封包去判斷是否俱有惡意行為,那麼吃效能會影響 Controller 的。我就在思考要把 Snort 跟 Ryu 拆開的可行辦法,最後找出一個解決方案,在不需要動 Snort 的 source code 之下,我們讓 Snort 那檯機器多跑一隻程式可以接 Unix Domain Socket 的資料再把他往 Network Socket 打出去就能跟 Ryu 接上,所以我又在 Ryu 那邊加入了一個開啓 Network socket Server 這就是讓我們可以把 Snort 跟 Ryu 分開中間的橋樑。

後來的改版,將 Snort 跟 Ryu 分開機器後的架構圖:

workflow02.png

以上這兩種模式,我都有實作進去 Ryu ,由應用程式開發者自己決定要選擇哪一個模式,只要記得把 Configure 設好就能選擇你要使用哪一種模式。

詳細的文件資料可以參考:Snort Integration 或是 ryu source code 目錄底下的 ryu/doc/snort_integrate.rst

Simple switch with snort


為了怕大家不太熟悉怎麼樣用這個 lib 就在 sample app 裡面加入了一隻簡單的範例程式simple_switch_snort.py ,這個程式除了可以做 L2 Switch 還可以把封包 mirror 給 Snort 。當 Ryu 收到 Alert message 的時候就把 Alert message 顯示出來,當然包括攻擊者的 5-Tuple 有了這些資訊,我們就能在 Controller 那端 Block 掉惡意的來源!

About Contribution


會寫這段的原因是一開始也不懂得怎麼加 Patch 後來看到 Ryubook 上的 [Contribution section] (http://osrg.github.io/ryu-book/en/html/contribute.html#sending-a-patch)有記錄,就稍微描述一下讓想要加 Patch 的朋友可以做一個參考。

Ryu 雖然把 Source Code 放在 GitHub 但不太一樣的是他不能做 Pull Request 他希望所有開發者能夠遞交 Patch 到他們的 Mailing List 上,這種方式跟 Linux kernel 的開發方式一樣,遞交 patch 需要來一個你的Signed-off 然後他們如果 accept 的話,就能夠收錄進官方的 Ryu Project.

我們可以使用 Git 來產生 Patch 然後對方接到這個 Patch 後,覺得滿意的話,他可以透過 git am 指令把 patch merge進去,可以參考以下步驟遞交 Patch:

  • 當你做完 source code 的變更後,我們通常會 Commit 寫一段你所做的變更的歷史記錄。

    1
    2
    $ git add sample.py
    $ git commit -m "Add sample application"
  • 接下來利用 Git 產生 Patch, 別忘了 -s 是簽名哦!他會去 .gitconfig 拿你的名字跟 email 放在 patch 的後面

    1
    $ git format-patch origin -s
  • 寄出你的 Patch 到 Mailing List 上。可以不加 -to 的選項 Git 會自動問你要寄給誰?

    1
    $ git send-email 0001-sample.patch -to ryu-devel@lists.sourceforge.net
  • 靜待回音囉!通常還蠻快速的,這份 patch 會有你的簽名,未來如果有人有疑問或是發現 Bug 記得要修啊!