-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ndpi integration #11671
Add ndpi integration #11671
Conversation
Add configure --enable-ndpi and --with-ndpi params Add nDPI metadata export in alerts/netflow (Eve JSON) Add ndpi-protocol signature match Add ndpi-risk signature match
NOTE: This PR may contain new authors. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #11671 +/- ##
==========================================
- Coverage 83.37% 83.37% -0.01%
==========================================
Files 910 910
Lines 257556 257562 +6
==========================================
- Hits 214748 214745 -3
- Misses 42808 42817 +9
Flags with carried forward coverage won't be shown. Click here to find out more. |
Thanks for the submission. Could you please create a ticket that discusses this feature, the benefits, etc. |
I created https://redmine.openinfosecfoundation.org/issues/7231 |
My big question is how could this work as a plugin ? |
@@ -580,6 +580,10 @@ typedef struct Packet_ | |||
uint8_t *payload; | |||
uint16_t payload_len; | |||
|
|||
#ifdef HAVE_NDPI | |||
uint16_t ip_len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we can avoid to store this, and recompute it based on the total packet length and offset of ip header...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we'll want to get rid of additional #ifdef here as well for the move to a plugin.
@@ -503,6 +503,12 @@ typedef struct Flow_ | |||
uint64_t todstbytecnt; | |||
uint64_t tosrcbytecnt; | |||
|
|||
#ifdef HAVE_NDPI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this somehow go into the storage section below ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps by using FlowStorageRegister
and friends? Example usage in app-layer-expectation.c
.
@@ -387,6 +387,41 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars | |||
{ | |||
SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f); | |||
|
|||
#ifdef HAVE_NDPI | |||
if (tv->ndpi_struct && f->ndpi_flow && (!f->detection_completed) && (p->ip_len > 0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we would need a hook here in FlowHandlePacketUpdate
for every packet...
JsonBuilder *JsonBuildFileInfoRecord( | ||
const Packet *p, const File *ff, void *tx, const uint64_t tx_id, const bool stored, | ||
uint8_t dir, HttpXFFCfg *xff_cfg, OutputJsonCtx *eve_ctx | ||
#ifdef HAVE_NDPI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could accept this for every case (even if it unused in most cases)
@@ -27,5 +27,8 @@ | |||
void JsonFlowLogRegister(void); | |||
void EveAddFlow(Flow *f, JsonBuilder *js); | |||
void EveAddAppProto(Flow *f, JsonBuilder *js); | |||
#ifdef HAVE_NDPI | |||
void EveAddnDPIProto(Flow *f, JsonBuilder *js, ThreadVars *tv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused ?
@@ -135,6 +135,10 @@ typedef struct ThreadVars_ { | |||
struct FlowQueue_ *flow_queue; | |||
bool break_loop; | |||
|
|||
#ifdef HAVE_NDPI | |||
struct ndpi_detection_module_struct *ndpi_struct; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... I do not know about this one... (how we could make it work as a plugin)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could just use thread_local
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we delay initialization until first use, which would be in the packet path then?
I don't think a callback on thread creation would work, as in the library work a thread may be provided by the user, in which case some sort of callback with some user storage in the ThreadVar might make more sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with user data on ThreadVars. When/how to construct/destruct needs some thought. Do plugins have "thread init" callbacks? Where it would be called once per thread at init?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with user data on ThreadVars. When/how to construct/destruct needs some thought. Do plugins have "thread init" callbacks? Where it would be called once per thread at init?
No they do not, but this is what I was thinking we might need.
@@ -120,4 +120,7 @@ OutputJsonThreadCtx *CreateEveThreadCtx(ThreadVars *t, OutputJsonCtx *ctx); | |||
void FreeEveThreadCtx(OutputJsonThreadCtx *ctx); | |||
void JSONFormatAndAddMACAddr(JsonBuilder *js, const char *key, const uint8_t *val, bool is_array); | |||
|
|||
#ifdef HAVE_NDPI | |||
void ndpiJsonBuilder(Flow *f, JsonBuilder *js, ThreadVars *tv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And we would need to hook into logging...
We are open to both a plugin and native support. The latter is the best IMHO as it enables all users to exploit it, but if a plugin is just a packaging detail fine for me. Just let us know what we can do to expedite your decision as we would like to push additional features after this PR is likely merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some discussion on our side, we'd like to help where we can to make this a plugin a.s.a.p. This will require some work on our side as we don't have all the support required yet, but this PR does help identify where we need to provide the hooks.
On your end could you:
- see about using thread local storage
- remove the additional fields from the header and see about using the storage apis
- register and
ndpi
feature so rules can conditinally use this
On our side we'll closely review this for the hooks that are needed and prepare a PR from our side.
I think this would be a plugin we'll bundle with Suricata though, so the user experience won't be much different than it is with this PR.
Hi @jasonish do you have some updates to share? We're ready to move forward with the plugin development as soon as you're ready. Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had some minor comments that for some reason were pending since forever 😓
#ifdef HAVE_NDPI | ||
|
||
static void ndpiJsonBuilderTLSQUIC(Flow *f, JsonBuilder *js, ThreadVars *tv) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we move these ndpi-related changes to their own file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: naming convention: s/n/N ?
ndpi_set_protocol_detection_bitmask2(tv->ndpi_struct, &protos); | ||
ndpi_finalize_initialization(tv->ndpi_struct); | ||
|
||
/* printf("%s - ndpi_init_detection_module()\n", __FUNCTION__); */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is keeping these necessary? If yes, couldn't they be changed to SCLogDebug
statements?
- Self-signed Certificate | ||
- Susp DGA Domain name | ||
- Malware host contacted | ||
- and many other... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Should we add any a reference here for what was consulted to define those and where people could check them, or isn't this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SCLogDebug("ndpi protocol match on protocol = %u.%u (match %u)", | ||
f->detected_l7_protocol.app_protocol, f->detected_l7_protocol.master_protocol, | ||
data->l7_protocol); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compile error here:
detect-ndpi-protocol.c: In function ‘DetectnDPIProtocolPacketMatch’:
detect-ndpi-protocol.c:80:40: error: ‘ndpi_protocol’ {aka ‘const struct ndpi_proto’} has no member named ‘app_protocol’
80 | f->detected_l7_protocol.app_protocol, f->detected_l7_protocol.master_protocol,
| ^
/**********************************Unittests***********************************/ | ||
|
||
#ifdef UNITTESTS | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These unit tests below also fail to compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lucaderi @cardigliano Can we get a rebase that builds against current nDPI, or a specific version of nDPI?
Linker error.. When I build Suricata with
this appears to be linking against the .a static library. Probably because I use --disable-shared. It works against the shared library. Is there a known reason why? |
I believe you have built nDPI with nBPF support and the nBPF library was not used during linking. I think you have /home/jason/PF_RING/userland/nbpf/libnbpf.a but that was not used during linking. |
@lucaderi @cardigliano Its still needs much review, but here's what I'm thinking for the support required for nDPI to be a plugin, including a stub plugin that shows off the call backs and user storage for threads and flows. |
Yeah, it picked up some older pfring install from /usr/local. Thanks. |
NOTE: This PR may contain new authors. |
Closing as this has been reworked as a plugin |
Make sure these boxes are signed before submitting your Pull Request -- thank you.
https://docs.suricata.io/en/latest/devguide/contributing/contribution-process.html
https://suricata.io/about/contribution-agreement/ (note: this is only required once)
Describe changes: