Implementing HTTPS and security headers in Fastify Docker containers is essential for protecting web applications from common vulnerabilities and ensuring secure communication between clients and servers. This guide provides a step-by-step approach to setting up HTTPS and configuring security headers within a Dockerized Fastify environment.

Prerequisites

  • Basic knowledge of Docker and Docker Compose
  • Familiarity with Fastify framework
  • SSL/TLS certificates (self-signed or from a certificate authority)
  • Node.js installed in your environment

Setting Up the Fastify Server with HTTPS

Create a new directory for your project and initialize a Node.js project:

mkdir fastify-https && cd fastify-https

npm init -y

Install Fastify:

npm install fastify

Create a server.js file:

const fastify = require('fastify')({ logger: true });
const fs = require('fs');

const options = {
  key: fs.readFileSync('/certs/server.key'),
  cert: fs.readFileSync('/certs/server.crt')
};

const server = fastify.createSecureServer(options);

server.get('/', async (request, reply) => {
  return { message: 'Secure Fastify Server' };
});

server.listen(443, (err, address) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  fastify.log.info(`Server listening at ${address}`);
});

Configuring Docker for HTTPS

Create a Dockerfile:

FROM node:14

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 443

CMD ["node", "server.js"]

Create a docker-compose.yml file:

version: '3'
services:
  fastify:
    build: .
    ports:
      - "443:443"
    volumes:
      - ./certs:/certs:ro

Managing SSL/TLS Certificates

Generate self-signed certificates for development purposes:

openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost"

Place the server.key and server.crt files into the certs directory.

Implementing Security Headers

Use Fastify's addHook to set security headers:

const fastify = require('fastify')({ logger: true });
const fs = require('fs');

const options = {
  key: fs.readFileSync('/certs/server.key'),
  cert: fs.readFileSync('/certs/server.crt')
};

const server = fastify.createSecureServer(options);

server.addHook('onSend', (request, reply, payload, done) => {
  reply.header('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
  reply.header('X-Content-Type-Options', 'nosniff');
  reply.header('X-Frame-Options', 'DENY');
  reply.header('X-XSS-Protection', '1; mode=block');
  reply.header('Referrer-Policy', 'no-referrer');
  reply.header('Content-Security-Policy', "default-src 'self'");
  done();
});

server.get('/', async (request, reply) => {
  return { message: 'Secure Fastify Server with Security Headers' };
});

server.listen(443, (err, address) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  fastify.log.info(`Server listening at ${address}`);
});

Running the Docker Container

Build the Docker image:

docker-compose build

Start the container:

docker-compose up

Testing the Setup

Open your browser and navigate to https://localhost. You should see the JSON message indicating a secure connection with security headers applied. For production, replace self-signed certificates with certificates from a trusted Certificate Authority.

Conclusion

Implementing HTTPS and security headers in Fastify Docker containers enhances the security posture of your web applications. Proper certificate management and security best practices, such as setting security headers, help protect against common vulnerabilities and ensure data integrity and confidentiality.