This project demonstrates how Mutual TLS (mTLS) works by implementing a secure server and client authentication using certificates.
- Overview
- Project Structure
- Prerequisites
- Quick Start
- Server Implementation
- Client Implementations
- End-to-End Testing
- Certificate Expiration Demonstration
- Docker Environment
- Detailed Documentation
- Security Note
- License
Mutual TLS, also known as two-way SSL, is a security protocol where both the client and server authenticate each other using X.509 certificates. This PoC shows:
- How to create a Certificate Authority (CA)
- How to generate and sign server and client certificates
- How to implement a secure HTTPS server with mTLS authentication
- How to connect clients using client certificates
- How client authentication is validated at the server side
mtls-poc/
├── certs/ # Stores all certificates and keys
├── server/ # Server implementation (Node.js)
├── clients/ # Client implementations (curl, Python)
├── scripts/ # Utility scripts for certificate management
└── docs/ # Additional documentation
- OpenSSL for certificate generation
- Node.js (v14+) for running the server
- curl for command-line client testing
- Python 3.x with requests library for the Python client (optional)
-
Generate certificates:
# Create CA ./scripts/create-ca.sh # Create server certificate ./scripts/create-server-cert.sh # Create client certificates ./scripts/create-client-cert.sh client1 ./scripts/create-client-cert.sh client2
-
Start the server:
cd server npm install node server.js
-
Test with curl:
# Run the automated test script ./clients/curl-test.sh # Or run individual commands manually # Test with valid client certificate curl --cacert certs/ca.crt --cert certs/client1.crt --key certs/client1.key https://localhost:8443/ # Test without client certificate (should fail) curl --cacert certs/ca.crt https://localhost:8443
The Node.js HTTPS server is configured to require mutual TLS authentication. Key features include:
- Validates client certificates against the CA
- Rejects unauthorized clients without valid certificates
- Provides detailed certificate information in responses
- Includes multiple API endpoints for testing
- / - Root endpoint with certificate details
- /api/secure-data - Example protected data API
- /api/status - Server status information
All endpoints require a valid client certificate signed by our CA.
A bash script is provided to test the server with curl:
./clients/curl-test.sh
This script tests multiple scenarios including valid certificate authentication and error cases.
A Python client is also available for programmatic testing:
# Install dependencies
cd clients/python
pip install -r requirements.txt
# Run the client with default settings
python client.py
# Or specify custom parameters
python client.py --url https://localhost:8443 --client-cert ../../certs/client2.crt --client-key ../../certs/client2.key
# Test without client certificate (should fail)
python client.py --no-client-auth
# Test a specific endpoint
python client.py --endpoint /api/secure-data
The Python client provides colored output and supports testing all available endpoints.
An automated script is provided to test the entire workflow from certificate generation to server and client testing:
./test-all.sh
This script performs the following steps:
- Checks prerequisites (OpenSSL, Node.js)
- Cleans up any previous test data
- Generates all certificates (CA, server, and clients)
- Prepares the Python client dependencies
- Starts the server in the background
- Runs curl and Python client tests
- Cleans up after testing
The script provides detailed output and preserves logs for inspection.
This project includes tools to demonstrate how expired certificates are handled in mTLS:
# Step 1: Generate an expired certificate (backdated)
./scripts/create-expired-cert.sh
# Step 2: Test server's handling of expired certificate
./clients/test-expired.sh
This demonstration shows:
- How mTLS rejects certificates that have expired
- Comparison between valid and expired certificate behavior
- Certificate validation errors and their meaning
See Certificate Management for more details on certificate expiration.
This project includes Docker support for running the mTLS PoC in an isolated environment:
# Start the Docker environment and run tests
./scripts/docker-test.sh
# Or use Docker Compose directly
docker-compose up -d
The Docker setup includes three services:
- mtls-cert-generator: Generates all required certificates
- mtls-server: Runs the Node.js HTTPS server with mTLS
- mtls-client: Provides an environment for testing the server
See Docker Setup for detailed instructions and troubleshooting.
A web-based UI is available to visualize and manage certificates, and demonstrate the mTLS handshake process:
# Install dependencies if needed
cd server
npm install
cd ..
# Start the web UI server
node server/web-server.js
# Open in browser:
# http://localhost:8080
The web UI provides:
- Certificate dashboard with status and expiry information
- Detailed certificate visualization and chain of trust
- Interactive mTLS handshake demonstration
- API testing console for different client certificates
See Web UI Documentation for detailed instructions.
- Certificate Management - Details on certificate creation and management
- Troubleshooting - Common issues and solutions
- Docker Setup - Running the PoC in Docker containers
- Web UI - Using the web-based certificate management interface
This is a proof of concept and educational tool. For production systems:
- Use stronger security parameters and keep certificates up-to-date
- Implement proper certificate revocation mechanisms (CRL/OCSP)
- Consider using managed certificate services or dedicated PKI solutions
- Secure private keys appropriately (HSM for high-security environments)
- Follow industry standards and compliance requirements
- Implement proper monitoring and certificate lifecycle management
- Regularly audit and test your mTLS implementation
- Use stronger cipher suites and TLS protocol versions
Refer to docs/certificate-management.md for more security considerations.
This project is licensed under the MIT License - see the LICENSE file for details.