Analyze TLS/SSL certificates, featuring profile detection, chain validation.
2.6K
A powerful, developer-friendly Python tool to analyze TLS/SSL certificates for any domain.
crt.sh for Certificate Transparency logs.pipx installs CLI tools in isolated environments, which is the safest way to install Python applications.
pipx install check-tls
pip install check-tls
Pull the latest image from Docker Hub or GHCR:
# From Docker Hub
docker pull obeoneorg/check-tls:latest
# Or from GHCR.io
docker pull ghcr.io/obeone/check-tls:latest
Running the Container
You can run the tool in either CLI mode or as a web server.
1. CLI Mode
To analyze a domain, pass it as a command to the container:
docker run --rm obeoneorg/check-tls:latest example.com
To output to a file on your host machine, mount a volume:
# Create a reports directory first: mkdir -p reports
docker run --rm -v "$(pwd)/reports:/app/reports" \
obeoneorg/check-tls:latest example.com -j /app/reports/report.json
2. Web Server Mode
To run the interactive web UI, use the --server flag and map the port:
docker run --rm -p 8000:8000 obeoneorg/check-tls:latest --server
The web interface will be available at http://localhost:8000β . The server listens on all interfaces, so you can also access it via http://<your-ip>:8000.
Example: Command-line output for analyzing a domain (including OCSP status)
Analyze a single domain:
check-tls example.com
Analyze a domain with a specific port:
# The port in the URL overrides the default or --connect-port
check-tls https://example.net:9000
Analyze multiple domains and output to a JSON file:
check-tls google.com https://github.com:443 -j report.json
The CLI provides human-readable output by default. Use -j for JSON and -c for CSV. When analyzing multiple domains, a progress indicator will be displayed.
Key Options:
-j, --json FILE: Output JSON to a file (use "-" for stdout).-c, --csv FILE: Output CSV to a file (use "-" for stdout).-P, --connect-port PORT: Port for TLS analysis (default: 443). Overridden by port in domain/URL.-m, --mode [simple|full]: Analysis mode. simple checks the leaf certificate only; full fetches intermediates (default).-l, --loglevel LEVEL: Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).-k, --insecure: Allow self-signed or invalid certificates.-s, --server: Launch the web UI.-p, --port PORT: Web server port for the UI (default: 8000).--no-transparency: Skip certificate transparency check.--no-crl-check: Skip CRL check.--no-ocsp-check: Disable OCSP revocation check.--no-caa-check: Disable DNS CAA check.To launch the interactive web interface, use the --server flag:
check-tls --server
Then, open http://localhost:8000β in your browser. The server listens on all network interfaces (IPv4 & IPv6).
The tool provides a REST API for programmatic analysis. When launched with --server, the API is available.
/api/analyzePOSTapplication/jsonRequest Body:
domains (array of strings, required): List of domains to analyze (e.g., ["example.com", "google.com:443"]).connect_port (integer, optional): Default port to connect to if not specified in the domain string. Defaults to 443.insecure (boolean, optional): Allow insecure (self-signed) certificates.no_transparency (boolean, optional): Skip certificate transparency check.no_crl_check (boolean, optional): Disable CRL check.no_ocsp_check (boolean,optional): Disable OCSP check.no_caa_check (boolean, optional): Disable CAA check.curl -X POST http://localhost:8000/api/analyze \
-H "Content-Type: application/json" \
-d '{"domains": ["example.com", "google.com"], "insecure": true, "no_transparency": true}'
[
{
"domain": "example.com:443",
"status": "completed",
"analysis_timestamp": "2025-04-26T08:30:00+00:00",
"connection_health": { ... },
"validation": { ... },
"certificates": [ ... ],
"crl_check": { ... },
"transparency": { ... },
"ocsp_check": { ... },
"caa_check": { ... }
}
]
The tool provides the following OCSP statuses for the leaf certificate:
good: The certificate is valid according to its OCSP responder.revoked: The certificate has been revoked.unknown: The OCSP responder does not have status information for the certificate.error: An error occurred during the OCSP check (e.g., network issue, responder unavailable).no_ocsp_url: The certificate does not contain an OCSP URI.skipped: The OCSP check was disabled or not applicable.
Example: HTML-based interactive certificate analysis (including OCSP status)
Starting from version 1.8.0, check-tls includes built-in protection against Server-Side Request Forgery (SSRF) attacks. By default, the tool blocks connections to private and internal IP addresses to prevent malicious users from:
Blocked IP Ranges:
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16127.0.0.0/8169.254.0.0/16SECURITY.md for complete list)For legitimate internal network analysis (e.g., in development or private infrastructure), you can disable SSRF protection using the ALLOW_INTERNAL_IPS environment variable:
# Allow analysis of internal IPs
export ALLOW_INTERNAL_IPS=true
check-tls 192.168.1.1
# Or inline for a single command
ALLOW_INTERNAL_IPS=true check-tls 10.0.0.50:8443
# For the web server
ALLOW_INTERNAL_IPS=true check-tls --server
β οΈ Security Warning:
ALLOW_INTERNAL_IPS=true in production environmentsSECURITY.md for detailed security documentation and best practicescheck-tls supports shell completion for bash, zsh, and fish. To enable it, add the appropriate command to your shell's configuration file (~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish).
Bash:
eval "$(check-tls --print-completion bash)"
Zsh:
eval "$(check-tls --print-completion zsh)"
Fish:
check-tls --print-completion fish | source
The project follows the standard src layout for packaging.
check-tls/
βββ src/
β βββ check_tls/
β βββ __init__.py
β βββ main.py # CLI entry point
β βββ tls_checker.py # Core analysis logic
β βββ web_server.py # Flask web server and API
β βββ static/ # CSS/JS for web UI
β βββ templates/ # HTML templates for web UI
β βββ utils/ # Utility modules
β βββ __init__.py
β βββ cert_utils.py
β βββ crl_utils.py
β βββ crtsh_utils.py
β βββ dns_utils.py
β βββ ocsp_utils.py
βββ pyproject.toml # Project metadata and dependencies
βββ Dockerfile
βββ LICENSE
βββ README.md
Q: What's the difference between --port and --connect-port?
A: --port (or -p) specifies the port for the web server UI (--server mode). --connect-port (or -P) specifies the default port for the TLS connection to the target domain.
Q: What does "No CDP" or "No OCSP URL" mean?
A: This means the certificate does not contain a URL for its Certificate Revocation List (CRL) or an OCSP responder. This is common and not necessarily an error, but it prevents the tool from performing that specific revocation check.
Q: How do I analyze a server that uses a self-signed certificate?
A: Use the -k or --insecure flag. This tells the tool to connect without validating the certificate against a trusted authority, which is necessary for self-signed certs.
Q: Can I use this tool without Python installed?
A: Yes! The Docker image provides a self-contained environment with all dependencies. See the "With Docker" section for instructions.
Q: How do I get JSON or CSV output?
A: Use -j file.json or -c file.csv. Use - as the filename to print to standard output.
Q: Can I analyze internal/private IP addresses?
A: By default, check-tls blocks connections to private IP ranges (192.168.x.x, 10.x.x.x, etc.) for security reasons. To analyze internal hosts in development/testing environments, use: ALLOW_INTERNAL_IPS=true check-tls 192.168.1.1. Never use this in production! See the Security section for more details.
Q: Why am I getting "Blocked connection to private/internal IP" errors?
A: This is the built-in SSRF protection. If you need to analyze internal hosts (e.g., in a development environment), use the ALLOW_INTERNAL_IPS=true environment variable. See the Security section for details and warnings.
Problem: ssl.SSLCertVerificationError
-k or --insecure flag to bypass validation. For production systems, this error indicates a misconfiguration that should be fixed.Problem: Connection Errors (Connection refused, timed out, gaierror)
Connection refused: The server is not listening on the specified port.timed out: The server is unreachable, or a firewall is blocking the connection.gaierror or Name or service not known: The domain name could not be resolved by DNS.Problem: ModuleNotFoundError or import errors.
pip install .). When running from source, use python -m check_tls.main ....Problem: Shell completion isn't working.
.bashrc, .zshrc, etc.) and have restarted your shell. For Fish, the completion file must be placed in the correct directory.Problem: Docker container exits immediately.
--server. For example: docker run --rm obeoneorg/check-tls:latest example.com.src/check_tls/.from check_tls.utils import ....pip install -e .. This allows you to test changes without reinstalling.python -m check_tls.main [OPTIONS].Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
MIT License Β© GrΓ©goire Compagnon (obeone)
To publish a new version to PyPI, create a new release on GitHub. The GitHub Actions workflow will build and publish the package automatically if the release tag matches the version in pyproject.toml.
See .github/workflows/publish-to-pypi.yaml for details.
Content type
Image
Digest
sha256:5659522ecβ¦
Size
251 Bytes
Last updated
2 months ago
docker pull obeoneorg/check-tls:sha256-a71df5efcafb1e2a0b3ceb2c227c70c28764d9acbb6913c315333ec572200145.sig