From fa921a732a886ddb6817116187c69e7763f1a854 Mon Sep 17 00:00:00 2001 From: Tero Saarni Date: Tue, 4 Mar 2025 16:22:00 +0200 Subject: [PATCH] Added support for ssl_cipher_suites * Added support to set cipher suites for TLS connection. * Replaced expired test certificate. Signed-off-by: Tero Saarni --- CHANGELOG.md | 1 + docs/index.asciidoc | 10 +++++++ lib/logstash/outputs/syslog.rb | 5 ++++ spec/fixtures/certs.yaml | 2 ++ spec/fixtures/client-key.pem | 52 ++++++++++++++++----------------- spec/fixtures/client.pem | 32 ++++++++++---------- spec/outputs/syslog_tls_spec.rb | 17 +++++++++-- 7 files changed, 75 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a363b..d584dd8 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 cipher suites for TLS connections [#75](https://github.com/logstash-plugins/logstash-output-syslog/pull/75) ## 3.0.5 - Docs: Set the default_codec doc attribute. diff --git a/docs/index.asciidoc b/docs/index.asciidoc index c33f48e..cb1c6e7 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 +| <> |list of <>|No | <> |<>|No | <> |<>|No |======================================================================= @@ -246,6 +247,15 @@ 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_cipher_suites"] +===== `ssl_cipher_suites` + + * Value type is a list of <> + * There is no default value for this setting + +The list of cipher suites to use, listed by priorities. +Supported cipher suites vary depending on the Java and protocol versions. + [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..d5ead9b 100644 --- a/lib/logstash/outputs/syslog.rb +++ b/lib/logstash/outputs/syslog.rb @@ -89,6 +89,10 @@ 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 + # The list of cipher suites to use, listed by priorities. + # Supported cipher suites vary depending on which version of Java is used. + config :ssl_cipher_suites, :validate => :string, :list => true + # use label parsing for severity and facility levels # use priority field if set to false config :use_labels, :validate => :boolean, :default => true @@ -247,6 +251,7 @@ def setup_ssl ssl_context = OpenSSL::SSL::SSLContext.new ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert)) ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@ssl_key),@ssl_key_passphrase) + ssl_context.ciphers = @ssl_cipher_suites if @ssl_cipher_suites&.any? if @ssl_verify cert_store = OpenSSL::X509::Store.new # Load the system default certificate path to the store 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..04ca7e3 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.cipher).to eq(chosen_cipher) if defined?(chosen_cipher) read = socket.sysread(100) expect(read.size).to be > 0 expect(read).to match(output) @@ -54,6 +55,7 @@ ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(server_cert_file)) ssl_context.key = OpenSSL::PKey::read(File.read(server_pkey_file), nil) ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER + ssl_context.ciphers = "ALL" ssl_context.cert_store = OpenSSL::X509::Store.new ssl_context.cert_store.add_cert(OpenSSL::X509::Certificate.new(File.read(File.join(FIXTURES_PATH, "ca.pem")))) OpenSSL::SSL::SSLServer.new(server, ssl_context) @@ -64,11 +66,22 @@ 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 cipher suites" do + let(:options ) { super().merge("ssl_cipher_suites" => ["TLS_CHACHA20_POLY1305_SHA256"]) } + let(:chosen_cipher) { "TLS_CHACHA20_POLY1305_SHA256" } + + it_behaves_like "syslog output" + end + end context "server with untrusted certificates" do