How to install self signed certificate for Java in Docker/Kubernetes? - spring-boot

I am running a Spring Boot application in Docker with Kubernetes.
While downloading an image I am getting the below error:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
How can I solve this problem?

Try adding the certificates to the docker image and installing them via keytool

After adding certificate to the docker now i am able to access the remote site.
Assure I need to download files or access abc.com over https
Add below lines to your Docker file
USER root
RUN cd $JAVA_HOME/lib/security && echo -n | openssl s_client -connect abc.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > abc.com.crt && keytool -keystore cacerts -keypass changeit -storepass changeit -noprompt -import -v -trustcacerts -alias abc.com -file abc.com.crt

Related

cannot run thinkorswim behind corporate firewall: "unable to find valid certification path to requested target"

In windows, when I install and run thinkorswim inside company network (with its own self-signed ssl cert), it cannot connect via https to tdameritrade's server. How do I update tos's java runtime with the self-signed cert?
open command prompt in windows and run the following command to install company's cacert into thinkorswim's jre:
cd C:\<thinkorswim-install-dir>\jre\bin\
keytool.exe -import -trustcacerts -noprompt -storepass changeit -alias mycertificate -keystore ..\lib\security\cacerts -file c:\mycert.cer
For MacOS
cd /Applications/thinkorswim/.install4j/jre.bundle/Contents/Home/jre/bin
./keytool -import -trustcacerts -noprompt -storepass changeit -alias mycertificate -keystore ../lib/security/cacerts -file /path/to/mycert.cer

How to plugin the SSL certificate into bitbucket-pipelines.yml file as the tests are over HTTPS?

I have got tests which need to run over HTTPS REST API webservices from bitbucket server CI pipeline, can anyone tell me the step-by-step instructions to plugin the .crt certificate file?
Similal issue, we got that resolved after adding the following line to the bitbucket pipeline yml file
keytool -importcert -trustcacerts -noprompt -alias -ouralias -file OUR.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass ourpass

How do I generate X.509 certificate from key generated by openssl

I've a web server running on an ec2-instance which internally calls a REST server that is built using Spring Boot. Now, I am trying to get this REST server running under SSL. Here's what I've done so far:
1) Created a CSR & a key file using this command
openssl req -newkey rsa:2048 -nodes -keyout mydomain.key -out mydomain.csr
2) Copied 'csr' to get SSL certificate from GoDaddy.
3) Successfully installed the certificate under Nginx on my ec2-instance.
4) When I hit the home page under https, it works. I no longer get 'Not secure' message from the browser.
5) Login fails because it makes a REST call but REST server is not running under SSL so I am trying to get it running under SSL.
6) Ran following commands:
keytool -import -alias mydomain -keystore tomcat.keystore -trustcacerts -file mydomain.com.chained.crt
keytool -import -alias mydomain-key -keystore tomcat.keystore -trustcacerts -file mydomain.key
The previous command gives me an error message:
"keytool error: java.lang.Exception: Input not an X.509 certificate"
But this was the one created in step 1 above & the same file works under Nginx. What am I missing (other than the fact that I know very little about setting up SSLs!)? I need the second command to specify the value of 'server.ssl.keyAlias' in application.properties, I believe.
Not really an answer but overflowed comment.
You don't need to 'generate' an X.509 cert; you already got that from GoDaddy. If (and only if) the SpringBoot server is accessed by the same name(s) as (external) nginx -- which is unclear to me -- you need to convert the pair of private key AND certificate CHAIN from PEM format to a format Java uses. See:
How to import an existing x509 certificate and private key in Java keystore to use in SSL?
How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application?
How to use .key and .crt file in java that generated by openssl?
Importing the private-key/public-certificate pair in the Java KeyStore
maybe Import key and SSL Certificate into java keystore
Thanks #Dave_thompson_085. Following 2 commands did the trick!
openssl pkcs12 -export -in mydomain.com.chained.crt -inkey mydomain.key -out keystore.p12 -name my-alias -caname root
keytool -importkeystore -deststorepass mypassword -destkeypass mypassword -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass mypassword -alias my-alias
and then in the application.properties I specified following properties:
server.port=8443
server.ssl.enabled=true
security.require-ssl=true
server.ssl.key-store=/etc/nginx/ssl/keystore.jks
server.ssl.key-store-password=mypassword
server.ssl.keyStoreType=JKS
server.ssl.keyAlias=my-alias

SAML HTTPS connection with kennisnet staging environment

I took sample webapp from https://github.com/vdenotaris/spring-boot-security-saml-sample and it is working file. Later. I tried to connect kennisnet staging environment.
Kennisnet details here
https://developers.wiki.kennisnet.nl/index.php?title=KNF:Hoofdpagina/en
I updated metadata which is downloadable from this url https://hub-s.entree.kennisnet.nl/openaselect/profiles/saml2/
I generated smalKeyStore.jks using below commands
keytool -genkey -alias tomcat -keyalg RSA -keystore samlKeyStore.jks
keytool -importkeystore -srckeystore samlKeyStore.jks -destkeystore
samlKeyStore.jks -deststoretype pkcs12
I followed all Spring SAML https threads in stackoverflow and not able to figure it out this issue.
LOGS:
Add the certificate to your JDK so that your application can get the metadata from URL https://aselect-s.entree.kennisnet.nl/openaselect/profiles/saml2.
These are the steps you need to fillow:
Download the certificate for aselect-s.entree.kennisnet.nl
Import the certificate to your JDK/JRE using this command:
keytool -keystore #path to java_home#/lib/security/cacerts -importcert -alias #anything relevent# -file #path to certificate#
Make sure your server is using same java_home where you are importing the certificate, also verify the subjectname in the certificate before importing, it must be "CN = *.entree.kennisnet.nl"
Restart the server.

Clojure Compojure Ring and https

I'm using Clojure (ring and compojure) to build a web app and I don't know where to start with https. I have a registration and login that will need to be secured, then once they're authenticated they'll need to stay in https.
I can't seem to find a good tutorial on setting up https in general or for a clojure app specifically.
I found this answer: How do you enable https and http->https redirects in ring / compojure
Does that mean I can write my compojure app as if there's no https and have nginx sit in front and take care of all that for me?
Yes, the standard procedure is to have nginx act as a reverse proxy in front of the ring based webapp. This is considered secure and it's easier to maintain because it's more standard. Every clojure based site I know about does it this way.
The reverse proxy approach does seem to be the most common option. However, as an 'experiment' I looked into using just ring, jetty compojure etc with https. It isn't that hard.
First you need to use keytool to generate a self signed certificate and install that into a new keystore. The keytool docs a pretty good and can walk you through this process. Note that if you use a self signed cert, you will need to add an exception rule with most browsers to say that you trust that certificate.
Copy the keystore file created into the root of your project tree
Update the jetty config parameters to specify ssl, ssl-port, keystore file and keystore password.
Add the ring/ring-defaults package to your project.clj
Add the wrap-defaults middleware with the secure-site-defaults configuration option to force https connections i.e. redirect http connections to https.
This is not the setup I would recommend for production use, but I found it simpler than also having to configure ngix when doing development etc. The hardest part was working through the keytool process. However, just following the docs and examples gives you enough provided you don't allow yoruself to be overwhelmed by all the options - just keep it simple.
Something like
keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-keypass $PASSWORD \
-storepass $PASSWORD \
-keyalg RSA -keysize 2048 \
-alias root \
-ext bc:c \
-dname "$ROOT_CN"
echo "CA Key"
keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-alias ca \
-ext bc:c \
-keypass $PASSWORD \
-keyalg RSA -keysize 2048 \
-storepass $PASSWORD \
-dname "$CA_CN"
echo "Server Key"
keytool -genkeypair \
-keystore $SSL_DIR/$KS_NAME \
-alias server \
-keypass $PASSWORD \
-storepass $PASSWORD \
-keyalg RSA -keysize 2048 \
-dname "$SERVER_CN"
echo "Root Cert"
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-alias root \
-exportcert \
-rfc > $SSL_DIR/root.pem
echo "CA Cert"
keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-certreq \
-alias ca | keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-gencert \
-alias root \
-ext BC=0 \
-rfc > $SSL_DIR/ca.pem
echo "Import CA cert"
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-importcert \
-alias ca \
-file $SSL_DIR/ca.pem
echo "Server Cert"
keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-certreq \
-alias server | keytool -storepass $PASSWORD \
-keystore $SSL_DIR/$KS_NAME \
-gencert \
-alias ca \
-rfc > $SSL_DIR/server.pem
echo "Import Server Cert"
cat $SSL_DIR/root.pem $SSL_DIR/ca.pem $SSL_DIR/server.pem | \
keytool -keystore $SSL_DIR/$KS_NAME \
-storepass $PASSWORD \
-keypass $PASSWORD \
-importcert \
-alias server
Usually application-level code does not care whether it's HTTPS or HTTP. Most often it's provided by application server or a proxy in front of it. If you're familiar, your choices are pretty much the same as in the Java world.
If you're using the Jetty adapter, it has ssl? and ssl-port options. See docs here and related blog post here.
You can run your Ring app in plain HTTP and place a proxy such as Nginx or Apache in front of it. Proxy would implement HTTPS and forward requests as plain HTTP to your app.
Another solution is to try nginx-clojure (http://nginx-clojure.github.io) by which you can deploy ring app on nginx directly. nginx can do https things more efficiently.
Here's an example about nginx.conf
http {
### jvm dynamic library path
jvm_path '/usr/lib/jvm/java-7-oracle/jre/lib/amd64/server/libjvm.so';
### my app jars e.g. clojure-1.5.1.jar , groovy-2.3.4.jar ,etc.
jvm_var my_other_jars 'my_jar_dir/clojure-1.5.1.jar';
### my app classpath, windows user should use ';' as the separator
jvm_options "-Djava.class.path=jars/nginx-clojure-0.3.0.jar:#{my_other_jars}";
server {
listen 80 default deferred;
server_name example.com;
###redirect to https
rewrite ^/(.+) https://example.com/$1 permanent;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /opt/mycert/my-unified.crt;
ssl_certificate_key /opt/mycert/my.key;
location /myapp {
content_handler_name 'my/ringapp';
}
}
}
You can get more details about SSL server configurations from http://nginx.org/en/docs/http/configuring_https_servers.html
You can setup Ring middleware that will force all requests to use SSL. An easy way to do this is to use the ring-defaults library.
From the ring-defaults documentation:
There are four configurations included with the middleware
- api-defaults
- site-defaults
- secure-api-defaults
- secure-site-defaults
...
The "secure" defaults force SSL. Unencrypted HTTP URLs are redirected to the equivlant HTTPS URL, and various headers and flags are sent to prevent the browser sending sensitive information over insecure channels.
Also note:
In order to enable local development without SSL, you can set which ring-defaults set you use based on an environment variable. Environ helps with this.
In order to enable SSL to work behind a load balancer or proxy, you have to set :proxy to true in the ring-defaults map.
Here's the general idea:
(ns my-app
(:require [ring.middleware.defaults :refer :all]
[environ.core :refer [env]]))
(defroutes app-routes
(GET "/" [] "home page"))
(def app
(-> app-routes
(wrap-defaults (if (= (env :environment) "dev")
site-defaults
(assoc secure-site-defaults :proxy true))))
I don't know about nginx, but I have this working for an app deployed to Heroku.
Its very simple. If you want to enable HTTPS support in your web app, just do the following:
Generate a Java KeyStore(.jks) file using a linux tool called keytool.
In the ring map of your project.clj file, add the following:
{
:ssl? true
:ssl-port 8443
:keystore "path to the jks file"
:key-password "the keystore password"
}
Fire up the server. Now your web app is HTTPS enabled.
I had a similar problem while I was trying to test my Sign-In using Social Media code which obviously had to authenticate over HTTPS and this did the trick for me.

Resources