Home > Blockchain >  nGinx SSL Passthrough to Spring boot server handshake not working
nGinx SSL Passthrough to Spring boot server handshake not working

Time:02-04

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.

  • Related