Configure SSL in Angular & Spring Boot application using Nginx - java

I have Spring Boot (backend) application which is running on Tomcat (port 8080) and Angular app (frontend) (port 4200).
Frontend consumes rest API from backend. How can I secure my applications using Nginx with SSL?
I have heard i could configure my Spring Boot as reverse proxy in nginx and then secure it with SSL but i dont know how to do it.

both spring boot and nginx should configure to get https.
for java and spring boot you should create certificate file using keytool that you can find it in jdk/bin.
keytool -genkey -alias <desired certificate alias>
-keystore <path to keystore.pfx>
-storetype PKCS12
-keyalg RSA
-storepass <password>
-validity 730
-keysize 2048
then put .p12 file beside application.properties.
for spring boot you should add this in your application.properties or application.yml:
server.ssl.enabled=true
server.ssl.key-store=classpath:client.p12
server.ssl.key-store-password=<password>
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=<desired certificate alias>
after that we should create certificate file for angular and nginx and add some configuration to nginx.conf.
for creating certificate file you can use openssl tool.
create openssl-custom.cnf file add put blow code in that:
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn
[dn]
C = US
ST = utah
L = US
O = IT
OU = IT Section
emailAddress = info#example.com
CN = localhost
[v3_req]
subjectAltName = #alt_names
[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
and then open terminal or cmd and run this command:
#!/bin/bash
openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.key \
-new \
-out server.crt \
-config ./openssl-custom.cnf \
-sha256 \
-days 365
then put server.key and server.crt in you angular project and add these code to nginx.conf:
listen 443 ssl;
ssl_certificate <path to .crt file>/server.crt;
ssl_certificate_key <path to .key file>/server.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
! for using ssl in nginx you should use port 443 not 80;
! for testing your angular open new tab and don't use your old tab

Related

Generating SSL keys for MySQL command-line client encrypted connection

I have started a project using MySQL in the cloud and I need to set up an SSL connection to it for the MySQL command line client.
I received the ca.pem file from the MySQL server which has a ton of certificates in there.
I already sorted out the SSL connection in MySQL Workbench and in Java, after a certain amount of trying different things. I've all the certificates now in my Java installation's cacerts trust store, and I've configured Java and Workbench to find my public / private SSL keys in my client.jks store.
None of that though helps with the command line MySQL client. According to the MySQL docs Configuring MySQL to use Secure Connections, this is the way to launch it:
mysql --ssl-ca=ca.pem \
--ssl-cert=client-cert.pem \
--ssl-key=client-key.pem
and these params can be put in my.cnf to make the command line easier.
And this told me some of what I needed to know: MySQL on Amazon RDS i.e. how to point mysql on the command line to the server certificate. That was easy, considering the Java procedure required me to import the whole lot into the Java certificate store using a command line tool that only reads the first certificate and silently ignores the remainder.
So after all faff with Java, and from the beginning having a public/private key pair for ssh, it occurred to me it would be sensible to keep all my keys together and in fact even re-use the same key to create the other formats I need.
According to Converting a Java Keystore into PEM Format I should be able to do that, or maybe I should instead use the SSH keys? They all share the same Country/State/Locality/Org/Unit/Name/Email.
The MySQL docs Creating SSL Certificates and Keys Using OpenSSL says I need to do this:
openssl req -newkey rsa:2048 -days 3600 \
-nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3600 \
-CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
This is problematic because I didn't generate the AWS certificates and I only got one pem file from there. Maybe the AWS ca.pem and server-cert.pem are both in the one pem file - guess I could check but I'll have to go and dig out the info about which CA signing authority they use so I could recognise the CA cert. And I guess the 'server-cert' is the public key from the actual host I've got.
But it doesn't work, I get the following error:
$ openssl.exe x509 -req -in client-req.pem -days 3600
-CA rds-combined-ca-bundle.pem -CAkey rds-combined-ca-bundle.pem
-set_serial 01 -out client-cert.pem
Signature ok
subject=/C=UK/ST=LN/L=LN/O=X/OU=XYZ/CN=xyz/emailAddress=adam#me.com
Getting CA Private Key
unable to load CA Private Key
4294956672:error:0906D06C:PEM routines:PEM_read_bio:no start
line:pem_lib.c:707:Expecting: ANY PRIVATE KEY
Turns out the SSL certificates are a red herring. You don't need them. All you need is this:
mysql -h myinstance.c9akciq32.rds-us-east-1.amazonaws.com
--ssl-ca=[full path]rds-combined-ca-bundle.pem --ssl-verify-server-cert
It's Cygwin and the standard Windows MySQL client don't play well together, hence the hanging when trying to start: connecting to mysql from cygwin

Client authentication in server Tomcat

i want to configure SSL for mutual authentication.
I work with eclipse + tomcat 8.
I do this passages:
I created private keys in this way:
openssl genrsa -des3 -out client_key.pem 2048
openssl genrsa -des3 -out server_key.pem 2048
I created self-signed certificates:
openssl req -new -x509 -key client_key.pem -out client.pem -days 365 -config <path to>\openssl.cnf
openssl req -new -x509 -key server_key.pem -out server.pem -days 365 -config <path to>\openssl.cnf
I created truststore and import certificates:
keytool –importcert -trustcacerts –keystore clienttruststore.jks –storetype jks –storepass <truststore_password> -file <path-to-file>\server.pem
keytool –importcert -trustcacerts –keystore servertruststore.jks –storetype jks –storepass <server_truststore_password> -file <path-to-file>\client.pem
I combined the certificate and the private key for the server and client respectively:
openssl pkcs12 –export –inkey client_key.pem –in client.pem –out client.p12
openssl pkcs12 –export –inkey server_key.pem –in server.pem –out server.p12
and finally i converted the keystore in pkcs12 format:
keytool –importkeystore –srckeystore client.p12 –srcstoretype pkcs12 –destkeystore client.jks –deststoretype jks
keytool –importkeystore –srckeystore server.p12 –srcstoretype pkcs12 –destkeystore server.jks –deststoretype jks
After this, i configured configure SSL/TLS support on Tomcat. So, i configured server.xml in Servers folder and setup the connector in this way:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="path\to\server.jks" keystorePass="*******" keystoreType="JKS"
truststoreFile="path\to\servertruststore.jks" truststorePass="********" truststoreType="JKS" />
Finally i clean and build the project.
I created a Dynamic Web Project in Eclipse that called "myproject". It works well.
The problem is that when myproject runs on server at URL https://localhost:8443/myproject
Google Chrome shows the red triangle (This page is insecure (broken HTTPS)).
What's wrong?
Where do i put client.jks e clienttruststore.jks in my project?
This picture shows problem:
Your certificates are self signed, meaning they are not signed by CA, meaning Chrome cannot trust them unless you approve them manually.
When generating certificate did you provide CN? It must match the hostname that you are using (in your case it's localhost), if CN doesn't match, Chrome will not allow SSL unless you approve it manually.
You said you want the mutual authentication, but you configured clientAuth="false" It should be true. As for the keystore, you supposed to use the same keystore for the certificates, therefore when client connects with it's certificate, tomcat will validate that corresponding certificate is located in the keystore.
Hope it helps.

Empty response after configure the spring-boot project to use SSL

I configure SSL in my current spring-boot project this way:
generation of the keystore file:
keytool -genkey -alias ... -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validi
ty 3650 -dname "CN=Kleber Mota, OU=lojadesoftware, O=Itabuna, L=Brazil, ST=Unknows, C=BR" -keypass ... -storepass ...
application.properties (added this lines):
# EMBEDDED SERVER CONFIGURATION
server.port=8443
server.ssl.enabled=true
server.ssl.key-alias=...
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=...
server.ssl.key-password=...
after that, when I run the application and go to url localhost:8443 I only got an error "Empty response from server".
Anyone can give a hint of what I am missing here?
if your application is running and has explicit mapping for (/) try the following, it should work
curl k https://localhost:8443
curl -k https://localhost:8443 ( this one is insecure)
curl -k -1 https://localhost:8443

SSL websockets proxy via nginx proxy with client auth

I'm having trouble setting up a reverse proxy through nginx to a websocket application with client certificate authentication; so far I've gotten the server SSL cert to work no problem. Here are my steps so far for the client auth:
Create the client cert:
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey \
ca.key -set_serial 01 -out client.crt
Configure nginx:
daemon off;
events {
worker_connections 4096;
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
ssl on;
server_name rserve;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
# ssl_client_certificate /etc/nginx/certs/ca.crt;
# ssl_verify_client on;
location / {
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
If I enable the ssl client stuff things stop working. On the client I'm using a jetty implementation (java), I import the client cert into a keystore with this line:
keytool -import -trustcacerts -keystore keystore.jks \
-storepass changeit -noprompt -alias client -file client.crt
This procedure worked for a selfsigned server cert. The failure is reported on the client as a failure to switch protocols, this is in line with my previous failures on behalf of the SSL handshake - the proxied application is websocket only.
You created the private key outside of the keystore and have now imported just the certificate. The client application needs access to both the private and public parts.
Either import the private key or generate the certificate signing request using keytool rather than openssl.

COMODO SSL certificate on Jboss7

I registered a domain and would like to set up SSL encryption for it. My domain provider offered me to get a SSL certificate from COMODO. I generated a key and a csr file using openSSL:
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
The command produced a private key, myserver.key and the csr file. I uploaded the content of the csr to comodo, and after verification, they sent me the following files:
Root CA Certificate - AddTrustExternalCARoot.crt
Intermediate CA Certificate - COMODORSAAddTrustCA.crt
Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
Your PositiveSSL Certificate - mydomain.crt
I'm lost on where to go from here. I followed these instructions:
https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/638/0/certificate-installation-java-based-web-servers-tomcat-using-keytool
and created a domain.keystore file, but I'm not sure if that's the right thing to do or not. My configuration in Jboss now looks like this:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="mydomain" password="*****" protocol="TLSv1" certificate-key-file="../standalone/configuration/domain.keystore"/>
</connector>
But that doesn't seem to work. I get no error in the server log, the page simply times out. If i use http it works normally. Any advice?
EDIT:
I took a different approach, I generated my keystore in this way:
keytool -genkey -alias domain -keyalg RSA -keysize 2048 -keystore domain.keystore
then I uploaded the new csr info to comodo and got the three .crt certificates back. I imported them into the keystore with this command:
keytool -import -trustcacerts -alias domain -file domain.crt -keystore domain.keystore
and then I used the keystore in the standalone.xml in this way:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="domain-ssl" key-alias="domain" password="******" certificate-key-file="../standalone/configuration/domain.keystore" protocol="TLSv1"/>
</connector>
The server starts, but when I try to connect to it, my browser says that the connection is untrusted:
domain uses an invalid security certificate.
The certificate is not trusted because it is self-signed.
(Error code: sec_error_ca_cert_invalid)
I finally managed to get the installation right! Here's how you do it:
Install the COMODO certificates into your keystore wit this command:
keytool -import -trustcacerts -alias <filename> -file <filename>.crt -keystore domain.keystore
in the following order:
» Root: AddTrustExternalCARoot.crt
» Intermediate 1: COMODOAddTrustServerCA.crt
» Intermediate 2: COMODOExtendedValidationSecureServerCA.crt
Then install your domain certificate:
keytool -import -trustcacerts -alias mykey -file yourDomainName.crt -keystore domain.keystore
You should use the same alias instead of mykey, that you used to generate your keystore. If you do everything correctly, you should get this output:
Certificate reply was installed in keystore
Anything else means, you probably didn't use the correct alias. The final thing you need to do is to modify your standalone.xml like this:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="<domain>-ssl" key-alias="<domain>" password="******" certificate-key-file="../standalone/configuration/<domain>.keystore"/>
</connector>
And you should be good to go!
My domain provider offered me to get a SSL certificate from COMODO...
...
Any advice?
Don't pay for the certificate. You can get a free Class 1 certificate from Startcom. The Class 1 is good for server authentication without a wildcard domain. If you want an extended validation certificate or a wilcard certificate, then you will have to buy a Class 2 or higher.
Also, while Startcom issues the certificate for free, they charge for revocation because that's where the cost lies.
I'm lost on where to go from here...
Convert Intermediate CA Certificate - COMODORSAAddTrustCA.crt, Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt and Your PositiveSSL Certificate - mydomain.crt to PEM files. PEM are the ones that start with ----- BEGIN CERTIFICATE ----- and finish with ----- END CERTIFICATE -----.
Then, concatenate your three PEM files into a single file. The file will have three certificates in it. Call it mydomain-chain.pem, and load that into your server. Also load myserver.key into your server.
Don't do anything with Root CA Certificate - AddTrustExternalCARoot.crt. Clients have to use it as a root. There's no {use|need} to send it to the client in the ServerHello.
You can test your setup with the following. Notice how the client uses the root:
openssl s_client -connect myserver:443 -CAfile AddTrustExternalCARoot.crt
The command should end with Verify (0) OK or similar.
Failed to load keystore type JKS with path ../standalone/configuration/mydomain-chain.pem due to Invalid keystore format: which mean your keystore is not valid. Dont create new one use the keystore file you were created while submitting csr file to them. Use same keystore if you change the keystore its not accept.

Categories

Resources