Hi everyone, I was able to get my Grails 6 applica...
# questions
t
Hi everyone, I was able to get my Grails 6 application connected to a MySQL database (hosted by AWS) using SSL by running the sample shell script in these instructions for creating a trust store file (
rds-truststore.jks
): https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL-certificate-rotation.html#UsingWithRDS.SSL-certificate-rotation-sample-script I modified the sample shell script so that the
rds-truststore.jks
file would be created in a directory named
certs
in the root directory of my Grails application. And I created a
grails-app/conf/application.groovy
file with the following:
Copy code
String KEY_STORE_FILE_PATH = "./certs/rds-truststore.jks"
/**
 * These properties need to be set here, because an exception would be thrown when starting the application
 * if we set them in grails-app/conf/application.yml instead.
 */
System.setProperty("javax.net.ssl.trustStore", "./certs/rds-truststore.jks")
System.setProperty("javax.net.ssl.trustStorePassword", "Not-The-Actual-Password")
And I added
dataSource.properties.dbProperties.sslMode: VERIFY_IDENTITY
to
grails-app/conf/application.yml
. I build the Grails application into a
.war
file and deploy it to AWS Elastic Beanstalk. Is there any way I can remove the line
System.setProperty("<http://javax.net|javax.net>.ssl.trustStorePassword", "Not-The-Actual-Password")
from
application.groovy
and still connect to the database using SSL, because I do not want to store the real password in my source code? Adding a
<http://javax.net|javax.net>.ssl.trustStorePassword
environment variable to my Elastic Beanstalk environment is not doing the trick. An exception gets thrown when attempting to start the application:
java.security.UnrecoverableKeyException: Password verification failed
In case the additional context is needed, I'm using the
"com.mysql:mysql-connector-j:8.3.0"
library.
m
I don't have any experience of Elastic Beanstalk, but it seem strange if you can't set a system property. I would dig deeper there, perhaps set a dummy system property value in the environment and log it out in the application startup.
t
It is strange. An exception is thrown before any code in Bootstrap.groovy gets executed; this same thing happens as well when I'm running the application locally with the
bootRun
Gradle task while I have the
<http://javax.net|javax.net>.ssl.trustStorePassword
environment variable.
j
The quick way is https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html#environments-cfg-softwaresettings-console this allows you to set environment variables which are set when the EC2 VM is started. You can also extend this using AWS Parameter Store to centralize configuration with environment specific versions. https://docs.awspring.io/spring-cloud-aws/docs/2.4.4/reference/html/index.html#integrating-your-spring-cloud-app[…]tion-with-the-aws-parameter-store
❤️ 1
And you may have to set it using the variable name
Copy code
JAVAX_NET_SSL_TRUST_STORE_PASSWORD
System.setProperty("<http://javax.net|javax.net>.ssl.trustStorePassword", "Not-The-Actual-Password")
That code in application.groovy will run last and overwrite what you set in the AWS Elastic Beanstalk EC2 environment parameter, so I'd remove that to test And if still not working, I'd set another environment variable
Copy code
TRUST_STORE_PASSWORD=THE_REAL_PASSWORD
And then use that to set
<http://javax.net|javax.net>.ssl.trustStorePassword
System.setProperty("<http://javax.net|javax.net>.ssl.trustStorePassword", System.getProperty("TRUST_STORE_PASSWORD")
t
Thank you @James Fredley for taking the time to help me out! After changing my
dataSource.properties.dbProperties.sslMode
to
PREFERRED
and actually looking in the logs of my Beanstalk environment for the log statements I put in
Bootstrap.groovy
for debugging, I realize that
./certs/rds-truststore.jks
is not a file that exists when my Grails application is deployed facepalm Does anyone have suggestions where I should put a
./certs/rds-truststore.jks
file in a Grails application for it to get automatically included in the
.war
build? I know I could always customize the
build.gradle
to grab the contents of my
./certs
directory and place them in a top-level
keystore-certs
directory of the
.war
file like so:
Copy code
// Transfer the files to the top level of my-application.war when it is built.
// <https://stackoverflow.com/a/33126733/8049180>
// <https://stackoverflow.com/a/61174893/8049180>
bootWar {
    from('certs') {
        into('keystore-certs')
    }
}
// Transfer the files to the top level of my-application-plain.war when it is built.
war {
    from('certs') {
        into('keystore-certs')
    }
}
But if there's a conventional spot to put a
.jks
file in a Grails application, I'd rather follow the convention.
g
Have you tried project-dir/src/main/resources ?
t
Placing the file at
src/main/resources/rds-truststore.jks
does result in it being located at
WEB-INF/classes/rds-truststore.jks
in the
.war
build file. Now I'm just not sure how to modify
Boostrap.groovy
to programatically get the correct path to that file, both when it is deployed and when it is running locally with
bootRun
🤔
g
In the url to access the file you can try “classpath:rds-truststore.jdk”
👍 1