How to Fix “Failed TLS Handshake: Missing IP SANs” in Logstash Forwarder Setup


2 views

When setting up secure communication between Logstash and its forwarder, many developers encounter the frustrating error:

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

This occurs because modern TLS implementations strictly validate certificate Subject Alternative Names (SANs), and your self-signed certificate lacks the necessary IP SAN entry for your server's IP address.

Here's how to generate a certificate that includes IP SANs:

sudo openssl req -x509 -batch -nodes -newkey rsa:2048 \
  -keyout private/logstash-forwarder.key \
  -out certs/logstash-forwarder.crt \
  -subj "/CN=logstash-server" \
  -addext "subjectAltName = IP:192.168.2.107"

Key points:

  • The -addext flag adds the critical IP SAN entry
  • Replace 192.168.2.107 with your actual server IP
  • The CN (Common Name) should match your server's hostname

Update your Logstash input configuration:

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

Your forwarder config should reference the updated certificate:

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

After making these changes:

  1. Restart both Logstash and the forwarder services
  2. Check logs for successful connection messages
  3. Verify data is flowing to Elasticsearch

For additional verification, you can inspect your certificate:

openssl x509 -in /etc/pki/tls/certs/logstash-forwarder.crt -text -noout

Look for the "X509v3 Subject Alternative Name" section containing your IP address.

If you're still facing issues, consider:

  • Using hostnames instead of IPs in your configuration
  • Setting up a proper CA hierarchy
  • Using DNS SANs if you have DNS resolution

Remember that while disabling certificate verification might seem tempting, it defeats the purpose of TLS security.


The error message "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" indicates a fundamental issue with your SSL certificate configuration. The problem occurs because modern TLS implementations require Subject Alternative Names (SANs) to properly validate certificates when connecting to IP addresses.

When generating certificates for services that will be accessed by IP address (rather than hostname), you must include the IP address in the SAN extension of the certificate. The simple certificate generation command you used:

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

doesn't include any SAN information, which is why the validation fails.

Here's how to generate a certificate that includes the IP SAN:

cat > openssl.cnf <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
C = US
ST = State
L = City
O = Company
OU = Org
CN = 192.168.2.107

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
IP.1 = 192.168.2.107
EOF

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
  -keyout private/logstash-forwarder.key \
  -out certs/logstash-forwarder.crt \
  -config openssl.cnf

After generating the certificate, verify it contains the proper SAN:

openssl x509 -in certs/logstash-forwarder.crt -noout -text | grep -A1 "Subject Alternative Name"

You should see output similar to:

X509v3 Subject Alternative Name: 
    IP Address:192.168.2.107

Once you have the new certificate, update your Logstash input configuration:

input {
  lumberjack {
    port => 5000
    type => "logs"
    ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"
    ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"
    ssl_verify => false # Only for testing, remove in production
  }
}

Update your forwarder configuration to use the new certificate:

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

After restarting both services, test the connection with:

openssl s_client -connect 192.168.2.107:5000 -showcerts

This should now complete successfully without any SAN-related errors.

If you prefer not to use IP SANs, you can:

  1. Add hostnames to your /etc/hosts files
  2. Generate certificates using those hostnames
  3. Configure both ends to use the hostnames

This approach is often cleaner in production environments.

While the solution above works, in production you should:

  • Use proper CA-signed certificates
  • Implement proper certificate rotation
  • Consider using hostname-based certificates instead of IP-based ones
  • Enable full certificate verification once testing is complete