Problem
The JS7 can be configured to send JS7 - Notification by mail in case of successful or failed execution of jobs and workflows. A number of errors can indicate that this connection does not work:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) javax.mail.MessagingException: Could not connect to SMTP host: mail.example.com, port: 587
javax.net.ssl.SSLException: Unsupported or unrecognized SSL message javax.mail.MessagingException: Could not connect to SMTP host: mail.example.com, port: 587
javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful
The error messages are raised by the JOC Cockpit JS7 - Monitor Service when trying to send mail. They can be found in the service-monitor.log
file, see JS7 - Log Files and Locations.
Analysis
For mail configuration there are a number of screws that users can turn. It is recommended to narrow down the problem in a systematic way:
- Follow the below steps in the given sequence.
- Do not turn too many screws at the same time. Instead, change one setting then check results by sending mail.
- Do not use mixed settings for different protocols. Instead, choose one protocol and apply settings recommended for that protocol only.
A larger number of e-mail settings is available, see https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html, however, in most cases they are not related to problems connecting to a mail server.
Step 1: Determine Protocol and Port Usage
Mail servers frequently use specific ports per protocol used with a connection. However, technically any port can be used. Your system administrator should provide the information about available protocols and ports:
Port | Protocol | Purpose | Certificate |
---|---|---|---|
25 | SMTP | Plain Text | no |
465 | SMTPS (Implicit SSL) | SMTP over SSL | yes |
587 / 2525 | SMTP (Explicit SSL) | SMTP over TLS (StartTLS) | yes |
Below examples check availability of TLS port 587, examples can similarly be applied to SSL port 465:
# should telnet be available telnet mail.example.com 587 # should nc or ncat be available ncat -v -u mail.example.com 587 # should curl be available curl --ssl --url mail.example.com:587
Output of the above commands has to be closely considered if it indicates availability of the respective port:
# test plain text port curl --ssl --url mail.example.com:25 # output returned # can indicate that the port is not available: # curl: (7) Failed to connect to mail.example.com port 25 after 2186 ms: Connection refused # can indicate that the port is available: # 220 mail.example.com ESMTP Postfix (Debian/GNU) # 221 2.7.0 Error: I can break rules, too. Goodbye. # test SMTP over SSL curl --ssl --url mail.example.com:465 # output returned can indicate that the port is available: # curl: (56) Recv failure: Connection reset by peer # test SMTP over TLS curl --ssl --url mail.example.com:587 # output returned can indicate that the port is not available: # curl: (7) Failed connect to mail.example.com:587; Connection refused
PowerShell can be used to check port availability like this:
Test-NetConnection -ComputerName mail.example.com -Port 587 # output returned includes the TcpTestSucceeded property that indicates availability of the port ComputerName : mail.example.com RemoteAddress : x.x.x.x RemotePort : 465 InterfaceAlias : Ethernet SourceAddress : y.y.y.y TcpTestSucceeded : True
Recommended E-Mail Settings for SMTP over SSL (Port 465)
Depending on the Java version in use different defaults might be in place, therefore users should allow/deny use of SSL/TLS:
Setting | |
---|---|
mail.smtp.starttls.enable | false |
mail.smtp.ssl.enable | true |
Recommended E-Mail Settings for SMTP over TLS (Port 587)
Depending on the Java version in use different defaults might be in place, therefore users should allow/deny use of TLS/SSL:
Setting | |
---|---|
mail.smtp.starttls.enable | true |
mail.smtp.ssl.enable | false |
Step 2: Check Certificates
To establish a secure connection with a TLS port or SSL port a server certificate is used. The mail server presents its server certificate and the client (JOC Cockpit or command line client) verifies the certificate.
# display server certificates openssl s_client -showcerts -connect mail.example.com:587
The above command returns the server certificate or certificate chain. To verify the certificate the client requires access to the Root CA Certificate that has been used to sign the server certificate.
- For use with OpenSSL certificates are available from
/etc/ssl/certs
or similar locations. - For JOC Cockpit operated with Java the certificates are available from the Java
cacerts
file that can be found from different locations depending on the Java version and distribution.- For a JDK 1.8 including a JRE provided by OpenJDK, for example the
jdk8u202-b08/jre/lib/security/cacerts
file is used. - For a JDK 17 provided by OpenJDK, for example the
jdk-17.0.1+12/lib/security/cacerts
file is used.
- For a JDK 1.8 including a JRE provided by OpenJDK, for example the
Usually mail servers use certificates signed by well known certificate authorities who's Root CA Certificates are included in distributions of OpenSSL and Java.
Should the Root CA Certificate not be available from the above location then it can be specified like this:
# verify server certificate from Root CA Certificate openssl s_client -showcerts -connect mail.example.com:587 -CAfile /home/sos/certs/root-ca.crt
The OpenSSL command returns output like this for certificate verification:
In addition to verifying certificates the above output provides information about the SSL protocol version in use and the cipher used for SSL handshake:
SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384
Recommended E-Mail Settings
Typically no settings are required as the mail server's Root CA Certificate can be assumed to be in place.
Should verification of the mail server certificate fail, for example in case of self-signed certificates, then users can
- copy the certificate displayed with above output to their clipboard and paste it to a file,
- import the certificate to the JOC Cockpit truststore, see JS7 - JOC Cockpit HTTPS Connections.
Step 3: Specify SSL Protocol Version
We frequently find the following SSL protocol versions in place:
Protocol Version | Considered Secure |
---|---|
TLSv1 | no |
TLSv1.1 | no |
TLSv1.2 | yes |
TLSv1.3 | yes |
SSLv3 | no |
The JOC Cockpit acting as a client and the mail server have to identify a common SSL protocol version:
- JOC Cockpit: The protocol version is determined by the Java version and by the
java.security
file in place:- An older Java version 1.8 for example, can allow TLSv1 and TLSv1.1 SSL protocol versions that are considered outdated or insecure with the
jdk8u202-b08/jre/lib/security/java.security
file:jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
- TLSv1 and TLSv1.1 protocol versions are not disabled.
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, \
EC keySize < 224, 3DES_EDE_CBC, anon
- A larger number of SSL protocol versions are disabled.
- A newer Java version 17 for example, can disable SSL protocol versions that are considered outdated or insecure with the
jdk-11.0.12+7/conf/security/java.security
file.jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
- It is common practice that the Java versions available in an organization include adjusted copies of the
java.security
file that limit use of SSL protocol versions.
- An older Java version 1.8 for example, can allow TLSv1 and TLSv1.1 SSL protocol versions that are considered outdated or insecure with the
- Mail Server: For compatibility reasons mail servers tend to support outdated or insecure protocol versions for a longer time.
- There is not a simple way to determine all protocol versions supported by a mail server. Typically this requires SSL debugging, see Logging. The SSL debug log states the list of protocol versions offered by the client and by the mail server. If in doubt then your system administrator should know the mail server's supported protocol versions.
Should JOC Cockpit and the mail server not identify a common SSL protocol version then the handshake in communication will fail. In this situation the Java version in use can be updated and/or the java.security
file can be adjusted to allow matching SSL protocol versions.
Recommended E-Mail Settings
A frequent problem is the requirement that the mail server and client should negotiate the protocol version. This does not perfectly work for a number of mail servers, particularly not for Microsoft Exchange® servers.
Users should therefore specify a single protocol version to be used. The above chapter Check Certificates explains the commands that help to determine the SSL protocol version supported by the mail server.
Setting | Value |
---|---|
mail.smtp.ssl.protocols | TLSv1.2 |
Note: Use of the following settings is discouraged:
Setting | Value | Comment |
---|---|---|
mail.smtp.ssl.protocols | TLSv1 | Do not specify an outdated protocol version |
mail.smtp.ssl.protocols | TLSv1.1,TLSv.1.2 | Do not specify more than one protocol version |
Step 4: Verify Ciphers
Wrong use or mismatch of ciphers is not a frequent issue in mail server connections. However, if users have good reason to assume mismatch of ciphers then consider the following explanation.
For handshake in SSL connections the JOC Cockpit acting as a client and the mail server require a common protocol version (see step 3) and a common cipher.
- The SSL protocol version in use determines available ciphers.
- The same ciphers have to be in place with the Java version used by the JOC Cockpit and with the mail server.
- JOC Cockpit: Ciphers are determined by the Java version and the
java.security
file in place:- Older Java versions, for example 1.8, tend to allow ciphers that are considered outdated or insecure. If no recent updates to Java have been applied then newer ciphers might not be available.
- Newer Java versions, for example 17, tend to disallow a number of ciphers that are considered outdated or insecure.
- Mail Server: There is not a simple way to determine all ciphers available with a mail server. Typically this requires SSL debugging, see Logging. The SSL debug log states the list of ciphers offered by the client and by the mail server.
- Cipher mismatch is a possible source of error for example in the following situations:
- An older Java version 1.8 (not recently updated) is used to connect to a mail server that is up-to-date when it comes to use of secure ciphers.
- The mail server denies use of outdated ciphers offered by Java. The Java does not know of newer ciphers offered by the mail server.
- A newer Java version 17 is used to connect to a mail server that is operated with older ciphers.
- The Java denies use of outdated ciphers offered by the mail server. The mail server does not know of newer ciphers offered by Java.
- An older Java version 1.8 (not recently updated) is used to connect to a mail server that is up-to-date when it comes to use of secure ciphers.
- JOC Cockpit: Ciphers are determined by the Java version and the
Should JOC Cockpit and the mail server not identify a common cipher then the handshake in communication will fail. In this situation the Java version in use can be updated and/or the java.security
file can be adjusted to allow a matching cipher.
Step 5: Specify Authentication
Mail servers can be configured to require authentication. Your system administrator provides this information.
To verify the credentials users can setup an e-mail client and check that credentials work.
Recommended E-Mail Settings
Setting | Value |
---|---|
mail.smtp.auth | true |
mail.smtp.user | <account@domain> |
mail.smtp.password | <password> |
Logging
When sending mail then error messages are raised by the JOC Cockpit JS7 - Monitor Service. They can be found in the service-monitor.log
file, see JS7 - Log Files and Locations.
For SSL debugging with JOC Cockpit see JS7 - Log Levels and Debug Options
- The
JAVA_OPTIONS
value-Djavax.net.debug=ssl
can be used - For newer Java versions the
JAVA_OPTIONS
value-Djavax.net.debug=all
can be used that will create more detailed output. - SSL debug output becomes available from the
jetty.log
file:- Consider that SSL debug output is logged for any SSL activity in JOC Cockpit, including access by clients from browsers using HTTPS connections, authentication with an LDAP server using SSL/TLS etc.
- Users should be trained to identify the SSL debug output related to sending mail.
Examples
Example for use of plain text connection (Port 25)
Area | Setting | Value | Comment |
---|---|---|---|
Connection | mail.smtp.host | <mail server host or IP address> | |
mail.smtp.port | 25 | ||
mail.smtp.starttls.enable | false | Deny SMTP over TLS | |
mail.smtp.ssl.enable | false | Deny SMTP over SSL | |
Authentication | mail.smtp.auth | true | Use if mail server requires authentication |
mail.smtp.user | <account@domain> | ||
mail.smtp.password | <password> |
Example for use of SMTP over SSL connection (Port 465)
Area | Setting | Value | Comment |
---|---|---|---|
Connection | mail.smtp.host | <mail server host or IP address> | |
mail.smtp.port | 465 | ||
mail.smtp.starttls.enable | false | Deny SMTP over TLS | |
mail.smtp.ssl.enable | true | Allow SMTP over SSL | |
Protocol Version | mail.smtp.ssl.protocols | TLSv1.2 | Specify the agreed-on protocol version |
Authentication | mail.smtp.auth | true | Use if mail server requires authentication |
mail.smtp.user | <account@domain> | ||
mail.smtp.password | <password> |
Example for use of SMTP over TLS connection (Port 587)
Area | Setting | Value | Comment |
---|---|---|---|
Connection | mail.smtp.host | <mail server host or IP address> | |
mail.smtp.port | 25 | ||
mail.smtp.starttls.enable | true | Allow SMTP over TLS | |
mail.smtp.ssl.enable | false | Deny SMTP over SSL | |
Protocol Version | mail.smtp.ssl.protocols | TLSv1.2 | Specify the agreed-on protocol version |
Authentication | mail.smtp.auth | true | Use if mail server requires authentication |
mail.smtp.user | <account@domain> | ||
mail.smtp.password | <password> |