Fast-Setup: Nginx Https Reverse Proxy for Springboot API

Leon Dong
2 min readFeb 1, 2023

When a strong inspiration comes to me, I am instantly involved in developing a flutter app. But, unfortunately, my HTTP request is blocked by the mobile operating system for an insecure connection. According to the error log, APIs should be secured with HTTPS.

https on nginx

Environment

  • Server OS: CentOS Linux release 7.6
  • Server Nginx: 1.20.1
  • Java Springboot API Service is running on the server using port 3001.
  • A domain name api.leon.com pointing to the server.
  • Local PC: mac (with OpenSSL installed)

Generate SSL certificates

I generated related certificates on my mac.

Firstly, I generated the private key and CSR file using the following commands:

# generate the private key and csr
openssl req -new -newkey rsa:2048 -nodes -keyout leon-api.key -out leon-api.csr

Notice:

  • When inputting information for CSR, the Common Name(CN) must be the corresponding domain name api.leon.com .
  • Country(C): Must be two-letter country code.

Secondly, generating the crt file with the private key and the CSR. Then, I convert the crt file into pem format for nginx.

# generate crt with the key and the csr
openssl x509 -req -days 36500 -in leon-api.csr -signkey leon-api.key -out leon-api.crt

# convert crt to pem
openssl x509 -in leon-api.crt -out leon-api.pem

Finally, copy the leon-api.key and leon-api.csr to server:

scp leon-api.key leon-api.csr root@121.x.x.101:/etc/nginx/conf.d/

/etc/nginx/conf.d/ is the configuration files folder of nginx.

Configure nginx

Create a new file called leon-api-com.cong in path of /etc/nginx/conf .

The configuration content is below:

server {
listen 80;
return 301 https://$host$request_uri;
}

server {

listen 443 ssl;
server_name api.leon.com;

ssl_certificate /etc/nginx/conf.d/leon-api.pem;
ssl_certificate_key /etc/nginx/conf.d/leon-api.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 500M;

location / {
proxy_read_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_pass http://127.0.0.1:3001;

proxy_redirect http://127.0.0.1:3001 https://api.leon.com;
}

}

First server configuration redirects all HTTP requests to HTTPS protocol.

Second server truly configures the HTTPS reverse proxy.

  • listen 443 ssl: listening all HTTPS requests from default port 443.
  • server_name api.leon.com: only handling the requests from domain name api.leon.com
  • ssl_certificate and ssl_certificate_key: pointing to SSL certificates.
  • proxy_pass http://127.0.0.1:3001: indicating that all requests from api.leon.com will be redirected to local API service.

Test https api

Use curl to test the API service running on server:

curl --location \
--cacert /path/to/rect-lifer-api.pem \
--request POST 'https://api.leon.com/book/search' \
--header 'Token: SHDYGYWGY' \
--header 'Content-Type: application/json' \
--data-raw '{
"bookName": "",
"pageSize": 6
}'

The param --cacert indicates the path to certificate.

In fact, I spent 2 days on configuring nginx. Next, I will continue to develop my mobile app strengthened by HTTPS API. 😄

--

--