Using SSL certificates in localhost

Using SSL certificates in localhost

A tool for accessing SSL/http2 for development. https://localhost.int

·

3 min read

Architecture of this post

  • Trust Authority [or, Certificate Authority]
  • SSL Certificate
  • Mapping domain names to local IP
  • Reverse proxy through nginX

Conventions:

  • pem - public key [used to verify if signed by correct private key]
  • key - private key [secret]
  • crt - certificate file [contains public key and metadata]
  • csr - certificate request

Certificate Authority

A certificate file which is trusted by browsers, systems and applications. Some default ones are GoDaddy, Google, Cloudflare, etc.

SSL Certificate

A certificate signed by Trust Authority

App.crt = CA.key + App.csr

Procedures

Run these commands to generate CA.key

openssl req \
    -x509 \
    -nodes \
    -new -sha256 -days 1024 \
    -newkey rsa:2048 \
    -keyout CA.key \
    -out CA.pem \
    -subj "/C=NP/CN=SHREE-SHREE-CA"

Create CA.crt

openssl x509 \
    -outform pem \
    -in CA.pem \
    -out CA.crt

Generate certificate request using new App.key

# Application keys
openssl req \
    -new -nodes \
    -newkey rsa:2048 \
    -keyout App.key \
    -out App.csr \
    -subj "/C=NP/ST=SHREE/L=SHREE/O=SHREE-SHREE-DOMAIN/CN=localhost.int"

Create domains.ext file and define alt_names

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = frontend.localhost.int
DNS.2 = backend.localhost.int
DNS.3 = cdn.localhost.int

Create certificate using CA.key

openssl x509 -req -sha256 \
    -in App.csr \
    -CA CA.pem \
    -CAkey CA.key \
    -CAcreateserial \
    -extfile domains.ext \
    -out App.crt

Establish Trust

Import CA.crt file into chrome using chrome://settings/certificates >> Authorities >> Import

Mapping DNS to IPs

Because localhost.int, frontend.localhost.int, backend.localhost.int and cdn.localhost.int all are hosted in our machine, we can map it to internal IP. Edit /etc/hosts/ file

# /etc/hosts
127.0.0.1    localhost 
127.0.0.1    localhost.int
127.0.0.1    frontend.localhost.int
127.0.0.1    backend.localhost.int
127.0.0.1    cdn.localhost.int

Note: 127.*.*.* is type C reserved IP and points to local machine

Reverse Proxy through nginX

  • Create files in /etc/nginx/sites-enabled/
# /etc/nginx/sites-enabled/cdn.localhost.int

server {
    listen      80;
    server_name cdn.localhost.int;
    return 301 https://cdn.localhost.int$request_uri;
}

# ssl http2 server
server {
    listen 443 ssl http2;
    server_name cdn.localhost.int;
    ssl_certificate      /codebase/rhrs/src/ssl-certificates/App.crt;
    ssl_certificate_key  /codebase/rhrs/src/ssl-certificates/App.key;

    location /favicon.ico {
        proxy_pass https://img.icons8.com/material-outlined/24/000000/infinity.png;
    }

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:5000;
    }
}
# /etc/nginx/sites-enabled/backend.localhost.int

server {
    listen      80;
    server_name backend.localhost.int;
    return 301 https://backend.localhost.int$request_uri;
}

# ssl http2 server
server {
    listen 443 ssl http2;
    server_name backend.localhost.int;
    ssl_certificate      /codebase/rhrs/src/ssl-certificates/App.crt;
    ssl_certificate_key  /codebase/rhrs/src/ssl-certificates/App.key;

    location /favicon.ico {
        proxy_pass https://img.icons8.com/material-outlined/24/000000/infinity.png;
    }

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8000;
    }
}
# /etc/nginx/sites-enabled/frontend.localhost.int

server {
    listen      80;
    server_name frontend.localhost.int;
    return 301 https://frontend.localhost.int$request_uri;
}

# ssl http2 server
server {
    listen 443 ssl http2;
    server_name frontend.localhost.int;
    ssl_certificate      /codebase/rhrs/src/ssl-certificates/App.crt;
    ssl_certificate_key  /codebase/rhrs/src/ssl-certificates/App.key;

    location /favicon.ico {
        proxy_pass https://img.icons8.com/material-outlined/24/000000/infinity.png;
    }

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:3000;
    }
}