diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a363b..af2a2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Added support for RFC5424 structured data [#67](https://github.com/logstash-plugins/logstash-output-syslog/pull/67) - The SNI (Server Name Indication) extension is now used when connecting to syslog server with TLS and `host` is set to FQDN (Fully Qualified Domain Name) [#66](https://github.com/logstash-plugins/logstash-output-syslog/pull/66) - Add support for CRL to check for the server certificate is revocation status [#62](https://github.com/logstash-plugins/logstash-output-syslog/pull/62) + - Added support for setting TLS protocol version [#77](https://github.com/logstash-plugins/logstash-output-syslog/pull/77) ## 3.0.5 - Docs: Set the default_codec doc attribute. diff --git a/docs/index.asciidoc b/docs/index.asciidoc index c33f48e..5d55e17 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -60,6 +60,7 @@ This plugin supports the following configuration options plus the <> |<>|No | <> |a valid filesystem path|No | <> |<>|No +| <> |<>|No | <> |<>|No | <> |<>|No |======================================================================= @@ -246,6 +247,23 @@ File may contain one or more PEM encoded CRLs. If this option is set to false, only the certificate at the end of the certificate chain will be subject to validation by CRL. If set to true the complete chain is validated. CRLs must be available from all CAs. +[id="plugins-{type}s-{plugin}-ssl_supported_protocols"] +===== `ssl_supported_protocols` + + * Value type is <> + * Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'` + * Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`. + `'TLSv1.1'` is not considered secure and is only provided for legacy applications. + +List of allowed SSL/TLS versions to use when establishing a connection to the HTTP endpoint. + +For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the +`LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash. + +NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash, +the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in +the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list. + [id="plugins-{type}s-{plugin}-use_labels"] ===== `use_labels` diff --git a/lib/logstash/outputs/syslog.rb b/lib/logstash/outputs/syslog.rb index c2b2171..f0e4deb 100644 --- a/lib/logstash/outputs/syslog.rb +++ b/lib/logstash/outputs/syslog.rb @@ -89,6 +89,9 @@ class LogStash::Outputs::Syslog < LogStash::Outputs::Base # Check CRL for only leaf certificate (false) or require CRL check for the complete chain (true) config :ssl_crl_check_all, :validate => :boolean, :default => false + # NOTE: the default setting [] uses Java SSL engine defaults. + config :ssl_supported_protocols, :validate => ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], :default => [], :list => true + # use label parsing for severity and facility levels # use priority field if set to false config :use_labels, :validate => :boolean, :default => true @@ -267,6 +270,15 @@ def setup_ssl ssl_context.cert_store = cert_store ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT end + + ssl_context.min_version = :TLS1_1 # not strictly required - JVM should have disabled TLSv1 + if ssl_supported_protocols.any? + disabled_protocols = ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'] - ssl_supported_protocols + # mapping 'TLSv1.2' -> OpenSSL::SSL::OP_NO_TLSv1_2 + disabled_protocols.map! { |v| OpenSSL::SSL.const_get "OP_NO_#{v.sub('.', '_')}" } + ssl_context.options = disabled_protocols.reduce(ssl_context.options, :|) + end + ssl_context end end diff --git a/spec/fixtures/certs.yaml b/spec/fixtures/certs.yaml index 479c6b2..e7f2bad 100644 --- a/spec/fixtures/certs.yaml +++ b/spec/fixtures/certs.yaml @@ -31,4 +31,6 @@ sans: subject: cn=client issuer: cn=ca key_type: RSA +not_before: 1970-01-01T00:00:00Z +not_after: 2100-01-01T00:00:00Z --- diff --git a/spec/fixtures/client-key.pem b/spec/fixtures/client-key.pem index 3cfcfd1..837a6f4 100644 --- a/spec/fixtures/client-key.pem +++ b/spec/fixtures/client-key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCnPqjlJMF4uvsN -t1kdrVP/Zi3KS3dvCg2Dpg1BAyo0nhe8vKHAAK0TE9//peTOqt5P+hps7fw4SG3N -ZNmmkOk8u6B0I15FLHywTsMPU9H+gLrte8Y/yZC4AbdmVrYFml83Q41wGj8UM05t -pslVMfkveNkG/LBzKrPENo2Wb2+2/Um/BzNsaX0bhg7MGesD8TjhMFmh+kvChUMp -jFK4dKDOlXFMBLd43wtNVeWDz7duNx/oz6LyQ5JsAmVCHCMxlgc4GQEeUJ2lEnkI -Jw+lwDCKutwIQ4lm6pWAm4KU/BTcA7h6PWM0ku6XnfW7/xbT0FdeKnga8uTO8+vM -7/GqawGLAgMBAAECggEAdJl38QG2LTDXNVHdvJYKGOapB/+jTfQJRf5wASJuu255 -CCnO72jJQaK6qaaEJh30jnfFEqq9DJRakTc9kyY2phP9otrBr6J7cAQJdFcw8anY -KRgBOJmT3uW7cosDrlZZCdN7+WsjDTdT95ivh0km/JTZYkir0C82U5bhEb+xeDZv -f/76b1gDYz3ZrvQMnb4x+60vb9U7iVrnXNEVxle/FhpLNbA9tsFLoSsm/6SbEnju -cyimwmkMnQhPdiN5wmdTzXaTTsM3Ayomtj2bZZMTM9VSrFYAFPYAh2GwX7xn1hmo -gacYqZcXgqu+uIE812hbWEAFmaS3vrxNVAXwa7IjkQKBgQDeR9EdabphDryvgjgA -MUm5TxKKp5Wm9Cz+FiEUASFxoduuCdSb4vq2YGL5PL22MNxmMtYq2oc/dZOMtr45 -hruq0IZmVBNlViqjjcY1J3zvBRWSn93JdSY32o3g3rpgx6/6AZvUzfJmbwVcZBZR -VimCf6oknoNt3lADEJXaVtYBAwKBgQDAnYyGPrufS52dRinnuFVImKX/FvbFDYJI -F31cfi2y4y+g0tFFh0vjG0qVkxkBII5Cy5y1brLYColVWd8gWKibQMJ0TVZfV1ez -gAkR69XIdMLlHl5oXzwyaMYLnsx6MYgzPRHB2ojhtGiEym0dUUrzovl4zB9+LpRd -z6hpMoti2QKBgQDPWo9osMh84hKCZyd2hoQPqgPR9KNWK1INdPdGggeAyUz0/Zao -FQVsPF4XwuH2o332mFXRhCnGuRf7nD23zEglAIFf0+6ECe2cxRSxYTTahBOrxBZR -aEdOs0LHEv8qaR1wSy/jRHtrswV9OqDXH1l5sz41CunwBAL/2Ojx1S+toQKBgQCB -iPK6TXIMXOPwowEHjtX77nykIqNuPfmB1ho+m7TL+zFKrLyET8rfPrlYAgbs1SIX -Faub8Ihh9iQJvFjr/fPWBSVA5cnScIDQfKic3sd0+eEgCN5gvrtTA1c89Vx6SNlZ -7BYHEpq/f35S33emIceQNegkLtJ3H4gz1rVhmdZXcQKBgQCl1OvIJI7FmBzG1XPz -VNkE1nCPhXZEnrR3csZsiJiHCkI+t7izoIwFZZnEaW/+rqrZAWjMdFu11hy0Fz1n -y74CmHrlupOoSbNZlB7w7MfqZydqXT6XXgjHdlnR9+celzkS7HnZ/jxwJChCnznm -JR8q9KOY82PMpTHNnlEoUDqCJA== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHLmhX4dMBPgXc +MoBHVH1IRnjAy3uLIQrCNE1HneZPTvLPAcLw1A6PTg3gLnREqz6o4prlGrcnt0OZ +unqqn3c6lTwG+kNweSip7dDjDNb5aS6Owp6EAmXfkIq7XTb6tAt+au57PnKJQpGV +vEIMoK4gb/USFm+BrOoHkxLfVCQNlLViQ9DF9o0r9VdJJanJWmPrHKsOuvra1ZZk +/9nYAO4KhAraeWXhZyWywXpfhxVjh+rk4ucQIVVSeFtcMHbOpfqSPmb3cKY5Er16 +SQiNTlBquHzF7sz3fIw39rDdaF8G5bieI9VK/5FElavjrGuAo6ST+m9vGqyl01gC +Dx6YYblFAgMBAAECggEAIs4dNZ4kfQcVhxDcEZrV+Zc26pmkEP/JHX5+MpGI+TrW +ew3XvrWPhcMh8ZasgoNaA7D1WCt+7dW8XlSTstUCxJ3nS2DYAANr86W25rYLqrGS +jSe9A1xX6OUdGPiE7vIfQAv3eFnFMe8L+ZpYAFTjmI93x51cBtDsZD5zAct2MVkI +CRB0AdWlvdY4j/FGmDJiDpgFTvBrYDh+fbckFll72Etxt1U7Ssfzw9UTvJWPH1XE +Pr9Ax/kxCwUy3D/h8dQv5q2jz1lGXCHoo7wq7D0vNRn2i/aA8tPHBdplvf2hN77+ +oUnLGTr+kxI42EkTdG+t/IrPslyG0pFz87TIE8DRAQKBgQDsWJr4dBVdWUUjERN/ +PkpcGHtzu6okxGnXmEcInesKo+E24BdEdrR0+XPtw+JDYhpuWRp4Dta1N2/7Btkk +MgL3Me3yuz366Q8GIOZqM0+9Sj8qXleb0R66ozIQJECIVEBUYZQN2JyM/wO8hgfL +oV2S64/fRlAdbqZnjCAFc7yAMQKBgQDXvqDGBxcdU0U1PmDitWydqc8tsNNEDklw +JyzXAXMZ0OEEYTxta7LP72GWleRm9CyUUcNCC7WLiPcTq77oWLjKzQKx//8JnZ9I +tDbsfh3LI9h4GG7vIW6tVLbG/CSMRbtVvqdJewNvQeLb6ARlRTpkAXUb5DQiU4O0 +4hydvHR5VQKBgQDazEBTKCwrKhx+FS3mi0UNs0B+aMpflVGi3H9OM9vHEuXJBnWj +1PzEmba/86rA1M5BP83oPVx5kSPi0XkuL/pc2+U75CnB4gYdl1GYGX6Fb3nAgGw8 +fMEk6TXMibMQQmb3dwo4M0LiqKbN3YrT8cQN4nNjsNU0Gh6FF80BHx7v0QKBgQDH +b7IhvZYxhrOYh6R6jqnsiXg6zZZO+EINCjnaO73SJJSOPvDkWcW/kJOO59tvDNNU +/MxadoaJicCVj5N4J+QTnTabo4F4uxvu0qFfNyqFigpm4ndSWX59fq1D/vwuK5wE +pKzyMWQ4ahiznqTJlRhoMCy47tj+zmMXSFqZugeVzQKBgAcGan9v9Lb7fOVwqcGm +HBFxzFMljr3NNXUwjAfY64NT8jDLoDj7fHgn+kf779CmHam1vqTRgxWouSlrw1DJ +qE7qwd6LsOL+WW0XXCWad5NtgFmoMLaCj2u+Fz9xmZX2QmdaZYo3xtlpDK0i2NzK +SSS5SK+adI5UqxmI0wLlDS4a -----END PRIVATE KEY----- diff --git a/spec/fixtures/client.pem b/spec/fixtures/client.pem index afef11b..52853a0 100644 --- a/spec/fixtures/client.pem +++ b/spec/fixtures/client.pem @@ -1,18 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIC0zCCAbugAwIBAgIIF4RwxFvwiMEwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UE -AxMCY2EwHhcNMjMwOTEzMTEwOTA4WhcNMjQwOTEyMTEwOTA4WjARMQ8wDQYDVQQD -EwZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnPqjlJMF4 -uvsNt1kdrVP/Zi3KS3dvCg2Dpg1BAyo0nhe8vKHAAK0TE9//peTOqt5P+hps7fw4 -SG3NZNmmkOk8u6B0I15FLHywTsMPU9H+gLrte8Y/yZC4AbdmVrYFml83Q41wGj8U -M05tpslVMfkveNkG/LBzKrPENo2Wb2+2/Um/BzNsaX0bhg7MGesD8TjhMFmh+kvC -hUMpjFK4dKDOlXFMBLd43wtNVeWDz7duNx/oz6LyQ5JsAmVCHCMxlgc4GQEeUJ2l -EnkIJw+lwDCKutwIQ4lm6pWAm4KU/BTcA7h6PWM0ku6XnfW7/xbT0FdeKnga8uTO -8+vM7/GqawGLAgMBAAGjMzAxMA4GA1UdDwEB/wQEAwIFoDAfBgNVHSMEGDAWgBRN -ukfgtxJMkwu7XMvQ8ETWqi5BVTANBgkqhkiG9w0BAQsFAAOCAQEAkyK273ywVTm8 -SFssX0igt/sGDD/PMy9D9X5ovg7083g6FFYqdP9bWrkIasXzVb5s0feeV/tAV+DO -sDjHcR7K5SwBjsNdYA+wie5WC1XaKAxSVNfe+VnwbZcgXaHcKPeqG7S3ZHJ3riRh -GTPMArnb/w9+RqWTTSsxEvzw1lPVVbqFDiAPHsg6FTKetNEr83xbOzk4EOAnD2Hq -CgKstcxl+lm8kaIhz1Jd5wVZ68i/+wDLRtk16inkoKIQYFvksdoMjNQLfhc5Cx+h -4+3gOylszUF92SSbipFmEBs5LJ88G3U35xHS/imI9OdsMNdj4HE9Tk7TiuYH3Kt7 -DUOgg4S+0w== +MIIC1TCCAb2gAwIBAgIIGCmaVaybuVEwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UE +AxMCY2EwIBcNNzAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMBExDzANBgNV +BAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcuaFfh +0wE+BdwygEdUfUhGeMDLe4shCsI0TUed5k9O8s8BwvDUDo9ODeAudESrPqjimuUa +tye3Q5m6eqqfdzqVPAb6Q3B5KKnt0OMM1vlpLo7CnoQCZd+QirtdNvq0C35q7ns+ +colCkZW8QgygriBv9RIWb4Gs6geTEt9UJA2UtWJD0MX2jSv1V0klqclaY+scqw66 ++trVlmT/2dgA7gqECtp5ZeFnJbLBel+HFWOH6uTi5xAhVVJ4W1wwds6l+pI+Zvdw +pjkSvXpJCI1OUGq4fMXuzPd8jDf2sN1oXwbluJ4j1Ur/kUSVq+Osa4CjpJP6b28a +rKXTWAIPHphhuUUCAwEAAaMzMDEwDgYDVR0PAQH/BAQDAgWgMB8GA1UdIwQYMBaA +FE26R+C3EkyTC7tcy9DwRNaqLkFVMA0GCSqGSIb3DQEBCwUAA4IBAQCqtyU6GOZX +7uoDQti9KhqNtvQIR2GueBN7A9h+E6xchIReWgWEId5PXzfmwxhlbGeRuB+fxrQ0 +KAsCRP5LxGz4oEU7gsnb6Gffez2urtHwd7Jhf/0pcsVzRdEQ1ZnwGlvc9WjkW37I +HdT9HVsWSotlnq66VPZLbXtnPN5QMmepuheCNl+I1uWEdtI7i+oF/18cFN1Qq8Q8 +N45qS6svlMTJ/Wt4IQR8gEaQgTGPr31UPF31bPik7H9NUDJvmeiJdE1ZGbzcR/X/ +1vCR71eHMXtYUOEb8G1sytiMhb4hZGbY00bmUX5UQjZY5XxJExpKtgxSN1/rSXpl +GXkJ7redVKpS -----END CERTIFICATE----- diff --git a/spec/outputs/syslog_tls_spec.rb b/spec/outputs/syslog_tls_spec.rb index fefd490..860e600 100644 --- a/spec/outputs/syslog_tls_spec.rb +++ b/spec/outputs/syslog_tls_spec.rb @@ -33,6 +33,7 @@ it "should write expected format" do Thread.start { sleep 0.25; subject.receive event } socket = secure_server.accept + expect(socket.ssl_version).to eq(chosen_tls_version) if defined?(chosen_tls_version) read = socket.sysread(100) expect(read.size).to be > 0 expect(read).to match(output) @@ -64,11 +65,36 @@ end context "server with valid certificates" do - let(:options ) { super().merge("ssl_verify" => true) } let(:server_cert_file) { File.join(FIXTURES_PATH, "valid-server.pem") } let(:server_pkey_file) { File.join(FIXTURES_PATH, "valid-server-key.pem") } - it_behaves_like "syslog output" + context "ssl_verify enabled" do + let(:options ) { super().merge("ssl_verify" => true) } + + it_behaves_like "syslog output" + end + + context "with TLSv1.2" do + let(:options ) { super().merge("ssl_supported_protocols" => ["TLSv1.2"]) } + let(:chosen_tls_version) { "TLSv1.2" } + + it_behaves_like "syslog output" + end + + context "with TLSv1.3" do + let(:options ) { super().merge("ssl_supported_protocols" => ["TLSv1.3"]) } + let(:chosen_tls_version) { "TLSv1.3" } + + it_behaves_like "syslog output" + end + + context "with TLSv1.2 and TLSv1.3" do + let(:options ) { super().merge("ssl_supported_protocols" => ["TLSv1.2", "TLSv1.3"]) } + let(:chosen_tls_version) { "TLSv1.3" } + + it_behaves_like "syslog output" + end + end context "server with untrusted certificates" do