# fluent-plugin-secure-forward
[Fluentd](http://fluentd.org) input/output plugin to forward fluentd messages over SSL with authentication.
## Plugin status
**NOTE: This plugin will not be updated anymore.**
[Fluentd v0.14.12](http://www.fluentd.org/blog/fluentd-v0.14.12-has-been-released) supports event forwarding via encrypted network communication. Use that feature instead of using this plugin.
## Overview
This plugin makes you to be able to:
* protect your data from others in transferring with SSL
* with certificate signed and registered correctly/publicly
* with private CA certificates generated by users
* with automatically generated and self-signed certificates **in vulnerable way**
* authenticate by shared\_key check from both of client(out\_secure\_forward) and server(in\_secure\_forward)
* authenticate with username / password pairs
## Installation
install with gem or fluent-gem command as:
```
### native gem
$ gem install fluent-plugin-secure-forward
### fluentd gem
$ fluent-gem install fluent-plugin-secure-forward
```
### Using SSL certificates issued from trusted CA
To communicate over SSL with valid certificate issued from public CA, configure params below for input plugin:
* `secure`: set `yes` or `true`
* `cert_path`: set path of certificate file issued from CA
* `private_key_path`: set path of private key file
* `private_key_passphrase`: set passphrase of private key
```apache
```
For output plugin, specify just 2 options below:
* `secure`: set `yes` or `true`
* `enable_strict_verification`: specify `yes` or `true` to verify FQDN of servers (input plugin)
```apache
@type secure_forward
self_hostname client.fqdn.local
shared_key secret_string
secure yes
enable_strict_verification yes
host server.fqdn.example.com # or IP
# port 24284
host 203.0.113.8 # ip address to connect
hostlabel server.fqdn.example.com # specify hostlabel for FQDN verification if ipaddress is used for host
```
### Using private CA file and key
This plugin has a simple utility command to generate private CA cert/key files just for secure-forward.
```
$ secure-forward-ca-generate /path/for/dir/of/certs "passphrase for private CA secret key"
```
This command generates `ca_cert.pem` and `ca_key.pem` on `/path/for/dir/of/certs`. For SSL communication with private CA, users must deploy both files for input plugins, and also must deploy `ca_cert.pem` for output plugins.
And then, configure Fluentd with these files and the passphrase. With this configuration, server certificates are automatically generated and issued by private CA.
```apache
```
For output plugin, specify just 2 options below:
* `secure`: set `yes` or `true`
* `enable_strict_verification`: specify `yes` or `true`
```apache
@type secure_forward
self_hostname myclient.local
shared_key secret_string
secure yes
ca_cert_path /path/for/certificate/ca_cert.pem
# enable_strict_verification yes
host server.fqdn.example.com # or IP
# port 24284
host 203.0.113.8 # ip address to connect
hostlabel server.fqdn.example.com # specify hostlabel for FQDN verification if ipaddress is used for host
```
### Using insecure self-signed certificates
**This is very dangerous and vulnerable to man-in-the-middle attacks**
For just testing or data center internal communications, this plugin has a feature to communicate without any verification of certificates. Turn `secure` option to `false` to use this feature.
```apache
```
Configure output plugin just same way:
```apache
@type secure_forward
self_hostname myclient.local
shared_key secret_string
secure no
host server.fqdn.example.com # or IP
```
In this mode, output plugin cannot verify peer node of connections. Man-in-the-middle attackers can spoof messages from output plugins under many various situations.
## Configuration
### SecureForwardInput
Default settings:
* listen 0.0.0.0:24284
* `bind 192.168.0.101`
* `port 24284`
* allow to accept from any sources
* allow to connect without authentications
* use certificate automatically generated
* `generate_private_key_length 2048`
* `generate_cert_country US`
* `generate_cert_state CA`
* `generate_cert_locality Mountain View`
* `generate_cert_common_name SAME_WITH_SELF_HOSTNAME_PARAMETER`
* use TLSv1.2
Minimal configurations like below:
```apache
```
To check username/password from clients, like this:
```apache
```
To deny unknown source IP/hosts:
```apache
```
You can use both of username/password check and client check:
```apache
```
### SecureForwardOutput
Minimal configurations like this:
```apache
@type secure_forward
shared_key secret_string
self_hostname client.fqdn.local
secure yes
# and configurations for certs/verification
host server.fqdn.local # or IP
# port 24284
```
Without hostname ACL (and it's not implemented yet), `self_hostname` is not checked in any state. `${hostname}` placeholder is available for such cases.
```apache
@type secure_forward
shared_key secret_string
self_hostname ${hostname}
secure yes
# and configurations for certs/verification
host server.fqdn.local # or IP
# port 24284
```
When specified 2 or more ``, this plugin uses these nodes in simple round-robin order. And servers with `standby yes` will be selected until all of non-standby servers goes down.
If server requires username/password, set `username` and `password` in `` section:
```apache
@type secure_forward
shared_key secret_string
self_hostname client.fqdn.local
secure yes
# and configurations for certs/verification
host first.fqdn.local
hostlabel server.fqdn.local
username repeatedly
password sushi
host second.fqdn.local
hostlabel server.fqdn.local
username sasatatsu
password karaage
host standby.fqdn.local
hostlabel server.fqdn.local
username kzk
password hawaii
standby yes
```
Specify `hostlabel` if server (`in_forward`) have different hostname (`self_host` configuration of `in_forward`) from DNS name (`first.fqdn.local`, `second.fqdn.local` or `standby.fqdn.local`). This configuration variable will be used to check common name (CN) of certifications.
To specify keepalive timeouts, use `keepalive` configuration with seconds. SSL connection will be disconnected and re-connected for each 1 hour with configuration below. In Default (and with `keepalive 0`), connections will not be disconnected without any communication troubles. (This feature is for dns name updates, and SSL common key refreshing.)
```apache
@type secure_forward
shared_key secret_string
self_hostname client.fqdn.local
secure yes
# and configurations for certs/verification
keepalive 3600
host server.fqdn.local # or IP
# port 24284
```
If you connect via Proxy,
set for `proxy_uri` in `` section:
```apache
@type secure_forward
shared_key secret_string
self_hostname client.fqdn.local
secure yes
# and configurations for certs/verification
host server.fqdn.local # or IP
# port 24284
proxy_uri http://foo.bar.local:3128
```
## Scenario (developer document)
* server
* in\_secure\_forward
* client
* out\_secure\_forward
### Handshake
1. (client) connect to server
* on SSL socket handshake, checks certificate and its significate (in client)
2. (server)
* check network/domain acl (if enabled)
* check client dns reverse lookup result (if enabled)
* disconnect when failed
3. (server) send HELO
* ['HELO', options(hash)]
* options:
* nonce: string as nonce: used for shared key digest (required, v0.3.2 or later)
* auth: string or blank\_string (string: authentication required, and its salt is this value)
* keepalive: bool (allowed or not)
4. (client) send PING
* ['PING', selfhostname, sharedkey\_salt, sha512\_hex(sharedkey\_salt + selfhostname + nonce + sharedkey), username || '', sha512\_hex(auth\_salt + username + password) || '']
5. (server) check PING
* check sharedkey
* check username / password (if required)
* send PONG FAILURE if failed
* ['PONG', false, 'reason of authentication failure', '', '']
6. (server) send PONG
* ['PONG', bool(authentication result), 'reason if authentication failed', selfhostname, sha512\_hex(salt + selfhostname + nonce + sharedkey)]
7. (client) check PONG
* check sharedkey
* disconnect when failed
8. connection established
* send data from client (until keepalive expiration)
### Data transferring
CONSIDER RETURN ACK OR NOT
* Current version has no ACKs
* only supports burst transferring (same as ForwardInput/Output)
* ack for each message ?
* pipeline mode and one-by-one mode ?
* data sequence number in keepalive session ?
## TODO
* ACK mode (protocol)
* support disabling keepalive (input/output)
* access control (input plugin)
* network acl / domain acl
* check connecting source ip and its dns reverse lookup result (for domaian acl)
* access deny on accept (against DoS)
* pluggable authentication database (input plugin)
* RDBMS, LDAP, or ...
* Authentication by clients certificate
* TESTS!
## Copyright
* Copyright (c) 2013- TAGOMORI Satoshi (tagomoris)
* License
* Apache License, Version 2.0