mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-06 08:20:50 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: configuring-tls-1.3-for-secure-communications
|
||||
description: TLS 1.3 (RFC 8446) is the latest version of the Transport Layer Security protocol, providing significant improvements over TLS 1.2 in both security and performance. It reduces handshake latency to 1-R
|
||||
domain: cybersecurity
|
||||
subdomain: cryptography
|
||||
tags: [cryptography, tls, ssl, transport-security, network-security]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
# Configuring TLS 1.3 for Secure Communications
|
||||
|
||||
## Overview
|
||||
|
||||
TLS 1.3 (RFC 8446) is the latest version of the Transport Layer Security protocol, providing significant improvements over TLS 1.2 in both security and performance. It reduces handshake latency to 1-RTT (and 0-RTT for resumed sessions), removes obsolete cipher suites, and mandates perfect forward secrecy. This skill covers configuring TLS 1.3 on servers, validating configurations, and testing for common misconfigurations.
|
||||
|
||||
## Objectives
|
||||
|
||||
- Configure TLS 1.3 on nginx and Apache web servers
|
||||
- Implement TLS 1.3 in Python applications using the ssl module
|
||||
- Validate TLS configurations with openssl and testssl.sh
|
||||
- Understand TLS 1.3 cipher suites and key exchange mechanisms
|
||||
- Configure 0-RTT early data with appropriate protections
|
||||
- Disable legacy TLS versions (1.0, 1.1) and weak cipher suites
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### TLS 1.3 Cipher Suites
|
||||
|
||||
| Cipher Suite | Key Exchange | Authentication | Encryption | Hash |
|
||||
|-------------|-------------|----------------|------------|------|
|
||||
| TLS_AES_256_GCM_SHA384 | ECDHE/DHE | Certificate | AES-256-GCM | SHA-384 |
|
||||
| TLS_AES_128_GCM_SHA256 | ECDHE/DHE | Certificate | AES-128-GCM | SHA-256 |
|
||||
| TLS_CHACHA20_POLY1305_SHA256 | ECDHE/DHE | Certificate | ChaCha20-Poly1305 | SHA-256 |
|
||||
|
||||
### TLS 1.3 vs 1.2 Improvements
|
||||
|
||||
- **1-RTT Handshake**: Full handshake completes in one round trip (vs 2 in TLS 1.2)
|
||||
- **0-RTT Resumption**: Resumed connections can send data immediately
|
||||
- **No RSA Key Exchange**: Only ephemeral Diffie-Hellman (mandatory PFS)
|
||||
- **Simplified Cipher Suites**: Removed CBC, RC4, 3DES, static RSA, SHA-1
|
||||
- **Encrypted Handshake**: Server certificate is encrypted after ServerHello
|
||||
|
||||
### Key Exchange Groups
|
||||
|
||||
- **x25519**: Curve25519 ECDH (preferred, fast)
|
||||
- **secp256r1**: NIST P-256 ECDH (widely supported)
|
||||
- **secp384r1**: NIST P-384 ECDH (higher security margin)
|
||||
- **x448**: Curve448 ECDH (highest security)
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. Verify OpenSSL version supports TLS 1.3 (1.1.1+)
|
||||
2. Generate or obtain TLS certificate and private key
|
||||
3. Configure server to use TLS 1.3 cipher suites
|
||||
4. Disable TLS 1.0 and 1.1 (optionally keep 1.2 for compatibility)
|
||||
5. Set preferred key exchange groups
|
||||
6. Enable OCSP stapling for certificate validation
|
||||
7. Test configuration with openssl s_client and testssl.sh
|
||||
8. Configure HSTS header for HTTP Strict Transport Security
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- 0-RTT data is vulnerable to replay attacks; limit to idempotent requests
|
||||
- Always include TLS 1.2 fallback if legacy client support is required
|
||||
- Use ECDSA certificates for better performance (vs RSA)
|
||||
- Enable OCSP stapling to improve client certificate validation
|
||||
- Set HSTS header with long max-age and includeSubDomains
|
||||
- Monitor for certificate transparency logs
|
||||
|
||||
## Validation Criteria
|
||||
|
||||
- [ ] TLS 1.3 handshake completes successfully
|
||||
- [ ] Only approved cipher suites are offered
|
||||
- [ ] Perfect forward secrecy is enforced
|
||||
- [ ] TLS 1.0 and 1.1 are rejected
|
||||
- [ ] OCSP stapling is functional
|
||||
- [ ] Certificate chain is valid and complete
|
||||
- [ ] testssl.sh reports no vulnerabilities
|
||||
@@ -0,0 +1,67 @@
|
||||
# TLS 1.3 Configuration Template
|
||||
|
||||
## Pre-Configuration Checklist
|
||||
|
||||
- [ ] Verify OpenSSL version >= 1.1.1 (`openssl version`)
|
||||
- [ ] Obtain valid TLS certificate from trusted CA
|
||||
- [ ] Identify all server endpoints requiring TLS
|
||||
- [ ] Determine minimum TLS version (1.2 or 1.3 only)
|
||||
- [ ] Plan certificate renewal automation (Let's Encrypt / ACME)
|
||||
- [ ] Review compliance requirements (PCI-DSS, HIPAA)
|
||||
|
||||
## nginx Configuration Template
|
||||
|
||||
```nginx
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_ecdh_curve X25519:secp256r1:secp384r1;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||
```
|
||||
|
||||
## Python TLS 1.3 Client Template
|
||||
|
||||
```python
|
||||
import ssl
|
||||
import socket
|
||||
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
context.minimum_version = ssl.TLSVersion.TLSv1_3
|
||||
context.load_default_certs()
|
||||
|
||||
with socket.create_connection(("example.com", 443)) as sock:
|
||||
with context.wrap_socket(sock, server_hostname="example.com") as tls:
|
||||
print(f"Protocol: {tls.version()}")
|
||||
print(f"Cipher: {tls.cipher()}")
|
||||
```
|
||||
|
||||
## Validation Commands
|
||||
|
||||
```bash
|
||||
# Test TLS 1.3 support
|
||||
openssl s_client -connect example.com:443 -tls1_3
|
||||
|
||||
# Show full certificate chain
|
||||
openssl s_client -connect example.com:443 -showcerts
|
||||
|
||||
# List supported cipher suites
|
||||
openssl s_client -connect example.com:443 -cipher 'ALL' -tls1_3
|
||||
|
||||
# Test with testssl.sh
|
||||
./testssl.sh --protocols --ciphers --headers example.com
|
||||
```
|
||||
|
||||
## Security Headers Checklist
|
||||
|
||||
| Header | Value | Purpose |
|
||||
|--------|-------|---------|
|
||||
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | Force HTTPS |
|
||||
| X-Content-Type-Options | nosniff | Prevent MIME sniffing |
|
||||
| X-Frame-Options | DENY | Prevent clickjacking |
|
||||
| Content-Security-Policy | default-src 'self' | Prevent XSS |
|
||||
| Referrer-Policy | strict-origin-when-cross-origin | Limit referrer leakage |
|
||||
@@ -0,0 +1,67 @@
|
||||
# Standards and References - TLS 1.3 Configuration
|
||||
|
||||
## Primary Standards
|
||||
|
||||
### RFC 8446 - The Transport Layer Security (TLS) Protocol Version 1.3
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc8446
|
||||
- **Description**: The core TLS 1.3 specification
|
||||
- **Key changes**: 1-RTT handshake, mandatory PFS, removed RSA key transport, encrypted handshake messages
|
||||
|
||||
### RFC 8447 - IANA Registry Updates for TLS and DTLS
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc8447
|
||||
- **Description**: Updates IANA registries for TLS cipher suites and extensions
|
||||
|
||||
### RFC 8449 - Record Size Limit Extension for TLS
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc8449
|
||||
- **Description**: Allows endpoints to negotiate maximum record size
|
||||
|
||||
### RFC 8470 - Using Early Data in HTTP (0-RTT)
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc8470
|
||||
- **Description**: Defines how 0-RTT early data works with HTTP, including replay protections
|
||||
|
||||
### RFC 6961 - TLS Multiple Certificate Status Extension (OCSP Stapling)
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc6961
|
||||
- **Description**: Allows servers to provide OCSP responses during handshake
|
||||
|
||||
### RFC 6797 - HTTP Strict Transport Security (HSTS)
|
||||
- **URL**: https://www.rfc-editor.org/rfc/rfc6797
|
||||
- **Description**: Forces browsers to use HTTPS for all connections
|
||||
|
||||
## NIST Guidelines
|
||||
|
||||
### NIST SP 800-52 Rev. 2 - Guidelines for TLS Implementations
|
||||
- **URL**: https://csrc.nist.gov/publications/detail/sp/800-52/rev-2/final
|
||||
- **Description**: Federal guidelines for TLS deployment
|
||||
- **TLS 1.3**: Recommended for all new deployments
|
||||
- **TLS 1.2**: Acceptable with approved cipher suites
|
||||
- **TLS 1.0/1.1**: Prohibited
|
||||
|
||||
### NIST SP 800-57 Part 3 Rev. 1 - Application-Specific Key Management
|
||||
- **URL**: https://csrc.nist.gov/publications/detail/sp/800-57-part-3/rev-1/final
|
||||
- **Description**: Key management guidance for TLS
|
||||
|
||||
## Testing Tools
|
||||
|
||||
### testssl.sh
|
||||
- **URL**: https://testssl.sh/
|
||||
- **GitHub**: https://github.com/drwetter/testssl.sh
|
||||
- **Description**: Command-line tool for checking TLS/SSL configurations
|
||||
|
||||
### SSL Labs Server Test
|
||||
- **URL**: https://www.ssllabs.com/ssltest/
|
||||
- **Description**: Online TLS configuration analyzer (Qualys)
|
||||
|
||||
### Mozilla SSL Configuration Generator
|
||||
- **URL**: https://ssl-config.mozilla.org/
|
||||
- **Description**: Generate recommended TLS configurations for various servers
|
||||
|
||||
## Compliance
|
||||
|
||||
### PCI DSS v4.0
|
||||
- TLS 1.0 and early TLS prohibited since June 2018
|
||||
- TLS 1.2+ required; TLS 1.3 recommended
|
||||
- Strong cipher suites must be configured
|
||||
|
||||
### HIPAA
|
||||
- Encryption in transit required for ePHI
|
||||
- TLS 1.2+ satisfies the requirement
|
||||
@@ -0,0 +1,87 @@
|
||||
# Workflows - Configuring TLS 1.3
|
||||
|
||||
## Workflow 1: TLS 1.3 Handshake (1-RTT)
|
||||
|
||||
```
|
||||
Client Server
|
||||
| |
|
||||
|--- ClientHello ------------------>|
|
||||
| (supported_versions: TLS 1.3) |
|
||||
| (key_share: x25519) |
|
||||
| (signature_algorithms) |
|
||||
| (cipher_suites) |
|
||||
| |
|
||||
|<-- ServerHello -------------------|
|
||||
| (selected cipher suite) |
|
||||
| (key_share: x25519) |
|
||||
|<-- {EncryptedExtensions} ---------|
|
||||
|<-- {Certificate} -----------------|
|
||||
|<-- {CertificateVerify} -----------|
|
||||
|<-- {Finished} --------------------|
|
||||
| |
|
||||
|--- {Finished} ------------------->|
|
||||
| |
|
||||
|<== Application Data ==============>|
|
||||
```
|
||||
|
||||
## Workflow 2: nginx TLS 1.3 Configuration
|
||||
|
||||
```
|
||||
1. Check OpenSSL version (>= 1.1.1)
|
||||
$ openssl version
|
||||
|
||||
2. Generate ECDSA certificate
|
||||
$ openssl ecparam -genkey -name prime256v1 -out server.key
|
||||
$ openssl req -new -x509 -key server.key -out server.crt -days 365
|
||||
|
||||
3. Configure nginx
|
||||
Edit /etc/nginx/nginx.conf
|
||||
|
||||
4. Test configuration
|
||||
$ nginx -t
|
||||
|
||||
5. Reload nginx
|
||||
$ systemctl reload nginx
|
||||
|
||||
6. Verify TLS 1.3
|
||||
$ openssl s_client -connect localhost:443 -tls1_3
|
||||
```
|
||||
|
||||
## Workflow 3: TLS Configuration Validation
|
||||
|
||||
```
|
||||
[Server] --> [openssl s_client test]
|
||||
|
|
||||
[Check protocol version]
|
||||
[Check cipher suite]
|
||||
[Check certificate chain]
|
||||
|
|
||||
[testssl.sh full scan]
|
||||
|
|
||||
[Check for vulnerabilities]
|
||||
- BEAST, POODLE, Heartbleed
|
||||
- ROBOT, DROWN, FREAK
|
||||
- Weak ciphers, expired certs
|
||||
|
|
||||
[SSL Labs grade assessment]
|
||||
Target: A+ rating
|
||||
```
|
||||
|
||||
## Workflow 4: Certificate Lifecycle
|
||||
|
||||
```
|
||||
[Generate Key Pair]
|
||||
|
|
||||
[Create CSR] --> [Submit to CA]
|
||||
|
|
||||
[CA Issues Certificate]
|
||||
|
|
||||
[Install Certificate]
|
||||
|
|
||||
[Configure OCSP Stapling]
|
||||
|
|
||||
[Set Up Auto-Renewal]
|
||||
(certbot / ACME)
|
||||
|
|
||||
[Monitor Expiration]
|
||||
```
|
||||
@@ -0,0 +1,419 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
TLS 1.3 Configuration and Validation Tool
|
||||
|
||||
Implements TLS 1.3 server/client testing, configuration generation,
|
||||
and vulnerability scanning using Python's ssl module and OpenSSL.
|
||||
|
||||
Requirements:
|
||||
pip install cryptography
|
||||
|
||||
Usage:
|
||||
python process.py test-server --host example.com --port 443
|
||||
python process.py generate-nginx --domain example.com --cert-path /etc/ssl
|
||||
python process.py generate-cert --domain example.com --output ./certs
|
||||
python process.py check-ciphers --host example.com
|
||||
"""
|
||||
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
import json
|
||||
import socket
|
||||
import argparse
|
||||
import logging
|
||||
import subprocess
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, List
|
||||
|
||||
from cryptography import x509
|
||||
from cryptography.x509.oid import NameOID, ExtensionOID
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec, rsa
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TLS_13_CIPHERS = [
|
||||
"TLS_AES_256_GCM_SHA384",
|
||||
"TLS_AES_128_GCM_SHA256",
|
||||
"TLS_CHACHA20_POLY1305_SHA256",
|
||||
]
|
||||
|
||||
RECOMMENDED_TLS_12_CIPHERS = [
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
"ECDHE-RSA-AES128-GCM-SHA256",
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
||||
"ECDHE-RSA-CHACHA20-POLY1305",
|
||||
]
|
||||
|
||||
|
||||
def test_tls_connection(host: str, port: int = 443, timeout: int = 10) -> Dict:
|
||||
"""Test TLS connection to a server and report protocol details."""
|
||||
results = {
|
||||
"host": host,
|
||||
"port": port,
|
||||
"tls_13_supported": False,
|
||||
"tls_12_supported": False,
|
||||
"protocol_version": None,
|
||||
"cipher_suite": None,
|
||||
"certificate": None,
|
||||
"issues": [],
|
||||
}
|
||||
|
||||
# Test TLS 1.3
|
||||
try:
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
|
||||
ctx.maximum_version = ssl.TLSVersion.TLSv1_3
|
||||
|
||||
with socket.create_connection((host, port), timeout=timeout) as sock:
|
||||
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
results["tls_13_supported"] = True
|
||||
results["protocol_version"] = ssock.version()
|
||||
cipher = ssock.cipher()
|
||||
results["cipher_suite"] = {
|
||||
"name": cipher[0],
|
||||
"protocol": cipher[1],
|
||||
"bits": cipher[2],
|
||||
}
|
||||
cert = ssock.getpeercert()
|
||||
results["certificate"] = {
|
||||
"subject": dict(x[0] for x in cert.get("subject", ())),
|
||||
"issuer": dict(x[0] for x in cert.get("issuer", ())),
|
||||
"notBefore": cert.get("notBefore"),
|
||||
"notAfter": cert.get("notAfter"),
|
||||
"serialNumber": cert.get("serialNumber"),
|
||||
"version": cert.get("version"),
|
||||
}
|
||||
logger.info(f"TLS 1.3 connection successful: {cipher[0]}")
|
||||
except ssl.SSLError as e:
|
||||
results["issues"].append(f"TLS 1.3 not supported: {e}")
|
||||
logger.warning(f"TLS 1.3 not supported on {host}:{port}")
|
||||
except Exception as e:
|
||||
results["issues"].append(f"Connection error: {e}")
|
||||
|
||||
# Test TLS 1.2
|
||||
try:
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
|
||||
ctx.maximum_version = ssl.TLSVersion.TLSv1_2
|
||||
|
||||
with socket.create_connection((host, port), timeout=timeout) as sock:
|
||||
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
results["tls_12_supported"] = True
|
||||
if not results["tls_13_supported"]:
|
||||
results["protocol_version"] = ssock.version()
|
||||
cipher = ssock.cipher()
|
||||
results["cipher_suite"] = {
|
||||
"name": cipher[0],
|
||||
"protocol": cipher[1],
|
||||
"bits": cipher[2],
|
||||
}
|
||||
except (ssl.SSLError, Exception):
|
||||
pass
|
||||
|
||||
# Test deprecated protocols
|
||||
for version_name, version_enum in [
|
||||
("TLS 1.1", ssl.TLSVersion.TLSv1_1),
|
||||
("TLS 1.0", ssl.TLSVersion.TLSv1),
|
||||
]:
|
||||
try:
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
ctx.minimum_version = version_enum
|
||||
ctx.maximum_version = version_enum
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
with socket.create_connection((host, port), timeout=timeout) as sock:
|
||||
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
results["issues"].append(
|
||||
f"VULNERABLE: {version_name} is still enabled (should be disabled)"
|
||||
)
|
||||
logger.warning(f"{version_name} is enabled on {host}:{port}")
|
||||
except (ssl.SSLError, OSError):
|
||||
pass
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def check_cipher_suites(host: str, port: int = 443, timeout: int = 10) -> Dict:
|
||||
"""Check which cipher suites a server supports."""
|
||||
results = {"host": host, "port": port, "supported_ciphers": [], "weak_ciphers": []}
|
||||
|
||||
weak_patterns = ["RC4", "DES", "3DES", "MD5", "NULL", "EXPORT", "anon"]
|
||||
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
try:
|
||||
with socket.create_connection((host, port), timeout=timeout) as sock:
|
||||
with ctx.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
cipher = ssock.cipher()
|
||||
results["negotiated_cipher"] = {
|
||||
"name": cipher[0],
|
||||
"protocol": cipher[1],
|
||||
"bits": cipher[2],
|
||||
}
|
||||
shared = ssock.shared_ciphers()
|
||||
if shared:
|
||||
for c in shared:
|
||||
cipher_info = {"name": c[0], "protocol": c[1], "bits": c[2]}
|
||||
results["supported_ciphers"].append(cipher_info)
|
||||
if any(weak in c[0] for weak in weak_patterns):
|
||||
results["weak_ciphers"].append(cipher_info)
|
||||
except Exception as e:
|
||||
results["error"] = str(e)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def generate_self_signed_cert(
|
||||
domain: str, output_dir: str, key_type: str = "ecdsa"
|
||||
) -> Dict:
|
||||
"""Generate a self-signed TLS certificate for testing."""
|
||||
output_path = Path(output_dir)
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if key_type == "ecdsa":
|
||||
private_key = ec.generate_private_key(ec.SECP256R1())
|
||||
key_filename = "server-ecdsa.key"
|
||||
cert_filename = "server-ecdsa.crt"
|
||||
else:
|
||||
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
key_filename = "server-rsa.key"
|
||||
cert_filename = "server-rsa.crt"
|
||||
|
||||
subject = issuer = x509.Name([
|
||||
x509.NameAttribute(NameOID.COUNTRY_NAME, "US"),
|
||||
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "California"),
|
||||
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Test Organization"),
|
||||
x509.NameAttribute(NameOID.COMMON_NAME, domain),
|
||||
])
|
||||
|
||||
cert = (
|
||||
x509.CertificateBuilder()
|
||||
.subject_name(subject)
|
||||
.issuer_name(issuer)
|
||||
.public_key(private_key.public_key())
|
||||
.serial_number(x509.random_serial_number())
|
||||
.not_valid_before(datetime.datetime.utcnow())
|
||||
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
|
||||
.add_extension(
|
||||
x509.SubjectAlternativeName([
|
||||
x509.DNSName(domain),
|
||||
x509.DNSName(f"*.{domain}"),
|
||||
]),
|
||||
critical=False,
|
||||
)
|
||||
.add_extension(
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
critical=True,
|
||||
)
|
||||
.sign(private_key, hashes.SHA256())
|
||||
)
|
||||
|
||||
key_path = output_path / key_filename
|
||||
cert_path = output_path / cert_filename
|
||||
|
||||
key_path.write_bytes(
|
||||
private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
)
|
||||
|
||||
cert_path.write_bytes(cert.public_bytes(serialization.Encoding.PEM))
|
||||
|
||||
logger.info(f"Generated {key_type.upper()} certificate for {domain}")
|
||||
logger.info(f" Key: {key_path}")
|
||||
logger.info(f" Cert: {cert_path}")
|
||||
|
||||
return {
|
||||
"domain": domain,
|
||||
"key_type": key_type,
|
||||
"key_path": str(key_path),
|
||||
"cert_path": str(cert_path),
|
||||
"valid_days": 365,
|
||||
}
|
||||
|
||||
|
||||
def generate_nginx_config(
|
||||
domain: str, cert_path: str, key_path: str, enable_tls12: bool = True
|
||||
) -> str:
|
||||
"""Generate nginx TLS 1.3 configuration."""
|
||||
tls_protocols = "TLSv1.3"
|
||||
if enable_tls12:
|
||||
tls_protocols = "TLSv1.2 TLSv1.3"
|
||||
|
||||
tls12_ciphers = ":".join(RECOMMENDED_TLS_12_CIPHERS)
|
||||
|
||||
config = f"""# TLS 1.3 Optimized nginx Configuration
|
||||
# Generated for: {domain}
|
||||
# Mozilla SSL Configuration Generator: Modern profile
|
||||
|
||||
server {{
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {domain};
|
||||
|
||||
# Certificate paths
|
||||
ssl_certificate {cert_path};
|
||||
ssl_certificate_key {key_path};
|
||||
|
||||
# Protocol versions
|
||||
ssl_protocols {tls_protocols};
|
||||
|
||||
# TLS 1.2 cipher suites (TLS 1.3 ciphers are configured automatically)
|
||||
ssl_ciphers '{tls12_ciphers}';
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# ECDH curve
|
||||
ssl_ecdh_curve X25519:secp256r1:secp384r1;
|
||||
|
||||
# OCSP Stapling
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
# Session configuration
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
# Security headers
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-XSS-Protection "0" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Root and index
|
||||
root /var/www/{domain}/html;
|
||||
index index.html;
|
||||
|
||||
location / {{
|
||||
try_files $uri $uri/ =404;
|
||||
}}
|
||||
}}
|
||||
|
||||
# HTTP to HTTPS redirect
|
||||
server {{
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {domain};
|
||||
return 301 https://$server_name$request_uri;
|
||||
}}
|
||||
"""
|
||||
return config
|
||||
|
||||
|
||||
def generate_apache_config(
|
||||
domain: str, cert_path: str, key_path: str, enable_tls12: bool = True
|
||||
) -> str:
|
||||
"""Generate Apache TLS 1.3 configuration."""
|
||||
tls_protocols = "TLSv1.3"
|
||||
if enable_tls12:
|
||||
tls_protocols = "TLSv1.2 TLSv1.3"
|
||||
|
||||
tls12_ciphers = ":".join(RECOMMENDED_TLS_12_CIPHERS)
|
||||
|
||||
config = f"""# TLS 1.3 Optimized Apache Configuration
|
||||
# Generated for: {domain}
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName {domain}
|
||||
DocumentRoot /var/www/{domain}/html
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile {cert_path}
|
||||
SSLCertificateKeyFile {key_path}
|
||||
|
||||
# Protocol versions
|
||||
SSLProtocol all -{" -".join(["SSLv3", "TLSv1", "TLSv1.1"])}
|
||||
{"" if enable_tls12 else "SSLProtocol TLSv1.3"}
|
||||
|
||||
# Cipher suites
|
||||
SSLCipherSuite {tls12_ciphers}
|
||||
SSLHonorCipherOrder off
|
||||
|
||||
# OCSP Stapling
|
||||
SSLUseStapling on
|
||||
SSLStaplingCache shmcb:/var/run/ocsp(128000)
|
||||
|
||||
# Security headers
|
||||
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set X-Frame-Options "DENY"
|
||||
</VirtualHost>
|
||||
|
||||
# HTTP to HTTPS redirect
|
||||
<VirtualHost *:80>
|
||||
ServerName {domain}
|
||||
Redirect permanent / https://{domain}/
|
||||
</VirtualHost>
|
||||
"""
|
||||
return config
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="TLS 1.3 Configuration Tool")
|
||||
subparsers = parser.add_subparsers(dest="command")
|
||||
|
||||
# Test server
|
||||
test = subparsers.add_parser("test-server", help="Test TLS configuration of a server")
|
||||
test.add_argument("--host", required=True, help="Server hostname")
|
||||
test.add_argument("--port", type=int, default=443, help="Server port")
|
||||
|
||||
# Check ciphers
|
||||
ciphers = subparsers.add_parser("check-ciphers", help="Check supported cipher suites")
|
||||
ciphers.add_argument("--host", required=True, help="Server hostname")
|
||||
ciphers.add_argument("--port", type=int, default=443, help="Server port")
|
||||
|
||||
# Generate certificate
|
||||
cert = subparsers.add_parser("generate-cert", help="Generate self-signed certificate")
|
||||
cert.add_argument("--domain", required=True, help="Domain name")
|
||||
cert.add_argument("--output", default="./certs", help="Output directory")
|
||||
cert.add_argument("--key-type", choices=["ecdsa", "rsa"], default="ecdsa")
|
||||
|
||||
# Generate nginx config
|
||||
nginx = subparsers.add_parser("generate-nginx", help="Generate nginx TLS config")
|
||||
nginx.add_argument("--domain", required=True, help="Domain name")
|
||||
nginx.add_argument("--cert-path", required=True, help="Certificate file path")
|
||||
nginx.add_argument("--key-path", required=True, help="Private key file path")
|
||||
nginx.add_argument("--tls12", action="store_true", default=True, help="Enable TLS 1.2")
|
||||
|
||||
# Generate Apache config
|
||||
apache = subparsers.add_parser("generate-apache", help="Generate Apache TLS config")
|
||||
apache.add_argument("--domain", required=True, help="Domain name")
|
||||
apache.add_argument("--cert-path", required=True, help="Certificate file path")
|
||||
apache.add_argument("--key-path", required=True, help="Private key file path")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "test-server":
|
||||
result = test_tls_connection(args.host, args.port)
|
||||
print(json.dumps(result, indent=2, default=str))
|
||||
elif args.command == "check-ciphers":
|
||||
result = check_cipher_suites(args.host, args.port)
|
||||
print(json.dumps(result, indent=2))
|
||||
elif args.command == "generate-cert":
|
||||
result = generate_self_signed_cert(args.domain, args.output, args.key_type)
|
||||
print(json.dumps(result, indent=2))
|
||||
elif args.command == "generate-nginx":
|
||||
config = generate_nginx_config(args.domain, args.cert_path, args.key_path, args.tls12)
|
||||
print(config)
|
||||
elif args.command == "generate-apache":
|
||||
config = generate_apache_config(args.domain, args.cert_path, args.key_path)
|
||||
print(config)
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user