46

I'm trying to set up logstash forwarder, but I have issues with making a proper secure channel. Trying to configure this with two ubuntu (server 14.04) machines running in virtualbox. They are 100% clean (not touched hosts file or installed any other packages other than the required java, ngix, elastisearch, etc, for logstash)

I do not believe this is a logstash issue, but improper handling of certificates or something not set correct either on the logstash ubuntu or forwarder machine.

I generated the keys:

sudo openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout private/logstash-forwarder.key -out certs/logstash-forwarder.crt

My input conf on logstash server:

input {
  lumberjack {
    port => 5000
    type => "logs"
    ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"
    ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"
  }
}

Keys were copied to forwarder host, which has the following config.

{
  "network": {
    "servers": [ "192.168.2.107:5000" ],
    "timeout": 15,
    "ssl ca": "/etc/pki/tls/certs/logstash-forwarder.crt"
    "ssl key": "/etc/pki/tls/certs/logstash-forwarder.key"
  },
  "files": [
    {
      "paths": [
        "/var/log/syslog",
        "/var/log/auth.log"
       ],
      "fields": { "type": "syslog" }
    }
   ]
}

With logstash server running, I 'sudo service logstash-forwarder start' on the forwarder machine, giving me the following repeated error:

Jul  9 05:06:21 ubuntu logstash-forwarder[1374]: 2014/07/09 05:06:21.589762 Connecting to [192.168.2.107]:5000 (192.168.2.107)
Jul  9 05:06:21 ubuntu logstash-forwarder[1374]: 2014/07/09 05:06:21.595105 Failed to tls handshake with 192.168.2.107 x509: cannot validate certificate for 192.168.2.107 because it doesn't contain any IP SANs
Jul  9 05:06:22 ubuntu logstash-forwarder[1374]: 2014/07/09 05:06:22.595971 Connecting to [192.168.2.107]:5000 (192.168.2.107)
Jul  9 05:06:22 ubuntu logstash-forwarder[1374]: 2014/07/09 05:06:22.602024 Failed to tls handshake with 192.168.2.107 x509: cannot validate certificate for 192.168.2.107 because it doesn't contain any IP SANs

As I mentioned earlier, I do not believe this is a logstash issue, but certificate/machine config issue. Problem is, I can't seem to solve it. Hopefully some clever minds here can help me out?

Thanks

connery
  • 495
  • 1
  • 4
  • 8

5 Answers5

51

... Failed to tls handshake with 192.168.2.107 x509: cannot validate certificate for 192.168.2.107 because it doesn't contain any IP SANs

SSL needs identification of the peer, otherwise your connection might be against a man-in-the-middle which decrypts + sniffs/modifies the data and then forwards them encrypted again to the real target. Identification is done with x509 certificates which need to be validated against a trusted CA and which need to identify the target you want to connect to.

Usually the target is given as a hostname and this is checked against the subject and subject alternative names of the certificate. In this case your target is a IP. The validate the certifcate successfully the IP must be given n the certificate inside the subject alternative names section, but not as an DNS entry (e.g. hostname) but instead as IP.

So what you need to is:

  1. Edit your /etc/ssl/openssl.cnf on the logstash host - add subjectAltName = IP:192.168.2.107 in [v3_ca] section.

  2. Recreate the certificate

  3. Copy the cert and key to both hosts

PS Consider adding -days 365 or more to the certificate creation commandline as the default certificate validity is just 30 days and you probably do not want to recreate it every month..

Greg Dubicki
  • 1,191
  • 1
  • 14
  • 30
Steffen Ullrich
  • 12,227
  • 24
  • 37
  • Thanks for the quick reply. I generated a new certificate on the server. A quick inspect gives me the following: Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=192.168.2.107 Where 2.107 is the logstash server ip. I then copy the crt and key over to the other machine (forwarder) and apply it to the configuration. Does this sound correct to you? Cause it's still whining about the same thing...:P – connery Jul 09 '14 at 04:53
  • Please ignore my comment above. I have now edited /etc/ssl/openssl.cnf and added subjectAltName=IP:192.168.2.107 Created a new cert with: 'sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout private/logstash-forwarder.key -out certs/logstash-forwarder.crt' Copied them over and applied config and restart (on both boxes). Unfortunately still the same issue. Having a hard time googling similar cases on this, so hopefully you are able to guide me to the correct path? :) – connery Jul 09 '14 at 05:12
  • 1
    Really the same issue or another error message (like unknown CA or similar)? Please post the essential part of the certificate, e.g. `openssl x509 -text` from the certificate installed on the server. Please check also with `openssl s_client` that the server returns the expected certificate and use `-CApath` with s_client to check that the trust chain can be verified against the configured CA. – Steffen Ullrich Jul 09 '14 at 05:26
  • I managed to get it to work. I put subjectAltName in the wrong section. Working method: Basically I edited openssl.cnf, in section [v3_ca] I added 'subjectAltName = IP:192.168.2.107'. Produced new certificate and added to server + client. Thanks for your help! :) – connery Jul 09 '14 at 18:54
13

There is a script for creating proper certs for lumberjack that was mentioned on a logstash github ticket: SSL handshake fails because IP SANs are missing

Download the file:

curl -O https://raw.githubusercontent.com/driskell/log-courier/1.x/src/lc-tlscert/lc-tlscert.go

...build it:

go build lc-tlscert.go

..and run:

./lc-tlscert 
Specify the Common Name for the certificate. The common name
can be anything, but is usually set to the server's primary
DNS name. Even if you plan to connect via IP address you
should specify the DNS name here.

Common name: you_domain_or_whatever

The next step is to add any additional DNS names and IP
addresses that clients may use to connect to the server. If
you plan to connect to the server via IP address and not DNS
then you must specify those IP addresses here.
When you are finished, just press enter.

DNS or IP address 1: 172.17.42.1 (th ip address to trust)
DNS or IP address 2: 

How long should the certificate be valid for? A year (365
days) is usual but requires the certificate to be regenerated
within a year or the certificate will cease working.

Number of days: 3650
Common name: what_ever
DNS SANs:
    None
IP SANs:
    172.17.42.1

The certificate can now be generated
Press any key to begin generating the self-signed certificate.

Successfully generated certificate
    Certificate: selfsigned.crt
    Private Key: selfsigned.key

Copy and paste the following into your Log Courier
configuration, adjusting paths as necessary:
    "transport": "tls",
    "ssl ca":    "path/to/selfsigned.crt",

Copy and paste the following into your LogStash configuration, 
adjusting paths as necessary:
    ssl_certificate => "path/to/selfsigned.crt",
    ssl_key         => "path/to/selfsigned.key",
GreatSUN
  • 3
  • 1
michaelbn
  • 283
  • 2
  • 10
8

I had a real issue with this. I'm not using logstash, I was simply trying to get IP SANs to work with docker tls. I would create the certificate as described in the docker article on https (https://docs.docker.com/articles/https/), then when I would connect from a docker client:

docker --tlsverify  -H tcp://127.0.0.1:2376 version

I would get this error :

...
FATA[0000] An error occurred trying to connect: Get https://127.0.0.1:2376/v1.16/version: \
x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs 

which was driving me crazy. I admit, I stumble around in all things openssl, so, everybody might already know what I discovered. The subjectAltName example here (and every where else) shows updating the openssl.cnf file. I couldn't get that to work. I did a locate on the openssl.cnf, copy it to a local directory, then made the changes to it. When I examined the cert it did not contain the extension:

openssl x509 -noout -text -in server-cert.pem

The command being used to create that cert is here (from the docker article):

openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem \
    -CAcreateserial -out server-cert.pem

You can't add a -config openssl.cnf line to this command, it is not valid. Nor can you copy the openssl.cnf file to the current directory, modify it, and hope to get it to work that way. A few lines later I noticed that the 'client' cert uses an -extfile extfile.cnf. So, I tried this:

echo subjectAltName = IP:127.0.0.1 > extfile.cnf
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
   -out server-cert.pem -extfile extfile.cnf

and that fixed it. So, for whatever reason my version of openssl wasn't allowing me to modify the openssl.cnf file, but, I could specify the subjectAltName like this. Works great!

You can specify any number of IP addresses, like IP:127.0.0.1,IP:127.0.1.1 (non localhost as well).

Greg
  • 181
  • 1
  • 3
  • Ah-Ha! Thank you, I am doing the same thing as you with docker and hit this issue. I will try your suggestions now. – Mark Jones Mar 17 '16 at 09:09
2

As of OpenSSL 1.1.1, providing subjectAltName directly on command line becomes much easier, with the introduction of the -addext flag to openssl req

Example:

export HOST="my.host"
export IP="127.0.0.1"
openssl req -newkey rsa:4096 -nodes -keyout ${HOST}.key -x509 -days 365 -out ${HOST}.crt -addext 'subjectAltName = IP:${IP}' -subj '/C=US/ST=CA/L=SanFrancisco/O=MyCompany/OU=RND/CN=${HOST}/'

Inspired by link

ofirule
  • 143
  • 7
0

Please see @Steffen Ullrich's solution above for the quick fix.

There is also an issue/a discussing about it in the logstash-forwarder project's github. See it (soon, as currently work on it is in progress) for an easier solution.

Greg Dubicki
  • 1,191
  • 1
  • 14
  • 30