Update guidelines.md with Approaches Considered and Lessons Learned section

This commit is contained in:
Mike Geppert 2025-07-20 23:35:05 -05:00
parent e39e002351
commit 6ddbfb93fe

View File

@ -297,6 +297,93 @@ def test_init_creates_cert_dir(self):
3. **Testing**: Write tests for all new features and bug fixes.
4. **Documentation**: Update documentation when making changes to the code.
## Approaches Considered and Lessons Learned
This section documents approaches that were tried during development but were modified or replaced because they didn't fully meet requirements. Understanding these decisions can help future developers avoid repeating work on approaches that have already been determined to be unsuitable.
### Certificate Generation Approaches
#### Self-Signed Certificates vs. Let's Encrypt
Initially, the project used self-signed certificates as the default certificate type. While self-signed certificates are easy to generate and don't require external validation, they have several limitations:
- Browsers display security warnings for self-signed certificates
- Each client device must manually trust the certificate
- No automatic renewal process
- Not suitable for production environments accessed by multiple users
The project switched to Let's Encrypt certificates as the default because they:
- Are trusted by browsers without warnings
- Support automatic renewal
- Provide better security assurances
- Are free and widely supported
Self-signed certificates are still supported with the `--type self-signed` option for testing or internal networks where Let's Encrypt validation isn't possible.
#### Let's Encrypt Staging vs. Production Environment
During initial development, the project used Let's Encrypt's staging environment by default (`use_staging: true` in config.json). The staging environment has higher rate limits but issues certificates that aren't trusted by browsers.
This approach was changed to use the production environment by default (`use_staging: false`) because:
- Production certificates are trusted by browsers without warnings
- Most users want trusted certificates for production use
- The staging environment is primarily useful for testing and development
The `--staging` flag is still available for testing purposes to avoid hitting rate limits during development.
### HTTP Validation Approaches
#### Default Port 80 vs. Configurable Port
Initially, the Let's Encrypt validation using the standalone method required port 80, which needs root privileges. This was problematic because:
- Running the script as root introduces security concerns
- Many users don't have root access on their servers
- Port 80 might already be in use by a web server
The solution was to add support for configurable HTTP ports through:
- The `http_port` configuration option in the Let's Encrypt section of config.json
- The `--http-port` command-line option
This allows users to specify a non-privileged port (e.g., 8080) for HTTP validation, eliminating the need for root privileges.
### DNS Validation Approaches
#### Manual DNS Checking vs. Automated Validation
The project initially relied on Let's Encrypt's built-in validation to check if a hostname is in public DNS. However, this led to confusing error messages when validation failed.
To improve the user experience, the project added a pre-validation step that:
- Resolves the hostname to an IP address
- Checks if the IP is public (not in private IP ranges)
- Provides a clear error message if the hostname isn't in public DNS
This approach helps users identify DNS issues before attempting certificate generation, saving time and avoiding Let's Encrypt rate limits.
### UniFi Device Connection Approaches
#### UnifiControl Library
The project attempted to use the unifiControl Python library to interact with UniFi devices. However, this approach encountered several challenges:
- Authentication issues (401 Unauthorized errors)
- Potential API version compatibility issues
- Limited flexibility for different UniFi device configurations
Instead of relying solely on the unifiControl library, the project adopted a more flexible approach:
- Storing UniFi connection parameters in the config file
- Supporting both API-based authentication and SSH-based authentication
- Allowing users to customize connection parameters based on their specific UniFi device
This approach provides more flexibility and reliability across different UniFi device types and configurations.
### Lessons Learned
1. **Prioritize user experience**: Choose defaults that work for most users without configuration (e.g., production Let's Encrypt environment).
2. **Provide flexibility**: Support multiple approaches (self-signed vs. Let's Encrypt, different validation methods) to accommodate various use cases.
3. **Minimize dependencies**: Avoid relying on external libraries when possible to reduce compatibility issues.
4. **Clear error messages**: Provide specific, actionable error messages to help users troubleshoot issues.
5. **Pre-validate inputs**: Check requirements (like DNS entries) early to provide better feedback before attempting operations that might fail.
## Deployment and Automation
### Cross-Machine Deployment