I have spring boot application running on port 8081 on localhost. I am running HTTPS using a self signed certificate.
First, I have created a ca certificate using OpenSSL.
openssl req \
-new \
-x509 \
-nodes \
-newkey rsa:2048\
-days 365 \
-subj '/CN=bcc' \
-keyout ca.key \
-out ca.crt
I have generated certificate for spring boot and nginx server using this ca certificate.
## Using this certificate for spring boot
openssl genrsa \
-out server.key 2048
openssl req \
-new \
-key server.key \
-subj '/CN=bcc-ca-website.org' \
-out server.csr
openssl x509 \
-req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 365 \
-extfile v3.ext \
-out server.crt
## Using this certificate for nginx server
openssl genrsa \
-out nginx-server.key 2048
openssl req \
-new \
-key nginx-server.key \
-subj '/CN=bcc-ca-website.org' \
-out nginx-server.csr
openssl x509 \
-req \
-in nginx-server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 365 \
-extfile v3.ext \
-out nginx-server.crt
Here is my application.yml
server:
port: 8081
ssl:
enabled: true
key-store: "classpath:server.p12"
key-store-password: 123456
key-store-type: PKCS12
client-auth: need
enabled-protocols: TLSv1.2
trust-store: "classpath:server.p12"
trust-store-type: pkcs12
trust-store-password: 123456
Note that, I am using client MTLS authentication and created client CA and certifcates using openssl in the same way.
So, I need to use nginx using passthrough mode, so that the ssl connections is to made to the spring boot server. Here is my sites-available/default
upstream node_basic {
server localhost:8081;
}
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/nginx-server.crt;
ssl_certificate_key /etc/ssl/nginx-server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
ssl_session_timeout 24h;
location / {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://node_basic;
}
}
But, I am getting error:
2023/02/02 11:37:51 [error] 22475#22475: *1 SSL_do_handshake() failed (SSL: error:0A000412:SSL routines::sslv3 alert bad certificate:SSL alert number 42) while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "https://127.0.0.1:8081/", host: "bcc-ca-website.org"
CodePudding user response:
As @dev_thompson_085 suggested, I configured nginx as a reverse stream proxy . Changed /etc/nginx/nginx.conf
and added this after http
block.
stream {
upstream spring-boot {
server localhost:8081;
}
server {
listen 443;
proxy_pass spring-boot;
}
}
In this way, nginx can pass through incoming request to spring boot encrypted.