0

Hello i followed some guides on how to do basic auth in logstash. However, when i check the outgoing packet from logstash, the HTTP protocol contains "Authorization: Basic %{password}" instead of "Authorization: Basic <base64 encoded string (user:pass)>"

Also, i want to note that i followed this thread

Here is a image of the HTTP packet

enter image description here

here is my config

input {
  beats {
host => "localhost"
port => 5044
  }
}

filter {
  mutate {
remove_field =>  [ "host", "@timestamp", "@version", "tags", "input", "ecs", "agent", "log", "offset"]
  }
  grok {
patterns_dir => ["C:\\logstash\\patterns"]
match => { "message" => "%{COMMON_TIMESTAMP:timestamp}"}
  }
  ruby {
    code => "
        require 'base64';
        event['password'] = Base64.encode64('root:root').sub(/\n/,'')
    "
  }
}

output {
  stdout { codec => rubydebug }
  http {
    headers => {"Authorization" => "Basic %{password}"}
    url => ["http://localhost:9999/api/v1/logs/data"]
    http_method => "post"
    content_type => "application/json"
    format => json
  }
}

Is there something i missed? plugin maybe?

Additionally i am using logstash-7.7.0

lemoncodes
  • 2,371
  • 11
  • 40
  • 66

1 Answers1

1

The thread you followed is old and a lot has changed since it was posted, now you need to use event.set to create a new field according to the documentation.

When you run your current ruby code it will give you an error in the logs.

Something like this:

[2021-03-26T10:36:44,090][ERROR][logstash.filters.ruby    ][main][3baa937b943ad54239f24db1ed6452cc66a0a3a60153d0a4dca57bf209157627] Ruby exception occurred: undefined method `[]=' for #<LogStash::Event:0x25a508e2>

You should use this code:

ruby {
    code => "
    require 'base64'
    event.set('password', Base64.encode64('root:root').sub(/\n/,''))
    "
}

This will create the password field in your event.

"password" => "cm9vdDpyb290"

update:

To use this password on the headers of the http output filter, you need to create a field with the content of the header first.

mutate {
    add_field => { "myHeader" => "Basic %{password}" }
} 

Then you need to set the header according to the documentation

headers => ["Authorization", "%{myHeader}"]
leandrojmp
  • 7,082
  • 2
  • 19
  • 24
  • Ohhh i see, i tried using `event.set()` however, i can't seem to get the value when i try to use `event.get('password')` in the `headers` fields on `http` or my usage of `event.get()` is wrong. how do i use the `event.get()` on `headers` field? – lemoncodes Mar 26 '21 at 16:34
  • It is not possible to use any filter in the `output` section, but look at the updated answer and see if it works for you. Basically you need to create a field with the content of the header and use this field in the `header` option of the `http` output filter. – leandrojmp Mar 26 '21 at 17:21
  • I tried this one, i get an error `The HTTP header line [authorization:Basic cm9vdDpyb2900] does not conform to RFC 7230 and has been ignored.`. i not sure though but isn't there a space between ":" on the HTTP header for `Authorization`. I checked the HTTP packet, it has space but when my spring app receives it, it has not space after ":" – lemoncodes Mar 27 '21 at 12:36
  • ohh i just notice, there is an extract character in the last part, the zero (0). Isn't this an output of `Base64.encode()`? – lemoncodes Mar 27 '21 at 12:41
  • Got it, I added a `chop` method after `encode()`. but it is kind of weird to think that the output is different. On my side, the output of `Base64.encode64('root:root')` is `cm9vdDpyb2900`, there is an extra `0` on the last. I had to `chop` it so it will be correct. Any ideas as to what happen to `encode`? – lemoncodes Mar 27 '21 at 12:56