Ruby Code - Converting Socket Address Error

I'm working with Auditd data. I have the SADDR within a log message and I'm trying to convert it using some ruby code.

Here is my snippet:

filter {
    ruby {
        code => "
            require 'socket'
            temp = event.get('[event_data][saddr]')
            unless temp == nil?
                hex = [temp].pack('H*')
                decoded = Socket.unpack_sockaddr_in(hex)
                event.set('[event_data][port]', decoded[0])
                event.set('[event_data][ip]', decoded[1])
            end
        "
    }
}

However, this throws an exception: "Ruby exception occurred: not an AF_INET/AF_INET6 sockaddr"

I know that should be working, because I can take a static one liner within irb that I confirmed works, but yet in logstash it will fail with the same exception:

filter {
      ruby {
        code => "
                #require 'socket'
                output = Socket.unpack_sockaddr_in(['020000357F0001010000000000000000'].pack('H*'))
        "
      }
    }
}

Any ideas on why this ruby code isn't working?

Hmm, I think this may have to do something with weird encoding.

I am extracting the SADDR and sticking the raw bytes into a field within elasticsearch:

ruby {
code => "
        require 'socket'
        temp = event.get('[event_data][saddr]')
        unless temp == nil?
                hex = [temp].pack('H*')
                event.set('[event_data][debug]', hex)
        end     
"
}

Raw Bytes of the Debug:

"debug": "\u0002\u0000\u00005\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000

I believe when I'm extracting the string from event.get and then converting it via the pack, the data is being modified to some unicode that is not accurate.

Another update.

I don't seem to be able to use event.set without it trying to do unicode data.

For that matter, I believe my pack('H*') is resulting in unicode, which I think is the crux of the problem. However, I am unable to figure out why it continues to transpose the data into unicode.

Working straight from ruby results in the expected results, but something within logstash filter of ruby is executing something that isn't representative or straight ruby.

Any ideas?

So the answer to this riddle is JRuby.

The function call Socket.unpack_sockaddr_in with JRuby does not unpack the same way regular ruby does.
We downloaded the JRuby which apparently differs than the JRuby built with Logstash 6.0.0.

E.g., if you have an saddr of: 02000050D02B66FA0000000000000000

This unpacks in normal ruby as:

\x02\x00\x00\x50\xD0\x2B\x66\xFA\x00\x00\x00\x00\x00\x00\x00\x00

In the specific version of JRuby (NOT regular JRuby which you can download, but the compiled version of Logstash 6.0.0), if you do the same function, you will get a different answer:

\x00\x02\x00\x50\xD0\x2B\x66\xFA\x00\x00\x00\x00\x00\x00\x00\x00

You'll notice that the first two bytes are flipped.

You can confirm this by entering into the interactive ruby session with the logstash:

./logstash --interactive=irb
irb(main):041:0> a = Socket.sockaddr_in(80, "208.43.102.250")
=> "\x00\x02\x00P\xD0+f\xFA\x00\x00\x00\x00\x00\x00\x00\x00"

So in order to compensate for this calculation, you'll have to flip the first two bytes (0200 to 0002) in order to get the correct answer.

I'd be very interested in why this is the reason from one of the devs.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.