Search code examples
httphttp-headerslogstashgroklogstash-grok

Logstash configuration: http output with Base 64 encoded headers


I use Logstash with File Input & Http Output to a homegrown service which requires credentials (username:password) to be sent as Base64 encoded value. Below is my Logstash configuration. Currently I can send the Base 64 encoded value via headers however I am looking for a way to encode a String (which would be available to Logstash via environment variable) to a Base 64 encoded String value. Would highly appreciate if anyone can throw some light on this.

input {
 file {
  path => "/home/tom/testData/test2.log"
  type => "log"
 }
}

filter {
 if [type] == "log" {
  grok {
    match => ["message", "%{TIMESTAMP_ISO8601:time} %{LOG:level} %{GREEDYDATA:lmessage}"]
  }
  ruby {
    code => "require 'base64';
    event['pass'] = Base64.encode64('User:Pwd')"
  }

}
}
output {
stdout { codec => rubydebug }
http {
http_method => "post"
  url => "http://10.1.2.3:1123/HomeService?User=Tom"
  format => "message"
  headers => {"Authorization" => "Basic %{pass}"}      
  content_type => "application/json"
  message => '{"Outer": { "Inner": [ {"doc": { "Timestamp": "%{time}", "Single": "%{level}","Double": "%{lmessage}" } } ] } }'
 }
}

Solution

  • You can pull in something from the environment and base64 encode it like this:

        ruby {
                code => "
                        require 'base64';
                        event['password'] = Base64.encode64(ENV['USER_PASS']).sub(/\n/,'')
                "
        }
    

    Then to use it:

     export USER_PASS="dog:cat"
     echo '{"test":1}' |  bin/logstash agent -f logstash.conf
    

    With a config file like this:

    input {
     stdin { codec => json }
    }
    
    filter {
        ruby {
            code => "
                require 'base64';
                event['password'] = Base64.encode64(ENV['USER_PASS'])
            "
        }
    }
    output {
        stdout { codec => rubydebug }
        http {
            http_method => "post"
            url => "http://localhost:1123"
            format => "message"
            headers => {"Authorization" => "Basic %{password}"}
            content_type => "application/json"
            message => '{"whatever": 1 }'
        }
    }
    

    You can see that it does the right thing by running nc -l 1123 and see:

    POST  HTTP/1.1
    host: localhost
    connection: keep-alive
    authorization: Basic ZG9nOmNhdA==
    content-type: application/json
    content-length: 15
    
    {"whatever": 1}
    

    Which is the right value:

    echo ZG9nOmNhdA== | base64 -D
    dog:cat