This commit includes: - SSL Manager implementation for certificate operations - Configuration file with UniFi device parameters - Test files for various components - Documentation for UniFi verification - Project guidelines
8.5 KiB
SSL Management Project Guidelines
This document provides guidelines for developing and maintaining the SSL Management project, which is a Python-based tool for managing SSL certificates for UniFi devices such as UDM-SE. The tool helps automate the process of obtaining, validating, and deploying SSL certificates to UniFi devices.
Build/Configuration Instructions
Prerequisites
- Python 3.6+: The project is written in Python and requires Python 3.6 or higher.
- OpenSSL: Required for certificate operations. Must be installed and available in your PATH.
- Virtual Environment: The project uses a virtual environment for dependency isolation.
- Linux Environment: The script is designed to run on Linux systems such as Ubuntu 24.04. While development can occur on any platform, deployment is expected on a Linux server.
Setup
-
Clone the repository:
git clone <repository-url> cd ssl-managment -
Create and activate a virtual environment:
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate -
No external Python packages are required as the project uses standard library modules.
Configuration
The SSL Manager uses a configuration file (config.json) to store default settings. The configuration file should be placed in the project root directory. Here's an example of the configuration file:
{
"cert_dir": "~/.ssl-certs",
"default_port": 443,
"connection_timeout": 3.0,
"default_validity_days": 365,
"key_size": 2048,
"unifi": {
"host": "unifi.example.com",
"username": "admin",
"password": "password",
"site": "default",
"ssh_port": 22,
"ssh_username": "root",
"ssh_password": "",
"ssh_key_path": "~/.ssh/id_rsa"
}
}
Configuration options:
cert_dir: Directory where certificates and keys will be storeddefault_port: Default port to use when checking certificate expirationconnection_timeout: Timeout in seconds for SSL connectionsdefault_validity_days: Default validity period in days for generated certificateskey_size: Key size in bits for generated certificatesunifi: UniFi device connection parametershost: Hostname or IP address of the UniFi deviceusername: Username for authenticating with the UniFi devicepassword: Password for authenticating with the UniFi devicesite: Site name for the UniFi device (default: 'default')ssh_port: SSH port for the UniFi device (default: 22)ssh_username: Username for SSH authentication with the UniFi devicessh_password: Password for SSH authentication (leave empty to use SSH key)ssh_key_path: Path to the SSH private key file for authentication
Usage
The SSL Manager provides three main commands. All commands support the following global options:
--config: Path to the config file (default: config.json)--cert-dir: Directory to store certificates (overrides config)
-
Check Certificate Expiration:
python src/ssl_manager.py check example.com [--port PORT]The
--portoption overrides thedefault_portfrom the config file. -
Generate Self-Signed Certificate:
python src/ssl_manager.py generate example.com [--days DAYS]The
--daysoption overrides thedefault_validity_daysfrom the config file. -
Validate Certificate Chain:
python src/ssl_manager.py validate path/to/certificate.crt [--ca-path path/to/ca.crt]
Testing Information
Running Tests
Tests are written using the Python unittest framework. To run all tests:
cd ssl-managment # Ensure you're in the project root
python -m unittest discover tests
To run a specific test file:
python -m tests.test_ssl_manager
Adding New Tests
-
Create a new test file in the
testsdirectory, following the naming conventiontest_*.py. -
Import the necessary modules and the
SSLManagerclass:import os import sys import unittest from unittest.mock import patch # Add the src directory to the Python path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src'))) from ssl_manager import SSLManager -
Create a test class that inherits from
unittest.TestCase:class TestYourFeature(unittest.TestCase): def setUp(self): # Set up test fixtures self.ssl_manager = SSLManager() def test_your_feature(self): # Test your feature result = self.ssl_manager.your_method() self.assertEqual(result, expected_value) -
Use mocking to avoid actual network or system calls:
@patch('ssl_manager.subprocess.run') def test_with_mock(self, mock_run): mock_run.return_value = MagicMock(returncode=0) # Test with mock
Test Example
Here's a simple test that verifies the SSLManager initializes correctly:
def test_init_creates_cert_dir(self):
"""Test that the constructor creates the certificate directory."""
test_path = os.path.expanduser("~/test-ssl-certs")
# Remove the directory if it exists
if os.path.exists(test_path):
os.rmdir(test_path)
# Create a new SSLManager with the test path
ssl_manager = SSLManager(cert_dir=test_path)
# Verify the directory was created
self.assertTrue(os.path.exists(test_path))
self.assertTrue(os.path.isdir(test_path))
# Clean up
os.rmdir(test_path)
Development Guidelines
Code Style
- PEP 8: Follow the PEP 8 style guide for Python code.
- Docstrings: Use docstrings for all modules, classes, and functions. Follow the Google style for docstrings.
- Type Hints: Use type hints for function parameters and return values.
Project Structure
src/: Contains the source codessl_manager.py: Main module with the SSLManager class
tests/: Contains test filestest_ssl_manager.py: Tests for the SSLManager class
Best Practices
- Error Handling: Use try-except blocks to handle exceptions gracefully.
- Logging: Use the Python logging module for logging instead of print statements.
- Testing: Write tests for all new features and bug fixes.
- Documentation: Update documentation when making changes to the code.
Deployment and Automation
Cross-Machine Deployment
The SSL Management tool can be developed on one machine and deployed to another server for production use. When deploying across machines:
- Ensure the target server meets all the prerequisites (Python 3.6+, OpenSSL, etc.)
- Transfer the entire project directory to the target server
- Set up the virtual environment on the target server
- Configure the
config.jsonfile with the appropriate settings for the target environment - Test the deployment by running a simple command like
python src/ssl_manager.py check <hostname>
Automated Certificate Updates
To automate certificate updates using cron:
-
Create a shell script wrapper for the SSL Manager:
#!/bin/bash # File: update_certificates.sh # Change to the project directory cd /path/to/ssl-managment # Activate the virtual environment source .venv/bin/activate # Run the SSL Manager to update certificates python src/ssl_manager.py generate your-unifi-device.example.com --days 90 # Additional commands to deploy the certificate to the UniFi device can be added here -
Make the script executable:
chmod +x update_certificates.sh -
Add a cron job to run the script periodically (e.g., every 60 days):
# Edit the crontab crontab -e # Add a line like this to run at 2:30 AM on the 1st of every other month 30 2 1 */2 * /path/to/update_certificates.sh >> /var/log/certificate-updates.log 2>&1 -
Verify the cron job is set up correctly:
crontab -l
Troubleshooting
Common Issues
-
OpenSSL Command Not Found
Ensure OpenSSL is installed and in your PATH.
-
Permission Denied When Creating Certificates
Check that you have write permissions to the certificate directory.
-
Import Errors in Tests
Make sure you're running tests from the project root directory.
Debugging
- Set the
SSL_DEBUG=1environment variable for verbose output - Check the OpenSSL version with
openssl version - Verify certificate paths are correct and accessible