Serving your API over HTTPS is becoming more and more crucial by the day, especially from a usability perspective since the browsers are shedding all the HTTP and other unsecure, legacy support nowadays
In this blog, I will teach you by example, how to generate an SSL/TLS certificate for any API you have & then use a proxy server (developed using NGINX) to basically start serving your simple HTTP API over HTTPS
Step 1 - The Domain Name Server (DNS) Resolution
You need a domain record (A or AAA) that basically acts as the entity that the certificate will be generated for
The only step to do here is to use for DNS service create a simple A record that points to the server you are going to use to host the API.
For me, I did it like this for a project :
Before you start the next step, make sure the DNS has propagated properly by running the following commands
Replace api.domain.com with your own API_DOMAIN_NAME
dig api.domain.com
nslookup api.domain.com
Next, we will generate a certificate attached to this domain.
Step 2 - Certificate generation
You can generate a public certificate & private key pair for free using letsencrypt
.
For this, you 1st install the package on your machine
sudo apt install letsencrypt
Next you generate a simple certificate for the domain you want to certify using the certbot
API that you can now access
For this step you need your port 80 unblocked so get that done by simply running
sudo fuser -k 80/tcp
Then you can safely run
sudo certbot certonly --standalone
Now, the CLI will prompt you to enter the domain name (here, it is api.domain.com) & then it will generate a pair of a public certificate & a private key
This is what will be actually used by our proxy server to even respond to requests to this API_DOMAIN_NAME
Step 3 - Proxy server setup
This is a simple nginx server we will setup that will listen on port 80 (HTTP) & port 443 (HTTPS) of our server & redirected it to our api's port.
We just pass the location of the generated certificate-key pair to NGINX in its configuration file
For writing a nginx.conf while, first install nginx
sudo apt install nginx
First stop running nginx service by running
sudo nginx -s stop
Next you should go to the directory where this configuration file is stored & override the code with the simple proxy code you have
cd /etc/nginx
sudo nano nginx.conf
In there, we specify a simple rule to pass the 80 (HTTP) & 443 (HTTPS) traffic to our backend. Here, I have even gone ahead & made this a load balancer with stickiness by specifying my api resolvers running on ports 8080, 8081, 8082 & add a #ip_hash
configuration option so that once the client gets associated with one api, its requests are always directed there:
And we pass the locations of the generated public certificate & private key pair to the nginx rule that is resolving port 443 using SSL.
Here's my configuration file
For you api.domain.com
would be whatever your API_DOMAIN_NAME is
http {
upstream allbackend {
#ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem;
location / {
proxy_pass http://allbackend/;
}
}
}
events { }
Then simply, clear any pending services on ports 80 & 443 restart nginx on them using :
sudo fuser -k 80/tcp
sudo fuser -k 443/tcp
sudo service nginx restart
That's that ! You've made your API HTTPS now