Hi Anoop,<br>
<br>
Thank you for the information. I have rewritten the code like you suggested and it is working OK now.<br>
<br>
As regards the alert-debug I can indeed write the XFF IP without overwriting 
the srcip, however my final goal is to add the XFF IP to the unified2 
alerts.<br>
<br>
As discussed at <a href="https://redmine.openinfosecfoundation.org/issues/478">https://redmine.openinfosecfoundation.org/issues/478</a> there are 2 ways we can do this:<br>
<br>
- Modify the current unified2 format used by suricata to support extrahdrs and include the XFF IP in there (like snort does)<br> 
-- Pros: we keep the original srcip of the packet untouched<br>  -- Cons: barnyard2 does not support the processing of these extrahdr records; we have to modify the current unified2 format used by suricata<br>
<br>
-  Overwrite the srcip of the logged packet by the XFF IP if the 
suricata administrator decides to activate this feature via the 
suricata.yaml file.<br>  -- Pros: simple to implement, no need to modify barnyard2<br>  -- Cons: we overwrite the original IP (however if the suricata administrator decides to activate this feature it is because there is a reverse proxy which performs SNAT and terminates the HTTP or HTTPS inbound connections and adds the XFF header, so I see no need to keep the actual src ip - the one of the reverse proxy)<br>

<br>We could also do it both ways, and let the user decide...<br><br>Regards,<br><br><div class="gmail_quote">On Thu, Jul 19, 2012 at 4:15 PM, Anoop Saldanha <span dir="ltr"><<a href="mailto:anoopsaldanha@gmail.com" target="_blank">anoopsaldanha@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Ignacio,<br>
<div class="im"><br>
On Wed, Jul 18, 2012 at 9:17 PM, I. Sanchez <<a href="mailto:sanchezmartin.ji@gmail.com">sanchezmartin.ji@gmail.com</a>> wrote:<br>
> Hi there!<br>
><br>
> I am trying to implement support for XFF (X-Forwarded-For). As a first step,<br>
> I would like to modify the alert-debuglog.c to replace the srcip of the<br>
> triggered alert by the client IP address specified by the XFF header, in<br>
> case the XFF has been enabled at the suricata.yaml file and the header is<br>
> present in the request.<br>
<br>
</div>What does this conf variable in the yaml allow?<br>
<br>
Replacing the srcip for the packet is wrong, since the info printed is<br>
not the srcip for the packet, but we will end up presenting the wrong<br>
ip as the packet srcip.  The right thing would be to check if XFF is<br>
present in the http state and if yes, print the ip specified by the<br>
the header separately.<br>
<br>
if (XFF-header present) {<br>
    MemBufferWrite("XFF-header: srcip");<br>
<div><div class="h5">}<br>
<br>
><br>
> I am inserting the XFF extraction code at the AlertDebugLogger function,<br>
> right after:<br>
><br>
>     char srcip[46], dstip[46];<br>
><br>
>     if (PKT_IS_IPV4(p)) {<br>
>         PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip,<br>
> sizeof(srcip));<br>
>         PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip,<br>
> sizeof(dstip));<br>
>     } else if (PKT_IS_IPV6(p)) {<br>
>         PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip,<br>
> sizeof(srcip));<br>
>         PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip,<br>
> sizeof(dstip));<br>
>     }<br>
><br>
><br>
> My code is currently:<br>
><br>
>     /* XFF Code */<br>
>     // strcpy(srcip,"0");<br>
>     if (aft->debuglog_ctx->flags & ALERT_DEBUGLOG_XFF) {<br>
>         // strcpy(srcip,"1");<br>
>         HtpState *htp_state=NULL;<br>
>         htp_tx_t *tx = NULL;<br>
>         htp_header_t *h_xff = NULL;<br>
>         size_t idx = 0;<br>
>         if (p->flow && AppLayerGetProtoFromPacket(p) == ALPROTO_HTTP &&<br>
>                         AppLayerTransactionGetLoggedId(p->flow) >= 0 &&<br>
>                         HtpTransactionGetLoggableId(p->flow) >= 0) {<br>
>             // strcpy(srcip,"2");<br>
>             htp_state = (HtpState *) AppLayerGetProtoStateFromPacket(p);<br>
>             size_t logged = (size_t)<br>
> AppLayerTransactionGetLoggedId(p->flow);<br>
>             size_t loggable = (size_t) HtpTransactionGetLoggableId(p->flow);<br>
>             if ( htp_state && htp_state->connp && htp_state->connp->conn &&<br>
> logged < loggable) {<br>
>                 // strcpy(srcip,"3");<br>
>                 for (idx = logged; idx < loggable; idx++) {<br>
>                     // strcpy(srcip,"4");<br>
>                     tx = list_get(htp_state->connp->conn->transactions,<br>
> idx);<br>
>                     if (tx != NULL && tx->request_headers != NULL) {<br>
>                         // strcpy(srcip,"5");<br>
>                         h_xff = table_getc(tx->request_headers,<br>
> aft->debuglog_ctx->xff_header);<br>
>                         if (h_xff != NULL) {<br>
>                             // strcpy(srcip,"6");<br>
>                             if (bstr_len(h_xff->value) ><br>
> ALERT_DEBUGLOG_XFF_MINLEN - 1 &&<br>
><br>
> bstr_len(h_xff->value) < 44) {<br>
>                                 strcpy(srcip,bstr_ptr(h_xff->value));<br>
>                                 // strcpy(srcip,"7");<br>
>                             }<br>
>                         }<br>
>                     }<br>
>                 }<br>
>             }<br>
>         }<br>
>     }<br>
><br>
> The problem is that it never arrives to "step 3" because logged is always >=<br>
> loggable (even though the XFF header is present in the request which<br>
> triggered the alert). I suspect this happens because at the point the alert<br>
> is triggered, the http transaction is not yet finished (it works fine in<br>
> log-httplog).<br>
><br>
> How should I modify the code to extract the XFF header, if available, even<br>
> when the transaction is not finished?<br>
><br>
<br>
</div></div>Debuglog depends on the presence of alerts and I see no way around it.<br>
 Instead you can retrieve the available transactions from the<br>
htp_state, pick the one which has the xff header and you have the ip<br>
you need.<br>
<br>
int size = (int)list_size(htp_state->connp->conn->transactions);<br>
for (idx = 0; idx < size; idx++) {<br>
<div class="im"><br>
    tx = list_get(htp_state->connp->conn->transactions, idx);<br>
</div>    if (tx == NULL)<br>
        continue;<br>
<br>
    if (tx has xff_header)<br>
        break;<br>
    tx = NULL;<br>
}<br>
<br>
if (tx != NULL) {<br>
    /* this tx has the xff header set.  use the ip */<br>
    xff_ip = retrieve_xff_header_value_for_tx(tx);<br>
<div class="im">}<br>
<br>
> Thank you! Regards,<br>
><br>
><br>
>   Ignacio Sanchez<br>
</div>> _______________________________________________<br>
> Oisf-devel mailing list<br>
> <a href="mailto:Oisf-devel@openinfosecfoundation.org">Oisf-devel@openinfosecfoundation.org</a><br>
> <a href="http://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel" target="_blank">http://lists.openinfosecfoundation.org/mailman/listinfo/oisf-devel</a><br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
--<br>
Anoop Saldanha<br>
</font></span></blockquote></div><br>