Skip to content

Commit

Permalink
Merge pull request #3 from onet-git/master
Browse files Browse the repository at this point in the history
Extend SSL support and add compatibility with fluentd 1.x
  • Loading branch information
richm committed Jan 7, 2020
2 parents f32f777 + fae647b commit 0ec2210
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 103 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
@@ -1,8 +1,8 @@
language: ruby
rvm:
- 2.1
- 2.2
- 2.3
- 2.5
- 2.6
- 2.7
gemfile:
- Gemfile

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed
- moved plugin version definition to separate file
- new configuration options for ssl

## [0.2.0] - 2017-10-19
### Added
Expand Down Expand Up @@ -42,4 +43,3 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Version number started to follow Semantic versioning
- First released rubygem with correct dependencies

34 changes: 21 additions & 13 deletions README.md
Expand Up @@ -22,7 +22,7 @@ Or install it yourself as:

just note that you will probably need ruby development libraries installed to do this.

You can also install through `bundler` and use `rake test` to run unit tests for plugin.
You can also install through `bundler` and use `rake test` to run unit tests for plugin.

## Usage

Expand All @@ -32,31 +32,39 @@ To use the plugin just add tou your fluent.conf file:
@type relp
#optionally, specify port on which to start relp server, defaults to 5170
port XXXX
#optionally, specify a tag with which to mark messages received over this connection
#optionally, specify a tag with which to mark messages received over this connection
tag your_tag_for_relp
#optionally, determine remote IP to bind to, by default binds to all incoming connections
bind XX.XX.XX.XX
#if you want to use TLS encryption, specify this config string
ssl_config /path_to/certificate_file:/path_to/key_file:/path_to/certificate_authority_file
#if you want to use TLS encryption specify this
<ssl_cert>
cert /path_to/certificate_file
key /path_to/key_file
<extra_cert>
cert /path_to/chain_file
</extra_cert>
</ssl_cert>
#if you need a CA file to verify clients specify this
ssl_ca_file /path_to/certificate_authority_file
</source>
```
With the above set up your fluentd is ready to accept messages transported by RELP, for example logs
sent by rsyslog's `omrelp` module, example of setting up (/etc/rsyslog.conf file):

```aconf
```aconf
module(load="omrelp")
*.* action(type="omrelp"
Target="your_fluentd_host_or_ip"
*.* action(type="omrelp"
Target="your_fluentd_host_or_ip"
Port="5170_or_yours_set"
# Add below part to use SSL encryption
# Add below part to use SSL encryption
tls="on"
tls.permittedPeer="SHA1:hash_of_your_certificate_file"
tls.authMode="fingerprint"
tls.mycert="/path_to/certificate_file"
tls.myprivkey="/path_to/key_file"
tls.cacert="/path_to/certificate_authority_file"
tls.permittedPeer="your_fluentd_host"
tls.authMode="name"
tls.mycert="/path_to/syslog_host_certificate_file"
tls.myprivkey="/path_to/syslog_host_key_file"
tls.cacert="/path_to/certificate_authority_file_for_fluentd_host"
)
```
make sure you have librelp and rsyslog relp plugin present on your system.
Expand Down
11 changes: 5 additions & 6 deletions Rakefile
@@ -1,10 +1,9 @@
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
require 'bundler/gem_tasks'
require 'rake/testtask'
Rake::TestTask.new do |test|
test.libs << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true
end

task :default => :test

task default: :test
25 changes: 12 additions & 13 deletions fluent-plugin-relp.gemspec
@@ -1,28 +1,27 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'fluent/plugin/relp/version'

Gem::Specification.new do |gem|
gem.name = 'fluent-plugin-relp'
gem.version = Fluent::RelpPlugin::VERSION
gem.author = "Jiří Vymazal"
gem.version = Fluent::RelpPlugin::VERSION
gem.author = 'Jiří Vymazal'
gem.email = ['jvymazal@redhat.com']
gem.summary = "Fluent plugin to receive messages via RELP"
gem.description = "Plugin allowing recieving log messages via RELP protocol from e.g. syslog"
gem.summary = 'Fluent plugin to receive messages via RELP'
gem.description = 'Plugin allowing recieving log messages via RELP protocol from e.g. syslog'
gem.homepage = 'https://github.com/ViaQ/fluent-plugin-relp'
gem.license = "MIT"
gem.license = 'MIT'

gem.files = Dir['{lib,bin,test}/**/*'] + ['LICENSE.txt', 'README.md', 'Rakefile', 'CHANGELOG.md']
gem.test_files = Dir['{test}/**/*']
gem.require_paths = ["lib"]
gem.require_paths = ['lib']

gem.required_ruby_version = '>= 2.0.0'
gem.required_ruby_version = '>= 2.5'

gem.add_development_dependency 'rake', '~> 0'
gem.add_development_dependency 'test-unit', '~> 3.1'
gem.add_development_dependency 'simplecov', '~> 0'
gem.add_development_dependency 'coveralls', '~> 0'
gem.add_runtime_dependency 'fluentd', '~> 0.12.0'
gem.add_development_dependency 'rake', '>= 10'
gem.add_development_dependency 'simplecov', '~> 0'
gem.add_development_dependency 'test-unit', '~> 3.1'
gem.add_runtime_dependency 'fluentd', '~> 1'
gem.add_runtime_dependency 'relp', '~> 0.2'
end
85 changes: 58 additions & 27 deletions lib/fluent/plugin/in_relp.rb
Expand Up @@ -14,47 +14,78 @@ class RelpInput < Input
desc 'The bind address to listen to.'
config_param :bind, :string, default: '0.0.0.0'
desc 'SSL configuration string, format certificate_path:key_path:certificate_authority_path'
config_param :ssl_config, :string, default: nil
config_param :ssl_config, :string, default: nil, deprecated: 'Use ssl_cert and ssl_ca_file instead'

config_section :ssl_cert, param_name: :ssl_certs, multi: true, required: false do
desc 'Path to server SSL cert'
config_param :cert, :string
desc 'Path to server SSL cert key'
config_param :key, :string
config_section :extra_cert, param_name: :extra_certs, multi: true, required: false do
desc 'Path to extra server SSL certs'
config_param :cert, :string
end
end
desc 'SSL ca_file for clients'
config_param :ssl_ca_file, :string, default: nil

@ssl_context = nil

def configure(conf)
super
super
if !@ssl_config.nil? || !@ssl_certs.empty? || !@ssl_ca_file.nil?
@ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1_2)
end
unless @ssl_config.nil?
@ssl_context.ca_file = @ssl_config.split(':')[2]
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
key = OpenSSL::PKey::RSA.new(File.open(@ssl_config.split(':')[1]))
cert = OpenSSL::X509::Certificate.new(File.open(@ssl_config.split(':')[0]))
@ssl_context.add_certificate(cert, key)
end
@ssl_certs.each do |ssl_cert|
cert = OpenSSL::X509::Certificate.new(File.open(ssl_cert.cert))
key = OpenSSL::PKey::RSA.new(File.open(ssl_cert.key))
extra = []
ssl_cert.extra_certs.each do |extra_cert|
extra << OpenSSL::X509::Certificate.new(File.open(extra_cert.cert))
end
@ssl_context.add_certificate(cert, key, extra)
end
if @ssl_ca_file
@ssl_context.ca_file = @ssl_ca_file
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
end
end

def start
super
ssl_context = nil
if @ssl_config != nil
ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1_2)
ssl_context.ca_file = @ssl_config.split(':')[2]
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
ssl_context.key = OpenSSL::PKey::RSA.new(File.open(@ssl_config.split(':')[1]))
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(@ssl_config.split(':')[0]))
end
log.info "config complete, RELP plugin:'v", RelpPlugin::VERSION, "' with RELP lib:'v", Relp::VERSION, "' starting..."
@server = Relp::RelpServer.new(@port, method(:on_message), @bind, ssl_context, log)
@thread = Thread.new(&method(:run))
super
log.info "config complete, RELP plugin:'v", RelpPlugin::VERSION, "' with RELP lib:'v", Relp::VERSION, "' starting..."
@server = Relp::RelpServer.new(@port, method(:on_message), @bind, @ssl_context, log)
@thread = Thread.new(&method(:run))
end

def shutdown
super
@server.server_shutdown
@thread.join
super
@server.server_shutdown
@thread.join
end

def run
@server.run()
rescue => e
log.error "unexpected error", error: e, error_class: e.class
log.error_backtrace
@server.run
rescue StandardError => e
log.error 'unexpected error', error: e, error_class: e.class
log.error_backtrace
retry
end

def on_message(msg)
time = Engine.now
record = {"message"=> msg}
router.emit(@tag, time, record)
rescue => e
log.error msg.dump, error: e, error_class: e.class
log.error_backtrace
time = Engine.now
record = { 'message' => msg }
router.emit(@tag, time, record)
rescue StandardError => e
log.error msg.dump, error: e, error_class: e.class
log.error_backtrace
end
end
end
2 changes: 1 addition & 1 deletion lib/fluent/plugin/relp/version.rb
@@ -1,5 +1,5 @@
module Fluent
module RelpPlugin
VERSION = '0.2.0'.freeze
VERSION = '0.3.0'.freeze
end
end
21 changes: 21 additions & 0 deletions test/ca.pem
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDgTCCAmmgAwIBAgIJAM/qMx/Jus/wMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAsMB0NBIENlcnQwHhcNMTkxMjMxMTgxMTA0
WhcNMjkxMjI4MTgxMTA0WjBXMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1T
dGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRAwDgYDVQQL
DAdDQSBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgb1/heu
RNpxibN3OL44CfYiwotJx91QRMVHs+FUsOLbKOcrulUJqqLsiIqn2bj8id3++95a
t3sasCVyo6gT/EMMC7yeHsMohSEjLMz1DFGmvKggZ61MEzu8nJ5rfGip3UrdGkGW
v2b4vS8wdBUqCZQQHP0EG7HbPGaGW9nFKdYrLnPCjk5jx70mAR0Wt8PtYWxjECtR
uILQxn+V2unZuh2UPGZbPguNHhMmTUr2xo2Q3DCE5vKhPgZwIACCp7IMZa3FnufB
M4eRCHUNEGU5cQoCTRwXqI258mYvLDfgX4VkybFtID0Q3ojAQ9Y/LI8WIlnPgb5f
Lf6cN1R2ER2CVwIDAQABo1AwTjAdBgNVHQ4EFgQUTgDOQ//ngoeN2AVhdfACYPxJ
+nUwHwYDVR0jBBgwFoAUTgDOQ//ngoeN2AVhdfACYPxJ+nUwDAYDVR0TBAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAQEARwPfIKgyMjiNknc/Rjoicoz7t+BkSuCGsMcj
KIvfpMDKlPHCnkg8OsEalc9O5P9PpfIWpokSfj++EY2yMsZq0IEtK+1m+NKL8W/o
5dGEMxpmQcaj1soJdHUmYRlyPXEMKADup6EFr7oaELad7MKRwBwxLhDTmqciMvJs
As0tqC6uSp6uSSGQblmgMlB7FM3UmatzAGxvYB3eiRttCK3r5w6rMVjbIaxYiXJ2
qQThzuI+nj40w4dHmU0qKFrOQibvyCndVUGsNfjDD7qPO7ucVme4xU4Wp4Zn0M8D
M7p27zUXpj/ZRJte9Q3nIYhi4l3MW1hM2C9OP/qQJUity6VR9w==
-----END CERTIFICATE-----
15 changes: 9 additions & 6 deletions test/helper.rb
@@ -1,14 +1,17 @@
# IMPORTANT: for code coverage testing to work, the 4 below lines MUST
# IMPORTANT: for code coverage testing to work, these lines MUST
# stay right on top (before anything else)
require 'simplecov'
SimpleCov.start
require 'coveralls'
Coveralls.wear!

# Use both simplecov local and coveralls remote coverage reports.
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::HTMLFormatter,
Coveralls::SimpleCov::Formatter
])
SimpleCov.start

# rest can continue below
###############################################################################
require 'bundler/setup'
require 'test/unit'

$LOAD_PATH.unshift(File.join(__dir__, '..', 'lib'))
$LOAD_PATH.unshift(__dir__)
require 'fluent/test'

0 comments on commit 0ec2210

Please sign in to comment.