7 Replies Latest reply on Feb 20, 2018 6:17 AM by andey

    Secured Communication between WildFly and MySQL

    nitin_jain

      Greetings,

       

      I have configured MySQL database and WildFly 10 for secured communication. To enable SSL MySQL server I have followed instructions listed on How to enable SSL for MySQL server and client - Xmodulo and https://mirocupak.com/secure-database-connection-with-wildfly

       

      The client certificates have been imported into a keystore/truststore and configured in WildFly using system properties javax.net.ssl.keyStore, javax.net.ssl.keyStorePassword, javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword. The datasource connection url looks as follows.

       

      <connection-url>jdbc:mysql://localhost:3306/app-ds?useSSL=true&amp;requireSSL=true&amp;verifyServerCertificate=true</connection-url>

       

      On starting the server I get the following exception.

       

      Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

       

      The last packet successfully received from the server was 363 milliseconds ago.  The last packet sent successfully to the server was 363 milliseconds ago.

              at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

              at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)

              at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

              at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

              at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)

              at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)

              at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:203)

              at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4901)

              at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1659)

              at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1226)

              at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2188)

              at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2035)

              ... 47 more

      Caused by: java.net.SocketException: Software caused connection abort: socket write error

              at java.net.SocketOutputStream.socketWrite0(Native Method)

              at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)

              at java.net.SocketOutputStream.write(SocketOutputStream.java:155)

              at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)

              at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)

              at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:886)

              at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:857)

              at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:727)

              at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1124)

              at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1216)

              at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1128)

              at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)

              at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)

              at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)

              at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)

              at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)

              at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)

              at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)

              at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:188)

       

      If I only configure javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword, WildFly is able to establish a connection with MySQL database.

       

      Please advise.

       

      Best Regards

      Nitin Jain

        • 1. Re: Secured Communication between WildFly and MySQL
          andey

          - The configuration of JDBC to use SSL is database vendor specific. The JBoss Administration and Configuration Guide discusses datasource configuration in chapter 6.

           

          - The <connection-url> and <connection-property> see[1] tags of the datasource provide the needed flexibility to add required JDBC configuration options to enable SSL database connections.

           

          - Check with the database vendor for the exact URL string and/or properties required. This might require specification of a truststore for the JVM hosting JBoss. A trust store might be specified as a JVM property (particularly when using XA for which there may not be a mechanism to pass properties to the datasource see 2#):

           

          - In JBoss EAP 6 and later, JVM properties may be specified via system-properties in the <standalone*|domain>.xml see 3#

          In domain mode the system property javax.net.ssl.trustStore needs to be set for the server which will be using the datasource .

          In older EAP releases (prior to EAP 6) this may be specified by updating JAVA_OPTS

          JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/path/to/db_cert.truststore

           

          1#See How to specify Connection Properties for limitations on property handling when using XA

           

          2#When multiple XA datasources using different SSL credentials are required, each certificate may need to be added to a single, shared trust store referenced by a system property.

           

          3#See <JBOSS_HOME>/docs/schema/jboss-as-config_*.xsd

           

          [1]https://access.redhat.com/solutions/274293

          • 2. Re: Secured Communication between WildFly and MySQL
            nitin_jain

            Hello Anup,

             

            Thanks for the update.

             

            The datasource configurations are correct. I am using a non-xa datasource. The reference that you have shared illustrates a more methodical way to provide vendor-specific configurations. Thanks.

             

            I would like to understand why option 1 listed below worked, but option 2 did not.

             

            Option [1] -

            set "JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.trustStore=D:/Projects/truststore.jks -Djavax.net.ssl.trustStorePassword=pass2"

             

            Option [2] -

            set "JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.keyStore=D:/Projects/keystore.jks -Djavax.net.ssl.keyStorePassword=pass1 -Djavax.net.ssl.trustStore=D:/Projects/truststore.jks -Djavax.net.ssl.trustStorePassword=pass2"

             

            Best Regards,

            Nitin jain

            • 3. Re: Secured Communication between WildFly and MySQL
              mayerw01

              I think this is more related to the MySQL driver than to WildFly.

              I understand there might be some issue when using system properties.

              verifyServerCertificate: When using this feature, the keystore parameters should be specified by the "clientCertificateKeyStore*" properties, rather than system properties. (MySQL :: MySQL Connector/J 5.1 Developer Guide :: 5.1 Driver/Datasource Class Names, URL Syntax and Configuration Proper… )

               

               

              At least in my environment the connection works fine when providing all parameters in the URL like:

               

              dbc:mysql://<hostname>:3306/<database>?autoReconnect=true&amp;useSSL=true&amp;verifyServerCertificate=true&amp;trustCertificateKeyStoreUrl=file:///<pathToTruststore>&amp;trustCertificateKeyStorePassword=<password>&amp;clientCertificateKeyStoreUrl=file:///<pathToKeystore>&amp;clientCertificateKeyStorePassword=<password>&amp;requireSSL=true

              • 4. Re: Secured Communication between WildFly and MySQL
                nitin_jain

                Hello Wolfgang,

                 

                Thanks for the update.

                 

                Earlier the keystore configurations were defined in "standalone.conf.bat". As per the example shared, I configured the connection-url with the keystore configuration; however, this time as well on JBoss startup, I encountered "Caused by: java.net.SocketException: Software caused connection abort: socket write error".

                 

                I am sharing an overview of the keystores so that we can rule out any mistake in their content.

                 

                trustCertificateKeyStore - Contains the MySQL CA and client certificates

                clientCertificateKeyStore - Contains the JBoss certificates

                 

                I have tested by keeping the 2 keystore contents separately as well as maintaining the only one keystore and using it as both trust and client certificate keystore. The outcome has not changed. It is only when I remove the reference to "client certificate keystore" or "javax.net.ssl.keyStore", JBoss is able to boot successfully.

                 

                Best Regards

                Nitin Jain

                • 5. Re: Secured Communication between WildFly and MySQL
                  andey

                  The server is asked to authenticate client certificate, but the client provides a certificate which Extended Key Usage doesn't support client auth, so the server doesn't accept the client's certificate, and then it closes the connection.

                   

                  "java.net.SocketException: Software caused connection abort: socket write error" error can occur when the local network system aborts a connection while closes an established connection after data retransmission fails (receiver never acknowledges data sent on a datastream socket).". See also Some information about 'software caused connect... | Oracle Community

                   

                  Possible solution: Make sure you're writing the correct length of bytes to the stream. So double check what you're sending. see this thread:  java - How to solve "Connection reset by peer: socket write error"? - Stack Overflow

                  • 6. Re: Secured Communication between WildFly and MySQL
                    nitin_jain

                    Hello Anup,

                     

                    I have just configured the keystore/certificates to have a secured communication between JBoss and MySQL. When you say "Possible solution: Make sure you're writing the correct length of bytes to the stream.", where I can fix this issue. In terms of code, I have not made any changes to my application apart from the keystore configurations.

                     

                    Best Regards,

                    Nitin

                    • 7. Re: Secured Communication between WildFly and MySQL
                      andey

                      The Error "com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure" means that the DB isn't reachable at all. This can have one or more of the following causes:

                      1.IP address or hostname in JDBC URL is wrong.

                      2.Hostname in JDBC URL is not recognized by local DNS server.

                      3.Port number is missing or wrong in JDBC URL (connection URL).

                      4.DB server is down.

                      5.DB server doesn't accept TCP/IP connections.

                      6.DB server has run out of connections.

                      7.Something in between Java and DB is blocking connections, e.g. a firewall or proxy.

                       

                      To solve the one or the other, follow the following advices:

                       

                      1.Verify and test them with ping.

                      2.Refresh DNS or use IP address in JDBC URL instead.

                      3.Verify it based on my.cnf of MySQL DB.

                      4.Start the DB.

                      5.Verify if mysqld is started without the --skip-networking option.

                      6.Restart the DB and fix your code accordingly that it closes connections in finally.

                      7.Disable firewall and/or configure firewall/proxy to allow/forward the port.

                       

                      The <connection-url> and <connection-property> tags of the datasource provide the needed flexibility to add required JDBC configuration options to enable SSL database connections.Check with the database vendor for the exact URL string and/or properties required. This might require specification of a truststore for the JVM hosting JBoss. A trust store might be specified as a JVM property (particularly when using XA for which there may not be a mechanism to pass properties to the datasource

                       

                      You will want to engage your network and/or DBA team to review the issue if this issue persists.  Also need to contact MySQL Support for further troubleshooting

                       

                      MySQL :: MySQL Connector/J 5.1 Developer Guide :: 5.5 Connecting Securely Using SSL

                      https://dev.mysql.com/doc/mysql-monitor/3.4/en/mem-ssl-installation.html

                      MySQL :: MySQL 5.7 Reference Manual :: 6.4.3.2 Creating SSL Certificates and Keys Using openssl

                      MySQL :: MySQL 5.7 Reference Manual :: 6.4.3.1 Creating SSL and RSA Certificates and Keys using MySQL

                      MySQL :: MySQL 5.7 Reference Manual :: 6.4.5 Building MySQL with Support for Encrypted Connections