Spring Cloud Discovery First Configuration Server Decryption Failed - spring-boot

I am trying discovery first implementation with Spring Cloud. I am getting failure for password decryption. I have .jks in the classpath. The same works when I go for Config First approach.
Following is the bootstrap.properties file for Config first approach.
eureka.instance.hostname=claims-dev
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.cloud.config.name=claim
spring.config.import=configserver:http://localhost:8888
spring.profiles.active=dev
spring.cloud.config.fail-fast=true
Following is the bootstrap for Discovery First approach.
eureka.instance.hostname=claims-dev
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.cloud.config.discovery.service-id=configserver
spring.cloud.config.discovery.enabled=true
spring.cloud.config.name=claim
spring.profiles.active=dev
spring.cloud.config.fail-fast=true
For Discovery First I am getting below exception
Caused by: java.lang.UnsupportedOperationException: No decryption for FailsafeTextEncryptor. Did you configure the keystore correctly?
at org.springframework.cloud.bootstrap.encrypt.TextEncryptorUtils$FailsafeTextEncryptor.decrypt(TextEncryptorUtils.java:188) ~[spring-cloud-context-3.1.0.jar:3.1.0]
at org.springframework.cloud.bootstrap.encrypt.AbstractEnvironmentDecrypt.decrypt(AbstractEnvironmentDecrypt.java:144) ~[spring-cloud-context-3.1.0.jar:3.1.0]
... 16 common frames omitted
What I am missing here?
UPDATE: Following are the config server properties
encrypt.keyStore.location=classpath:/store name
encrypt.keyStore.password=store password
encrypt.keyStore.alias=alias
encrypt.key-store.type=jks
spring.cloud.config.server.encrypt.enabled=false
It works if I opt for server side password decryption.

Related

Spring Boot 2.7.1 LetsEncrypt PEM keystore throws Resource location must not be null

So I read that Spring Boot now supports PEM since 2.7.0
https://docs.spring.io/spring-boot/docs/2.7.0-SNAPSHOT/reference/htmlsingle/#howto.webserver.configure-ssl 17.3.7. Configure SSL
So I am using PEM generated by certbot.
My application.properties
spring.jpa.generate-ddl=true
spring1.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=false
server.port=443
server.ssl.certificate=fullchain1.pem
server.ssl.certificate.certificate-private-key=privkey1.pem
server.ssl.trust-certificate=fullchain1.pem
When I launch I get
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Could not load key store 'null'
Caused by: org.springframework.boot.web.server.WebServerException: Could not load key store 'null'
Caused by: java.lang.IllegalArgumentException: Resource location must not be null
As per the documentation SSL configuration springboot
UPDATE:
Adding the content from link to directly in the answer, as link can
get updates
SSL can be configured declaratively by setting the various
server.ssl.* properties, typically in application.properties or
application.yml. The following example shows setting SSL properties
using a Java KeyStore file:
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
The following example shows setting SSL properties using PEM-encoded
certificate and private key files:
server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt
Your properties are not correctly declared,
server.ssl.certificate.certificate-private-key=privkey1.pem should be changed to server.ssl.certificate-private-key=privkey1.pem
So this workaround works
#Configuration
public class SSLConfig {
#Bean
public ConfigurableServletWebServerFactory webServerFactory() throws Exception {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
Ssl ssl = new Ssl();
ssl.setEnabled(true);
ssl.setCertificate("cert1.pem");
ssl.setCertificatePrivateKey("privkey1.pem");
ssl.setKeyStoreType("PKCS12");
ssl.setKeyStorePassword(""); // without this decrytption fails
factory.setSsl(ssl);
factory.setPort(443);
return factory;
}
}
server.ssl.key-store=file:///Users/...
Have you tried this way of setting the path? First, make sure your application up with the correct path, then dig into the next step.

encrypt key Property binding error in spring boot 2.7.0

I have Spring boot 2.7.0 application which connects config server with following configuration to decrypt secrets. But when I include below configuration in (application.yml or bootstrap.yml) getting binding error. Not sure what is the root cause of this issue as format is correct for the keys but still getting this error. Same config is working fine with Spring boot 2.2.1.
I have used same config in application.yml without bootstrap.yml as it depricated in 2.7.0 but still same issue.
encrypt:
key-store:
location: file:${key.path}
password: anthem$$docker
alias: docker
secret: anthem$$docker
org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'encrypt.key-store.alias' to java.lang.String
at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:384)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:344)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:469)
at org.springframework.boot.context.properties.bind.Binder$$Lambda$78/234145890.bindProperty(Unknown Source)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:95)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:83)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:59)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:473)
Description:
Failed to bind properties under 'encrypt.key-store.alias' to java.lang.String:
Property: encrypt.key-store.alias
Value: docker
Origin: class path resource [bootstrap.yml] - 40:12
Reason: org.springframework.boot.context.config.InactiveConfigDataAccessException: Inactive property source 'Config resource 'class path resource [bootstrap.yml]' via location 'optional:classpath:/' (document #5)' imported from location 'class path resource [bootstrap.yml]' cannot contain property 'encrypt.key-store.alias' [origin: class path resource [bootstrap.yml] - 40:12]
Action:
Update your application's configuration

${VAULT_SCHEME} not working in bootstrap.properties

I have configured spring boot application to take properties from my environment but strangely I am facing an error while starting my application.
I have added the properties in my ~/.bash_profile and also did source ~/.bash_profile after adding them to the profile.
This is how my bootstrap.properties look like:
spring.application.name=gamification
spring.cloud.vault.enabled=${VAULT_ENABLE:true}
spring.cloud.vault.fail-fast=false
spring.cloud.vault.token=${VAULT_TOKEN}
spring.cloud.vault.scheme=${VAULT_SCHEME}
spring.cloud.vault.host=${VAULT_HOST}
spring.cloud.vault.port=${VAULT_PORT:8200}
I am getting this error:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Scheme must be http or https
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:216) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:310) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 30 common frames omitted
Caused by: java.lang.IllegalArgumentException: Scheme must be http or https
at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.vault.client.VaultEndpoint.setScheme(VaultEndpoint.java:167) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.cloud.vault.config.VaultConfigurationUtil.createVaultEndpoint(VaultConfigurationUtil.java:91) ~[spring-cloud-vault-config-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration.<init>(VaultReactiveBootstrapConfiguration.java:110) ~[spring-cloud-vault-config-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_231]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_231]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_231]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:203) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 32 common frames omitted
I added a debug point in Vault Endpoint and found this:
Here as you can see, the VAULT_HOST is being taken as VAULT_HOST instead of the value of that environment variable, and same with the VAULT_SCHEME
[EDIT]
Adding bash_profile vault configuration:
export VAULT_ENABLE=true
export VAULT_SCHEME=http
export VAULT_HOST=vault-1.dev.lokal
export VAULT_PORT=8200
export VAULT_TOKEN=5F97X
[EDIT #2]
Tried out the solution suggested by #Gopinath
I am getting environment as null when trying to autowire it
The root cause of the problem can be found form this error message:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting
from type [java.lang.String]
to type [org.springframework.cloud.vault.config.VaultProperties$Config]
The above message indicates that the VaultProperties object could not be initialized using the string parameter supplied.
Here is the link to documentation and instructions on configuring VaultProperties:
https://spring.io/guides/gs/vault-config/
Some more information to help understand vault:
References:
Spring Cloud Vault: https://cloud.spring.io/spring-cloud-vault/
Hashicorp Vault: https://www.vaultproject.io
What is a Vault?
A vault is a secure storage space meant for storing secret information.
Hashicorp Vault is one tool that offers vault functionality for cloud applications.
What is Spring Boot Vault?
Spring Boot applications commonly require secret information for those to work.
Some examples of secret information are:
Database password
Private key
API key
Usually, the input parameters are passed to Spring boot application through the
"application.properties" file or "bootstrap.properties" file.
The use of such properties file poses a security risk, if secret data is directly mentioned in the file.
Spring Boot Vault addresses this risk.
It pulls secret information from vault and supplies to the application at the start-up time.
The .properties file will only tell the application the names of parameters that it can expect from Vault.
The actual values of the parameters will be taken from vault.
How to setup Vault?
Step 1: Install and launch HashiCorp Vault from
https://www.vaultproject.io/downloads.html:
Step 2: After installing Vault, test whether it works, by launching
it in a console window.
> vault server --dev --dev-root-token-id="spring-boot-vault-demo"
==> Vault server configuration:
Api Address: http://127.0.0.1:8200
Cgo: disabled
Cluster Address: https://127.0.0.1:8201
Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
Log Level: info
Mlock: supported: false, enabled: false
Recovery Mode: false
Storage: inmem
Version: Vault v1.4.1
WARNING! dev mode is enabled!
.....
You may need to set the following environment variable:
PowerShell:
$env:VAULT_ADDR="http://127.0.0.1:8200"
cmd.exe:
set VAULT_ADDR=http://127.0.0.1:8200
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: +Dihvgj/oRN2zo6/97ZqpWt086/CFRZEPkuauDu4uQo=
Root Token: spring-boot-vault-demo
Step 3: Store some secret data in the vault,
by running these commands in a separate command window:
> set VAULT_ADDR=http://127.0.0.1:8200
> set VAULT_TOKEN=spring-boot-vault-demo
> vault kv put secret/spring-boot-vault-demo password=££££$$$$%%%%
Key Value
--- -----
created_time 2020-05-02T09:59:41.2233332Z
deletion_time n/a
destroyed false
version 1
I did this:
I made a shell script called setenv.sh and put this under it:
#!/bin/bash
launchctl setenv VAULT_ENABLE true
launchctl setenv VAULT_SCHEME http
launchctl setenv VAULT_HOST vault-1.dev.lokal
launchctl setenv VAULT_PORT 8200
launchctl setenv VAULT_TOKEN 5F97X
And then, before starting the application I ran the shell script with
sudo sh setenv.sh
And the application seems to work fine without any errors. Strangely if I do it with my previous approach of adding the env variables inside the .bash_profile, it doesn't work.

Spring Boot not loading keystore specified in application.yml

I am attempting to run and test a Spring Boot application that I have packaged into a zip file and unpacked on a Linux VM. The zip contains everything the application needs (at least to my knowledge). When I attempt to execute the application, it starts but quickly fails because it cannot load a keystore needed for SSH/TLS secure communications.
I have the following in my application.yml:
server:
port: 8091
ssl:
enabled: true
protocol: TLS
trust-store-type: JKS
trust-store: classpath:keystore/server.keystore
trust-store-password: <hidden>
key-store-type: JKS
key-store: classpath:keystore/ra/server.keystore
key-store-password: <hidden>
The directory structure on the test system is as follows:
[centos#route-assessor route-assessor]$ ls -R
.:
config elastic-apm-agent-1.10.0.jar lib run-route-assessor.sh services-0.0.1-SNAPSHOT.jar
./config:
application.yml keystore log4j2.xml
./config/keystore:
mp ra rg server.keystore
./config/keystore/mp:
server.keystore
./config/keystore/ra:
server.keystore
./config/keystore/rg:
server.keystore
./lib
<dependency jars>
Here is the exception thrown:
[2019-10-23 13:21:31.419] main WARN : context.AnnotationConfigServletWebServerApplicationContext:557 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Could not load key store 'classpath:keystore/server.keystore'
The Spring Boot "runtime" obviously sees and accesses the config directory, but doesn't seem to see the keystore directory contained within. Do I need to specify the paths differently in application.yml or do I need to put the keystore files somewhere else?
Note: I can run this application with the application.yml configured as shown from eclipse without any problem. Granted, all resources are located in src/main/resources for that situation.
UPDATE:
As per #borban's suggestion, I modified the application.yml as follows:
key-store: file:config/keystore/ra/server.keystore
trust-store: file:config/keystore/server.keystore
That seems to have solved one problem, but I'm not out of the woods yet:
[2019-10-23 15:07:17.671] main ERROR: boot.SpringApplication:821 - Application run failed
org.springframework.boot.web.server.WebServerException: Unable to start embedded Jetty server
...
Caused by: java.lang.IllegalStateException: no valid keystore
...
As far as I know, my keystore files are valid and correct (I've been using them on my Windows development box for months). They are copied over as part of the zip distribution. Is there something maybe I'm missing?
I'm also a little concerned with a few other messages in the log. I'm not sure if they're related, but it seems that they could be:
[2019-10-23 15:07:10.153] main WARN : resource.Resource:126 - java.lang.IllegalArgumentException: URI is not hierarchical
[2019-10-23 15:07:10.155] main WARN : resource.Resource:126 - java.lang.IllegalArgumentException: URI is not hierarchical
I don't recall seeing them before.
Are you are trying to access this keystore outside of the classpath and from the filesystem itself? From the folder structure you are giving, that seems to be the case. If you remove the "classpath" prefix and then update your path appropriately, it should work.
From this post, it looks like you have to prefix with "file"
https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
You can use maven resource plugin to add the folders you need to the plugin:
https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
then use without classpath??

Issue connecting to Websphere application server from local machine

I'm trying to connect to IBM WAS from local machine. I'm trying to connect to server using following code:
Properties Props = new Properties()
Props.setProperty(AdminClient.CONNECTOR_TYPE,
AdminClient.CONNECTOR_TYPE_SOAP)
Props.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, "true")
Props.setProperty(AdminClient.CACHE_DISABLED, "false")
Props.setProperty("javax.net.ssl.trustStore", "WebAS")
Props.setProperty("javax.net.ssl.trustStorePassword", "WebAS")
Props.setProperty(AdminClient.CONNECTOR_HOST, "127.0.0.1")
Props.setProperty(AdminClient.CONNECTOR_PORT, "9060")
Props.setProperty(AdminClient.USERNAME, "user")
Props.setProperty(AdminClient.PASSWORD, "password")
System.setProperty("com.ibm.SSL.ConfigURL", /specified location of
file/ "ssl.client.props") Props.setProperty("com.ibm.SSL.ConfigURL",
/specified location of file/ "ssl.client.props") //I generated
keystore.jks `
Props.setProperty("javax.net.ssl.trustStore",directory.toURI().toURL()+"keystore‌​.jks"
); Props.setProperty("javax.net.ssl.keyStore",
directory.toURI().toURL()+"keystore.jks");
this.adminClient=AdminClientFactory.createAdminClient(Props)
When run the following code, I get following error
com.ibm.websphere.management.exception.ConnectorException: ADMC0016E: The system cannot create a SOAP connector to connect to host 127.0.0.1 at port 9043.
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NoClassDefFoundError: com/ibm/security/certclient/util/PkSsCertFactory
Caused by: java.lang.ClassNotFoundException: com.ibm.security.certclient.util.PkSsCertFactory
I looked up for classname: com.ibm.security.certclient.util.PkSsCertFactory to include. I cannot find neither the IBM jar file or groupId, artifact id, version. Please help me out
Export the dmgr's CA certificate to nodes truststore and give a try.
As I can see your node agent is taking port 9043 to connect to dmgr, if all configurations made are default, then this should not happen.
please check your nodes and dmgrs serverindex.xml file.

Resources