DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Enterprise AI Trend Report: Gain insights on ethical AI, MLOps, generative AI, large language models, and much more.

2024 Cloud survey: Share your insights on microservices, containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our Trend Reports.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

AI Automation Essentials. Check out the latest Refcard on all things AI automation, including model training, data security, and more.

Related

  • 7 Microservices Best Practices for Developers
  • How Kafka Can Make Microservice Planet a Better Place
  • Spring Cloud Stream: A Brief Guide
  • Lightweight Kubernetes k3s: Installation and Spring Application Example in Azure Cloud

Trending

  • WebSocket vs. Server-Sent Events: Choosing the Best Real-Time Communication Protocol
  • Understanding Escape Analysis in Go
  • Real-Time Communication Protocols: A Developer's Guide With JavaScript
  • Dapr For Java Developers
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Spring Cloud Config and Self-Signed Certificates

Spring Cloud Config and Self-Signed Certificates

What is a Spring Cloud Config? And how can I implement it with a self-signed certificate?

By 
Scott Sosna user avatar
Scott Sosna
DZone Core CORE ·
Nov. 28, 18 · Presentation
Like (3)
Save
Tweet
Share
12.8K Views

Join the DZone community and get the full member experience.

Join For Free

My corporate IT security team decreed earlier this year that internal-facing, infrastructure servers must implement HTTPS using standard self-signed SSL certificates, replacing the official corporate certificates used previously.

At first glance, this sounds simple enough — register the certificates in your browser and continue on unaffected. Subsequently, we realized that configuration changes were not getting to our Docker instances using the Spring Cloud Config server, and we didn't understand why.

What Is a Spring Cloud Config?

From the Spring Cloud Config homepage:

"Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labeled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration."

So, in a nutshell, a Spring Cloud Config server clones a Git repo and provides configuration to applications. As new or updated configurations are pushed to the underlying repo, the server pulls the changes and provides the updated configurations.

What is especially useful is a Spring Cloud Config implemented as a Docker service, where other services deployed in the swarm reference the Spring Cloud Config server internally for the environment the swarm supports, e.g., production, testing, development, etc.

Investigation

Check Server Health

Now, to try and find out what's happening, the server has a /health endpoint. Perhaps, it'll provide something useful.

[ssosna@slartibartfast spring-config]$ curl http://slartibartfast:9101/health
{"status":"DOWN"}[ssosna@slartibartfast spring-config]$ 


This is not very helpful since I already know the service is done.

I learned that /health is secured but can be made unsecured by defining management.security.enabled=false. After adding this environment variable to my Docker service, I got this:

[ssosna@slartibartfast spring-config]$ curl http://slartibartfast:9101/health
{"status":"DOWN","diskSpace":{"status":"UP","total":52576092160,"free":37885374464,"threshold":10485760},"rabbit":{"status":"UP","version":"3.7.8"},"refreshScope":{"status":"UP"},"configServer":{"status":"DOWN","repository":{"application":"app","profiles":"default"},"error":"java.lang.IllegalStateException: Cannot clone or checkout repository"}}[ssosna@slartibartfast spring-config]$ 


Scroll right for the interesting bit: java.lang.IllegalStateException: Cannot clone or checkout repository. This is very helpful, but I have no idea why.

Server logs were no more helpful, logging the same IllegalStateException but with no additional context to help understand what's happening.

Search Spring Source

Since no breadcrumbs were provided at run-time, I cloned the project and dug into the code, finding the error string in the class JGitEnvironmentRepository. The method refresh() creates a Git client and attempts to clone or pull the repository. The biggest revelation is that Spring uses the JGit for its Git operations.

Test JGit Alone

JGit is an API-based, pure-Java implementation of Git, without any external dependencies on a separate Git installation or other OS-specific requirements. To simplify testing, I added a simple JGit repository clone to an existing project.

try {
    System.out.println ("************ Before cloning.");
    Git.cloneRepository().setURI("https://Scott_Sosna@stash.mycompany.com/scm/project/project-to-clone.git").call();
    System.out.println ("************ After cloning.");
} catch (Exception e) {
    System.out.println ("************ JGit Exception: " + e);
}


The Maven build created the Docker image and pushed it into Docker. I then created a container and started interactively, and voila!

************ Before cloning.
************ JGit Exception: org.eclipse.jgit.api.errors.TransportException: https://Scott_Sosna@stash.mycompany.com/scm/project/project-to-clone.git: Secure connection to https://Scott_Sosna@stash.mycompany.com/scm/project/project-to-clone.git c


The new self-signed certificates are not available inside Docker, causing the repository clone to fail.

Solution

The certificates need to be added to the Java keystore inside the Docker container.

Add Certificates to the Project

The certificates are resources added to the project wherever appropriate for your build tool. Maven projects would add the certificates in main/src/resources. I created a specific subdirectory for them:

Load Certificates to Java Keystore

The Dockerfile definition file needs to include steps for copying the certificates to the Docker image and updating the global keystore.

USER root
COPY src/main/resources/certs $JAVA_HOME/jre/lib/security/
RUN \
    cd $JAVA_HOME/jre/lib/security && \
    echo $JAVA_HOME && \
    keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias Dell101 -file "MyCompany Issuing Certificate Authority 101.crt" && \
    keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias Dell102 -file "MyCompany Issuing Certificate Authority 102.crt" && \
    keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias Dell301 -file "MyCompany Issuing Certificate Authority 301.crt" && \
    keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias Dell302 -file "MyCompany Issuing Certificate Authority 302.crt" && \
    keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias DellRoot2015 -file "MyCompany Root Certificate Authority 2015.crt"


Load and Go

Your newly-built Docker image should contain the self-signed certificates, and the Spring Cloud Config server should behave as expected.

Final Thoughts

  • The environment variable spring.cloud.config.server.git.skipSslValidation is documented but did not affect how JGit functioned.
  • JGit does almost no logging, making it difficult to do any debugging when problems like this arise.
Spring Cloud Spring Framework Docker (software)

Opinions expressed by DZone contributors are their own.

Related

  • 7 Microservices Best Practices for Developers
  • How Kafka Can Make Microservice Planet a Better Place
  • Spring Cloud Stream: A Brief Guide
  • Lightweight Kubernetes k3s: Installation and Spring Application Example in Azure Cloud

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: